source: trunk/tools/designer/uic/uic.cpp@ 144

Last change on this file since 144 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 35.5 KB
Line 
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Designer.
5**
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.
10**
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.
14**
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.
17**
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.
21**
22** Contact info@trolltech.com if any conditions of this licensing are
23** not clear to you.
24**
25**********************************************************************/
26
27#include "uic.h"
28#include "parser.h"
29#include "widgetdatabase.h"
30#include "domtool.h"
31#include <qfile.h>
32#include <qstringlist.h>
33#include <qdatetime.h>
34#define NO_STATIC_COLORS
35#include <globaldefs.h>
36#include <qregexp.h>
37#include <stdio.h>
38#include <stdlib.h>
39
40bool Uic::isMainWindow = FALSE;
41
42QString Uic::getComment( const QDomNode& n )
43{
44 QDomNode child = n.firstChild();
45 while ( !child.isNull() ) {
46 if ( child.toElement().tagName() == "comment" )
47 return child.toElement().firstChild().toText().data();
48 child = child.nextSibling();
49 }
50 return QString::null;
51}
52
53QString Uic::mkBool( bool b )
54{
55 return b? "TRUE" : "FALSE";
56}
57
58QString Uic::mkBool( const QString& s )
59{
60 return mkBool( s == "true" || s == "1" );
61}
62
63bool Uic::toBool( const QString& s )
64{
65 return s == "true" || s.toInt() != 0;
66}
67
68QString Uic::fixString( const QString &str, bool encode )
69{
70 QString s;
71 if ( !encode ) {
72 s = str;
73 s.replace( "\\", "\\\\" );
74 s.replace( "\"", "\\\"" );
75 s.replace( "\r", "" );
76 s.replace( "\n", "\\n\"\n\"" );
77 } else {
78 QCString utf8 = str.utf8();
79 const int l = utf8.length();
80 for ( int i = 0; i < l; ++i )
81 s += "\\x" + QString::number( (uchar)utf8[i], 16 );
82 }
83
84 return "\"" + s + "\"";
85}
86
87QString Uic::trcall( const QString& sourceText, const QString& comment )
88{
89 if ( sourceText.isEmpty() && comment.isEmpty() )
90 return "QString::null";
91
92 QString t = trmacro;
93 bool encode = FALSE;
94 if ( t.isNull() ) {
95 t = "tr";
96 for ( int i = 0; i < (int) sourceText.length(); i++ ) {
97 if ( sourceText[i].unicode() >= 0x80 ) {
98 t = "trUtf8";
99 encode = TRUE;
100 break;
101 }
102 }
103 }
104
105 if ( comment.isEmpty() ) {
106 return t + "( " + fixString( sourceText, encode ) + " )";
107 } else {
108 return t + "( " + fixString( sourceText, encode ) + ", " +
109 fixString( comment, encode ) + " )";
110 }
111}
112
113QString Uic::mkStdSet( const QString& prop )
114{
115 return QString( "set" ) + prop[0].upper() + prop.mid(1);
116}
117
118
119
120/*!
121 \class Uic uic.h
122 \brief User Interface Compiler
123
124 The class Uic encapsulates the user interface compiler (uic).
125 */
126Uic::Uic( const QString &fn, const char *outputFn, QTextStream &outStream,
127 QDomDocument doc, bool decl, bool subcl, const QString &trm,
128 const QString& subClass, bool omitForwardDecls )
129 : out( outStream ), trout( &languageChangeBody ),
130 outputFileName( outputFn ), trmacro( trm ), nofwd( omitForwardDecls )
131{
132 fileName = fn;
133 writeFunctImpl = TRUE;
134 defMargin = BOXLAYOUT_DEFAULT_MARGIN;
135 defSpacing = BOXLAYOUT_DEFAULT_SPACING;
136 externPixmaps = FALSE;
137 indent = " "; // default indent
138
139 item_used = cg_used = pal_used = 0;
140
141 layouts << "hbox" << "vbox" << "grid";
142 tags = layouts;
143 tags << "widget";
144
145 pixmapLoaderFunction = getPixmapLoaderFunction( doc.firstChild().toElement() );
146 nameOfClass = getFormClassName( doc.firstChild().toElement() );
147
148 uiFileVersion = doc.firstChild().toElement().attribute("version");
149 stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") );
150
151 if ( doc.firstChild().isNull() || doc.firstChild().firstChild().isNull() )
152 return;
153 QDomElement e = doc.firstChild().firstChild().toElement();
154 QDomElement widget;
155 while ( !e.isNull() ) {
156 if ( e.tagName() == "widget" ) {
157 widget = e;
158 } else if ( e.tagName() == "pixmapinproject" ) {
159 externPixmaps = TRUE;
160 } else if ( e.tagName() == "layoutdefaults" ) {
161 defSpacing = e.attribute( "spacing", defSpacing.toString() );
162 defMargin = e.attribute( "margin", defMargin.toString() );
163 } else if ( e.tagName() == "layoutfunctions" ) {
164 defSpacing = e.attribute( "spacing", defSpacing.toString() );
165 bool ok;
166 defSpacing.toInt( &ok );
167 if ( !ok ) {
168 QString buf = defSpacing.toString();
169 defSpacing = buf.append( "()" );
170 }
171 defMargin = e.attribute( "margin", defMargin.toString() );
172 defMargin.toInt( &ok );
173 if ( !ok ) {
174 QString buf = defMargin.toString();
175 defMargin = buf.append( "()" );
176 }
177 }
178 e = e.nextSibling().toElement();
179 }
180 e = widget;
181
182 if ( nameOfClass.isEmpty() )
183 nameOfClass = getObjectName( e );
184 namespaces = QStringList::split( "::", nameOfClass );
185 bareNameOfClass = namespaces.last();
186 namespaces.remove( namespaces.fromLast() );
187
188 if ( subcl ) {
189 if ( decl )
190 createSubDecl( e, subClass );
191 else
192 createSubImpl( e, subClass );
193 } else {
194 if ( decl )
195 createFormDecl( e );
196 else
197 createFormImpl( e );
198 }
199
200}
201
202/*! Extracts a pixmap loader function from \a e
203 */
204QString Uic::getPixmapLoaderFunction( const QDomElement& e )
205{
206 QDomElement n;
207 for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
208 if ( n.tagName() == "pixmapfunction" )
209 return n.firstChild().toText().data();
210 }
211 return QString::null;
212}
213
214
215/*! Extracts the forms class name from \a e
216 */
217QString Uic::getFormClassName( const QDomElement& e )
218{
219 QDomElement n;
220 QString cn;
221 for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
222 if ( n.tagName() == "class" ) {
223 QString s = n.firstChild().toText().data();
224 int i;
225 while ( ( i = s.find(' ' )) != -1 )
226 s[i] = '_';
227 cn = s;
228 }
229 }
230 return cn;
231}
232
233/*! Extracts a class name from \a e.
234 */
235QString Uic::getClassName( const QDomElement& e )
236{
237 QString s = e.attribute( "class" );
238 if ( s.isEmpty() && e.tagName() == "toolbar" )
239 s = "QToolBar";
240 else if ( s.isEmpty() && e.tagName() == "menubar" )
241 s = "QMenuBar";
242 return s;
243}
244
245/*! Returns TRUE if database framework code is generated, else FALSE.
246*/
247
248bool Uic::isFrameworkCodeGenerated( const QDomElement& e )
249{
250 QDomElement n = getObjectProperty( e, "frameworkCode" );
251 if ( n.attribute("name") == "frameworkCode" &&
252 !DomTool::elementToVariant( n.firstChild().toElement(), QVariant( TRUE, 0 ) ).toBool() )
253 return FALSE;
254 return TRUE;
255}
256
257/*! Extracts an object name from \a e. It's stored in the 'name'
258 property.
259 */
260QString Uic::getObjectName( const QDomElement& e )
261{
262 QDomElement n = getObjectProperty( e, "name" );
263 if ( n.firstChild().toElement().tagName() == "cstring" )
264 return n.firstChild().toElement().firstChild().toText().data();
265 return QString::null;
266}
267
268/*! Extracts an layout name from \a e. It's stored in the 'name'
269 property of the preceeding sibling (the first child of a QLayoutWidget).
270 */
271QString Uic::getLayoutName( const QDomElement& e )
272{
273 QDomElement p = e.parentNode().toElement();
274 QString name;
275
276 if ( getClassName(p) != "QLayoutWidget" )
277 name = "Layout";
278
279 QDomElement n = getObjectProperty( p, "name" );
280 if ( n.firstChild().toElement().tagName() == "cstring" ) {
281 name.prepend( n.firstChild().toElement().firstChild().toText().data() );
282 return QStringList::split( "::", name ).last();
283 }
284 return e.tagName();
285}
286
287
288QString Uic::getDatabaseInfo( const QDomElement& e, const QString& tag )
289{
290 QDomElement n;
291 QDomElement n1;
292 int child = 0;
293 // database info is a stringlist stored in this order
294 if ( tag == "connection" )
295 child = 0;
296 else if ( tag == "table" )
297 child = 1;
298 else if ( tag == "field" )
299 child = 2;
300 else
301 return QString::null;
302 n = getObjectProperty( e, "database" );
303 if ( n.firstChild().toElement().tagName() == "stringlist" ) {
304 // find correct stringlist entry
305 QDomElement n1 = n.firstChild().firstChild().toElement();
306 for ( int i = 0; i < child && !n1.isNull(); ++i )
307 n1 = n1.nextSibling().toElement();
308 if ( n1.isNull() )
309 return QString::null;
310 return n1.firstChild().toText().data();
311 }
312 return QString::null;
313}
314
315
316void Uic::registerLayouts( const QDomElement &e )
317{
318 if ( layouts.contains(e.tagName())) {
319 createObjectDecl(e);
320 QString t = e.tagName();
321 if ( t == "vbox" || t == "hbox" || t == "grid" )
322 createSpacerDecl( e );
323 }
324
325 QDomNodeList nl = e.childNodes();
326 for ( int i = 0; i < (int) nl.length(); ++i )
327 registerLayouts( nl.item(i).toElement() );
328}
329
330
331/*!
332 Returns include file for class \a className or a null string.
333 */
334QString Uic::getInclude( const QString& className )
335{
336 int wid = WidgetDatabase::idFromClassName( className );
337 if ( wid != -1 )
338 return WidgetDatabase::includeFile( wid );
339 return QString::null;
340}
341
342
343void Uic::createActionDecl( const QDomElement& e )
344{
345 QString objClass = e.tagName() == "action" ? "QAction" : "QActionGroup";
346 QString objName = getObjectName( e );
347 if ( objName.isEmpty() )
348 return;
349 out << " " << objClass << "* " << objName << ";" << endl;
350 if ( e.tagName() == "actiongroup" ) {
351 for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
352 if ( n.tagName() == "action" || n.tagName() == "actiongroup" )
353 createActionDecl( n );
354 }
355 }
356}
357
358void Uic::createToolbarDecl( const QDomElement &e )
359{
360 if ( e.tagName() == "toolbar" )
361 out << " " << "QToolBar *" << getObjectName( e ) << ";" << endl;
362}
363
364void Uic::createMenuBarDecl( const QDomElement &e )
365{
366 if ( e.tagName() == "item" ) {
367 out << " " << "QPopupMenu *" << e.attribute( "name" ) << ";" << endl;
368 createPopupMenuDecl( e );
369 }
370}
371
372void Uic::createPopupMenuDecl( const QDomElement &e )
373{
374 for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
375 if ( n.tagName() == "action" ) {
376 QDomElement n2 = n.nextSibling().toElement();
377 if ( n2.tagName() == "item" ) { // the action has a sub menu
378 out << " " << "QPopupMenu *" << n2.attribute( "name" ) << ";" << endl;
379 createPopupMenuDecl( n2 );
380 n = n2;
381 }
382 }
383 }
384}
385
386void Uic::createActionImpl( const QDomElement &n, const QString &parent )
387{
388 for ( QDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) {
389 QString objName = registerObject( getObjectName( ae ) );
390 if ( ae.tagName() == "action" )
391 out << indent << objName << " = new QAction( " << parent << ", \"" << objName << "\" );" << endl;
392 else if ( ae.tagName() == "actiongroup" )
393 out << indent << objName << " = new QActionGroup( " << parent << ", \"" << objName << "\" );" << endl;
394 else
395 continue;
396 bool subActionsDone = FALSE;
397 bool hasMenuText = FALSE;
398 QString actionText;
399 for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) {
400 if ( n2.tagName() == "property" ) {
401 bool stdset = stdsetdef;
402 if ( n2.hasAttribute( "stdset" ) )
403 stdset = toBool( n2.attribute( "stdset" ) );
404 QString prop = n2.attribute("name");
405 if ( prop == "name" )
406 continue;
407 QString value = setObjectProperty( "QAction", objName, prop, n2.firstChild().toElement(), stdset );
408 if ( value.isEmpty() )
409 continue;
410
411 QString call = objName + "->";
412 if ( stdset ) {
413 call += mkStdSet( prop ) + "( ";
414 } else {
415 call += "setProperty( \"" + prop + "\", ";
416 }
417 call += value + " );";
418
419 if (prop == "menuText")
420 hasMenuText = TRUE;
421 else if (prop == "text")
422 actionText = value;
423
424 if ( n2.firstChild().toElement().tagName() == "string" ) {
425 trout << indent << call << endl;
426 } else {
427 out << indent << call << endl;
428 }
429 } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) {
430 createActionImpl( n2, objName );
431 subActionsDone = TRUE;
432 }
433 }
434 // workaround for loading pre-3.3 files expecting bogus QAction behavior
435 if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3")
436 trout << indent << objName << "->setMenuText(" << actionText << ");" << endl;
437 }
438}
439
440QString get_dock( const QString &d )
441{
442 if ( d == "0" )
443 return "DockUnmanaged";
444 if ( d == "1" )
445 return "DockTornOff";
446 if ( d == "2" )
447 return "DockTop";
448 if ( d == "3" )
449 return "DockBottom";
450 if ( d == "4" )
451 return "DockRight";
452 if ( d == "5" )
453 return "DockLeft";
454 if ( d == "6" )
455 return "DockMinimized";
456 return "";
457}
458
459void Uic::createToolbarImpl( const QDomElement &n, const QString &parentClass, const QString &parent )
460{
461 QDomNodeList nl = n.elementsByTagName( "toolbar" );
462 for ( int i = 0; i < (int) nl.length(); i++ ) {
463 QDomElement ae = nl.item( i ).toElement();
464 QString dock = get_dock( ae.attribute( "dock" ) );
465 QString objName = getObjectName( ae );
466 out << indent << objName << " = new QToolBar( QString(\"\"), this, " << dock << " ); " << endl;
467 createObjectImpl( ae, parentClass, parent );
468 for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) {
469 if ( n2.tagName() == "action" ) {
470 out << indent << n2.attribute( "name" ) << "->addTo( " << objName << " );" << endl;
471 } else if ( n2.tagName() == "separator" ) {
472 out << indent << objName << "->addSeparator();" << endl;
473 } else if ( n2.tagName() == "widget" ) {
474 if ( n2.attribute( "class" ) != "Spacer" ) {
475 createObjectImpl( n2, "QToolBar", objName );
476 } else {
477 QString child = createSpacerImpl( n2, parentClass, parent, objName );
478 out << indent << "QApplication::sendPostedEvents( " << objName
479 << ", QEvent::ChildInserted );" << endl;
480 out << indent << objName << "->boxLayout()->addItem( " << child << " );" << endl;
481 }
482 }
483 }
484 }
485}
486
487void Uic::createMenuBarImpl( const QDomElement &n, const QString &parentClass, const QString &parent )
488{
489 QString objName = getObjectName( n );
490 out << indent << objName << " = new QMenuBar( this, \"" << objName << "\" );" << endl;
491 createObjectImpl( n, parentClass, parent );
492 int i = 0;
493 QDomElement c = n.firstChild().toElement();
494 while ( !c.isNull() ) {
495 if ( c.tagName() == "item" ) {
496 QString itemName = c.attribute( "name" );
497 out << endl;
498 out << indent << itemName << " = new QPopupMenu( this );" << endl;
499 createPopupMenuImpl( c, parentClass, itemName );
500 out << indent << objName << "->insertItem( QString(\"\"), " << itemName << ", " << i << " );" << endl;
501 QString findItem(objName + "->findItem(%1)");
502 findItem = findItem.arg(i);
503 trout << indent << "if (" << findItem << ")" << endl;
504 trout << indent << indent << findItem << "->setText( " << trcall( c.attribute( "text" ) ) << " );" << endl;
505 } else if ( c.tagName() == "separator" ) {
506 out << endl;
507 out << indent << objName << "->insertSeparator( " << i << " );" << endl;
508 }
509 c = c.nextSibling().toElement();
510 i++;
511 }
512}
513
514void Uic::createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent )
515{
516 int i = 0;
517 for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
518 if ( n.tagName() == "action" ) {
519 QDomElement n2 = n.nextSibling().toElement();
520 if ( n2.tagName() == "item" ) { // the action has a sub menu
521 QString itemName = n2.attribute( "name" );
522 QString itemText = n2.attribute( "text" );
523 out << indent << itemName << " = new QPopupMenu( this );" << endl;
524 out << indent << parent << "->setAccel( tr( \"" << n2.attribute( "accel" ) << "\" ), " << endl;
525 out << indent << indent << parent << "->insertItem( " << n.attribute( "name" ) << "->iconSet(), ";
526 out << trcall( itemText ) << ", " << itemName << " ) );" << endl;
527 trout << indent << parent << "->changeItem( " << parent << "->idAt( " << i << " ), ";
528 trout << trcall( itemText ) << " );" << endl;
529 createPopupMenuImpl( n2, parentClass, itemName );
530 n = n2;
531 } else {
532 out << indent << n.attribute( "name" ) << "->addTo( " << parent << " );" << endl;
533 }
534 } else if ( n.tagName() == "separator" ) {
535 out << indent << parent << "->insertSeparator();" << endl;
536 }
537 ++i;
538 }
539}
540
541/*!
542 Creates implementation of an listbox item tag.
543*/
544
545QString Uic::createListBoxItemImpl( const QDomElement &e, const QString &parent,
546 QString *value )
547{
548 QDomElement n = e.firstChild().toElement();
549 QString txt;
550 QString com;
551 QString pix;
552 while ( !n.isNull() ) {
553 if ( n.tagName() == "property" ) {
554 QString attrib = n.attribute( "name" );
555 QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
556 if ( attrib == "text" ) {
557 txt = v.toString();
558 com = getComment( n );
559 } else if ( attrib == "pixmap" ) {
560 pix = v.toString();
561 if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
562 pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) );
563 pix.append( QString( externPixmaps ? "\"" : "" ) + " )" );
564 }
565 }
566 }
567 n = n.nextSibling().toElement();
568 }
569
570 if ( value )
571 *value = trcall( txt, com );
572
573 if ( pix.isEmpty() ) {
574 return parent + "->insertItem( " + trcall( txt, com ) + " );";
575 } else {
576 return parent + "->insertItem( " + pix + ", " + trcall( txt, com ) + " );";
577 }
578}
579
580/*!
581 Creates implementation of an iconview item tag.
582*/
583
584QString Uic::createIconViewItemImpl( const QDomElement &e, const QString &parent )
585{
586 QDomElement n = e.firstChild().toElement();
587 QString txt;
588 QString com;
589 QString pix;
590 while ( !n.isNull() ) {
591 if ( n.tagName() == "property" ) {
592 QString attrib = n.attribute( "name" );
593 QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
594 if ( attrib == "text" ) {
595 txt = v.toString();
596 com = getComment( n );
597 } else if ( attrib == "pixmap" ) {
598 pix = v.toString();
599 if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
600 pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) );
601 pix.append( QString( externPixmaps ? "\"" : "" ) + " )" );
602 }
603 }
604 }
605 n = n.nextSibling().toElement();
606 }
607
608 if ( pix.isEmpty() )
609 return "(void) new QIconViewItem( " + parent + ", " + trcall( txt, com ) + " );";
610 else
611 return "(void) new QIconViewItem( " + parent + ", " + trcall( txt, com ) + ", " + pix + " );";
612}
613
614/*!
615 Creates implementation of an listview item tag.
616*/
617
618QString Uic::createListViewItemImpl( const QDomElement &e, const QString &parent,
619 const QString &parentItem )
620{
621 QString s;
622
623 QDomElement n = e.firstChild().toElement();
624
625 bool hasChildren = e.elementsByTagName( "item" ).count() > 0;
626 QString item;
627
628 if ( hasChildren ) {
629 item = registerObject( "item" );
630 s = indent + "QListViewItem * " + item + " = ";
631 } else {
632 item = "item";
633 if ( item_used )
634 s = indent + item + " = ";
635 else
636 s = indent + "QListViewItem * " + item + " = ";
637 item_used = TRUE;
638 }
639
640 if ( !parentItem.isEmpty() )
641 s += "new QListViewItem( " + parentItem + ", " + lastItem + " );\n";
642 else
643 s += "new QListViewItem( " + parent + ", " + lastItem + " );\n";
644
645 QStringList texts;
646 QStringList pixmaps;
647 while ( !n.isNull() ) {
648 if ( n.tagName() == "property" ) {
649 QString attrib = n.attribute("name");
650 QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
651 if ( attrib == "text" )
652 texts << v.toString();
653 else if ( attrib == "pixmap" ) {
654 QString pix = v.toString();
655 if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
656 pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) );
657 pix.append( QString( externPixmaps ? "\"" : "" ) + " )" );
658 }
659 pixmaps << pix;
660 }
661 } else if ( n.tagName() == "item" ) {
662 s += indent + item + "->setOpen( TRUE );\n";
663 s += createListViewItemImpl( n, parent, item );
664 }
665 n = n.nextSibling().toElement();
666 }
667
668 for ( int i = 0; i < (int)texts.count(); ++i ) {
669 if ( !texts[ i ].isEmpty() )
670 s += indent + item + "->setText( " + QString::number( i ) + ", " + trcall( texts[ i ] ) + " );\n";
671 if ( !pixmaps[ i ].isEmpty() )
672 s += indent + item + "->setPixmap( " + QString::number( i ) + ", " + pixmaps[ i ] + " );\n";
673 }
674
675 lastItem = item;
676 return s;
677}
678
679/*!
680 Creates implementation of an listview column tag.
681*/
682
683QString Uic::createListViewColumnImpl( const QDomElement &e, const QString &parent,
684 QString *value )
685{
686 QDomElement n = e.firstChild().toElement();
687 QString txt;
688 QString com;
689 QString pix;
690 bool clickable = FALSE, resizable = FALSE;
691 while ( !n.isNull() ) {
692 if ( n.tagName() == "property" ) {
693 QString attrib = n.attribute("name");
694 QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
695 if ( attrib == "text" ) {
696 txt = v.toString();
697 com = getComment( n );
698 } else if ( attrib == "pixmap" ) {
699 pix = v.toString();
700 if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
701 pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) );
702 pix.append( QString( externPixmaps ? "\"" : "" ) + " )" );
703 }
704 } else if ( attrib == "clickable" )
705 clickable = v.toBool();
706 else if ( attrib == "resizable" || attrib == "resizeable" )
707 resizable = v.toBool();
708 }
709 n = n.nextSibling().toElement();
710 }
711
712 if ( value )
713 *value = trcall( txt, com );
714
715 QString s;
716 s = indent + parent + "->addColumn( " + trcall( txt, com ) + " );\n";
717 if ( !pix.isEmpty() )
718 s += indent + parent + "->header()->setLabel( " + parent + "->header()->count() - 1, " + pix + ", " + trcall( txt, com ) + " );\n";
719 if ( !clickable )
720 s += indent + parent + "->header()->setClickEnabled( FALSE, " + parent + "->header()->count() - 1 );\n";
721 if ( !resizable )
722 s += indent + parent + "->header()->setResizeEnabled( FALSE, " + parent + "->header()->count() - 1 );\n";
723 return s;
724}
725
726QString Uic::createTableRowColumnImpl( const QDomElement &e, const QString &parent,
727 QString *value )
728{
729 QString objClass = getClassName( e.parentNode().toElement() );
730 QDomElement n = e.firstChild().toElement();
731 QString txt;
732 QString com;
733 QString pix;
734 QString field;
735 bool isRow = e.tagName() == "row";
736 while ( !n.isNull() ) {
737 if ( n.tagName() == "property" ) {
738 QString attrib = n.attribute("name");
739 QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
740 if ( attrib == "text" ) {
741 txt = v.toString();
742 com = getComment( n );
743 } else if ( attrib == "pixmap" ) {
744 pix = v.toString();
745 if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
746 pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) );
747 pix.append( QString( externPixmaps ? "\"" : "" ) + " )" );
748 }
749 } else if ( attrib == "field" )
750 field = v.toString();
751 }
752 n = n.nextSibling().toElement();
753 }
754
755 if ( value )
756 *value = trcall( txt, com );
757
758 // ### This generated code sucks! We have to set the number of
759 // rows/cols before and then only do setLabel/()
760 // ### careful, though, since QDataTable has an API which makes this code pretty good
761
762 QString s;
763 if ( isRow ) {
764 s = indent + parent + "->setNumRows( " + parent + "->numRows() + 1 );\n";
765 if ( pix.isEmpty() )
766 s += indent + parent + "->verticalHeader()->setLabel( " + parent + "->numRows() - 1, "
767 + trcall( txt, com ) + " );\n";
768 else
769 s += indent + parent + "->verticalHeader()->setLabel( " + parent + "->numRows() - 1, "
770 + pix + ", " + trcall( txt, com ) + " );\n";
771 } else {
772 if ( objClass == "QTable" ) {
773 s = indent + parent + "->setNumCols( " + parent + "->numCols() + 1 );\n";
774 if ( pix.isEmpty() )
775 s += indent + parent + "->horizontalHeader()->setLabel( " + parent + "->numCols() - 1, "
776 + trcall( txt, com ) + " );\n";
777 else
778 s += indent + parent + "->horizontalHeader()->setLabel( " + parent + "->numCols() - 1, "
779 + pix + ", " + trcall( txt, com ) + " );\n";
780 } else if ( objClass == "QDataTable" ) {
781 if ( !txt.isEmpty() && !field.isEmpty() ) {
782 if ( pix.isEmpty() )
783 out << indent << parent << "->addColumn( " << fixString( field ) << ", " << trcall( txt, com ) << " );" << endl;
784 else
785 out << indent << parent << "->addColumn( " << fixString( field ) << ", " << trcall( txt, com ) << ", " << pix << " );" << endl;
786 }
787 }
788 }
789 return s;
790}
791
792/*!
793 Creates the implementation of a layout tag. Called from createObjectImpl().
794 */
795QString Uic::createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout )
796{
797 QDomElement n;
798 QString objClass, objName;
799 objClass = e.tagName();
800
801 QString qlayout = "QVBoxLayout";
802 if ( objClass == "hbox" )
803 qlayout = "QHBoxLayout";
804 else if ( objClass == "grid" )
805 qlayout = "QGridLayout";
806
807 bool isGrid = e.tagName() == "grid" ;
808 objName = registerObject( getLayoutName( e ) );
809 layoutObjects += objName;
810
811 QString margin = DomTool::readProperty( e, "margin", defMargin ).toString();
812 QString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString();
813 QString resizeMode = DomTool::readProperty( e, "resizeMode", QString::null ).toString();
814
815 QString optcells;
816 if ( isGrid )
817 optcells = "1, 1, ";
818 if ( (parentClass == "QGroupBox" || parentClass == "QButtonGroup") && layout.isEmpty() ) {
819 // special case for group box
820 out << indent << parent << "->setColumnLayout(0, Qt::Vertical );" << endl;
821 out << indent << parent << "->layout()->setSpacing( " << spacing << " );" << endl;
822 out << indent << parent << "->layout()->setMargin( " << margin << " );" << endl;
823 out << indent << objName << " = new " << qlayout << "( " << parent << "->layout() );" << endl;
824 out << indent << objName << "->setAlignment( Qt::AlignTop );" << endl;
825 } else {
826 out << indent << objName << " = new " << qlayout << "( ";
827 if ( layout.isEmpty() )
828 out << parent;
829 else {
830 out << "0";
831 if ( !DomTool::hasProperty( e, "margin" ) )
832 margin = "0";
833 }
834 out << ", " << optcells << margin << ", " << spacing << ", \"" << objName << "\"); " << endl;
835 }
836 if ( !resizeMode.isEmpty() )
837 out << indent << objName << "->setResizeMode( QLayout::" << resizeMode << " );" << endl;
838
839 if ( !isGrid ) {
840 for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
841 if ( n.tagName() == "spacer" ) {
842 QString child = createSpacerImpl( n, parentClass, parent, objName );
843 out << indent << objName << "->addItem( " << child << " );" << endl;
844 } else if ( tags.contains( n.tagName() ) ) {
845 QString child = createObjectImpl( n, parentClass, parent, objName );
846 if ( isLayout( child ) )
847 out << indent << objName << "->addLayout( " << child << " );" << endl;
848 else
849 out << indent << objName << "->addWidget( " << child << " );" << endl;
850 }
851 }
852 } else {
853 for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
854 QDomElement ae = n;
855 int row = ae.attribute( "row" ).toInt();
856 int col = ae.attribute( "column" ).toInt();
857 int rowspan = ae.attribute( "rowspan" ).toInt();
858 int colspan = ae.attribute( "colspan" ).toInt();
859 if ( rowspan < 1 )
860 rowspan = 1;
861 if ( colspan < 1 )
862 colspan = 1;
863 if ( n.tagName() == "spacer" ) {
864 QString child = createSpacerImpl( n, parentClass, parent, objName );
865 if ( rowspan * colspan != 1 )
866 out << indent << objName << "->addMultiCell( " << child << ", "
867 << row << ", " << ( row + rowspan - 1 ) << ", " << col << ", " << ( col + colspan - 1 ) << " );" << endl;
868 else
869 out << indent << objName << "->addItem( " << child << ", "
870 << row << ", " << col << " );" << endl;
871 } else if ( tags.contains( n.tagName() ) ) {
872 QString child = createObjectImpl( n, parentClass, parent, objName );
873 out << endl;
874 QString o = "Widget";
875 if ( isLayout( child ) )
876 o = "Layout";
877 if ( rowspan * colspan != 1 )
878 out << indent << objName << "->addMultiCell" << o << "( " << child << ", "
879 << row << ", " << ( row + rowspan - 1 ) << ", " << col << ", " << ( col + colspan - 1 ) << " );" << endl;
880 else
881 out << indent << objName << "->add" << o << "( " << child << ", "
882 << row << ", " << col << " );" << endl;
883 }
884 }
885 }
886
887 return objName;
888}
889
890
891
892QString Uic::createSpacerImpl( const QDomElement &e, const QString& /*parentClass*/, const QString& /*parent*/, const QString& /*layout*/)
893{
894 QDomElement n;
895 QString objClass, objName;
896 objClass = e.tagName();
897 objName = registerObject( getObjectName( e ) );
898
899 QSize size = DomTool::readProperty( e, "sizeHint", QSize( 0, 0 ) ).toSize();
900 QString sizeType = DomTool::readProperty( e, "sizeType", "Expanding" ).toString();
901 bool isVspacer = DomTool::readProperty( e, "orientation", "Horizontal" ) == "Vertical";
902
903 if ( sizeType != "Expanding" && sizeType != "MinimumExpanding" &&
904 DomTool::hasProperty( e, "geometry" ) ) { // compatibility Qt 2.2
905 QRect geom = DomTool::readProperty( e, "geometry", QRect(0,0,0,0) ).toRect();
906 size = geom.size();
907 }
908
909 if ( isVspacer )
910 out << " " << objName << " = new QSpacerItem( "
911 << size.width() << ", " << size.height()
912 << ", QSizePolicy::Minimum, QSizePolicy::" << sizeType << " );" << endl;
913 else
914 out << " " << objName << " = new QSpacerItem( "
915 << size.width() << ", " << size.height()
916 << ", QSizePolicy::" << sizeType << ", QSizePolicy::Minimum );" << endl;
917
918 return objName;
919}
920
921static const char* const ColorRole[] = {
922 "Foreground", "Button", "Light", "Midlight", "Dark", "Mid",
923 "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow",
924 "Highlight", "HighlightedText", "Link", "LinkVisited", 0
925};
926
927
928/*!
929 Creates a colorgroup with name \a name from the color group \a cg
930 */
931void Uic::createColorGroupImpl( const QString& name, const QDomElement& e )
932{
933 QColorGroup cg;
934 int r = -1;
935 QDomElement n = e.firstChild().toElement();
936 QString color;
937 while ( !n.isNull() ) {
938 if ( n.tagName() == "color" ) {
939 r++;
940 QColor col = DomTool::readColor( n );
941 color = "QColor( %1, %2, %3)";
942 color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() );
943 if ( col == white )
944 color = "white";
945 else if ( col == black )
946 color = "black";
947 if ( n.nextSibling().toElement().tagName() != "pixmap" ) {
948 out << indent << name << ".setColor( QColorGroup::" << ColorRole[r] << ", " << color << " );" << endl;
949 }
950 } else if ( n.tagName() == "pixmap" ) {
951 QString pixmap = n.firstChild().toText().data();
952 if ( !pixmapLoaderFunction.isEmpty() ) {
953 pixmap.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) );
954 pixmap.append( QString( externPixmaps ? "\"" : "" ) + " )" );
955 }
956 out << indent << name << ".setBrush( QColorGroup::"
957 << ColorRole[r] << ", QBrush( " << color << ", " << pixmap << " ) );" << endl;
958 }
959 n = n.nextSibling().toElement();
960 }
961}
962
963/*!
964 Auxiliary function to load a color group. The colorgroup must not
965 contain pixmaps.
966 */
967QColorGroup Uic::loadColorGroup( const QDomElement &e )
968{
969 QColorGroup cg;
970 int r = -1;
971 QDomElement n = e.firstChild().toElement();
972 QColor col;
973 while ( !n.isNull() ) {
974 if ( n.tagName() == "color" ) {
975 r++;
976 cg.setColor( (QColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) );
977 }
978 n = n.nextSibling().toElement();
979 }
980 return cg;
981}
982
983/*! Returns TRUE if the widget properties specify that it belongs to
984 the database \a connection and \a table.
985*/
986
987bool Uic::isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table )
988{
989 QString conn = getDatabaseInfo( e, "connection" );
990 QString tab = getDatabaseInfo( e, "table" );
991 if ( conn == connection && tab == table )
992 return TRUE;
993 return FALSE;
994}
995
996/*!
997 Registers all database connections, cursors and forms.
998*/
999
1000void Uic::registerDatabases( const QDomElement& e )
1001{
1002 QDomElement n;
1003 QDomNodeList nl;
1004 int i;
1005 nl = e.parentNode().toElement().elementsByTagName( "widget" );
1006 for ( i = 0; i < (int) nl.length(); ++i ) {
1007 n = nl.item(i).toElement();
1008 QString conn = getDatabaseInfo( n, "connection" );
1009 QString tab = getDatabaseInfo( n, "table" );
1010 QString fld = getDatabaseInfo( n, "field" );
1011 if ( !conn.isNull() ) {
1012 dbConnections += conn;
1013 if ( !tab.isNull() ) {
1014 dbCursors[conn] += tab;
1015 if ( !fld.isNull() )
1016 dbForms[conn] += tab;
1017 }
1018 }
1019 }
1020}
1021
1022/*!
1023 Registers an object with name \a name.
1024
1025 The returned name is a valid variable identifier, as similar to \a
1026 name as possible and guaranteed to be unique within the form.
1027
1028 \sa registeredName(), isObjectRegistered()
1029 */
1030QString Uic::registerObject( const QString& name )
1031{
1032 if ( objectNames.isEmpty() ) {
1033 // some temporary variables we need
1034 objectNames += "img";
1035 objectNames += "item";
1036 objectNames += "cg";
1037 objectNames += "pal";
1038 }
1039
1040 QString result = name;
1041 int i;
1042 while ( ( i = result.find(' ' )) != -1 ) {
1043 result[i] = '_';
1044 }
1045
1046 if ( objectNames.contains( result ) ) {
1047 int i = 2;
1048 while ( objectNames.contains( result + "_" + QString::number(i) ) )
1049 i++;
1050 result += "_";
1051 result += QString::number(i);
1052 }
1053 objectNames += result;
1054 objectMapper.insert( name, result );
1055 return result;
1056}
1057
1058/*!
1059 Returns the registered name for the original name \a name
1060 or \a name if \a name wasn't registered.
1061
1062 \sa registerObject(), isObjectRegistered()
1063 */
1064QString Uic::registeredName( const QString& name )
1065{
1066 if ( !objectMapper.contains( name ) )
1067 return name;
1068 return objectMapper[name];
1069}
1070
1071/*!
1072 Returns whether the object \a name was registered yet or not.
1073 */
1074bool Uic::isObjectRegistered( const QString& name )
1075{
1076 return objectMapper.contains( name );
1077}
1078
1079
1080/*!
1081 Unifies the entries in stringlist \a list. Should really be a QStringList feature.
1082 */
1083QStringList Uic::unique( const QStringList& list )
1084{
1085 if ( list.isEmpty() )
1086 return list;
1087
1088 QStringList result;
1089 for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) {
1090 if ( !result.contains(*it) )
1091 result += *it;
1092 }
1093 return result;
1094}
1095
1096
1097
1098/*!
1099 Creates an instance of class \a objClass, with parent \a parent and name \a objName
1100 */
1101QString Uic::createObjectInstance( const QString& objClass, const QString& parent, const QString& objName )
1102{
1103
1104 if ( objClass.mid( 1 ) == "ComboBox" ) {
1105 return objClass + "( FALSE, " + parent + ", \"" + objName + "\" )";
1106 }
1107 return objClass + "( " + parent + ", \"" + objName + "\" )";
1108}
1109
1110bool Uic::isLayout( const QString& name ) const
1111{
1112 return layoutObjects.contains( name );
1113}
1114
1115
1116
Note: See TracBrowser for help on using the repository browser.