1
/**********************************************************************
2
** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
4
** This file is part of Qt Designer.
6
** This file may be distributed and/or modified under the terms of the
7
** GNU General Public License version 2 as published by the Free Software
8
** Foundation and appearing in the file LICENSE.GPL included in the
9
** packaging of this file.
11
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
12
** licenses may use this file in accordance with the Qt Commercial License
13
** Agreement provided with the Software.
15
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
** See http://www.trolltech.com/gpl/ for GPL licensing information.
19
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
20
** information about Qt Commercial License Agreements.
22
** Contact info@trolltech.com if any conditions of this licensing are
25
**********************************************************************/
34
#include <qdatetime.h>
40
#include <qsizepolicy.h>
43
The .uib file format is the binary counterpart of the .ui file
44
format. It is generated by the ui2uib converter and understood by
45
QWidgetFactory; in a future version, it might also be understood
46
by a uib2ui converter. Experiments show that .uib files are about
47
2.5 times faster to load and 6 times smaller than .ui files.
49
The .uib format, unlike the .ui format, is internal to Trolltech
50
and is not officially documented; it is assumed that anybody who
51
needs to understand the file format can read the ui2uib and
52
QWidgetFactory source code, with some guidance. And here's some
55
A .uib file starts with a 32-bit magic number that allows
56
QWidgetFactory to determine the file type. The magic number is
57
followed by '\n' (0x0a) and '\r' (0x0d), which ensure that the
58
file wasn't corrupted during transfer between different
59
platforms. For example, transferring a .ui file from Windows to
60
Unix using FTP with type ASCII will produce a file with '\r\n\r'
61
in place of '\n\r'. This is followed by the QDataStream format
64
The rest of the file is made up of blocks, each of which starts
65
with a block type (Block_XXX) and a block length. Block_Intro and
66
Block_Widget are mandatory; the others are optional.
67
QWidgetFactory makes certain assumptions about the order of the
68
blocks; for example, it expects Block_String before any other
69
block that refers to a string and Block_Images before
70
Block_Widget. The order generated by ui2uib is one of the orders
71
that make sense. Just after the last block, a Block_End marker
72
indicates the end of the file.
74
The division of .uib files into blocks corresponds grossly to the
75
division of .ui files in top-level XML elements. Thus,
76
Block_Widget corresponds to <widget> and Block_Toolbars to
77
<toolbars>. The internal organization of each block also mimics
78
the organization of the corresponding XML elements.
80
These are the major differences, all of which contribute to
81
making .uib files more compact:
83
1. The strings are gathered in Block_Strings, a string-table.
84
When a string is needed later, it is referenced by a 32-bit
85
index into that table. The UicStringTable class makes the
86
whole process of inserting and looking up strings very
87
simple. The advantage of this scheme is that if a string is
88
used more than once, it is stored only once. Also, the
89
string-table is preinitialized with very common strings, so
90
that these need not be stored along with .uib files.
92
2. QObjects are referred to by index in a table rather than by
93
name. The table itself is not stored in the .uib file; it is
94
rather build dynamically by ui2uib and QWidgetFactory as new
95
objects are specified. In ui2uib, the table is represented by
96
a UibIndexMap object; in QWidgetFactory, a plain array of
97
QObject pointers suffices.
99
3. The data is packed to take as little place as possible,
100
without slowing down QLayoutFactory too much. For example, an
101
index into the string-table is a 32-bit integer, but in
102
practice it is rarely above 65534, so only 16 bits are used
103
for them; when an index above 65534 is met, the index is
104
saved as 65535 followed by the 32-bit index, for a total of
107
4. The name of a signal or slot and its signature are saved
108
separately. That way, if a signal 'foo(const QString&)' is
109
connected to a slot 'bar(const QString&)', the string-table
110
will only contain 'foo', 'bar', and '(const QString&)',
111
instead of the longer 'foo(const QString&)' and 'bar(const
112
QString&)'. The signatures are normalized beforehand to
113
ensure that trivial spacing problems don't result in multiple
114
string-table entries.
116
5. In a signal-to-slot connection, a sender, signal, receiver,
117
or slot is not repeated if it's the same as for the previous
118
connection. Bit flags indicate what is repeated and what is
121
6. Some of the information stored in a .ui file is useful only
122
by uic, not to QLayoutFactory. That information is, for now,
123
not taken along in the .uib file. Likewise, needless
124
QLayoutWidget objects are not taken along.
126
The arbitrary constants related to the .uib file formats are
127
defined in uib.h. Constants such as Block_Actions and
128
Object_SubWidget are given values such as 'A' and 'W' to make
129
.uib files easier to read in a hexadecimal editor.
131
The file format isn't designed to be extensible. Any extension
132
that prevents an older version of QLayoutWidget of reading the
133
file correctly must have a different magic number. The plan is to
134
use UibMagic + 1 for version 2, UibMagic + 2 for version 3, etc.
137
static QCString layoutForTag( const QString& tag )
139
if ( tag == "grid" ) {
140
return "QGridLayout";
141
} else if ( tag == "hbox" ) {
142
return "QHBoxLayout";
143
} else if ( tag == "vbox" ) {
144
return "QVBoxLayout";
150
class UibHack : public QObject
153
static QString normalize( const QString& member ) {
154
return QString::fromUtf8( QObject::normalizeSignalSlot(member.utf8()) );
161
UibIndexMap() : next( 0 ) { }
163
void insert( const QString& name ) { setName( insert(), name ); }
164
int insert() { return next++; }
165
void setName( int no, const QString& name );
167
int find( const QString& name, int deflt = -1 ) const;
168
int count() const { return next; }
171
QMap<QString, int> nameMap;
172
QMap<QString, int> conflicts;
176
void UibIndexMap::setName( int no, const QString& name )
178
if ( !name.isEmpty() ) {
179
if ( *nameMap.insert(name, no, FALSE) != no )
180
conflicts.insert( name, 0 );
184
int UibIndexMap::find( const QString& name, int deflt ) const
186
QMap<QString, int>::ConstIterator no = nameMap.find( name );
187
if ( no == nameMap.end() || conflicts.contains(name) ) {
194
static void packUInt16( QDataStream& out, Q_UINT16 n )
199
out << (Q_UINT8) 255;
204
static void packUInt32( QDataStream& out, Q_UINT32 n )
209
out << (Q_UINT16) 65535;
214
static void packByteArray( QDataStream& out, const QByteArray& array )
216
packUInt32( out, array.size() );
217
out.writeRawBytes( array.data(), array.size() );
220
static void packCString( UibStrTable& strings, QDataStream& out,
223
packUInt32( out, strings.insertCString(cstr) );
226
static void packString( UibStrTable& strings, QDataStream& out,
229
packUInt32( out, strings.insertString(str) );
232
static void packStringSplit( UibStrTable& strings, QDataStream& out,
233
const QString& str, QChar sep )
235
int pos = str.find( sep );
238
packString( strings, out, str.left(pos) );
239
packString( strings, out, str.mid(pos) );
242
static void packVariant( UibStrTable& strings, QDataStream& out,
243
QVariant value, QString tag = "" )
245
QStringList::ConstIterator s;
247
Q_UINT8 type = value.type();
248
if ( tag == "pixmap" ) {
249
type = QVariant::Pixmap;
250
} else if ( tag == "image" ) {
251
type = QVariant::Image;
252
} else if ( tag == "iconset" ) {
253
type = QVariant::IconSet;
258
case QVariant::String:
259
case QVariant::Pixmap:
260
case QVariant::Image:
261
case QVariant::IconSet:
262
packString( strings, out, value.asString() );
264
case QVariant::StringList:
265
packUInt16( out, value.asStringList().count() );
266
s = value.asStringList().begin();
267
while ( s != value.asStringList().end() ) {
268
packString( strings, out, *s );
273
out << value.asFont();
276
packUInt16( out, value.asRect().x() );
277
packUInt16( out, value.asRect().y() );
278
packUInt16( out, value.asRect().width() );
279
packUInt16( out, value.asRect().height() );
282
packUInt16( out, value.asSize().width() );
283
packUInt16( out, value.asSize().height() );
285
case QVariant::Color:
286
out << value.asColor();
288
case QVariant::Point:
289
packUInt16( out, value.asPoint().x() );
290
packUInt16( out, value.asPoint().y() );
293
packUInt32( out, value.asInt() );
296
out << (Q_UINT8) value.asBool();
298
case QVariant::Double:
299
out << value.asDouble();
301
case QVariant::CString:
302
packCString( strings, out, value.asCString() );
304
case QVariant::Cursor:
305
out << value.asCursor();
308
out << value.asDate();
311
out << value.asTime();
313
case QVariant::DateTime:
314
out << value.asDateTime();
321
static void outputProperty( QMap<int, QStringList>& buddies, int objectNo,
322
UibStrTable& strings, QDataStream& out,
325
QCString name = elem.attribute( "name" ).latin1();
326
QDomElement f = elem.firstChild().toElement();
327
QString tag = f.tagName();
331
if ( name == "resizeable" )
334
if ( tag == "font" ) {
336
Q_UINT16 pointSize = 65535;
337
Q_UINT8 fontFlags = 0;
339
QDomElement g = f.firstChild().toElement();
340
while ( !g.isNull() ) {
341
QString text = g.firstChild().toText().data();
342
if ( g.tagName() == "family" ) {
343
fontFlags |= Font_Family;
345
} else if ( g.tagName() == "pointsize" ) {
346
fontFlags |= Font_PointSize;
347
pointSize = (Q_UINT16) text.toUInt();
349
if ( g.firstChild().toText().data().toInt() != 0 ) {
350
if ( g.tagName() == "bold" ) {
351
fontFlags |= Font_Bold;
352
} else if ( g.tagName() == "italic" ) {
353
fontFlags |= Font_Italic;
354
} else if ( g.tagName() == "underline" ) {
355
fontFlags |= Font_Underline;
356
} else if ( g.tagName() == "strikeout" ) {
357
fontFlags |= Font_StrikeOut;
361
g = g.nextSibling().toElement();
364
out << (Q_UINT8) Object_FontProperty;
365
packCString( strings, out, name );
367
if ( fontFlags & Font_Family )
368
packString( strings, out, family );
369
if ( fontFlags & Font_PointSize )
370
packUInt16( out, pointSize );
371
} else if ( tag == "palette" ) {
372
out << (Q_UINT8) Object_PaletteProperty;
373
packCString( strings, out, name );
375
QDomElement g = f.firstChild().toElement();
376
while ( !g.isNull() ) {
377
QDomElement h = g.firstChild().toElement();
378
while ( !h.isNull() ) {
379
value = DomTool::elementToVariant( h, Qt::gray );
380
if ( h.tagName() == "color" ) {
381
out << (Q_UINT8) Palette_Color;
382
out << value.asColor();
383
} else if ( h.tagName() == "pixmap" ) {
384
out << (Q_UINT8) Palette_Pixmap;
385
packVariant( strings, out, value, "pixmap" );
387
h = h.nextSibling().toElement();
390
if ( g.tagName() == "active" ) {
391
out << (Q_UINT8) Palette_Active;
392
} else if ( g.tagName() == "inactive" ) {
393
out << (Q_UINT8) Palette_Inactive;
395
out << (Q_UINT8) Palette_Disabled;
397
g = g.nextSibling().toElement();
399
out << (Q_UINT8) Palette_End;
401
value = DomTool::elementToVariant( f, value, comment );
402
if ( value.isValid() ) {
403
if ( name == "buddy" ) {
404
buddies[objectNo] += value.asString();
406
if ( tag == "string" ) {
407
out << (Q_UINT8) Object_TextProperty;
408
packCString( strings, out, name );
409
packCString( strings, out, value.asString().utf8() );
410
packCString( strings, out, comment.utf8() );
412
out << (Q_UINT8) Object_VariantProperty;
413
packCString( strings, out, name );
414
packVariant( strings, out, value, tag );
421
static void outputGridCell( QDataStream& out, QDomElement elem )
423
int column = elem.attribute( "column", "0" ).toInt();
424
int row = elem.attribute( "row", "0" ).toInt();
425
int colspan = elem.attribute( "colspan", "1" ).toInt();
426
int rowspan = elem.attribute( "rowspan", "1" ).toInt();
432
if ( column != 0 || row != 0 || colspan != 1 || rowspan != 1 ) {
433
out << (Q_UINT8) Object_GridCell;
434
packUInt16( out, column );
435
packUInt16( out, row );
436
packUInt16( out, colspan );
437
packUInt16( out, rowspan );
441
static int outputObject( QMap<int, QStringList>& buddies,
442
UibIndexMap& objects, UibStrTable& strings,
443
QDataStream& out, QDomElement elem,
444
QCString className = "" );
446
static void outputLayoutWidgetsSubLayout( QMap<int, QStringList>& buddies,
447
UibIndexMap& objects,
448
UibStrTable& strings,
449
QDataStream& out, QDomElement elem )
451
int subLayoutNo = -1;
453
QDomElement nameElem;
455
QDomElement f = elem.firstChild().toElement();
456
while ( !f.isNull() ) {
457
QString tag = f.tagName();
458
if ( tag == "grid" || tag == "hbox" || tag == "vbox" ) {
459
out << (Q_UINT8) Object_SubLayout;
460
subLayoutNo = outputObject( buddies, objects, strings, out, f,
462
} else if ( tag == "property" ) {
463
if ( f.attribute("name") == "name" ) {
464
name = DomTool::elementToVariant( f, name ).asCString();
468
f = f.nextSibling().toElement();
471
if ( subLayoutNo != -1 ) {
473
Remove the sub-layout's Object_End marker, append the grid
474
cell and the correct name property, and put the Object_End
477
out.device()->at( out.device()->at() - 1 );
478
outputGridCell( out, elem );
479
outputProperty( buddies, subLayoutNo, strings, out, nameElem );
480
out << (Q_UINT8) Object_End;
482
objects.setName( subLayoutNo, name );
486
static int outputObject( QMap<int, QStringList>& buddies,
487
UibIndexMap& objects, UibStrTable& strings,
488
QDataStream& out, QDomElement elem,
491
bool isQObject = !className.isEmpty();
493
if ( className == "QToolBar" )
494
out << (Q_UINT8) elem.attribute( "dock", "0" ).toInt();
495
if ( className == "QWidget" )
496
className = elem.attribute( "class", className ).latin1();
500
packCString( strings, out, className );
501
objectNo = objects.insert();
504
outputGridCell( out, elem );
506
// optimization: insert '&Foo' into string-table before 'Foo'
507
if ( className == "QAction" || className == "QActionGroup" ) {
508
QVariant value = DomTool::readProperty( elem, "menuText", QVariant() );
509
if ( value.asString().startsWith("&") )
510
strings.insertString( value.asString() );
513
QDomElement f = elem.firstChild().toElement();
514
while ( !f.isNull() ) {
515
QString tag = f.tagName();
516
if ( tag == "action" ) {
517
if ( elem.tagName() == "item" || elem.tagName() == "toolbar" ) {
518
QString actionName = f.attribute( "name" );
519
int no = objects.find( actionName );
521
out << (Q_UINT8) Object_ActionRef;
522
packUInt16( out, no );
525
out << (Q_UINT8) Object_SubAction;
526
outputObject( buddies, objects, strings, out, f, "QAction" );
528
} else if ( tag == "actiongroup" ) {
529
out << (Q_UINT8) Object_SubAction;
530
outputObject( buddies, objects, strings, out, f, "QActionGroup" );
531
} else if ( tag == "attribute" ) {
532
out << (Q_UINT8) Object_Attribute;
533
outputProperty( buddies, objectNo, strings, out, f );
534
} else if ( tag == "column" ) {
535
out << (Q_UINT8) Object_Column;
536
outputObject( buddies, objects, strings, out, f );
537
} else if ( tag == "event" ) {
538
out << (Q_UINT8) Object_Event;
539
packCString( strings, out, f.attribute("name").latin1() );
540
packVariant( strings, out,
541
QStringList::split(',', f.attribute("functions")) );
542
} else if ( tag == "grid" || tag == "hbox" || tag == "vbox" ) {
543
out << (Q_UINT8) Object_SubLayout;
544
outputObject( buddies, objects, strings, out, f,
546
} else if ( tag == "item" ) {
547
if ( elem.tagName() == "menubar" ) {
548
out << (Q_UINT8) Object_MenuItem;
549
packCString( strings, out, f.attribute("name").latin1() );
550
packCString( strings, out, f.attribute("text").utf8() );
551
outputObject( buddies, objects, strings, out, f );
553
out << (Q_UINT8) Object_Item;
554
outputObject( buddies, objects, strings, out, f );
556
} else if ( tag == "property" ) {
557
outputProperty( buddies, objectNo, strings, out, f );
558
} else if ( tag == "row" ) {
559
out << (Q_UINT8) Object_Row;
560
outputObject( buddies, objects, strings, out, f );
561
} else if ( tag == "separator" ) {
562
out << (Q_UINT8) Object_Separator;
563
} else if ( tag == "spacer" ) {
564
out << (Q_UINT8) Object_Spacer;
565
outputObject( buddies, objects, strings, out, f );
566
} else if ( tag == "widget" ) {
567
if ( f.attribute("class") == "QLayoutWidget" &&
568
elem.tagName() != "widget" ) {
569
outputLayoutWidgetsSubLayout( buddies, objects, strings, out,
572
out << (Q_UINT8) Object_SubWidget;
573
outputObject( buddies, objects, strings, out, f, "QWidget" );
576
f = f.nextSibling().toElement();
578
out << (Q_UINT8) Object_End;
580
objects.setName( objectNo,
581
DomTool::readProperty(elem, "name", "").asString() );
585
static void outputBlock( QDataStream& out, BlockTag tag,
586
const QByteArray& data )
588
if ( !data.isEmpty() ) {
589
out << (Q_UINT8) tag;
590
packByteArray( out, data );
594
void convertUiToUib( QDomDocument& doc, QDataStream& out )
596
QByteArray introBlock;
597
QByteArray actionsBlock;
598
QByteArray buddiesBlock;
599
QByteArray connectionsBlock;
600
QByteArray functionsBlock;
601
QByteArray imagesBlock;
602
QByteArray menubarBlock;
603
QByteArray slotsBlock;
604
QByteArray tabstopsBlock;
605
QByteArray toolbarsBlock;
606
QByteArray variablesBlock;
607
QByteArray widgetBlock;
609
QDomElement actionsElem;
610
QDomElement connectionsElem;
611
QDomElement imagesElem;
612
QDomElement menubarElem;
613
QDomElement tabstopsElem;
614
QDomElement toolbarsElem;
615
QDomElement widgetElem;
617
QMap<int, QStringList> buddies;
622
Q_INT16 defaultMargin = -32768;
623
Q_INT16 defaultSpacing = -32768;
624
Q_UINT8 introFlags = 0;
626
QDomElement elem = doc.firstChild().toElement().firstChild().toElement();
627
while ( !elem.isNull() ) {
628
QString tag = elem.tagName();
630
switch ( tag[0].latin1() ) {
632
if ( tag == "actions" )
636
if ( tag == "class" ) {
637
className = elem.firstChild().toText().data().latin1();
638
} else if ( tag == "connections" ) {
639
connectionsElem = elem;
643
if ( tag == "functions" ) {
644
QDataStream out2( functionsBlock, IO_WriteOnly );
645
QDomElement f = elem.firstChild().toElement();
646
while ( !f.isNull() ) {
647
if ( f.tagName() == "function" ) {
648
packStringSplit( strings, out2,
649
f.attribute("name").latin1(), '(' );
650
packString( strings, out2,
651
f.firstChild().toText().data() );
653
f = f.nextSibling().toElement();
658
if ( tag == "images" ) {
659
QDataStream out2( imagesBlock, IO_WriteOnly );
660
QDomElement f = elem.firstChild().toElement();
661
while ( !f.isNull() ) {
662
if ( f.tagName() == "image" ) {
663
QString name = f.attribute( "name" );
664
QDomElement g = f.firstChild().toElement();
665
if ( g.tagName() == "data" ) {
666
QString format = g.attribute( "format", "PNG" );
667
QString hex = g.firstChild().toText().data();
668
int n = hex.length() / 2;
669
QByteArray data( n );
670
for ( int i = 0; i < n; i++ )
671
data[i] = (char) hex.mid( 2 * i, 2 )
674
packString( strings, out2, name );
675
packString( strings, out2, format );
676
packUInt32( out2, g.attribute("length").toInt() );
677
packByteArray( out2, data );
680
f = f.nextSibling().toElement();
685
if ( tag == "layoutdefaults" ) {
686
QString margin = elem.attribute( "margin" );
687
if ( !margin.isEmpty() )
688
defaultMargin = margin.toInt();
689
QString spacing = elem.attribute( "spacing" );
690
if ( !spacing.isEmpty() )
691
defaultSpacing = spacing.toInt();
695
if ( tag == "menubar" )
699
if ( tag == "pixmapinproject" )
700
introFlags |= Intro_Pixmapinproject;
703
if ( tag == "slots" ) {
704
QDataStream out2( slotsBlock, IO_WriteOnly );
705
QDomElement f = elem.firstChild().toElement();
706
while ( !f.isNull() ) {
707
if ( f.tagName() == "slot" ) {
708
QString language = f.attribute( "language", "C++" );
709
QString slot = UibHack::normalize(
710
f.firstChild().toText().data() );
711
packString( strings, out2, language );
712
packStringSplit( strings, out2, slot, '(' );
714
f = f.nextSibling().toElement();
719
if ( tag == "tabstops" ) {
721
} else if ( tag == "toolbars" ) {
726
if ( tag == "variable" ) {
727
QDataStream out2( variablesBlock, IO_WriteOnly | IO_Append );
728
packString( strings, out2, elem.firstChild().toText().data() );
729
} else if ( tag == "variables" ) {
730
QDataStream out2( variablesBlock, IO_WriteOnly );
731
QDomElement f = elem.firstChild().toElement();
732
while ( !f.isNull() ) {
733
if ( f.tagName() == "variable" )
734
packString( strings, out2,
735
f.firstChild().toText().data() );
736
f = f.nextSibling().toElement();
741
if ( tag == "widget" )
744
elem = elem.nextSibling().toElement();
748
QDataStream out2( widgetBlock, IO_WriteOnly );
749
widgetNo = outputObject( buddies, objects, strings, out2, widgetElem,
753
if ( !tabstopsElem.isNull() ) {
754
QDataStream out2( tabstopsBlock, IO_WriteOnly );
755
QDomElement f = tabstopsElem.firstChild().toElement();
756
while ( !f.isNull() ) {
757
if ( f.tagName() == "tabstop" ) {
758
QString widgetName = f.firstChild().toText().data();
759
int no = objects.find( widgetName );
761
packUInt16( out2, no );
763
f = f.nextSibling().toElement();
767
if ( !actionsElem.isNull() ) {
768
QDataStream out2( actionsBlock, IO_WriteOnly );
769
outputObject( buddies, objects, strings, out2, actionsElem );
772
if ( !menubarElem.isNull() ) {
773
QDataStream out2( menubarBlock, IO_WriteOnly );
774
outputObject( buddies, objects, strings, out2, menubarElem,
778
if ( !toolbarsElem.isNull() ) {
779
QDataStream out2( toolbarsBlock, IO_WriteOnly );
780
QDomElement f = toolbarsElem.firstChild().toElement();
781
while ( !f.isNull() ) {
782
if ( f.tagName() == "toolbar" )
783
outputObject( buddies, objects, strings, out2, f, "QToolBar" );
784
f = f.nextSibling().toElement();
788
if ( !buddies.isEmpty() ) {
789
QDataStream out2( buddiesBlock, IO_WriteOnly );
790
QMap<int, QStringList>::ConstIterator a = buddies.begin();
791
while ( a != buddies.end() ) {
792
QStringList::ConstIterator b = (*a).begin();
793
while ( b != (*a).end() ) {
794
int no = objects.find( *b );
796
packUInt16( out2, a.key() );
797
packUInt16( out2, no );
805
if ( !connectionsElem.isNull() ) {
806
QString prevLanguage = "C++";
807
int prevSenderNo = 0;
808
QString prevSignal = "clicked()";
809
int prevReceiverNo = 0;
810
QString prevSlot = "accept()";
812
QDataStream out2( connectionsBlock, IO_WriteOnly );
813
QDomElement f = connectionsElem.firstChild().toElement();
814
while ( !f.isNull() ) {
815
if ( f.tagName() == "connection" ) {
816
QMap<QString, QString> argMap;
818
QDomElement g = f.firstChild().toElement();
819
while ( !g.isNull() ) {
820
argMap[g.tagName()] = g.firstChild().toText().data();
821
g = g.nextSibling().toElement();
824
QString language = f.attribute( "language", "C++" );
825
int senderNo = objects.find( argMap["sender"], widgetNo );
826
int receiverNo = objects.find( argMap["receiver"], widgetNo );
827
QString signal = UibHack::normalize( argMap["signal"] );
828
QString slot = UibHack::normalize( argMap["slot"] );
830
Q_UINT8 connectionFlags = 0;
831
if ( language != prevLanguage )
832
connectionFlags |= Connection_Language;
833
if ( senderNo != prevSenderNo )
834
connectionFlags |= Connection_Sender;
835
if ( signal != prevSignal )
836
connectionFlags |= Connection_Signal;
837
if ( receiverNo != prevReceiverNo )
838
connectionFlags |= Connection_Receiver;
839
if ( slot != prevSlot )
840
connectionFlags |= Connection_Slot;
841
out2 << connectionFlags;
843
if ( connectionFlags & Connection_Language )
844
packString( strings, out2, language );
845
if ( connectionFlags & Connection_Sender )
846
packUInt16( out2, senderNo );
847
if ( connectionFlags & Connection_Signal )
848
packStringSplit( strings, out2, signal, '(' );
849
if ( connectionFlags & Connection_Receiver )
850
packUInt16( out2, receiverNo );
851
if ( connectionFlags & Connection_Slot )
852
packStringSplit( strings, out2, slot, '(' );
854
prevLanguage = language;
855
prevSenderNo = senderNo;
857
prevReceiverNo = receiverNo;
859
} else if ( f.tagName() == "slot" ) {
862
f = f.nextSibling().toElement();
867
QDataStream out2( introBlock, IO_WriteOnly );
869
out2 << defaultMargin;
870
out2 << defaultSpacing;
871
packUInt16( out2, objects.count() );
872
packCString( strings, out2, className );
876
out << (Q_UINT8) '\n';
877
out << (Q_UINT8) '\r';
878
out << (Q_UINT8) out.version();
879
outputBlock( out, Block_Strings, strings.block() );
880
outputBlock( out, Block_Intro, introBlock );
881
outputBlock( out, Block_Images, imagesBlock );
882
outputBlock( out, Block_Widget, widgetBlock );
883
outputBlock( out, Block_Slots, slotsBlock );
884
outputBlock( out, Block_Tabstops, tabstopsBlock );
885
outputBlock( out, Block_Actions, actionsBlock );
886
outputBlock( out, Block_Menubar, menubarBlock );
887
outputBlock( out, Block_Toolbars, toolbarsBlock );
888
outputBlock( out, Block_Variables, variablesBlock );
889
outputBlock( out, Block_Functions, functionsBlock );
890
outputBlock( out, Block_Buddies, buddiesBlock );
891
outputBlock( out, Block_Connections, connectionsBlock );
892
out << (Q_UINT8) Block_End;