diff options
Diffstat (limited to 'pytquic3')
-rw-r--r-- | pytquic3/LICENSE.GPL | 280 | ||||
-rw-r--r-- | pytquic3/domtool.cpp | 447 | ||||
-rw-r--r-- | pytquic3/domtool.h | 47 | ||||
-rw-r--r-- | pytquic3/embed.cpp | 322 | ||||
-rw-r--r-- | pytquic3/form.cpp | 938 | ||||
-rw-r--r-- | pytquic3/globaldefs.h | 56 | ||||
-rw-r--r-- | pytquic3/main.cpp | 244 | ||||
-rw-r--r-- | pytquic3/object.cpp | 704 | ||||
-rw-r--r-- | pytquic3/parser.cpp | 66 | ||||
-rw-r--r-- | pytquic3/parser.h | 33 | ||||
-rw-r--r-- | pytquic3/pytquic-prof.sbf | 24 | ||||
-rw-r--r-- | pytquic3/pytquic.pro.in | 36 | ||||
-rw-r--r-- | pytquic3/pytquic.sbf | 24 | ||||
-rw-r--r-- | pytquic3/subclassing.cpp | 185 | ||||
-rw-r--r-- | pytquic3/uic.cpp | 1145 | ||||
-rw-r--r-- | pytquic3/uic.h | 183 | ||||
-rw-r--r-- | pytquic3/widgetdatabase.cpp | 953 | ||||
-rw-r--r-- | pytquic3/widgetdatabase.h | 96 | ||||
-rw-r--r-- | pytquic3/widgetinterface.h | 29 |
19 files changed, 5812 insertions, 0 deletions
diff --git a/pytquic3/LICENSE.GPL b/pytquic3/LICENSE.GPL new file mode 100644 index 0000000..c7aea18 --- /dev/null +++ b/pytquic3/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/pytquic3/domtool.cpp b/pytquic3/domtool.cpp new file mode 100644 index 0000000..740088e --- /dev/null +++ b/pytquic3/domtool.cpp @@ -0,0 +1,447 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "domtool.h" + +#include <tqsizepolicy.h> +#include <tqcolor.h> +#include <tqcursor.h> +#include <tqdatetime.h> +#include <tqrect.h> +#include <tqsize.h> +#include <tqfont.h> +#include <tqdom.h> + +/*! + \class DomTool domtool.h + \brief Tools for the dom + + A collection of static functions used by Resource (part of the + designer) and Uic. + +*/ + +/*! + Returns the contents of property \a name of object \a e as + variant or the variant passed as \a defValue if the property does + not exist. + + \sa hasProperty() +*/ +TQVariant DomTool::readProperty( const TQDomElement& e, const TQString& name, const TQVariant& defValue, TQString& comment ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + if ( n.attribute( "name" ) != name ) + continue; + return elementToVariant( n.firstChild().toElement(), defValue, comment ); + } + } + return defValue; +} + + +/*! + \overload + */ +TQVariant DomTool::readProperty( const TQDomElement& e, const TQString& name, const TQVariant& defValue ) +{ + TQString comment; + return readProperty( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines property \a name or not. + + \sa readProperty() + */ +bool DomTool::hasProperty( const TQDomElement& e, const TQString& name ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + if ( n.attribute( "name" ) != name ) + continue; + return TRUE; + } + } + return FALSE; +} + +TQStringList DomTool::propertiesOfType( const TQDomElement& e, const TQString& type ) +{ + TQStringList result; + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + TQDomElement n2 = n.firstChild().toElement(); + if ( n2.tagName() == type ) + result += n.attribute( "name" ); + } + } + return result; +} + + +TQVariant DomTool::elementToVariant( const TQDomElement& e, const TQVariant& defValue ) +{ + TQString dummy; + return elementToVariant( e, defValue, dummy ); +} + +/*! + Interprets element \a e as variant and returns the result of the interpretation. + */ +TQVariant DomTool::elementToVariant( const TQDomElement& e, const TQVariant& defValue, TQString &comment ) +{ + TQVariant v; + if ( e.tagName() == "rect" ) { + TQDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( TQRect( x, y, w, h ) ); + } else if ( e.tagName() == "point" ) { + TQDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( TQPoint( x, y ) ); + } else if ( e.tagName() == "size" ) { + TQDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( TQSize( w, h ) ); + } else if ( e.tagName() == "color" ) { + v = TQVariant( readColor( e ) ); + } else if ( e.tagName() == "font" ) { + TQDomElement n3 = e.firstChild().toElement(); + TQFont f( defValue.toFont() ); + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + f.setFamily( n3.firstChild().toText().data() ); + else if ( n3.tagName() == "pointsize" ) + f.setPointSize( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "bold" ) + f.setBold( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "italic" ) + f.setItalic( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "underline" ) + f.setUnderline( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "strikeout" ) + f.setStrikeOut( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( f ); + } else if ( e.tagName() == "string" ) { + v = TQVariant( e.firstChild().toText().data() ); + TQDomElement n = e; + n = n.nextSibling().toElement(); + if ( n.tagName() == "comment" ) + comment = n.firstChild().toText().data(); + } else if ( e.tagName() == "cstring" ) { + v = TQVariant( TQCString( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "number" ) { + bool ok = TRUE; + v = TQVariant( e.firstChild().toText().data().toInt( &ok ) ); + if ( !ok ) + v = TQVariant( e.firstChild().toText().data().toDouble() ); + } else if ( e.tagName() == "bool" ) { + TQString t = e.firstChild().toText().data(); + v = TQVariant( t == "true" || t == "1" ); + } else if ( e.tagName() == "pixmap" ) { + v = TQVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "iconset" ) { + v = TQVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "image" ) { + v = TQVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "enum" ) { + v = TQVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "set" ) { + v = TQVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "sizepolicy" ) { + TQDomElement n3 = e.firstChild().toElement(); + TQSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (TQSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (TQSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( sp ); + } else if ( e.tagName() == "cursor" ) { + v = TQVariant( TQCursor( e.firstChild().toText().data().toInt() ) ); + } else if ( e.tagName() == "stringlist" ) { + TQStringList lst; + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + lst << n.firstChild().toText().data(); + v = TQVariant( lst ); + } else if ( e.tagName() == "date" ) { + TQDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( TQDate( y, m, d ) ); + } else if ( e.tagName() == "time" ) { + TQDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( TQTime( h, m, s ) ); + } else if ( e.tagName() == "datetime" ) { + TQDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d ; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = TQVariant( TQDateTime( TQDate( y, mo, d ), TQTime( h, mi, s ) ) ); + } + return v; +} + + +/*! Returns the color which is returned in the dom element \a e. + */ + +TQColor DomTool::readColor( const TQDomElement &e ) +{ + TQDomElement n = e.firstChild().toElement(); + int r= 0, g = 0, b = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "red" ) + r = n.firstChild().toText().data().toInt(); + else if ( n.tagName() == "green" ) + g = n.firstChild().toText().data().toInt(); + else if ( n.tagName() == "blue" ) + b = n.firstChild().toText().data().toInt(); + n = n.nextSibling().toElement(); + } + + return TQColor( r, g, b ); +} + +/*! + Returns the contents of attribute \a name of object \a e as + variant or the variant passed as \a defValue if the attribute does + not exist. + + \sa hasAttribute() + */ +TQVariant DomTool::readAttribute( const TQDomElement& e, const TQString& name, const TQVariant& defValue, TQString& comment ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "attribute" ) { + if ( n.attribute( "name" ) != name ) + continue; + return elementToVariant( n.firstChild().toElement(), defValue, comment ); + } + } + return defValue; +} + +/*! + \overload +*/ +TQVariant DomTool::readAttribute( const TQDomElement& e, const TQString& name, const TQVariant& defValue ) +{ + TQString comment; + return readAttribute( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines attribute \a name or not. + + \sa readAttribute() + */ +bool DomTool::hasAttribute( const TQDomElement& e, const TQString& name ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "attribute" ) { + if ( n.attribute( "name" ) != name ) + continue; + return TRUE; + } + } + return FALSE; +} + +static bool toBool( const TQString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +/*! + Convert TQt 2.x format to TQt 3.0 format if necessary +*/ +void DomTool::fixDocument( TQDomDocument& doc ) +{ + TQDomElement e; + TQDomNode n; + TQDomNodeList nl; + int i = 0; + + e = doc.firstChild().toElement(); + if ( e.tagName() != "UI" ) + return; + + // latest version, don't do anything + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.0 ) + return; + + nl = doc.elementsByTagName( "property" ); + + // in 3.0, we need to fix a spelling error + if ( e.hasAttribute("version") && e.attribute("version").toDouble() == 3.0 ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement el = nl.item(i).toElement(); + TQString s = el.attribute( "name" ); + if ( s == "resizeable" ) { + el.removeAttribute( "name" ); + el.setAttribute( "name", "resizable" ); + } + } + return; + } + + + // in versions smaller than 3.0 we need to change more + e.setAttribute( "version", 3.0 ); + + e.setAttribute("stdsetdef", 1 ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + TQString name; + TQDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + if ( name == "resizeable" ) + e.setAttribute( "name", "resizable" ); + else + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + bool stdset = toBool( e.attribute( "stdset" ) ); + if ( stdset || name == "toolTip" || name == "whatsThis" || + name == "buddy" || + e.parentNode().toElement().tagName() == "item" || + e.parentNode().toElement().tagName() == "spacer" || + e.parentNode().toElement().tagName() == "column" + ) + e.removeAttribute( "stdset" ); + else + e.setAttribute( "stdset", 0 ); + } + + nl = doc.elementsByTagName( "attribute" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + TQString name; + TQDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + } + + nl = doc.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + TQString name; + TQDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + } + + nl = doc.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + TQString name; + TQDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "class" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "class", name ); + e.removeChild( n2 ); + } + } + +} + diff --git a/pytquic3/domtool.h b/pytquic3/domtool.h new file mode 100644 index 0000000..87fbaf6 --- /dev/null +++ b/pytquic3/domtool.h @@ -0,0 +1,47 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DOMTOOL_H +#define DOMTOOL_H + +#include <tqvariant.h> +#include <tqnamespace.h> + +class TQDomElement; +class TQDomDocument; + +class DomTool : public TQt +{ +public: + static TQVariant readProperty( const TQDomElement& e, const TQString& name, const TQVariant& defValue ); + static TQVariant readProperty( const TQDomElement& e, const TQString& name, const TQVariant& defValue, TQString& comment ); + static bool hasProperty( const TQDomElement& e, const TQString& name ); + static TQStringList propertiesOfType( const TQDomElement& e, const TQString& type ); + static TQVariant elementToVariant( const TQDomElement& e, const TQVariant& defValue ); + static TQVariant elementToVariant( const TQDomElement& e, const TQVariant& defValue, TQString &comment ); + static TQVariant readAttribute( const TQDomElement& e, const TQString& name, const TQVariant& defValue ); + static TQVariant readAttribute( const TQDomElement& e, const TQString& name, const TQVariant& defValue, TQString& comment ); + static bool hasAttribute( const TQDomElement& e, const TQString& name ); + static TQColor readColor( const TQDomElement &e ); + static void fixDocument( TQDomDocument& ); +}; + + +#endif // DOMTOOL_H diff --git a/pytquic3/embed.cpp b/pytquic3/embed.cpp new file mode 100644 index 0000000..9bf0071 --- /dev/null +++ b/pytquic3/embed.cpp @@ -0,0 +1,322 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** Copyright (c) 2002 Riverbank Computing Limited <info@riverbankcomputing.co.uk> +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "uic.h" +#include <tqfile.h> +#include <tqimage.h> +#include <tqstringlist.h> +#include <tqdatetime.h> +#include <tqfileinfo.h> +#include <stdio.h> +#include <ctype.h> + +// on embedded, we do not compress image data. Rationale: by mapping +// the ready-only data directly into memory we are both faster and +// more memory efficient +#if (TQT_VERSION < 0x030100 || defined(Q_WS_QWS)) && !defined(TQT_NO_IMAGE_COLLECTION_COMPRESSION) +#define TQT_NO_IMAGE_COLLECTION_COMPRESSION +#endif + +struct EmbedImage +{ + ~EmbedImage() { delete[] colorTable; } + int width, height, depth; + int numColors; + TQRgb* colorTable; + TQString name; + TQString cname; + bool alpha; +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + ulong compressed; +#endif +}; + +static TQString convertToCIdentifier( const char *s ) +{ + TQString r = s; + int len = r.length(); + if ( len > 0 && !isalpha( (char)r[0].latin1() ) ) + r[0] = '_'; + for ( int i=1; i<len; i++ ) { + if ( !isalnum( (char)r[i].latin1() ) ) + r[i] = '_'; + } + return r; +} + + +static ulong embedData( TQTextStream& out, const uchar* input, int nbytes ) +{ +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + TQByteArray bazip( tqCompress( input, nbytes ) ); + uint len = bazip.size(); +#else + uint len = (uint)nbytes; +#endif + static const char hexdigits[] = "0123456789abcdef"; + TQString s; + for ( uint i=0; i<len; i++ ) { + if ( (i%14) == 0 ) { + if (i) + s += '"'; + + s += " \\\n \""; + out << (const char*)s; + s.truncate( 0 ); + } + uint v = (uchar) +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + bazip +#else + input +#endif + [(int)i]; + s += "\\x"; + s += hexdigits[(v >> 4) & 15]; + s += hexdigits[v & 15]; + if ( i == len-1 ) + s += "\"\n"; + } + if ( s.length() ) + out << (const char*)s; + return (ulong)len; +} + +static void embedData( TQTextStream& out, const TQRgb* input, int n ) +{ + out << hex; + const TQRgb *v = input; + for ( int i=0; i<n; i++ ) { + if ( (i%14) == 0 ) + out << "\n "; + out << "0x"; + out << hex << *v++; + if ( i < n-1 ) + out << ','; + } + out << dec; // back to decimal mode +} + +void Uic::embed( TQTextStream& out, const char* project, const TQStringList& images ) +{ + + TQString cProject = convertToCIdentifier( project ); + + TQStringList::ConstIterator it; + out << "# Image collection for project '" << project << "'.\n"; + out << "#\n"; + out << "# Generated from reading image files: \n"; + for ( it = images.begin(); it != images.end(); ++it ) + out << "# " << *it << "\n"; + out << "#\n"; + out << "# Created by: The PyTQt User Interface Compiler (pytquic) " << PYTQT_VERSION << "\n"; + out << "#\n"; + out << "# WARNING! All changes made in this file will be lost!\n"; + + out << "\n"; + out << "\n"; + out << "from PyTQt.tqt import TQImage, TQMimeSourceFactory"; +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + out << ", tqUncompress"; +#endif + out << "\n"; + out << "\n"; + out << "\n"; + + + TQPtrList<EmbedImage> list_image; + list_image.setAutoDelete( TRUE ); + int image_count = 0; + for ( it = images.begin(); it != images.end(); ++it ) { + TQImage img; + if ( !img.load( *it ) ) { + fprintf( stderr, "pytquic: cannot load image file %s\n", (*it).utf8() ); + continue; + } + EmbedImage *e = new EmbedImage; + e->width = img.width(); + e->height = img.height(); + e->depth = img.depth(); + e->numColors = img.numColors(); + e->colorTable = new TQRgb[e->numColors]; + e->alpha = img.hasAlphaBuffer(); + memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(TQRgb)); + TQFileInfo fi( *it ); + e->name = fi.fileName(); + e->cname = TQString("image_%1").arg( image_count++); + list_image.append( e ); + out << "# " << *it << "\n"; + TQString s; + if ( e->depth == 1 ) + img = img.convertBitOrder(TQImage::BigEndian); + out << s.sprintf( "%s_data =", + (const char *)e->cname ); +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + e->compressed = +#endif + embedData( out, img.bits(), img.numBytes() ); + out << "\n"; + if ( e->numColors ) { + out << s.sprintf( "%s_ctable = [", + (const char *)e->cname ); + embedData( out, e->colorTable, e->numColors ); + out << "\n]\n\n"; + } + } + + if ( !list_image.isEmpty() ) { + out << indent << "embed_image_vec = [\n"; + ++indent; + EmbedImage *e = list_image.first(); + while ( e ) { + out << indent << "[" + << e->width << "," + << e->height << "," + << e->depth << "," + << e->cname << "_data," +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + << e->compressed << "," +#endif + << e->numColors << ","; + if ( e->numColors ) + out << e->cname << "_ctable,"; + else + out << "None,"; + if ( e->alpha ) + out << "1,"; + else + out << "0,"; + out << "\"" << e->name << "\"],\n"; + e = list_image.next(); + } + --indent; + out << indent << "]\n"; + + out << "\n" + "\n" + "def uic_findImage(name):\n"; + ++indent; + out << indent << "global embed_image_vec\n"; + out << "\n"; +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + out << indent << "for (w,h,depth,data,comp,nrCol,colTab,alpha,iname) in embed_image_vec:" << endl; +#else + out << indent << "for (w,h,depth,data,nrCol,colTab,alpha,iname) in embed_image_vec:" << endl; +#endif + ++indent; + out << indent << "if iname == str(name):" << endl; + ++indent; +#ifndef TQT_NO_IMAGE_COLLECTION_COMPRESSION + // Keep the data object alive until we have a deep copy of the image. + out << indent << "data = tqUncompress(data).data()\n"; +#endif + out << indent << "img = TQImage(data,w,h,depth,colTab,nrCol,TQImage.BigEndian).copy()\n"; + out << "\n"; + out << indent << "if alpha:\n"; + ++indent; + out << indent << "img.setAlphaBuffer(1)\n"; + --indent; + out << "\n"; + out << indent << "return img\n"; + --indent; + --indent; + out << endl; + out << indent << "return TQImage()\n"; + --indent; + out << "\n"; + out << "\n"; + + out << indent << "class MimeSourceFactory_" << cProject << "(TQMimeSourceFactory):\n"; + ++indent; + out << indent << "def __init__(self):\n"; + ++indent; + out << indent << "TQMimeSourceFactory.__init__(self)\n"; + out << "\n"; + --indent; + out << indent << "def data(self,abs_name):\n"; + ++indent; + out << indent << "d = TQMimeSourceFactory.data(self,abs_name)\n"; + out << indent << "if d or abs_name.isNull():\n"; + ++indent; + out << indent << "return d\n"; + --indent; + out << "\n"; + out << indent << "img = uic_findImage(abs_name)\n"; + out << indent << "if not img.isNull():\n"; + ++indent; + out << indent << "self.setImage(abs_name,img)\n"; + --indent; + out << "\n"; + out << indent << "return TQMimeSourceFactory.data(self,abs_name)\n"; + --indent; + --indent; + out << "\n"; + out << "\n"; + + out << indent << "factory = None\n"; + out << "\n"; + + out << indent << "def tqInitImages_" << cProject << "():\n"; + ++indent; + out << indent << "global factory\n"; + out << "\n"; + out << indent << "if factory is None:\n"; + ++indent; + out << indent << "factory = MimeSourceFactory_" << cProject << "()\n"; + out << indent << "TQMimeSourceFactory.defaultFactory().addFactory(factory)\n"; + --indent; + --indent; + out << "\n"; + out << "\n"; + + out << indent << "def tqCleanupImages_" << cProject << "():\n"; + ++indent; + out << indent << "global factory\n"; + out << "\n"; + out << indent << "if factory is not None:\n"; + ++indent; + out << indent << "TQMimeSourceFactory.defaultFactory().removeFactory(factory)\n"; + out << indent << "factory = None\n"; + --indent; + --indent; + out << "\n"; + out << "\n"; + + out << indent << "class StaticInitImages_" << cProject << ":\n"; + ++indent; + out << indent << "def __init__(self):\n"; + ++indent; + out << indent << "self.cleanup = tqCleanupImages_" << cProject << "\n"; + out << indent << "tqInitImages_" << cProject << "()\n"; + --indent; + out << "\n"; + out << indent << "def __del__(self):\n"; + ++indent; + out << indent << "self.cleanup()\n"; + --indent; + --indent; + out << "\n"; + out << "\n"; + + out << "staticImages = StaticInitImages_" << cProject << "()\n"; + } +} diff --git a/pytquic3/form.cpp b/pytquic3/form.cpp new file mode 100644 index 0000000..e5912f1 --- /dev/null +++ b/pytquic3/form.cpp @@ -0,0 +1,938 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include <stdio.h> +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <tqstringlist.h> +#include <tqfile.h> +#include <tqfileinfo.h> +#include <tqregexp.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> + +#if TQT_VERSION < 0x030100 +#include <zlib.h> +#endif + +static TQByteArray unzipXPM( TQString data, ulong& length ) +{ +#if TQT_VERSION >= 0x030100 + const int lengthOffset = 4; + int baSize = data.length() / 2 + lengthOffset; + uchar *ba = new uchar[ baSize ]; + for ( int i = lengthOffset; i < baSize; ++i ) { + char h = data[ 2 * (i-lengthOffset) ].latin1(); + char l = data[ 2 * (i-lengthOffset) + 1 ].latin1(); + uchar r = 0; + if ( h <= '9' ) + r += h - '0'; + else + r += h - 'a' + 10; + r = r << 4; + if ( l <= '9' ) + r += l - '0'; + else + r += l - 'a' + 10; + ba[ i ] = r; + } + // tqUncompress() expects the first 4 bytes to be the expected length of the + // uncompressed data + ba[0] = ( length & 0xff000000 ) >> 24; + ba[1] = ( length & 0x00ff0000 ) >> 16; + ba[2] = ( length & 0x0000ff00 ) >> 8; + ba[3] = ( length & 0x000000ff ); + TQByteArray baunzip = tqUncompress( ba, baSize ); + delete[] ba; + return baunzip; +#else + uchar *ba = new uchar[ data.length() / 2 ]; + for ( int i = 0; i < (int)data.length() / 2; ++i ) { + char h = data[ 2 * i ].latin1(); + char l = data[ 2 * i + 1 ].latin1(); + uchar r = 0; + if ( h <= '9' ) + r += h - '0'; + else + r += h - 'a' + 10; + r = r << 4; + if ( l <= '9' ) + r += l - '0'; + else + r += l - 'a' + 10; + ba[ i ] = r; + } + // I'm not sure this makes sense. Why couldn't the compressed data be + // less than 20% of the original data? Maybe it's enough to trust the + // `length' passed as an argument. Quoting the zlib header: + // Upon entry, destLen is the total size of the destination + // buffer, which must be large enough to hold the entire + // uncompressed data. (The size of the uncompressed data must + // have been saved previously by the compressor and transmitted + // to the decompressor by some mechanism outside the scope of + // this compression library.) + // Which is the role of `length'. On the other hand this could prevent + // crashes in some cases of slightly corrupt UIC files. + if ( length < data.length() * 5 ) + length = data.length() * 5; + TQByteArray baunzip( length ); + ::uncompress( (uchar*) baunzip.data(), &length, ba, data.length()/2 ); + delete[] ba; + return baunzip; +#endif +} + + + +/*! + Creates an implementation ( cpp-file ) for the form given in \a e + + \sa createFormDecl(), createObjectImpl() + */ +void Uic::createFormImpl( const TQDomElement &e ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + TQString objName = getObjectName( e ); + + // generate local and local includes required + TQStringList globalIncludes; + TQStringList::Iterator it; + TQStringList sqlClasses; + TQStringList axwidgets, databrowsers; + + TQMap<TQString, CustomInclude> customWidgetIncludes; + TQMap<TQString, TQString> functionImpls; + // find additional slots and functions + TQStringList extraSlots; + TQStringList extraSlotTypes; + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString slotName = n.firstChild().toText().data().stripWhiteSpace(); + if ( slotName.endsWith( ";" ) ) + slotName = slotName.left( slotName.length() - 1 ); + + extraSlots += Parser::cleanArgs(slotName); + extraSlotTypes += n.attribute( "returnType", "void" ); + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "functions" ) { // compatibility + for ( TQDomElement n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "function" ) { + TQString fname = n2.attribute( "name" ); + fname = Parser::cleanArgs( fname ); + functionImpls.insert( fname, n2.firstChild().toText().data() ); + } + } + } + } + + // additional includes (local or global ) and forward declaractions + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) { + if ( s.right( 5 ) == ".ui.h" && !TQFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + globalIncludes += s; + } + } + + // do the local includes afterwards, since global includes have priority on clashes + TQFileInfo fi(fileName); + + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( s.right( 5 ) != ".ui.h" ) + continue; + + if ( !TQFile::exists( s ) ) + { + s = fi.dirPath() + "/" + s; + + if ( !TQFile::exists( s ) ) + continue; + } + + if ( TQFile::exists( s ) ) + { + TQFile f(s); + f.open(IO_ReadOnly); + TQTextStream headerStream(&f); + TQString line; + TQString functionText; + TQString functionName; + TQRegExp rx("void .*::(.*\\(.*\\))"); + int pos, inFunction = 0; + + while (line = headerStream.readLine()) + { + pos = rx.search(line); + + if (pos > -1) + { + if (inFunction) + functionImpls.insert(Parser::cleanArgs(functionName),functionText); + + functionName = rx.cap(1); + functionText = ""; + inFunction = 1; + } + functionText += line + "\n"; + } + + if (inFunction) + functionImpls.insert(Parser::cleanArgs(functionName),functionText); + } + } + } + + // additional custom widget headers + nl = e.parentNode().toElement().elementsByTagName( "header" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) + globalIncludes += s; + } + + // includes for child widgets + for ( it = tags.begin(); it != tags.end(); ++it ) { + nl = e.parentNode().toElement().elementsByTagName( *it ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + TQString name = getClassName( nl.item(i).toElement() ); + if ( name == "Spacer" ) { + globalIncludes += "tqlayout.h"; + globalIncludes += "tqapplication.h"; + continue; + } + if ( name.mid( 1 ) == "ListView" ) + globalIncludes += "tqheader.h"; + else if ( name == "TQAxWidget" ) + axwidgets += getObjectName(nl.item(i).toElement()); + else if ( name == "TQDataBrowser" ) + databrowsers += getObjectName(nl.item(i).toElement()); + if ( name != objClass ) { + int wid = WidgetDatabase::idFromClassName( name ); + TQMap<TQString, CustomInclude>::Iterator it = customWidgetIncludes.find( name ); + if ( it == customWidgetIncludes.end() ) + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + } + + if (globalIncludes.findIndex("tqtable.h") >= 0) + out << indent << "from PyTQt.tqttable import TQTable" << endl; + + if (!axwidgets.empty()) + out << indent << "from PyTQt.tqtaxcontainer import TQAxWidget" << endl; + + if (globalIncludes.findIndex("tqextscintilla.h") >= 0) + out << indent << "from PyTQt.tqtext import TQextScintilla" << endl; + + registerDatabases( e ); + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + sqlClasses += "TQSqlDatabase"; + if ( dbCursors.count() ) + sqlClasses += "TQSqlCursor"; + bool dbForm = FALSE; + if ( dbForms[ "(default)" ].count() ) + dbForm = TRUE; + bool subDbForms = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)" ) { + if ( dbForms[ (*it) ].count() ) { + subDbForms = TRUE; + break; + } + } + } + if ( dbForm || subDbForms ) { + sqlClasses += "TQSqlForm"; + sqlClasses += "TQSqlRecord"; + } + + if (globalIncludes.findIndex("tqdatatable.h") >= 0) + sqlClasses += "TQDataTable"; + + if (globalIncludes.findIndex("tqtableview.h") >= 0) + sqlClasses += "TQTableView"; + + if (globalIncludes.findIndex("tqdatabrowser.h") >= 0) + sqlClasses += "TQDataBrowser"; + + if (globalIncludes.findIndex("tqdataview.h") >= 0) + sqlClasses += "TQDataView"; + + if ( !sqlClasses.empty() ) { + out << indent << "from PyTQt.tqtsql import"; + const char *sep = " "; + + for ( it = sqlClasses.begin(); it != sqlClasses.end(); ++it ) { + out << sep << (*it); + sep = ", "; + } + + out << endl; + } + + // Add any code from the comments. + if (!pyCode.isEmpty()) + out << pyCode; + + out << endl; + + // find out what images are required + TQStringList requiredImages; + static const char *imgTags[] = { "pixmap", "iconset", 0 }; + for ( i = 0; imgTags[i] != 0; i++ ) { + nl = e.parentNode().toElement().elementsByTagName( imgTags[i] ); + for ( int j = 0; j < (int) nl.length(); j++ ) { + TQDomNode nn = nl.item(j); + while ( nn.parentNode() != e.parentNode() ) + nn = nn.parentNode(); + if ( nn.nodeName() != "customwidgets" ) + requiredImages += nl.item(j).firstChild().toText().data(); + } + } + + // register the object and unify its name + objName = registerObject( objName ); + + TQStringList images; + TQStringList xpmImages; + if ( pixmapLoaderFunction.isEmpty() && !externPixmaps ) { + // create images + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "images" ) { + nl = n.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString img = registerObject( nl.item(i).toElement().attribute( "name" ) ); + if ( !requiredImages.contains( img ) ) + continue; + TQDomElement tmp = nl.item(i).firstChild().toElement(); + if ( tmp.tagName() != "data" ) + continue; + TQString format = tmp.attribute("format", "PNG" ); + TQString data = tmp.firstChild().toText().data(); + if ( format == "XPM.GZ" ) { + xpmImages += img; + ulong length = tmp.attribute("length").toULong(); + TQByteArray baunzip = unzipXPM( data, length ); + length = baunzip.size(); + // shouldn't we test the initial `length' against the + // resulting `length' to catch corrupt UIC files? + int a = 0; + out << indent << img << "_data = [" << endl; + while ( baunzip[a] != '\"' ) + a++; + for ( ; a < (int) length; a++ ) + { + char ch; + + if ((ch = baunzip[a]) == '}') + { + out << endl << "]"; + break; + } + + out << ch; + } + out << endl; + } else { + images += img; + out << indent << img << "_data = \\" << endl; + ++indent; + out << indent << "\""; + int a ; + for ( a = 0; a < (int) (data.length()/2)-1; a++ ) { + out << "\\x" << TQString(data[2*a]) << TQString(data[2*a+1]); + if ( a % 12 == 11 ) + out << "\" \\" << endl << indent << "\""; + } + out << "\\x" << TQString(data[2*a]) << TQString(data[2*a+1]) << "\"" << endl; + --indent; + } + } + } + } + out << endl; + } else if ( externPixmaps ) { +#if TQT_VERSION >= 0x030100 + pixmapLoaderFunction = "TQPixmap.fromMimeSource"; +#else + out << indent << "def uic_load_pixmap_" << objName << "(name):" << endl; + ++indent; + out << indent << "pix = TQPixmap()" << endl; + out << indent << "m = TQMimeSourceFactory.defaultFactory().data(name)" << endl; + out << endl; + out << indent << "if m:" << endl; + ++indent; + out << indent << "TQImageDrag.decode(m,pix)" << endl; + --indent; + out << endl; + out << indent << "return pix" << endl; + --indent; + out << endl; + out << endl; + pixmapLoaderFunction = "uic_load_pixmap_" + objName; +#endif + } + + + // constructor(s) + + out << indent << "class " << nameOfClass << "(" << objClass << "):" << endl; + ++indent; + + if ( objClass == "TQDialog" || objClass == "TQWizard" ) { + out << indent << "def __init__(self,parent = None,name = None,modal = 0,fl = 0):" << endl; + ++indent; + out << indent << objClass << ".__init__(self,parent,name,modal,fl)" << endl; + } else if ( objClass == "TQWidget" ) { + out << indent << "def __init__(self,parent = None,name = None,fl = 0):" << endl; + ++indent; + out << indent << objClass << ".__init__(self,parent,name,fl)" << endl; + } else if ( objClass == "TQMainWindow" ) { + out << indent << "def __init__(self,parent = None,name = None,fl = 0):" << endl; + ++indent; + out << indent << objClass << ".__init__(self,parent,name,fl)" << endl; + out << indent << "self.statusBar()" << endl; + isMainWindow = TRUE; + } else { + out << indent << "def __init__(self,parent = None,name = None):" << endl; + ++indent; + out << indent << objClass << ".__init__(self,parent,name)" << endl; + } + + out << endl; + + // create pixmaps for all images + if ( !images.isEmpty() ) { + TQStringList::Iterator it; + for ( it = images.begin(); it != images.end(); ++it ) { + out << indent << "self." << (*it) << " = TQPixmap()" << endl; + out << indent << "self." << (*it) << ".loadFromData(" << (*it) << "_data,\"PNG\")" << endl; + } + } + // create pixmaps for all images + if ( !xpmImages.isEmpty() ) { + for ( it = xpmImages.begin(); it != xpmImages.end(); ++it ) { + out << indent << "self." << (*it) << " = TQPixmap(" << (*it) << "_data)" << endl; + } + out << endl; + } + + + // set the properties + TQSize geometry( 0, 0 ); + + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + TQString prop = n.attribute("name"); + TQDomElement n2 = n.firstChild().toElement(); + TQString value = setObjectProperty( objClass, TQString::null, prop, n2, stdset ); + if ( value.isEmpty() ) + continue; + + if ( prop == "geometry" && n2.tagName() == "rect") { + TQDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + geometry.setWidth( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "height" ) + geometry.setHeight( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else { + TQString call; + if ( stdset ) + call = "self." + mkStdSet( prop ) + "(" + value + ")"; + else + call = "self.setProperty(\"" + prop + "\",TQVariant(" + value + "))"; + + if ( n2.tagName() == "string" ) { + trout << trindent << call << endl; + } else if ( prop == "name" ) { + out << indent << "if not name:" << endl; + ++indent; + out << indent << call << endl; + --indent; + out << endl; + } else { + out << indent << call << endl; + } + } + } + } + + out << endl; + + // create all children, some forms have special requirements + + if ( objClass == "TQWizard" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, "self" ); + TQString comment; + TQString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << "self.addPage(" << page << ",TQString(\"\"))" << endl; + trout << trindent << "self.setTitle(" << page << ","<< trcall( label, comment ) << ")" << endl; + TQVariant def( FALSE ); + if ( DomTool::hasAttribute( n, "backEnabled" ) ) + out << indent << "self.setBackEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "backEnabled", def).toBool() ) << ")" << endl; + if ( DomTool::hasAttribute( n, "nextEnabled" ) ) + out << indent << "self.setNextEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "nextEnabled", def).toBool() ) << ")" << endl; + if ( DomTool::hasAttribute( n, "finishEnabled" ) ) + out << indent << "self.setFinishEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "finishEnabled", def).toBool() ) << ")" << endl; + if ( DomTool::hasAttribute( n, "helpEnabled" ) ) + out << indent << "self.setHelpEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "helpEnabled", def).toBool() ) << ")" << endl; + if ( DomTool::hasAttribute( n, "finish" ) ) + out << indent << "self.setFinish( " << page << "," << mkBool( DomTool::readAttribute( n, "finish", def).toBool() ) << ")" << endl; + } + } + } else { // standard widgets + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objName, "self" ); + } + } + + // database support + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + out << endl; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)") { + out << indent << "self." << (*it) << "Connection = TQSqlDatabase.database(\"" <<(*it) << "\")" << endl; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + TQString s = getClassName( n ); + if ( (dbForm || subDbForms) && (s == "TQDataBrowser" || s == "TQDataView") ) { + TQString objName = getObjectName( n ); + TQString tab = getDatabaseInfo( n, "table" ); + TQString con = getDatabaseInfo( n, "connection" ); + out << indent << objName << "Form = TQSqlForm(self,\"" << objName << "Form\")" << endl; + TQDomElement n2; + for ( n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) + createFormImpl( n2, objName, con, tab ); + out << indent << "self." << objName << ".setForm(" << objName << "Form)" << endl; + } + } + + // actions, toolbars, menubar + bool needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "actions" ) { + if ( !needEndl ) + out << endl; + createActionImpl( n.firstChild().toElement(), "self" ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "toolbars" ) { + if ( !needEndl ) + out << endl; + createToolbarImpl( n, objClass, objName ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "menubar" ) { + if ( !needEndl ) + out << endl; + createMenuBarImpl( n, objClass, objName ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + + out << endl; + out << indent << "self.languageChange()" << endl; + out << endl; + + // take minimumSizeHint() into account, for height-for-width widgets + if ( !geometry.isNull() ) { + out << indent << "self.resize(TQSize(" << geometry.width() << "," + << geometry.height() <<").expandedTo(self.minimumSizeHint()))" << endl; + out << indent << "self.clearWState(TQt.WState_Polished)" << endl; + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "connections" ) { + // setup signals and slots connections + out << endl; + nl = n.elementsByTagName( "connection" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString sender, receiver, signal, slot; + for ( TQDomElement n2 = nl.item(i).firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "sender" ) + sender = n2.firstChild().toText().data(); + else if ( n2.tagName() == "receiver" ) + receiver = n2.firstChild().toText().data(); + else if ( n2.tagName() == "signal" ) + signal = n2.firstChild().toText().data(); + else if ( n2.tagName() == "slot" ) + slot = n2.firstChild().toText().data(); + } + if ( sender.isEmpty() || + receiver.isEmpty() || + signal.isEmpty() || + slot.isEmpty() ) + continue; + if ( sender[0] == '<' || + receiver[0] == '<' || + signal[0] == '<' || + slot[0] == '<' ) + continue; + + sender = registeredName( sender ); + receiver = registeredName( receiver ); + + // translate formwindow name to "self" + if ( sender == objName ) + sender = "self"; + else + sender = "self." + sender; + + bool isaxwidget = (axwidgets.findIndex(receiver) >= 0); + bool isdatabrowser = (databrowsers.findIndex(receiver) >= 0); + + if ( receiver == objName ) + receiver = "self"; + else + receiver = "self." + receiver; + + out << indent << "self.connect(" << sender + << ",SIGNAL(\"" << signal << "\")," << receiver; + + // Normally we never use the SLOT() macro in case the + // connection is to a method of a Python custom widget. The + // exception is if the receiver is a TQAxWidget where it must be + // used because the slots are dynamic. + if (isaxwidget) + out << ",SLOT(\"" << slot << "\")"; + else + { + TQString mname = slot.left(slot.find('(')); + + // Rename slots that have different names in PyTQt. + if (isdatabrowser && mname == "del") + mname = "delOnCursor"; + + out << "." << mname; + } + + out << ")" << endl; + } + } else if ( n.tagName() == "tabstops" ) { + // setup tab order + out << endl; + TQString lastName; + TQDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "tabstop" ) { + TQString name = n2.firstChild().toText().data(); + name = registeredName( name ); + if ( !lastName.isEmpty() ) + out << indent << "self.setTabOrder(self." << lastName << ",self." << name << ")" << endl; + lastName = name; + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // buddies + bool firstBuddy = TRUE; + for ( TQValueList<Buddy>::Iterator buddy = buddies.begin(); buddy != buddies.end(); ++buddy ) { + if ( isObjectRegistered( (*buddy).buddy ) ) { + if ( firstBuddy ) { + out << endl; + } + out << indent << "self." << (*buddy).key << ".setBuddy(self." << registeredName( (*buddy).buddy ) << ")" << endl; + firstBuddy = FALSE; + } + + } + + if ( extraSlots.find( "init()" ) != extraSlots.end() ) + out << endl << indent << "self.init()" << endl; + + // end of constructor + --indent; + + // destructor + if ( extraSlots.find( "destroy()" ) != extraSlots.end() ) { + out << endl; + out << indent << "def __del__(self):" << endl; + ++indent; + out << indent << "self.destroy()" << endl; + --indent; + } + + // handle application events if required + bool needFontEventHandler = FALSE; + bool needSqlTableEventHandler = FALSE; + bool needSqlDataBrowserEventHandler = FALSE; + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + if ( !DomTool::propertiesOfType( nl.item(i).toElement() , "font" ).isEmpty() ) + needFontEventHandler = TRUE; + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQDataTable" || s == "TQDataBrowser" ) { + if ( !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) + continue; + if ( s == "TQDataTable" ) + needSqlTableEventHandler = TRUE; + if ( s == "TQDataBrowser" ) + needSqlDataBrowserEventHandler = TRUE; + } + if ( needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler ) + break; + } + if ( needFontEventHandler && FALSE ) { + // indent = "\t"; // increase indentation for if-clause below + out << "/* " << endl; + out << " * Main event handler. Reimplemented to handle" << endl; + out << " * application font changes"; + out << " */" << endl; + out << "bool " << nameOfClass << "::event( TQEvent* ev )" << endl; + out << "{" << endl; + out << " bool ret = " << objClass << "::event( ev ); " << endl; + if ( needFontEventHandler ) { + ++indent; + out << " if ( ev->type() == TQEvent::ApplicationFontChange ) {" << endl; + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + TQStringList list = DomTool::propertiesOfType( n, "font" ); + for ( it = list.begin(); it != list.end(); ++it ) + createExclusiveProperty( n, *it ); + } + out << " }" << endl; + --indent; + } + out << "}" << endl; + out << endl; + } + + if ( needSqlTableEventHandler || needSqlDataBrowserEventHandler ) { + out << endl; + out << indent << "# Widget polish. Reimplemented to handle default data" << endl; + if ( needSqlTableEventHandler ) + out << indent << "# table initialization." << endl; + if ( needSqlDataBrowserEventHandler ) + out << indent << "# browser initialization." << endl; + out << indent << "def polish(self):" << endl; + ++indent; + if ( needSqlTableEventHandler ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQDataTable" ) { + n = nl.item(i).toElement(); + TQString c = getObjectName( n ); + TQString conn = getDatabaseInfo( n, "connection" ); + TQString tab = getDatabaseInfo( n, "table" ); + if ( !( conn.isEmpty() || tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if self." << c << ":" << endl; + ++indent; + out << indent << "cursor = self." << c << ".sqlCursor()" << endl; + out << endl; + out << indent << "if not cursor:" << endl; + ++indent; + if ( conn == "(default)" ) + out << indent << "cursor = TQSqlCursor(\"" << tab << "\")" << endl; + else + out << indent << "cursor = TQSqlCursor(\"" << tab << "\",1,self." << conn << "Connection)" << endl; + out << indent << "if self." << c << ".isReadOnly():" << endl; + ++indent; + out << indent << "cursor.setMode(TQSqlCursor.ReadOnly)" << endl; + --indent; + out << indent << "self." << c << ".setSqlCursor(cursor,0,1)" << endl; + --indent; + out << endl; + out << indent << "if not cursor.isActive():" << endl; + ++indent; + out << indent << "self." << c << ".refresh(TQDataTable.RefreshAll)" << endl; + --indent; + --indent; + } + } + } + } + if ( needSqlDataBrowserEventHandler ) { + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQDataBrowser" ) { + TQString obj = getObjectName( nl.item(i).toElement() ); + TQString tab = getDatabaseInfo( nl.item(i).toElement(), + "table" ); + TQString conn = getDatabaseInfo( nl.item(i).toElement(), + "connection" ); + if ( !(tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if self." << obj << ":" << endl; + ++indent; + out << indent << "if not self." << obj << ".sqlCursor():" << endl; + ++indent; + if ( conn == "(default)" ) + out << indent << "cursor = TQSqlCursor(\"" << tab << "\")" << endl; + else + out << indent << "cursor = TQSqlCursor(\"" << tab << "\",1,self." << conn << "Connection)" << endl; + out << indent << "self." << obj << ".setSqlCursor(cursor,1)" << endl; + out << indent << "self." << obj << ".refresh()" << endl; + out << indent << "self." << obj << ".first()" << endl; + --indent; + --indent; + } + } + } + } + out << indent << objClass << ".polish(self)" << endl; + --indent; + } + + out << endl; + out << endl; + out << indent << "def languageChange(self):" << endl; + uint old = indent.setIndent(0); + out << languageChangeBody << endl; + indent.setIndent(old); + + // create stubs for additional slots if necessary + if ( !extraSlots.isEmpty() && writeFunctImpl ) { + TQStringList::ConstIterator cit; + + for ( cit = extraSlots.begin(); cit != extraSlots.end(); ++cit ) { + pySlot(cit); + + bool createWarning = TRUE; + TQString fname = Parser::cleanArgs( *cit ); + TQMap<TQString, TQString>::Iterator fit = functionImpls.find( fname ); + if ( fit != functionImpls.end() ) { + int begin = (*fit).find( "{" ); + TQString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 ); + createWarning = body.simplifyWhiteSpace().isEmpty(); + if ( !createWarning ) + { + ++indent; + TQString formatted_body = body.replace(TQRegExp("\n"), TQString("\n") + TQString(indent)); + out << formatted_body << endl; + --indent; + } + } + if ( createWarning ) { + out << endl; + ++indent; + if ( *cit != "init()" && *cit != "destroy()" ) + out << indent << "print(\"" << nameOfClass << "." << (*cit) << ": Not implemented yet\")" << endl; + else + out << indent << "pass" << endl; + --indent; + } + } + } + + --indent; +} + + +/*! Creates form support implementation code for the widgets given + in \a e. + + Traverses recursively over all children. + */ + +void Uic::createFormImpl( const TQDomElement& e, const TQString& form, const TQString& connection, const TQString& table ) +{ + if ( e.tagName() == "widget" && + e.attribute( "class" ) != "TQDataTable" ) { + TQString field = getDatabaseInfo( e, "field" ); + if ( !field.isEmpty() ) { + if ( isWidgetInTable( e, connection, table ) ) + out << indent << form << "Form.insert(self." << getObjectName( e ) << "," << fixString( field ) << ")" << endl; + } + } + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + createFormImpl( n, form, connection, table ); + } +} + + +// Generate a Python slot definition. + +void Uic::pySlot(TQStringList::ConstIterator &it) +{ + out << endl; + + int astart = (*it).find('('); + out << indent << "def " << (*it).left(astart) << "(self"; + + // We don't reproduce the argument names (if any) because we would have to + // remove the types - too complicated for the moment, so we just count them + // and give them names based on their position. + + TQString args = (*it).mid(astart + 1,(*it).find(')') - astart - 1).stripWhiteSpace(); + + if (!args.isEmpty()) { + int nrargs = args.contains(',') + 1; + + for (int i = 0; i < nrargs; ++i) + out << ",a" << i; + } + + out << "):"; +} diff --git a/pytquic3/globaldefs.h b/pytquic3/globaldefs.h new file mode 100644 index 0000000..4704ff9 --- /dev/null +++ b/pytquic3/globaldefs.h @@ -0,0 +1,56 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef GLOBALDEFS_H +#define GLOBALDEFS_H + +#include <tqcolor.h> +#include <tqapplication.h> + +#define BOXLAYOUT_DEFAULT_MARGIN 11 +#define BOXLAYOUT_DEFAULT_SPACING 6 + +#ifndef NO_STATIC_COLORS +static TQColor *backColor1 = 0; +static TQColor *backColor2 = 0; +static TQColor *selectedBack = 0; + +static void init_colors() +{ + if ( backColor1 ) + return; + +#if 0 // a calculated alternative for backColor1 + TQColorGroup myCg = tqApp->palette().active(); + int h1, s1, v1; + int h2, s2, v2; + myCg.color( TQColorGroup::Base ).hsv( &h1, &s1, &v1 ); + myCg.color( TQColorGroup::Background ).hsv( &h2, &s2, &v2 ); + TQColor c( h1, s1, ( v1 + v2 ) / 2, TQColor::Hsv ); +#endif + + backColor1 = new TQColor( 250, 248, 235 ); + backColor2 = new TQColor( 255, 255, 255 ); + selectedBack = new TQColor( 230, 230, 230 ); +} + +#endif + +#endif diff --git a/pytquic3/main.cpp b/pytquic3/main.cpp new file mode 100644 index 0000000..0158545 --- /dev/null +++ b/pytquic3/main.cpp @@ -0,0 +1,244 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <tqapplication.h> +#include <tqfile.h> +#include <tqstringlist.h> +#include <tqdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <tqregexp.h> +#include <stdio.h> +#include <stdlib.h> + +int main( int argc, char * argv[] ) +{ + PyIndent indent; + bool testCode = FALSE, execCode = FALSE; + bool subcl = FALSE; + bool imagecollection = FALSE; + TQStringList images; + const char *error = 0; + const char* fileName = 0; + TQCString outputFile; + const char* projectName = 0; + const char* trmacro = 0; + bool fix = FALSE; + TQApplication app(argc, argv, FALSE); + TQString className, uicClass; + + for ( int n = 1; n < argc && error == 0; n++ ) { + TQCString arg = argv[n]; + if ( arg[0] == '-' ) { // option + TQCString opt = &arg[1]; + if ( opt[0] == 'o' ) { // output redirection + if ( opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing output-file name"; + break; + } + outputFile = argv[++n]; + } else + outputFile = &opt[1]; + } else if ( opt[0] == 'e' || opt == "embed" ) { + imagecollection = TRUE; + if ( opt == "embed" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing name of project"; + break; + } + projectName = argv[++n]; + } else + projectName = &opt[1]; + } else if ( opt == "subimpl" ) { + subcl = TRUE; + if ( !(n < argc-1) ) { + error = "Missing class name"; + break; + } + className = argv[++n]; + } else if ( opt == "tr" ) { + if ( opt == "tr" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing tr macro"; + break; + } + trmacro = argv[++n]; + } else { + trmacro = &opt[1]; + } + } else if ( opt == "version" ) { + fprintf( stderr, + "Python User Interface Compiler %s for TQt version %s\n", + PYTQT_VERSION, TQT_VERSION_STR ); + return 1; + } else if ( opt == "help" ) { + break; + } else if ( opt == "fix" ) { + fix = TRUE; + } else if ( opt[0] == 'p' ) { + uint tabstop; + bool ok; + + if ( opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing Python indent"; + break; + } + tabstop = TQCString(argv[++n]).toUInt(&ok); + } else + tabstop = opt.mid(1).toUInt(&ok); + + if (ok) + indent.setTabStop(tabstop); + else + error = "Invalid Python indent"; + } else if ( opt == "test" ) { + testCode = TRUE; + } else if ( opt == "x" ) { + execCode = TRUE; + } else { + error = "Unrecognized option"; + } + } else { + if ( imagecollection ) + images << argv[n]; + else if ( fileName ) // can handle only one file + error = "Too many input files specified"; + else + fileName = argv[n]; + } + } + + if ( argc < 2 || error || (!fileName && !imagecollection ) ) { + fprintf( stderr, "PyTQt user interface compiler.\n" ); + if ( error ) + fprintf( stderr, "pytquic: %s\n", error ); + + fprintf( stderr, "Usage: %s [options] [mode] <uifile>\n" + "\nGenerate implementation:\n" + " %s [options] <uifile>\n" + "Generate image collection:\n" + " %s [options] -embed <project> <image1> <image2> <image3> ...\n" + "\t<project>\tproject name\n" + "\t<image[0..n]>\timage files\n" + "Generate subclass implementation:\n" + " %s [options] -subimpl <classname> <uifile>\n" + "\t<classname>\tname of the subclass to generate\n" + "Options:\n" + "\t-o file\t\tWrite output to file rather than stdout\n" + "\t-p indent\tSet the Python indent in spaces (0 to use a tab)\n" + "\t-tr func\tUse func() rather than TQApplication.translate() for i18n\n" + "\t-x\t\tGenerate extra code to test and display the class\n" + "\t-test\t\tGenerate extra code to test but not display the class\n" + "\t-version\tDisplay version of pytquic\n" + "\t-help\t\tDisplay this information\n" + , argv[0], argv[0], argv[0], argv[0]); + return 1; + } + + Uic::setIndent(indent); + + TQFile fileOut; + if ( !outputFile.isEmpty() ) { + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) + tqFatal( "pytquic: Could not open output file '%s'", outputFile.data() ); + } else { + fileOut.open( IO_WriteOnly, stdout ); + } + TQTextStream out( &fileOut ); + + if ( imagecollection ) { + out.setEncoding( TQTextStream::UnicodeUTF8 ); + out << "# -*- coding: latin-1 -*-\n\n"; + Uic::embed( out, projectName, images ); + return 0; + } + + + out.setEncoding( TQTextStream::UnicodeUTF8 ); + TQFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) + tqFatal( "pytquic: Could not open file '%s' ", fileName ); + + TQDomDocument doc; + TQString errMsg; + int errLine; + if ( !doc.setContent( &file, &errMsg, &errLine ) ) + tqFatal( TQString("pytquic: Failed to parse %s: ") + errMsg + TQString (" in line %d\n"), fileName, errLine ); + + TQDomElement e = doc.firstChild().toElement(); + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.3 ) { + tqWarning( TQString("pytquic: File generated with too recent version of TQt Designer (%s vs. %s)"), + e.attribute("version").utf8(), TQT_VERSION_STR ); + return 1; + } + + DomTool::fixDocument( doc ); + + if ( fix ) { + out << doc.toString(); + return 0; + } + + out << "# -*- coding: utf-8 -*-\n\n"; + + if ( !subcl ) { + out << "# Form implementation generated from reading ui file '" << fileName << "'" << endl; + out << "#" << endl; + out << "# Created by: The PyTQt User Interface Compiler (pytquic) " << PYTQT_VERSION << endl; + out << "#" << endl; + out << "# WARNING! All changes made in this file will be lost!" << endl; + out << endl; + out << endl; + } + + if (testCode || execCode) + out << "import sys" << endl; + + out << "from PyTQt.tqt import *" << endl; + + Uic( fileName, outputFile, out, doc, subcl, trmacro, className, uicClass ); + + if (testCode || execCode) { + out << endl; + out << indent << "if __name__ == \"__main__\":" << endl; + ++indent; + out << indent << "a = TQApplication(sys.argv)" << endl; + out << indent << "TQObject.connect(a,SIGNAL(\"lastWindowClosed()\"),a,SLOT(\"quit()\"))" << endl; + out << indent << "w = " << (subcl ? className : uicClass) << "()" << endl; + out << indent << "a.setMainWidget(w)" << endl; + + if (execCode) { + out << indent << "w.show()" << endl; + out << indent << "a.exec_loop()" << endl; + } + + --indent; + } + + return 0; +} diff --git a/pytquic3/object.cpp b/pytquic3/object.cpp new file mode 100644 index 0000000..6b26e8c --- /dev/null +++ b/pytquic3/object.cpp @@ -0,0 +1,704 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "domtool.h" +#include <tqregexp.h> +#include <tqsizepolicy.h> +#include <tqstringlist.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> + + +/*! + Creates an implementation for the object given in \a e. + + Traverses recursively over all children. + + Returns the name of the generated child object. + */ + +static bool createdCentralWidget = FALSE; + +TQString Uic::createObjectImpl( const TQDomElement &e, const TQString& parentClass, const TQString& par, const TQString& layout ) +{ + TQString parent( par ); + if ( parent == "self" && isMainWindow ) { + if ( !createdCentralWidget ) + out << indent << "self.setCentralWidget(TQWidget(self,\"tqt_central_widget\"))" << endl; + createdCentralWidget = TRUE; + parent = "self.centralWidget()"; + } + TQDomElement n; + TQString objClass, objName, fullObjName; + int numItems = 0; + int numColumns = 0; + int numRows = 0; + + if ( layouts.contains( e.tagName() ) ) + return createLayoutImpl( e, parentClass, parent, layout ); + + objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return objName; + objName = getObjectName( e ); + + TQString definedName = objName; + bool isTmpObject = objName.isEmpty() || objClass == "TQLayoutWidget"; + if ( isTmpObject ) { + if ( objClass[0] == 'Q' ) + objName = objClass.mid(1); + else + objName = objClass.lower(); + } + + bool isLine = objClass == "Line"; + if ( isLine ) + objClass = "TQFrame"; + + out << endl; + if ( objClass == "TQLayoutWidget" ) { + if ( layout.isEmpty() ) { + // register the object and unify its name + objName = registerObject( objName ); + out << indent << objName << " = TQWidget(" << parent << ",\"" << definedName << "\")" << endl; + } else { + // the layout widget is not necessary, hide it by creating its child in the parent + TQString result; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if (tags.contains( n.tagName() ) ) + result = createObjectImpl( n, parentClass, parent, layout ); + } + return result; + } + + // Layouts don't go into the class instance dictionary. + fullObjName = objName; + } else if ( objClass != "TQToolBar" && objClass != "TQMenuBar" ) { + // register the object and unify its name + objName = registerObject( objName ); + + // Temporary objects don't go into the class instance dictionary. + fullObjName = isTmpObject ? objName : "self." + objName; + + out << indent << fullObjName << " = " << createObjectInstance( objClass, parent, objName ) << endl; + } + else + fullObjName = "self." + objName; + + if ( objClass == "TQAxWidget" ) { + TQString controlId; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.attribute( "name" ) == "control" ) { + controlId = n.firstChild().toElement().text(); + } + } + out << indent << fullObjName << ".setControl(\"" << controlId << "\")" << endl; + } + + lastItem = "None"; + // set the properties and insert items + bool hadFrameShadow = FALSE; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + TQString prop = n.attribute( "name" ); + if ( prop == "database" ) + continue; + TQString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + if ( prop == "name" ) + continue; + if ( isLine && prop == "frameShadow" ) + hadFrameShadow = TRUE; + if ( prop == "buddy" && value.startsWith("\"") && value.endsWith("\"") ) { + buddies << Buddy( objName, value.mid(1, value.length() - 2 ) ); + continue; + } + if ( isLine && prop == "orientation" ) { + prop = "frameShape"; + if ( value.right(10) == "Horizontal" ) + value = "TQFrame.HLine"; + else + value = "TQFrame.VLine"; + if ( !hadFrameShadow ) { + prop = "frameStyle"; + value += " | TQFrame.Sunken"; + } + } + if ( prop == "buttonGroupId" ) { + if ( parentClass == "TQButtonGroup" ) + out << indent << parent << ".insert( " << fullObjName << "," << value << ")" << endl; + continue; + } + if ( prop == "frameworkCode" ) + continue; + if ( objClass == "TQMultiLineEdit" && + TQRegExp("echoMode|hMargin|maxLength|maxLines|undoEnabled").exactMatch(prop) ) + continue; + TQString call = fullObjName + "."; + TQString tail; + if ( stdset ) { + call += mkStdSet( prop ) + "("; + tail = ")"; + } else { + call += "setProperty(\"" + prop + "\",TQVariant("; + tail = "))"; + } + if ( prop == "accel" ) { + call += "TQKeySequence("; + tail += ")"; + } + call += value + tail; + + if ( n.firstChild().toElement().tagName() == "string" || + prop == "currentItem" ) { + trout << trindent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( n.tagName() == "item" ) { + TQString call; + TQString value; + + if ( objClass.contains( "ListBox" ) ) { + call = createListBoxItemImpl( n, fullObjName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << trindent << fullObjName << ".clear()" << endl; + trout << trindent << call << endl; + } + } else if ( objClass.contains( "ComboBox" ) ) { + call = createListBoxItemImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << trindent << fullObjName << ".clear()" << endl; + trout << trindent << call << endl; + } + } else if ( objClass.contains( "IconView" ) ) { + call = createIconViewItemImpl( n, fullObjName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << trindent << fullObjName << ".clear()" << endl; + trout << trindent << call << endl; + } + } else if ( objClass.contains( "ListView" ) ) { + call = createListViewItemImpl( n, fullObjName, TQString::null ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << trindent << fullObjName << ".clear()" << endl; + trout << call << endl; + } + } + if ( !call.isEmpty() ) + numItems++; + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + TQString call; + TQString value; + + if ( objClass.contains( "ListView" ) ) { + call = createListViewColumnImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << trindent << fullObjName << ".header().setLabel(" + << numColumns++ << "," << value << ")\n"; + } + } else if ( objClass == "TQTable" || objClass == "TQDataTable" ) { + bool isCols = ( n.tagName() == "column" ); + call = createTableRowColumnImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << trindent << fullObjName << "." + << ( isCols ? "horizontalHeader" : "verticalHeader" ) + << "().setLabel(" + << ( isCols ? numColumns++ : numRows++ ) + << "," << value << ")\n"; + } + } + } + } + + // create all children, some widgets have special requirements + + if ( objClass == "TQTabWidget" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, fullObjName ); + TQString comment; + TQString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << fullObjName << ".insertTab(" << page << ",TQString.fromUtf8(\"\"))" << endl; + trout << trindent << fullObjName << ".changeTab(" << page << "," << trcall( label, comment ) << ")" << endl; + } + } + } else if ( objClass == "TQWidgetStack" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, fullObjName ); + int id = DomTool::readAttribute( n, "id", "" ).toInt(); + out << indent << fullObjName << ".addWidget(" << page << "," << id << ")" << endl; + } + } + } else if ( objClass == "TQToolBox" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, fullObjName ); + TQString comment; + TQString label = DomTool::readAttribute( n, "label", "", comment ).toString(); + out << indent << fullObjName << ".addItem(" << page << ",TQString.fromUtf8(\"\"))" << endl; + trout << trindent << fullObjName << ".setItemLabel(" << fullObjName + << ".indexOf(" << page << ")," << trcall( label, comment ) + << ")" << endl; + } + } + } else if ( objClass != "TQToolBar" && objClass != "TQMenuBar" ) { // standard widgets + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objClass, fullObjName ); + } + } + + return fullObjName; +} + + + +/*! + Creates a set-call for property \a exclusiveProp of the object + given in \a e. + + If the object does not have this property, the function does nothing. + + Exclusive properties are used to generate the implementation of + application font or palette change handlers in createFormImpl(). + + */ +void Uic::createExclusiveProperty( const TQDomElement & e, const TQString& exclusiveProp ) +{ + TQDomElement n; + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + TQString objName = getObjectName( e ); +#if 0 // it's not clear whether this check should be here or not + if ( objName.isEmpty() ) + return; +#endif + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + TQString prop = n.attribute( "name" ); + if ( prop != exclusiveProp ) + continue; + TQString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + out << indent << indent << objName << ".setProperty(\"" << prop << "\",TQVariant(" << value << "))" << endl; + } + } +} + + +/* Convert a TQSizePolicy::SizeType to text. */ +static TQString mapSizeType(TQSizePolicy::SizeType st) +{ + const char *txt; + + switch (st) + { + case TQSizePolicy::Fixed: + txt = "TQSizePolicy.Fixed"; + break; + + case TQSizePolicy::Minimum: + txt = "TQSizePolicy.Minimum"; + break; + + case TQSizePolicy::Maximum: + txt = "TQSizePolicy.Maximum"; + break; + + case TQSizePolicy::Preferred: + txt = "TQSizePolicy.Preferred"; + break; + + case TQSizePolicy::MinimumExpanding: + txt = "TQSizePolicy.MinimumExpanding"; + break; + + case TQSizePolicy::Expanding: + txt = "TQSizePolicy.Expanding"; + break; + + case TQSizePolicy::Ignored: + txt = "TQSizePolicy.Ignored"; + break; + + default: + txt = "Invalid TQSizePolicy::SizeType"; + } + + return txt; +} + + +/*! Attention: this function has to be in sync with + Resource::saveProperty() and DomTool::elementToVariant. If you + change one, change all. + */ +TQString Uic::setObjectProperty( const TQString& objClass, const TQString& obj, const TQString &prop, const TQDomElement &e, bool stdset ) +{ + TQString v; + if ( e.tagName() == "rect" ) { + TQDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQRect(%1,%2,%3,%4)"; + v = v.arg(x).arg(y).arg(w).arg(h); + + } else if ( e.tagName() == "point" ) { + TQDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQPoint(%1,%2)"; + v = v.arg(x).arg(y); + } else if ( e.tagName() == "size" ) { + TQDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQSize(%1,%2)"; + v = v.arg(w).arg(h); + } else if ( e.tagName() == "color" ) { + TQDomElement n3 = e.firstChild().toElement(); + int r = 0, g = 0, b = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "red" ) + r = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "green" ) + g = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "blue" ) + b = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQColor(%1,%2,%3)"; + v = v.arg(r).arg(g).arg(b); + } else if ( e.tagName() == "font" ) { + TQDomElement n3 = e.firstChild().toElement(); + TQString attrname = e.parentNode().toElement().attribute( "name", "font" ); + TQString fontname; + if ( !obj.isEmpty() ) { + fontname = registerObject( obj + "_" + attrname ); + out << indent << fontname << " = TQFont(self." << obj << ".font())" << endl; + } else { + fontname = registerObject( "f" ); + out << indent << fontname << " = TQFont(self.font())" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + out << indent << fontname << ".setFamily(\"" << n3.firstChild().toText().data() << "\")" << endl; + else if ( n3.tagName() == "pointsize" ) + out << indent << fontname << ".setPointSize(" << n3.firstChild().toText().data() << ")" << endl; + else if ( n3.tagName() == "bold" ) + out << indent << fontname << ".setBold(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + else if ( n3.tagName() == "italic" ) + out << indent << fontname << ".setItalic(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + else if ( n3.tagName() == "underline" ) + out << indent << fontname << ".setUnderline(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + else if ( n3.tagName() == "strikeout" ) + out << indent << fontname << ".setStrikeOut(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + n3 = n3.nextSibling().toElement(); + } + + if ( prop == "font" ) { + if ( !obj.isEmpty() ) + out << indent << "self." << obj << ".setFont(" << fontname << ")" << endl; + else + out << indent << "self.setFont(" << fontname << ")" << endl; + } else { + v = fontname; + } + } else if ( e.tagName() == "string" ) { + TQString txt = e.firstChild().toText().data(); + TQString com = getComment( e.parentNode() ); + + if ( prop == "toolTip" && objClass != "TQAction" && objClass != "TQActionGroup" ) { + if ( !obj.isEmpty() ) + trout << trindent << "TQToolTip.add(self." << obj << "," + << trcall( txt, com ) << ")" << endl; + else + trout << trindent << "TQToolTip.add(self," + << trcall( txt, com ) << ")" << endl; + } else if ( prop == "whatsThis" && objClass != "TQAction" && objClass != "TQActionGroup" ) { + if ( !obj.isEmpty() ) + trout << trindent << "TQWhatsThis.add(self." << obj << "," + << trcall( txt, com ) << ")" << endl; + else + trout << trindent << "TQWhatsThis.add(self," + << trcall( txt, com ) << ")" << endl; + } else { + v = trcall( txt, com ); + } + } else if ( e.tagName() == "cstring" ) { + v = "\"%1\""; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "number" ) { + v = "%1"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "bool" ) { + if ( stdset ) + v = "%1"; + else + v = "TQVariant(%1)"; + v = v.arg( mkBool( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "pixmap" ) { + v = e.firstChild().toText().data(); + if ( !v.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + v.prepend( "self." ); + } else { + v.prepend( pixmapLoaderFunction + "(" + TQString( externPixmaps ? "\"" : "" ) ); + v.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } else if ( e.tagName() == "iconset" ) { + v = "TQIconSet(%1)"; + TQString s = e.firstChild().toText().data(); + if ( !s.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + s.prepend( "self." ); + } else { + s.prepend( pixmapLoaderFunction + "(" + TQString( externPixmaps ? "\"" : "" ) ); + s.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + v = v.arg( s ); + } else if ( e.tagName() == "image" ) { + v = e.firstChild().toText().data() + ".convertToImage()"; + } else if ( e.tagName() == "enum" ) { + v = "%1.%2"; + TQString oc = objClass; + TQString ev = e.firstChild().toText().data(); + if ( oc == "TQListView" && ev == "Manual" ) // #### workaround, rename TQListView::Manual in 4.0 + oc = "TQScrollView"; + v = v.arg( oc ).arg( ev ); + } else if ( e.tagName() == "set" ) { + TQString keys( e.firstChild().toText().data() ); + TQStringList lst = TQStringList::split( '|', keys ); + v = ""; + TQStringList::Iterator it = lst.begin(); + while ( it != lst.end() ) { + v += objClass + "." + *it; + if ( it != lst.fromLast() ) + v += " | "; + ++it; + } + } else if ( e.tagName() == "sizepolicy" ) { + TQDomElement n3 = e.firstChild().toElement(); + TQSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (TQSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (TQSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + TQString tmp = "self."; + if ( !obj.isEmpty() ) + tmp += obj + "."; + v = "TQSizePolicy(%1,%2,%3,%4," + tmp + "sizePolicy().hasHeightForWidth())"; + v = v.arg( mapSizeType(sp.horData()) ).arg( mapSizeType(sp.verData()) ).arg( sp.horStretch() ).arg( sp.verStretch() ); + } else if ( e.tagName() == "palette" ) { + TQPalette pal; + bool no_pixmaps = e.elementsByTagName( "pixmap" ).count() == 0; + TQDomElement n; + if ( no_pixmaps ) { + n = e.firstChild().toElement(); + while ( !n.isNull() ) { + TQColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + pal.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + pal.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + pal.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + } + if ( no_pixmaps && pal == TQPalette( pal.active().button(), pal.active().background() ) ) { + v = "TQPalette(TQColor(%1,%2,%3),TQColor(%1,%2,%3))"; + v = v.arg( pal.active().button().red() ).arg( pal.active().button().green() ).arg( pal.active().button().blue() ); + v = v.arg( pal.active().background().red() ).arg( pal.active().background().green() ).arg( pal.active().background().blue() ); + } else { + TQString palette = "pal"; + if ( !pal_used ) { + out << indent << palette << " = TQPalette()" << endl; + pal_used = TRUE; + } + TQString cg = "cg"; + if ( !cg_used ) { + out << indent << cg << " = TQColorGroup()" << endl; + cg_used = TRUE; + } + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "active" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setActive(" << cg << ")" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "inactive" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setInactive(" << cg << ")" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "disabled" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setDisabled(" << cg << ")" << endl; + v = palette; + } + } else if ( e.tagName() == "cursor" ) { + v = "TQCursor(%1)"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "date" ) { + TQDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQDate(%1,%2,%3)"; + v = v.arg(y).arg(m).arg(d); + } else if ( e.tagName() == "time" ) { + TQDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQTime(%1,%2,%3)"; + v = v.arg(h).arg(m).arg(s); + } else if ( e.tagName() == "datetime" ) { + TQDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQDateTime(TQDate(%1,%2,%3),TQTime(%4,%5,%6))"; + v = v.arg(y).arg(mo).arg(d).arg(h).arg(mi).arg(s); + } else if ( e.tagName() == "stringlist" ) { + TQStringList l; + TQDomElement n3 = e.firstChild().toElement(); + TQString listname = "l"; + if ( !obj.isEmpty() ) { + listname = obj + "_stringlist"; + listname = registerObject( listname ); + out << indent << listname << " = TQStringList()" << endl; + } else { + out << indent << listname << " = TQStringList()" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "string" ) + out << indent << listname << ".append(\"" << n3.firstChild().toText().data().simplifyWhiteSpace() << "\")" << endl; + n3 = n3.nextSibling().toElement(); + } + v = listname; + } + return v; +} + + + + +/*! Extracts a named object property from \a e. + */ +TQDomElement Uic::getObjectProperty( const TQDomElement& e, const TQString& name ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); + !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.toElement().attribute("name") == name ) + return n; + } + return n; +} + diff --git a/pytquic3/parser.cpp b/pytquic3/parser.cpp new file mode 100644 index 0000000..fc6aae4 --- /dev/null +++ b/pytquic3/parser.cpp @@ -0,0 +1,66 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "parser.h" +#include <tqobject.h> +#include <tqstringlist.h> + +class NormalizeObject : public TQObject +{ +public: + NormalizeObject() : TQObject() {} + static TQCString normalizeSignalSlot( const char *signalSlot ) { return TQObject::normalizeSignalSlot( signalSlot ); } +}; + +TQString Parser::cleanArgs( const TQString &func ) +{ + TQString slot( func ); + int begin = slot.find( "(" ) + 1; + TQString args = slot.mid( begin ); + args = args.left( args.find( ")" ) ); + TQStringList lst = TQStringList::split( ',', args ); + TQString res = slot.left( begin ); + for ( TQStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( it != lst.begin() ) + res += ","; + TQString arg = *it; + int pos = 0; + if ( ( pos = arg.find( "&" ) ) != -1 ) { + arg = arg.left( pos + 1 ); + } else if ( ( pos = arg.find( "*" ) ) != -1 ) { + arg = arg.left( pos + 1 ); + } else { + arg = arg.simplifyWhiteSpace(); + if ( ( pos = arg.find( ':' ) ) != -1 ) + arg = arg.left( pos ).simplifyWhiteSpace() + ":" + arg.mid( pos + 1 ).simplifyWhiteSpace(); + TQStringList l = TQStringList::split( ' ', arg ); + if ( l.count() == 2 ) { + if ( l[ 0 ] != "const" && l[ 0 ] != "unsigned" && l[ 0 ] != "var" ) + arg = l[ 0 ]; + } else if ( l.count() == 3 ) { + arg = l[ 0 ] + " " + l[ 1 ]; + } + } + res += arg; + } + res += ")"; + + return TQString::fromUtf8( NormalizeObject::normalizeSignalSlot( res.utf8() ) ); +} diff --git a/pytquic3/parser.h b/pytquic3/parser.h new file mode 100644 index 0000000..5fdbdc2 --- /dev/null +++ b/pytquic3/parser.h @@ -0,0 +1,33 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef PARSER_H +#define PARSER_H + +#include <tqstring.h> + +class Parser +{ +public: + static TQString cleanArgs( const TQString &func ); + +}; + +#endif diff --git a/pytquic3/pytquic-prof.sbf b/pytquic3/pytquic-prof.sbf new file mode 100644 index 0000000..8a5cfa7 --- /dev/null +++ b/pytquic3/pytquic-prof.sbf @@ -0,0 +1,24 @@ +# This is the build file for pytquic for TQt v3 Professional Edition. +# +# Copyright (c) 2007 +# Riverbank Computing Limited <info@riverbankcomputing.co.uk> +# +# This file is part of PyTQt. +# +# This copy of PyTQt is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. +# +# PyTQt is supplied 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 General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# PyTQt; see the file LICENSE. If not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +target = pytquic +sources = main.cpp uic.cpp form.cpp object.cpp subclassing.cpp embed.cpp widgetdatabase.cpp domtool.cpp parser.cpp tqdom.cpp tqxml.cpp +headers = domtool.h globaldefs.h parser.h uic.h widgetdatabase.h widgetinterface.h diff --git a/pytquic3/pytquic.pro.in b/pytquic3/pytquic.pro.in new file mode 100644 index 0000000..326e0e5 --- /dev/null +++ b/pytquic3/pytquic.pro.in @@ -0,0 +1,36 @@ +# Copyright (c) 2001 +# Phil Thompson <phil@river-bank.demon.co.uk> +# Copyright (c) 2002, 2003 +# Riverbank Computing Limited <info@riverbankcomputing.co.uk> +# +# The project file for pytquic for TQt v3. + + +TEMPLATE = app +CONFIG += tqt console warn_on release @PYTQT_RBPROF@ +INCLUDEPATH += @BLX_INCLUDEPATH@ $(TQTDIR)/src/3rdparty/zlib +DEFINES += UIC TQT_INTERNAL_XML @BLX_DEFINES@ + +DESTDIR = @PYTQT_BINDIR@ +TARGET = pytquic + +HEADERS = uic.h \ + widgetdatabase.h \ + domtool.h \ + parser.h \ + widgetinterface.h + +SOURCES = main.cpp \ + uic.cpp \ + form.cpp \ + object.cpp \ + subclassing.cpp \ + embed.cpp \ + widgetdatabase.cpp \ + domtool.cpp \ + parser.cpp + +rbprof:exists($(TQTDIR)/src/tqt_professional.pri) { + TQT_SOURCE_TREE = $(TQTDIR) + include($(TQTDIR)/src/tqt_professional.pri) +} diff --git a/pytquic3/pytquic.sbf b/pytquic3/pytquic.sbf new file mode 100644 index 0000000..86360b6 --- /dev/null +++ b/pytquic3/pytquic.sbf @@ -0,0 +1,24 @@ +# This is the build file for pytquic for TQt v3. +# +# Copyright (c) 2007 +# Riverbank Computing Limited <info@riverbankcomputing.co.uk> +# +# This file is part of PyTQt. +# +# This copy of PyTQt is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. +# +# PyTQt is supplied 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 General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# PyTQt; see the file LICENSE. If not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +target = pytquic +sources = main.cpp uic.cpp form.cpp object.cpp subclassing.cpp embed.cpp widgetdatabase.cpp domtool.cpp parser.cpp +headers = domtool.h globaldefs.h parser.h uic.h widgetdatabase.h widgetinterface.h diff --git a/pytquic3/subclassing.cpp b/pytquic3/subclassing.cpp new file mode 100644 index 0000000..9cb1ee1 --- /dev/null +++ b/pytquic3/subclassing.cpp @@ -0,0 +1,185 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <tqfile.h> +#include <tqstringlist.h> +#include <tqdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <tqregexp.h> +#include <stdio.h> +#include <stdlib.h> + + +/*! + Creates an implementation for a subclass \a subClass of the form + given in \a e + + \sa createSubDecl() + */ +void Uic::createSubImpl( const TQDomElement &e, const TQString& subClass ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + + TQString supClsMod = fileName; + int tail = supClsMod.findRev('.',-1); + if (tail >= 0) + supClsMod.truncate(tail); + + out << indent << "from " << supClsMod << " import " << nameOfClass << endl; + out << endl; + out << endl; + + out << indent << "class " << subClass << "(" << nameOfClass << "):" << endl; + ++indent; + out << endl; + + // constructor + if ( objClass == "TQDialog" || objClass == "TQWizard" ) { + out << indent << "def __init__(self,parent = None,name = None,modal = 0,fl = 0):" << endl; + ++indent; + out << indent << nameOfClass << ".__init__(self,parent,name,modal,fl)" << endl; + } else { // standard TQWidget + out << indent << "def __init__(self,parent = None,name = None,fl = 0):" << endl; + ++indent; + out << indent << nameOfClass << ".__init__(self,parent,name,fl)" << endl; + } + --indent; + + // find additional functions + TQStringList publicSlots, protectedSlots, privateSlots; + TQStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + TQStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + TQStringList publicFuncts, protectedFuncts, privateFuncts; + TQStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + TQStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString returnType = n.attribute( "returnType", "void" ); + TQString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + TQString specifier = n.attribute( "specifier" ); + TQString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedSlots += functionName; + protectedSlotTypes += returnType; + protectedSlotSpecifier += specifier; + } else if ( access == "private" ) { + privateSlots += functionName; + privateSlotTypes += returnType; + privateSlotSpecifier += specifier; + } else { + publicSlots += functionName; + publicSlotTypes += returnType; + publicSlotSpecifier += specifier; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString returnType = n.attribute( "returnType", "void" ); + TQString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + TQString specifier = n.attribute( "specifier" ); + TQString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedFuncts += functionName; + protectedFunctRetTyp += returnType; + protectedFunctSpec += specifier; + } else if ( access == "private" ) { + privateFuncts += functionName; + privateFunctRetTyp += returnType; + privateFunctSpec += specifier; + } else { + publicFuncts += functionName; + publicFunctRetTyp += returnType; + publicFunctSpec += specifier; + } + } + + if ( !publicFuncts.isEmpty() ) + writeFunctionsSubImpl( publicFuncts, publicFunctRetTyp, publicFunctSpec, subClass, "public function" ); + + // create stubs for public additional slots + if ( !publicSlots.isEmpty() ) + writeFunctionsSubImpl( publicSlots, publicSlotTypes, publicSlotSpecifier, subClass, "public slot" ); + + if ( !protectedFuncts.isEmpty() ) + writeFunctionsSubImpl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec, subClass, "protected function" ); + + // create stubs for protected additional slots + if ( !protectedSlots.isEmpty() ) + writeFunctionsSubImpl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier, subClass, "protected slot" ); + + if ( !privateFuncts.isEmpty() ) + writeFunctionsSubImpl( privateFuncts, privateFunctRetTyp, privateFunctSpec, subClass, "private function" ); + + // create stubs for private additional slots + if ( !privateSlots.isEmpty() ) + writeFunctionsSubImpl( privateSlots, privateSlotTypes, privateSlotSpecifier, subClass, "private slot" ); + + --indent; +} + +void Uic::writeFunctionsSubImpl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst, + const TQString &subClass, const TQString &descr ) +{ + TQValueListConstIterator<TQString> it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + TQString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + out << endl; + out << indent << "# " << descr << endl; + pySlot(it); + ++indent; + out << endl; + out << indent << "print(\"" << subClass << "." << (*it) << ": Not implemented yet\")" << endl; + --indent; + } + out << endl; +} diff --git a/pytquic3/uic.cpp b/pytquic3/uic.cpp new file mode 100644 index 0000000..8d0613c --- /dev/null +++ b/pytquic3/uic.cpp @@ -0,0 +1,1145 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2004 Phil Thompson <phil@riverbankcomputing.co.uk> +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <tqfile.h> +#include <tqstringlist.h> +#include <tqdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <tqregexp.h> +#include <stdio.h> +#include <stdlib.h> + +bool Uic::isMainWindow = FALSE; +PyIndent Uic::indent; +PyIndent Uic::trindent; + + +// Re-calculate the indent string based on the current number and nature of the +// indent. +void PyIndent::calc() +{ + indstr.truncate(0); + + for (uint i = current; i > 0; --i) + if (tabStop == 0) + indstr += '\t'; + else + for (uint t = 0; t < tabStop; ++t) + indstr += ' '; +} + + +TQString Uic::getComment( const TQDomNode& n ) +{ + TQDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == "comment" ) + return child.toElement().firstChild().toText().data(); + child = child.nextSibling(); + } + return TQString::null; +} + +TQString Uic::mkBool( bool b ) +{ + return b? "1" : "0"; +} + +TQString Uic::mkBool( const TQString& s ) +{ + return mkBool( s == "true" || s == "1" ); +} + +bool Uic::toBool( const TQString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +TQString Uic::fixString( const TQString &str, bool encode ) +{ +#if TQT_VERSION >= 0x030100 + TQString s; + if ( !encode ) { + s = str; + s.replace( "\\", "\\\\" ); + s.replace( "\"", "\\\"" ); + s.replace( "\r", "" ); + s.replace( "\n", "\\n\"\n\"" ); + } else { + TQCString utf8 = str.utf8(); + const int l = utf8.length(); + + for ( int i = 0; i < l; ++i ) { + uchar ch = (uchar)utf8[i]; + + if (ch != 0x0d) { // skip \r + s += "\\x"; + + if (ch <= 0x0f) + s += "0"; + + s += TQString::number( ch, 16 ); + } + } + } +#else + TQString s( str ); + s.replace( TQRegExp( "\\\\" ), "\\\\" ); + s.replace( TQRegExp( "\"" ), "\\\"" ); + s.replace( TQRegExp( "\r?\n" ), "\\n\"\n\"" ); +#endif + return "\"" + s + "\""; +} + +TQString Uic::trcall( const TQString& sourceText, const TQString& comment ) +{ + if ( sourceText.isEmpty() && comment.isEmpty() ) + return "TQString.null"; + + TQString t = trmacro; + bool encode = FALSE; + if ( t.isNull() ) { + t = "self.__tr"; + for ( int i = 0; i < (int) sourceText.length(); i++ ) { + if ( sourceText[i].unicode() >= 0x80 ) { + t = "self.__trUtf8"; + encode = TRUE; + break; + } + } + + if (encode) + pyNeedTrUtf8 = TRUE; + else + pyNeedTr = TRUE; + } + + if ( comment.isEmpty() ) { + return t + "(" + fixString( sourceText, encode ) + ")"; + } else { + return t + "(" + fixString( sourceText, encode ) + "," + + fixString( comment, encode ) + ")"; + } +} + +TQString Uic::mkStdSet( const TQString& prop ) +{ + return TQString( "set" ) + prop[0].upper() + prop.mid(1); +} + + + +/*! + \class Uic uic.h + \brief User Interface Compiler + + The class Uic encapsulates the user interface compiler (uic). + */ +Uic::Uic( const TQString &fn, const char *outputFn, TQTextStream &outStream, + TQDomDocument doc, bool subcl, const TQString &trm, + const TQString& subClass, TQString &uicClass ) + : out( outStream ), trout (&languageChangeBody ), + outputFileName( outputFn ), trmacro( trm ), + pyNeedTr(FALSE), pyNeedTrUtf8(FALSE) +{ + fileName = fn; + writeFunctImpl = TRUE; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + externPixmaps = FALSE; + + trindent.setIndent(2); + + item_used = cg_used = pal_used = 0; + + layouts << "hbox" << "vbox" << "grid"; + tags = layouts; + tags << "widget"; + + pixmapLoaderFunction = getPixmapLoaderFunction( doc.firstChild().toElement() ); + nameOfClass = getFormClassName( doc.firstChild().toElement() ); + +#if TQT_VERSION >= 0x030300 + uiFileVersion = doc.firstChild().toElement().attribute("version"); +#endif + stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") ); + + if ( doc.firstChild().isNull() || doc.firstChild().firstChild().isNull() ) + return; + + // Extract any Python code in the comments. + TQStringList comm = TQStringList::split('\n',getComment(doc.firstChild())); + + for (TQStringList::Iterator it = comm.begin(); it != comm.end(); ++it) + if ((*it).startsWith("Python:")) + pyCode += (*it).mid(7) + "\n"; + + TQDomElement e = doc.firstChild().firstChild().toElement(); + TQDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "widget" ) { + widget = e; + } else if ( e.tagName() == "pixmapinproject" ) { + externPixmaps = TRUE; + } else if ( e.tagName() == "layoutdefaults" ) { + defSpacing = e.attribute( "spacing", defSpacing.toString() ); + defMargin = e.attribute( "margin", defMargin.toString() ); + } else if ( e.tagName() == "layoutfunctions" ) { + defSpacing = e.attribute( "spacing", defSpacing.toString() ); + + bool ok; + defSpacing.toInt( &ok ); + if ( !ok ) { + TQString buf = defSpacing.toString(); + defSpacing = buf.append( "()" ); + } + defMargin = e.attribute( "margin", defMargin.toString() ); + defMargin.toInt( &ok ); + if ( !ok ) { + TQString buf = defMargin.toString(); + defMargin = buf.append( "()" ); + } + } + e = e.nextSibling().toElement(); + } + e = widget; + + if ( nameOfClass.isEmpty() ) + nameOfClass = getObjectName( e ); + + uicClass = nameOfClass; + + namespaces = TQStringList::split( "::", nameOfClass ); + bareNameOfClass = namespaces.last(); + namespaces.remove( namespaces.fromLast() ); + + if ( subcl ) { + createSubImpl( e, subClass ); + } else { + createFormImpl( e ); + } + + ++indent; + + if (pyNeedTr) + { + out << "\n"; + out << indent << "def __tr(self,s,c = None):\n"; + ++indent; + out << indent << "return tqApp.translate(b\"" << nameOfClass << "\",s.encode(),c)\n"; + --indent; + } + + if (pyNeedTrUtf8) + { + out << "\n"; + out << indent << "def __trUtf8(self,s,c = None):\n"; + ++indent; + out << indent << "return tqApp.translate(b\"" << nameOfClass << "\",s.encode(),c,TQApplication.UnicodeUTF8)\n"; + --indent; + } + + --indent; +} + +/*! Extracts a pixmap loader function from \a e + */ +TQString Uic::getPixmapLoaderFunction( const TQDomElement& e ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "pixmapfunction" ) + return n.firstChild().toText().data(); + } + return TQString::null; +} + + +/*! Extracts the forms class name from \a e + */ +TQString Uic::getFormClassName( const TQDomElement& e ) +{ + TQDomElement n; + TQString cn; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "class" ) { + TQString s = n.firstChild().toText().data(); + int i; + while ( ( i = s.find(' ' )) != -1 ) + s[i] = '_'; + cn = s; + } + } + return cn; +} + +/*! Extracts a class name from \a e. + */ +TQString Uic::getClassName( const TQDomElement& e ) +{ + TQString s = e.attribute( "class" ); + if ( s.isEmpty() && e.tagName() == "toolbar" ) + s = "TQToolBar"; + else if ( s.isEmpty() && e.tagName() == "menubar" ) + s = "TQMenuBar"; + return s; +} + +/*! Returns TRUE if database framework code is generated, else FALSE. +*/ + +bool Uic::isFrameworkCodeGenerated( const TQDomElement& e ) +{ + TQDomElement n = getObjectProperty( e, "frameworkCode" ); + if ( n.attribute("name") == "frameworkCode" && + !DomTool::elementToVariant( n.firstChild().toElement(), TQVariant( TRUE ) ).toBool() ) + return FALSE; + return TRUE; +} + +/*! Extracts an object name from \a e. It's stored in the 'name' + property. + */ +TQString Uic::getObjectName( const TQDomElement& e ) +{ + TQDomElement n = getObjectProperty( e, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) + return n.firstChild().toElement().firstChild().toText().data(); + return TQString::null; +} + +/*! Extracts an layout name from \a e. It's stored in the 'name' + property of the preceeding sibling (the first child of a TQLayoutWidget). + */ +TQString Uic::getLayoutName( const TQDomElement& e ) +{ + TQDomElement p = e.parentNode().toElement(); + TQString name; + + if ( getClassName(p) != "TQLayoutWidget" ) + name = "Layout"; + + TQDomElement n = getObjectProperty( p, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) { + name.prepend( n.firstChild().toElement().firstChild().toText().data() ); + return TQStringList::split( "::", name ).last(); + } + return e.tagName(); +} + + +TQString Uic::getDatabaseInfo( const TQDomElement& e, const TQString& tag ) +{ + TQDomElement n; + TQDomElement n1; + int child = 0; + // database info is a stringlist stored in this order + if ( tag == "connection" ) + child = 0; + else if ( tag == "table" ) + child = 1; + else if ( tag == "field" ) + child = 2; + else + return TQString::null; + n = getObjectProperty( e, "database" ); + if ( n.firstChild().toElement().tagName() == "stringlist" ) { + // find correct stringlist entry + TQDomElement n1 = n.firstChild().firstChild().toElement(); + for ( int i = 0; i < child && !n1.isNull(); ++i ) + n1 = n1.nextSibling().toElement(); + if ( n1.isNull() ) + return TQString::null; + return n1.firstChild().toText().data(); + } + return TQString::null; +} + + +/*! + Returns include file for class \a className or a null string. + */ +TQString Uic::getInclude( const TQString& className ) +{ + int wid = WidgetDatabase::idFromClassName( className ); + if ( wid != -1 ) + return WidgetDatabase::includeFile( wid ); + return TQString::null; +} + + +void Uic::createActionImpl( const TQDomElement &n, const TQString &parent ) +{ + for ( TQDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) { + TQString objName = registerObject( getObjectName( ae ) ); + if ( ae.tagName() == "action" ) + out << indent << "self." << objName << " = TQAction(" << parent << ",\"" << objName << "\")" << endl; + else if ( ae.tagName() == "actiongroup" ) + out << indent << "self." << objName << " = TQActionGroup(" << parent << ",\"" << objName << "\")" << endl; + else + continue; + bool subActionsDone = FALSE; +#if TQT_VERSION >= 0x030300 + bool hasMenuText = FALSE; + TQString actionText; +#endif + for ( TQDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n2.hasAttribute( "stdset" ) ) + stdset = toBool( n2.attribute( "stdset" ) ); + TQString prop = n2.attribute("name"); + if ( prop == "name" ) + continue; + TQString value = setObjectProperty( "TQAction", objName, prop, n2.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + + TQString call = "self." + objName + "."; + if ( stdset ) + call += mkStdSet( prop ) + "(" + value + ")"; + else + call += "setProperty(\"" + prop + "\",TQVariant(" + value + "))"; + +#if TQT_VERSION >= 0x030300 + if (prop == "menuText") + hasMenuText = TRUE; + else if (prop == "text") + actionText = value; +#endif + + if ( n2.firstChild().toElement().tagName() == "string" ) { + trout << trindent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) { + createActionImpl( n2, "self." + objName ); + subActionsDone = TRUE; + } + } +#if TQT_VERSION >= 0x030300 + // workaround for loading pre-3.3 files expecting bogus TQAction behavior + if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3") + trout << indent << "self." << objName << ".setMenuText(" << actionText << ")" << endl; +#endif + } +} + +TQString get_dock( const TQString &d ) +{ + if ( d == "0" ) + return "TQt.DockUnmanaged"; + if ( d == "1" ) + return "TQt.DockTornOff"; + if ( d == "2" ) + return "TQt.DockTop"; + if ( d == "3" ) + return "TQt.DockBottom"; + if ( d == "4" ) + return "TQt.DockRight"; + if ( d == "5" ) + return "TQt.DockLeft"; + if ( d == "6" ) + return "TQt.DockMinimized"; + return ""; +} + +void Uic::createToolbarImpl( const TQDomElement &n, const TQString &parentClass, const TQString &parent ) +{ + TQDomNodeList nl = n.elementsByTagName( "toolbar" ); + for ( int i = 0; i < (int) nl.length(); i++ ) { + TQDomElement ae = nl.item( i ).toElement(); + TQString dock = get_dock( ae.attribute( "dock" ) ); + TQString objName = getObjectName( ae ); + out << indent << "self." << objName << " = TQToolBar(TQString(\"\"),self," << dock << ")" << endl; + createObjectImpl( ae, parentClass, parent ); + for ( TQDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "action" ) { + out << indent << "self." << n2.attribute( "name" ) << ".addTo(self." << objName << ")" << endl; + } else if ( n2.tagName() == "separator" ) { + out << indent << "self." << objName << ".addSeparator()" << endl; + } else if ( n2.tagName() == "widget" ) { + if ( n2.attribute( "class" ) != "Spacer" ) { + createObjectImpl( n2, "TQToolBar", "self." + objName ); + } else { + TQString child = createSpacerImpl( n2, parentClass, parent, objName ); + out << indent << "TQApplication.sendPostedEvents(self." << objName + << ",TQEvent.ChildInserted)" << endl; + out << indent << "self." << objName << ".boxLayout().addItem(" << child << ")" << endl; + } + } + } + } +} + +void Uic::createMenuBarImpl( const TQDomElement &n, const TQString &parentClass, const TQString &parent ) +{ + TQString objName = getObjectName( n ); + out << indent << "self." << objName << " = TQMenuBar(self,\"" << objName << "\")" << endl; + createObjectImpl( n, parentClass, parent ); + + int i = 0; + TQDomElement c = n.firstChild().toElement(); + while ( !c.isNull() ) { + if ( c.tagName() == "item" ) { + TQString itemName = "self." + c.attribute( "name" ); + out << endl; + out << indent << itemName << " = TQPopupMenu(self)" << endl; + createPopupMenuImpl( c, parentClass, itemName ); + out << indent << "self." << objName << ".insertItem(TQString(\"\")," << itemName << "," << i << ")" << endl; + TQString findItem("self." + objName + ".findItem(%1)"); + findItem = findItem.arg(i); + trout << indent << "if " << findItem << ":" << endl; + ++indent; + trout << indent << findItem << ".setText(" << trcall( c.attribute( "text" ) ) << ")" << endl; + --indent; + } else if ( c.tagName() == "separator" ) { + out << endl; + out << indent << "self." << objName << ".insertSeparator(" << i << ")" << endl; + } + c = c.nextSibling().toElement(); + i++; + } +} + +void Uic::createPopupMenuImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ) +{ + int i = 0; + for ( TQDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + TQDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + TQString itemName = "self." + n2.attribute( "name" ); + TQString itemText = n2.attribute( "text" ); + out << indent << itemName << " = TQPopupMenu(self)" << endl; + out << indent << parent << ".setAccel(" << trcall( n2.attribute( "accel" ) ) << ","; + out << parent << ".insertItem(" << "self." << n.attribute( "name" ) << ".iconSet(),"; + out << trcall( itemText ) << "," << itemName << "))" << endl; + trout << indent << parent << ".changeItem(" << parent << ".idAt(" << i << "),"; + trout << trcall( itemText ) << ")" << endl; + createPopupMenuImpl( n2, parentClass, itemName ); + n = n2; + } else { + out << indent << "self." << n.attribute( "name" ) << ".addTo(" << parent << ")" << endl; + } + } else if ( n.tagName() == "separator" ) { + out << indent << parent << ".insertSeparator()" << endl; + } + ++i; + } +} + +/*! + Creates implementation of an listbox item tag. +*/ + +TQString Uic::createListBoxItemImpl( const TQDomElement &e, const TQString &parent , + TQString *value ) +{ + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute( "name" ); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + pix.prepend( "self." ); + } else { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "self." ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + if ( pix.isEmpty() ) + return parent + ".insertItem(" + trcall( txt, com ) + ")"; + + return parent + ".insertItem(" + pix + "," + trcall( txt, com ) + ")"; +} + +/*! + Creates implementation of an iconview item tag. +*/ + +TQString Uic::createIconViewItemImpl( const TQDomElement &e, const TQString &parent ) +{ + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute( "name" ); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + pix.prepend( "self." ); + } else { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "self." ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } + } + n = n.nextSibling().toElement(); + } + + if ( pix.isEmpty() ) + return "TQIconViewItem(" + parent + "," + trcall( txt, com ) + ")"; + else + return "TQIconViewItem(" + parent + "," + trcall( txt, com ) + "," + pix + ")"; +} + +/*! + Creates implementation of an listview item tag. +*/ + +TQString Uic::createListViewItemImpl( const TQDomElement &e, const TQString &parent, + const TQString &parentItem ) +{ + TQString s; + + TQDomElement n = e.firstChild().toElement(); + + bool hasChildren = e.elementsByTagName( "item" ).count() > 0; + TQString item; + + if ( hasChildren ) { + item = registerObject( "item" ); + } else { + item = "item"; + item_used = TRUE; + } + s = trindent + item + " = "; + + if ( !parentItem.isEmpty() ) + s += "TQListViewItem(" + parentItem + "," + lastItem + ")\n"; + else + s += "TQListViewItem(" + parent + "," + lastItem + ")\n"; + + TQStringList texts; + TQStringList pixmaps; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute("name"); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) + texts << v.toString(); + else if ( attrib == "pixmap" ) { + TQString pix = v.toString(); + if ( !pix.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + pix.prepend( "self." ); + } else { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "self." ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + pixmaps << pix; + } + } else if ( n.tagName() == "item" ) { + s += trindent + item + ".setOpen(1)\n"; + s += createListViewItemImpl( n, parent, item ); + } + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < (int)texts.count(); ++i ) { + if ( !texts[ i ].isEmpty() ) + s += trindent + item + ".setText(" + TQString::number( i ) + "," + trcall( texts[ i ] ) + ")\n"; + if ( !pixmaps[ i ].isEmpty() ) + s += trindent + item + ".setPixmap(" + TQString::number( i ) + "," + pixmaps[ i ] + ")\n"; + } + + lastItem = item; + return s; +} + +/*! + Creates implementation of an listview column tag. +*/ + +TQString Uic::createListViewColumnImpl( const TQDomElement &e, const TQString &parent, + TQString *value ) +{ + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + bool clickable = FALSE, resizable = FALSE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute("name"); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + pix.prepend( "self." ); + } else { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "self." ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" || attrib == "resizeable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + TQString s; + s = indent + parent + ".addColumn(" + trcall( txt, com ) + ")\n"; + if ( !pix.isEmpty() ) + s += indent + parent + ".header().setLabel(" + parent + ".header().count() - 1,TQIconSet(" + pix + ")," + trcall( txt, com ) + ")\n"; + if ( !clickable ) + s += indent + parent + ".header().setClickEnabled(0," + parent + ".header().count() - 1)\n"; + if ( !resizable ) + s += indent + parent + ".header().setResizeEnabled(0," + parent + ".header().count() - 1)\n"; + return s; +} + +TQString Uic::createTableRowColumnImpl( const TQDomElement &e, const TQString &parent, + TQString *value ) +{ + TQString objClass = getClassName( e.parentNode().toElement() ); + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + TQString field; + bool isRow = e.tagName() == "row"; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute("name"); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() ) { + if ( pixmapLoaderFunction.isEmpty() ) { + pix.prepend( "self." ); + } else { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "self." ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } else if ( attrib == "field" ) + field = v.toString(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + // ### This generated code sucks! We have to set the number of + // rows/cols before and then only do setLabel/() + // ### careful, though, since TQDataTable has an API which makes this code pretty good + + TQString s; + if ( isRow ) { + s = indent + parent + ".setNumRows(" + parent + ".numRows() + 1)\n"; + if ( pix.isEmpty() ) + s += indent + parent + ".verticalHeader().setLabel(" + parent + ".numRows() - 1," + + trcall( txt, com ) + ")\n"; + else + s += indent + parent + ".verticalHeader().setLabel(" + parent + ".numRows() - 1,TQIconSet(" + + pix + ")," + trcall( txt, com ) + ")\n"; + } else { + if ( objClass == "TQTable" ) { + s = indent + parent + ".setNumCols(" + parent + ".numCols() + 1)\n"; + if ( pix.isEmpty() ) + s += indent + parent + ".horizontalHeader().setLabel(" + parent + ".numCols() - 1," + + trcall( txt, com ) + ")\n"; + else + s += indent + parent + ".horizontalHeader().setLabel(" + parent + ".numCols() - 1,TQIconSet(" + + pix + ")," + trcall( txt, com ) + ")\n"; + } else if ( objClass == "TQDataTable" ) { + if ( !txt.isEmpty() && !field.isEmpty() ) { + if ( pix.isEmpty() ) + out << indent << parent << ".addColumn(" << fixString( field ) << "," << trcall( txt, com ) << ")" << endl; + else + out << indent << parent << ".addColumn(" << fixString( field ) << "," << trcall( txt, com ) << ",TQIconSet(" << pix << "))" << endl; + } + } + } + return s; +} + +/*! + Creates the implementation of a layout tag. Called from createObjectImpl(). + */ +TQString Uic::createLayoutImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout ) +{ + TQDomElement n; + TQString objClass, objName; + objClass = e.tagName(); + + TQString qlayout = "TQVBoxLayout"; + if ( objClass == "hbox" ) + qlayout = "TQHBoxLayout"; + else if ( objClass == "grid" ) + qlayout = "TQGridLayout"; + + bool isGrid = e.tagName() == "grid" ; + objName = registerObject( getLayoutName( e ) ); + layoutObjects += objName; + + TQString margin = DomTool::readProperty( e, "margin", defMargin ).toString(); + TQString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString(); + TQString resizeMode = DomTool::readProperty( e, "resizeMode", TQString::null ).toString(); + + TQString optcells; + if ( isGrid ) + optcells = "1,1,"; + if ( (parentClass == "TQGroupBox" || parentClass == "TQButtonGroup") && layout.isEmpty() ) { + // special case for group box + out << indent << parent << ".setColumnLayout(0,TQt.Vertical)" << endl; + out << indent << parent << ".layout().setSpacing(" << spacing << ")" << endl; + out << indent << parent << ".layout().setMargin(" << margin << ")" << endl; + out << indent << objName << " = " << qlayout << "(" << parent << ".layout())" << endl; + out << indent << objName << ".setAlignment(TQt.AlignTop)" << endl; + } else { + out << indent << objName << " = " << qlayout << "("; + if ( layout.isEmpty() ) + out << parent; + else { + out << "None"; + if ( !DomTool::hasProperty( e, "margin" ) ) + margin = "0"; + } + out << "," << optcells << margin << "," << spacing << ",\"" << objName << "\")" << endl; + } + if ( !resizeMode.isEmpty() ) + out << indent << objName << ".setResizeMode(TQLayout." << resizeMode << ")" << endl; + + if ( !isGrid ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "spacer" ) { + TQString child = createSpacerImpl( n, parentClass, parent, objName ); + out << indent << objName << ".addItem(" << child << ")" << endl; + } else if ( tags.contains( n.tagName() ) ) { + TQString child = createObjectImpl( n, parentClass, parent, objName ); + if ( isLayout( child ) ) + out << indent << objName << ".addLayout(" << child << ")" << endl; + else + out << indent << objName << ".addWidget(" << child << ")" << endl; + } + } + } else { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + TQDomElement ae = n; + int row = ae.attribute( "row" ).toInt(); + int col = ae.attribute( "column" ).toInt(); + int rowspan = ae.attribute( "rowspan" ).toInt(); + int colspan = ae.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + if ( n.tagName() == "spacer" ) { + TQString child = createSpacerImpl( n, parentClass, parent, objName ); + if ( rowspan * colspan != 1 ) + out << indent << objName << ".addMultiCell(" << child << "," + << row << "," << ( row + rowspan - 1 ) << "," << col << "," << ( col + colspan - 1 ) << ")" << endl; + else + out << indent << objName << ".addItem(" << child << "," + << row << "," << col << ")" << endl; + } else if ( tags.contains( n.tagName() ) ) { + TQString child = createObjectImpl( n, parentClass, parent, objName ); + out << endl; + TQString o = "Widget"; + if ( isLayout( child ) ) + o = "Layout"; + if ( rowspan * colspan != 1 ) + out << indent << objName << ".addMultiCell" << o << "(" << child << "," + << row << "," << ( row + rowspan - 1 ) << "," << col << "," << ( col + colspan - 1 ) << ")" << endl; + else + out << indent << objName << ".add" << o << "(" << child << "," + << row << "," << col << ")" << endl; + } + } + } + + return objName; +} + + + +TQString Uic::createSpacerImpl( const TQDomElement &e, const TQString& /*parentClass*/, const TQString& /*parent*/, const TQString& /*layout*/) +{ + TQDomElement n; + TQString objClass, objName; + objClass = e.tagName(); + objName = registerObject( getObjectName( e ) ); + + TQSize size = DomTool::readProperty( e, "sizeHint", TQSize( 0, 0 ) ).toSize(); + TQString sizeType = DomTool::readProperty( e, "sizeType", "Expanding" ).toString(); + bool isVspacer = DomTool::readProperty( e, "orientation", "Horizontal" ) == "Vertical"; + + if ( sizeType != "Expanding" && sizeType != "MinimumExpanding" && + DomTool::hasProperty( e, "geometry" ) ) { // compatibility TQt 2.2 + TQRect geom = DomTool::readProperty( e, "geometry", TQRect(0,0,0,0) ).toRect(); + size = geom.size(); + } + + if ( isVspacer ) + out << indent << objName << " = TQSpacerItem(" + << size.width() << "," << size.height() + << ",TQSizePolicy.Minimum,TQSizePolicy." << sizeType << ")" << endl; + else + out << indent << objName << " = TQSpacerItem(" + << size.width() << "," << size.height() + << ",TQSizePolicy." << sizeType << ",TQSizePolicy.Minimum)" << endl; + + return objName; +} + +static const char* const ColorRole[] = { + "Foreground", "Button", "Light", "Midlight", "Dark", "Mid", + "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow", + "Highlight", "HighlightedText", "Link", "LinkVisited", 0 +}; + + +/*! + Creates a colorgroup with name \a name from the color group \a cg + */ +void Uic::createColorGroupImpl( const TQString& name, const TQDomElement& e ) +{ + TQColorGroup cg; + int r = -1; + TQDomElement n = e.firstChild().toElement(); + TQString color; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + TQColor col = DomTool::readColor( n ); + color = "TQColor(%1,%2,%3)"; + color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() ); + if ( col == white ) + color = "TQt.white"; + else if ( col == black ) + color = "TQt.black"; + if ( n.nextSibling().toElement().tagName() != "pixmap" ) { + out << indent << name << ".setColor(TQColorGroup." << ColorRole[r] << "," << color << ")" << endl; + } + } else if ( n.tagName() == "pixmap" ) { + TQString pixmap = n.firstChild().toText().data(); + if ( pixmapLoaderFunction.isEmpty() ) { + pixmap.prepend( "self." ); + } else { + pixmap.prepend( pixmapLoaderFunction + "(" + TQString( externPixmaps ? "\"" : "self." ) ); + pixmap.append( TQString( externPixmaps ? "\"" : "" ) + ")" ); + } + out << indent << name << ".setBrush(TQColorGroup." + << ColorRole[r] << ",TQBrush(" << color << "," << pixmap << "))" << endl; + } + n = n.nextSibling().toElement(); + } +} + +/*! + Auxiliary function to load a color group. The colorgroup must not + contain pixmaps. + */ +TQColorGroup Uic::loadColorGroup( const TQDomElement &e ) +{ + TQColorGroup cg; + int r = -1; + TQDomElement n = e.firstChild().toElement(); + TQColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (TQColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +/*! Returns TRUE if the widget properties specify that it belongs to + the database \a connection and \a table. +*/ + +bool Uic::isWidgetInTable( const TQDomElement& e, const TQString& connection, const TQString& table ) +{ + TQString conn = getDatabaseInfo( e, "connection" ); + TQString tab = getDatabaseInfo( e, "table" ); + if ( conn == connection && tab == table ) + return TRUE; + return FALSE; +} + +/*! + Registers all database connections, cursors and forms. +*/ + +void Uic::registerDatabases( const TQDomElement& e ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); ++i ) { + n = nl.item(i).toElement(); + TQString conn = getDatabaseInfo( n, "connection" ); + TQString tab = getDatabaseInfo( n, "table" ); + TQString fld = getDatabaseInfo( n, "field" ); + if ( !conn.isNull() ) { + dbConnections += conn; + if ( !tab.isNull() ) { + dbCursors[conn] += tab; + if ( !fld.isNull() ) + dbForms[conn] += tab; + } + } + } +} + +/*! + Registers an object with name \a name. + + The returned name is a valid variable identifier, as similar to \a + name as possible and guaranteed to be unique within the form. + + \sa registeredName(), isObjectRegistered() + */ +TQString Uic::registerObject( const TQString& name ) +{ + if ( objectNames.isEmpty() ) { + // some temporary variables we need + objectNames += "img"; + objectNames += "item"; + objectNames += "cg"; + objectNames += "pal"; + } + + TQString result = name; + int i; + while ( ( i = result.find(' ' )) != -1 ) { + result[i] = '_'; + } + + if ( objectNames.contains( result ) ) { + int i = 2; + while ( objectNames.contains( result + "_" + TQString::number(i) ) ) + i++; + result += "_"; + result += TQString::number(i); + } + objectNames += result; + objectMapper.insert( name, result ); + return result; +} + +/*! + Returns the registered name for the original name \a name + or \a name if \a name wasn't registered. + + \sa registerObject(), isObjectRegistered() + */ +TQString Uic::registeredName( const TQString& name ) +{ + if ( !objectMapper.contains( name ) ) + return name; + return objectMapper[name]; +} + +/*! + Returns whether the object \a name was registered yet or not. + */ +bool Uic::isObjectRegistered( const TQString& name ) +{ + return objectMapper.contains( name ); +} + + +/*! + Unifies the entries in stringlist \a list. Should really be a TQStringList feature. + */ +TQStringList Uic::unique( const TQStringList& list ) +{ + if ( list.isEmpty() ) + return list; + + TQStringList result; + for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { + if ( !result.contains(*it) ) + result += *it; + } + return result; +} + + + +/*! + Creates an instance of class \a objClass, with parent \a parent and name \a objName + */ +TQString Uic::createObjectInstance( const TQString& objClass, const TQString& parent, const TQString& objName ) +{ + + if ( objClass.mid( 1 ) == "ComboBox" ) { + return objClass + "(0," + parent + ",\"" + objName + "\")"; + } + return objClass + "(" + parent + ",\"" + objName + "\")"; +} + +bool Uic::isLayout( const TQString& name ) const +{ + return layoutObjects.contains( name ); +} diff --git a/pytquic3/uic.h b/pytquic3/uic.h new file mode 100644 index 0000000..1cda66b --- /dev/null +++ b/pytquic3/uic.h @@ -0,0 +1,183 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef UIC_H +#define UIC_H +#include <tqdom.h> +#include <tqstring.h> +#include <tqstringlist.h> +#include <tqmap.h> +#include <tqtextstream.h> +#include <tqpalette.h> +#include <tqvariant.h> + + +#define PYTQT_VERSION "3.18.1" + + +class PyIndent +{ +public: + PyIndent() : tabStop(4), current(0) {calc();} + + void setTabStop(uint n) {tabStop = n; calc();} + uint setIndent(uint i) {uint old = current; current = i; calc(); return old;} + void operator++() {++current; calc();} + void operator--() {--current; calc();} + operator TQString() {return indstr;} + +private: + uint tabStop; + uint current; + TQString indstr; + + void calc(); +}; + + +class Uic : public TQt +{ +public: + Uic( const TQString &fn, const char *outputFn, TQTextStream& out, + TQDomDocument doc, bool subcl, const TQString &trm, + const TQString& subclname, TQString &uicClass ); + + static void setIndent(const PyIndent &pyind) {indent = pyind; trindent = pyind;} + + void createFormImpl( const TQDomElement &e ); + + void createSubImpl( const TQDomElement &e, const TQString& subclname ); + + void createActionImpl( const TQDomElement& e, const TQString &parent ); + void createToolbarImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ); + void createMenuBarImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ); + void createPopupMenuImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ); + TQString createObjectImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout = TQString::null ); + TQString createLayoutImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout = TQString::null ); + TQString createObjectInstance( const TQString& objClass, const TQString& parent, const TQString& objName ); + TQString createSpacerImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout = TQString::null ); + void createExclusiveProperty( const TQDomElement & e, const TQString& exclusiveProp ); + TQString createListBoxItemImpl( const TQDomElement &e, const TQString &parent, TQString *value = 0 ); + TQString createIconViewItemImpl( const TQDomElement &e, const TQString &parent ); + TQString createListViewColumnImpl( const TQDomElement &e, const TQString &parent, TQString *value = 0 ); + TQString createTableRowColumnImpl( const TQDomElement &e, const TQString &parent, TQString *value = 0 ); + TQString createListViewItemImpl( const TQDomElement &e, const TQString &parent, + const TQString &parentItem ); + void createColorGroupImpl( const TQString& cg, const TQDomElement& e ); + TQColorGroup loadColorGroup( const TQDomElement &e ); + + TQDomElement getObjectProperty( const TQDomElement& e, const TQString& name ); + TQString getPixmapLoaderFunction( const TQDomElement& e ); + TQString getFormClassName( const TQDomElement& e ); + TQString getClassName( const TQDomElement& e ); + TQString getObjectName( const TQDomElement& e ); + TQString getLayoutName( const TQDomElement& e ); + TQString getInclude( const TQString& className ); + + TQString setObjectProperty( const TQString& objClass, const TQString& obj, const TQString &prop, const TQDomElement &e, bool stdset ); + + TQString registerObject( const TQString& name ); + TQString registeredName( const TQString& name ); + bool isObjectRegistered( const TQString& name ); + TQStringList unique( const TQStringList& ); + + TQString trcall( const TQString& sourceText, const TQString& comment = "" ); + + static void embed( TQTextStream& out, const char* project, const TQStringList& images ); + +private: + TQTextStream& out; + TQTextOStream trout; + TQString languageChangeBody; + TQCString outputFileName; + TQStringList objectNames; + TQMap<TQString,TQString> objectMapper; + TQStringList tags; + TQStringList layouts; + TQString formName; + TQString lastItem; + TQString trmacro; + static PyIndent indent, trindent; + + struct Buddy + { + Buddy( const TQString& k, const TQString& b ) + : key( k ), buddy( b ) {} + Buddy(){} // for valuelist + TQString key; + TQString buddy; + bool operator==( const Buddy& other ) const + { return (key == other.key); } + }; + struct CustomInclude + { + TQString header; + TQString location; + }; + TQValueList<Buddy> buddies; + + TQStringList layoutObjects; + bool isLayout( const TQString& name ) const; + + uint item_used : 1; + uint cg_used : 1; + uint pal_used : 1; + uint stdsetdef : 1; + uint externPixmaps : 1; + +#if TQT_VERSION >= 0x030300 + TQString uiFileVersion; +#endif + TQString nameOfClass; + TQStringList namespaces; + TQString bareNameOfClass; + TQString pixmapLoaderFunction; + + void registerDatabases( const TQDomElement& e ); + bool isWidgetInTable( const TQDomElement& e, const TQString& connection, const TQString& table ); + bool isFrameworkCodeGenerated( const TQDomElement& e ); + TQString getDatabaseInfo( const TQDomElement& e, const TQString& tag ); + void createFormImpl( const TQDomElement& e, const TQString& form, const TQString& connection, const TQString& table ); + void writeFunctionsSubImpl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst, + const TQString &subClass, const TQString &descr ); + TQStringList dbConnections; + TQMap< TQString, TQStringList > dbCursors; + TQMap< TQString, TQStringList > dbForms; + + static bool isMainWindow; + static TQString mkBool( bool b ); + static TQString mkBool( const TQString& s ); + bool toBool( const TQString& s ); + static TQString fixString( const TQString &str, bool encode = FALSE ); + static bool onlyAscii; + static TQString mkStdSet( const TQString& prop ); + static TQString getComment( const TQDomNode& n ); + TQVariant defSpacing, defMargin; + TQString fileName; + bool writeFunctImpl; + + void pySlot(TQStringList::ConstIterator &it); + + TQString pyCode; + bool pyNeedTr, pyNeedTrUtf8; +}; + +#endif diff --git a/pytquic3/widgetdatabase.cpp b/pytquic3/widgetdatabase.cpp new file mode 100644 index 0000000..3e075b0 --- /dev/null +++ b/pytquic3/widgetdatabase.cpp @@ -0,0 +1,953 @@ +/********************************************************************** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition +** licenses may use this file in accordance with the TQt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about TQt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "widgetdatabase.h" +#include "widgetinterface.h" + +#include <tqapplication.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <tqstrlist.h> +#include <tqdict.h> +#include <tqfile.h> +#include <tqtextstream.h> +#include <tqcleanuphandler.h> +#include <tqfeatures.h> + +#include <stdlib.h> + +const int dbsize = 300; +const int dbcustom = 200; +const int dbdictsize = 211; +static WidgetDatabaseRecord* db[ dbsize ]; +static TQDict<int> *className2Id = 0; +static int dbcount = 0; +static int dbcustomcount = 200; +static TQStrList *wGroups; +static TQStrList *invisibleGroups; +static bool whatsThisLoaded = FALSE; +static TQPluginManager<WidgetInterface> *widgetPluginManager = 0; +static bool plugins_set_up = FALSE; +static bool was_in_setup = FALSE; + +TQCleanupHandler<TQPluginManager<WidgetInterface> > cleanup_manager; + +WidgetDatabaseRecord::WidgetDatabaseRecord() +{ + isForm = FALSE; + isContainer = FALSE; + icon = 0; + nameCounter = 0; + isCommon = FALSE; + isPlugin = FALSE; +} + +WidgetDatabaseRecord::~WidgetDatabaseRecord() +{ + delete icon; +} + + +/*! + \class WidgetDatabase widgetdatabase.h + \brief The WidgetDatabase class holds information about widgets + + The WidgetDatabase holds information about widgets like toolTip(), + iconSet(), ... It works Id-based, so all access functions take the + widget id as parameter. To get the id for a widget (classname), use + idFromClassName(). + + All access functions are static. Having multiple widgetdatabases in + one application doesn't make sense anyway and so you don't need more + than an instance of the widgetdatabase. + + For creating widgets, layouts, etc. see WidgetFactory. +*/ + +/*! + Creates widget database. Does nothing. +*/ + +WidgetDatabase::WidgetDatabase() +{ +} + +/*! Sets up the widget database. If the static widgetdatabase already + exists, the functions returns immediately. +*/ + +void WidgetDatabase::setupDataBase( int id ) +{ + was_in_setup = TRUE; +#ifndef UIC + Q_UNUSED( id ) + if ( dbcount ) + return; +#else + if ( dbcount && id != -2 ) + return; + if ( dbcount && !plugins_set_up ) { + setupPlugins(); + return; + } + if ( dbcount && plugins_set_up) + return; +#endif + + wGroups = new TQStrList; + invisibleGroups = new TQStrList; + invisibleGroups->append( "Forms" ); + invisibleGroups->append( "Temp" ); + className2Id = new TQDict<int>( dbdictsize ); + className2Id->setAutoDelete( TRUE ); + + WidgetDatabaseRecord *r = 0; + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_pushbutton.png"; + r->name = "TQPushButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Push Button"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_toolbutton.png"; + r->name = "TQToolButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Tool Button"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_radiobutton.png"; + r->name = "TQRadioButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Radio Button"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_checkbox.png"; + r->name = "TQCheckBox"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Check Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_groupbox.png"; + r->name = "TQGroupBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Group Box"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_buttongroup.png"; + r->name = "TQButtonGroup"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Button Group"; + r->isContainer = TRUE; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_frame.png"; + r->name = "TQFrame"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Frame"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "TQTabWidget"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tabwidget"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_widgetstack.png"; + r->name = "TQWidgetStack"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Widget Stack"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_toolbox.png"; + r->name = "TQToolBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tool Box"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_listbox.png"; + r->name = "TQListBox"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_listview.png"; + r->name = "TQListView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List View"; + + append( r ); + +#if !defined(TQT_NO_ICONVIEW) || defined(UIC) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_iconview.png"; + r->name = "TQIconView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Icon View"; + + append( r ); +#endif + +#if !defined(TQT_NO_TABLE) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_table.png"; + r->name = "TQTable"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Table"; + + append( r ); +#endif + +#if !defined(TQT_NO_SQL) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_datatable.png"; + r->includeFile = "tqdatatable.h"; + r->name = "TQDataTable"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Table"; + + append( r ); +#endif + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_lineedit.png"; + r->name = "TQLineEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Line Edit"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_spinbox.png"; + r->name = "TQSpinBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Spin Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_dateedit.png"; + r->name = "TQDateEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date Edit"; + r->includeFile = "tqdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_timeedit.png"; + r->name = "TQTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Time Edit"; + r->includeFile = "tqdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_datetimeedit.png"; + r->name = "TQDateTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date-Time Edit"; + r->includeFile = "tqdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_multilineedit.png"; + r->name = "TQMultiLineEdit"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Multi Line Edit"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_richtextedit.png"; + r->name = "TQTextEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Rich Text Edit"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_combobox.png"; + r->name = "TQComboBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Combo Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_slider.png"; + r->name = "TQSlider"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Slider"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_scrollbar.png"; + r->name = "TQScrollBar"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Scrollbar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_dial.png"; + r->name = "TQDial"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Dial"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_label.png"; + r->name = "TQLabel"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Label"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_label.png"; + r->name = "TextLabel"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Text Label"; + r->whatsThis = "The Text Label provides a widget to display static text."; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_pixlabel.png"; + r->name = "PixmapLabel"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Pixmap Label"; + r->whatsThis = "The Pixmap Label provides a widget to display pixmaps."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_lcdnumber.png"; + r->name = "TQLCDNumber"; + r->group = widgetGroup( "Display" ); + r->toolTip = "LCD Number"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_line.png"; + r->name = "Line"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Line"; + r->includeFile = "tqframe.h"; + r->whatsThis = "The Line widget provides horizontal and vertical lines."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_progress.png"; + r->name = "TQProgressBar"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Progress Bar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_textview.png"; + r->name = "TQTextView"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Text View"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_textbrowser.png"; + r->name = "TQTextBrowser"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Text Browser"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_spacer.png"; + r->name = "Spacer"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Spacer"; + r->whatsThis = "The Spacer provides horizontal and vertical spacing to be able to manipulate the behaviour of layouts."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "TQWidget"; + r->isForm = TRUE; + r->group = widgetGroup( "Forms" ); + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "TQDialog"; + r->group = widgetGroup( "Forms" ); + r->isForm = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "TQWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "TQDesignerWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "TQLayoutWidget"; + r->group = widgetGroup( "Temp" ); + r->includeFile = ""; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "TQSplitter"; + r->group = widgetGroup( "Temp" ); + r->includeFile = "tqsplitter.h"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "TQDesignerTabWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "TQDesignerWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "TQDesignerDialog"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "TQMainWindow"; + r->includeFile = "tqmainwindow.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "TQDesignerAction"; + r->includeFile = "tqaction.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = FALSE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "TQDesignerActionGroup"; + r->includeFile = "tqaction.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = FALSE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "TQScrollView"; + r->includeFile = "tqscrollview.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + +#ifndef TQT_NO_SQL + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "TQDataBrowser"; + r->includeFile = "tqdatabrowser.h"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Browser"; + r->iconSet = "designer_databrowser.png"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "TQDataView"; + r->includeFile = "tqdataview.h"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data View"; + r->iconSet = "designer_dataview.png"; + r->isContainer = TRUE; + + append( r ); +#endif + +#ifndef UIC + setupPlugins(); +#endif +} + +void WidgetDatabase::setupPlugins() +{ + if ( plugins_set_up ) + return; + plugins_set_up = TRUE; + TQStringList widgets = widgetManager()->featureList(); + for ( TQStringList::Iterator it = widgets.begin(); it != widgets.end(); ++it ) { + if ( hasWidget( *it ) ) + continue; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + WidgetInterface *iface = 0; + widgetManager()->queryInterface( *it, &iface ); + if ( !iface ) + continue; + +#ifndef UIC + TQIconSet icon = iface->iconSet( *it ); + if ( !icon.pixmap().isNull() ) + r->icon = new TQIconSet( icon ); +#endif + TQString grp = iface->group( *it ); + if ( grp.isEmpty() ) + grp = "3rd party widgets"; + r->group = widgetGroup( grp ); + r->toolTip = iface->toolTip( *it ); + r->whatsThis = iface->whatsThis( *it ); + r->includeFile = iface->includeFile( *it ); + r->isContainer = iface->isContainer( *it ); + r->name = *it; + r->isPlugin = TRUE; + append( r ); + iface->release(); + } +} + +/*! + Returns the number of elements in the widget database. +*/ + +int WidgetDatabase::count() +{ + setupDataBase( -1 ); + return dbcount; +} + +/*! + Returns the id at which the ids of custom widgets start. +*/ + +int WidgetDatabase::startCustom() +{ + setupDataBase( -1 ); + return dbcustom; +} + +/*! + Returns the iconset which represents the class registered as \a id. +*/ + +TQIconSet WidgetDatabase::iconSet( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return TQIconSet(); +#if !defined(UIC) && !defined(RESOURCE) + if ( !r->icon ) { + if ( r->iconSet.isEmpty() ) + return TQIconSet(); + TQPixmap pix = TQPixmap::fromMimeSource( r->iconSet ); + if ( pix.isNull() ) + pix = TQPixmap( r->iconSet ); + r->icon = new TQIconSet( pix ); + } + return *r->icon; +#else + return TQIconSet(); +#endif +} + +/*! + Returns the classname of the widget which is registered as \a id. +*/ + +TQString WidgetDatabase::className( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return TQString::null; + return r->name; +} + +/*! + Returns the group the widget registered as \a id belongs to. +*/ + +TQString WidgetDatabase::group( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return TQString::null; + return r->group; +} + +/*! + Returns the tooltip text of the widget which is registered as \a id. +*/ + +TQString WidgetDatabase::toolTip( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return TQString::null; + return r->toolTip; +} + +/*! + Returns the what's this? text of the widget which is registered as \a id. +*/ + +TQString WidgetDatabase::whatsThis( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return TQString::null; + return r->whatsThis; +} + +/*! + Returns the include file if the widget which is registered as \a id. +*/ + +TQString WidgetDatabase::includeFile( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return TQString::null; + if ( r->includeFile.isNull() ) + return r->name.lower() + ".h"; + return r->includeFile; +} + +/*! Returns whether the widget registered as \a id is a form. +*/ +bool WidgetDatabase::isForm( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isForm; +} + +/*! Returns whether the widget registered as \a id can have children. +*/ + +bool WidgetDatabase::isContainer( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isContainer || r->isForm; +} + +bool WidgetDatabase::isCommon( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isCommon; +} + +TQString WidgetDatabase::createWidgetName( int id ) +{ + setupDataBase( id ); + TQString n = className( id ); + if ( n == "TQLayoutWidget" ) + n = "Layout"; + if ( n[ 0 ] == 'Q' && n[ 1 ].lower() != n[ 1 ] ) + n = n.mid( 1 ); + int colonColon = n.findRev( "::" ); + if ( colonColon != -1 ) + n = n.mid( colonColon + 2 ); + + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return n; + n += TQString::number( ++r->nameCounter ); + n[0] = n[0].lower(); + return n; +} + +/*! Returns the id for \a name or -1 if \a name is unknown. + */ +int WidgetDatabase::idFromClassName( const TQString &name ) +{ + setupDataBase( -1 ); + if ( name.isEmpty() ) + return 0; + int *i = className2Id->find( name ); + if ( i ) + return *i; + if ( name == "FormWindow" ) + return idFromClassName( "TQLayoutWidget" ); +#ifdef UIC + setupDataBase( -2 ); + i = className2Id->find( name ); + if ( i ) + return *i; +#endif + return -1; +} + +bool WidgetDatabase::hasWidget( const TQString &name ) +{ + return className2Id->find( name ) != 0; +} + +WidgetDatabaseRecord *WidgetDatabase::at( int index ) +{ + if ( index < 0 ) + return 0; + if ( index >= dbcustom && index < dbcustomcount ) + return db[ index ]; + if ( index < dbcount ) + return db[ index ]; + return 0; +} + +void WidgetDatabase::insert( int index, WidgetDatabaseRecord *r ) +{ + if ( index < 0 || index >= dbsize ) + return; + db[ index ] = r; + className2Id->insert( r->name, new int( index ) ); + if ( index < dbcustom ) + dbcount = TQMAX( dbcount, index ); +} + +void WidgetDatabase::append( WidgetDatabaseRecord *r ) +{ + if ( !was_in_setup ) + setupDataBase( -1 ); + insert( dbcount++, r ); +} + +TQString WidgetDatabase::widgetGroup( const TQString &g ) +{ + if ( wGroups->find( g ) == -1 ) + wGroups->append( g ); + return g; +} + +bool WidgetDatabase::isGroupEmpty( const TQString &grp ) +{ + WidgetDatabaseRecord *r = 0; + for ( int i = 0; i < dbcount; ++i ) { + if ( !( r = db[ i ] ) ) + continue; + if ( r->group == grp ) + return FALSE; + } + return TRUE; +} + +TQString WidgetDatabase::widgetGroup( int i ) +{ + setupDataBase( -1 ); + if ( i >= 0 && i < (int)wGroups->count() ) + return wGroups->at( i ); + return TQString::null; +} + +int WidgetDatabase::numWidgetGroups() +{ + setupDataBase( -1 ); + return wGroups->count(); +} + +bool WidgetDatabase::isGroupVisible( const TQString &g ) +{ + setupDataBase( -1 ); + return invisibleGroups->find( g ) == -1; +} + +int WidgetDatabase::addCustomWidget( WidgetDatabaseRecord *r ) +{ + insert( dbcustomcount++, r ); + return dbcustomcount - 1; +} + +void WidgetDatabase::customWidgetClassNameChanged( const TQString &oldName, + const TQString &newName ) +{ + int id = idFromClassName( oldName ); + if ( id == -1 ) + return; + WidgetDatabaseRecord *r = db[ id ]; + r->name = newName; + className2Id->remove( oldName ); + className2Id->insert( newName, new int( id ) ); +} + +bool WidgetDatabase::isCustomWidget( int id ) +{ + if ( id >= dbcustom && id < dbcustomcount ) + return TRUE; + return FALSE; +} + +bool WidgetDatabase::isCustomPluginWidget( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isPlugin; +} + +bool WidgetDatabase::isWhatsThisLoaded() +{ + return whatsThisLoaded; +} + +void WidgetDatabase::loadWhatsThis( const TQString &docPath ) +{ + TQString whatsthisFile = docPath + "/whatsthis"; + TQFile f( whatsthisFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + TQTextStream ts( &f ); + while ( !ts.atEnd() ) { + TQString s = ts.readLine(); + TQStringList l = TQStringList::split( " | ", s ); + int id = idFromClassName( l[ 1 ] ); + WidgetDatabaseRecord *r = at( id ); + if ( r ) + r->whatsThis = l[ 0 ]; + } + whatsThisLoaded = TRUE; +} + + +// ### TQt 3.1: make these publically accessible via TQWidgetDatabase API +#if defined(UIC) +bool dbnounload = FALSE; +TQStringList *dbpaths = 0; +#else +extern TQString *qwf_plugin_dir; +#endif + + +TQPluginManager<WidgetInterface> *widgetManager() +{ + if ( !widgetPluginManager ) { + TQString pluginDir = "/designer"; +#if !defined(UIC) + if ( qwf_plugin_dir ) + pluginDir = *qwf_plugin_dir; +#endif + widgetPluginManager = new TQPluginManager<WidgetInterface>( IID_Widget, TQApplication::libraryPaths(), pluginDir ); + cleanup_manager.add( &widgetPluginManager ); +#if defined(UIC) + if ( dbnounload ) + widgetPluginManager->setAutoUnload( FALSE ); + if ( dbpaths ) { + TQStringList::ConstIterator it = dbpaths->begin(); + for ( ; it != dbpaths->end(); ++it ) + widgetPluginManager->addLibraryPath( *it ); + } +#endif + } + return widgetPluginManager; +} diff --git a/pytquic3/widgetdatabase.h b/pytquic3/widgetdatabase.h new file mode 100644 index 0000000..18b63af --- /dev/null +++ b/pytquic3/widgetdatabase.h @@ -0,0 +1,96 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition +** licenses may use this file in accordance with the TQt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about TQt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef WIDGETDATABASE_H +#define WIDGETDATABASE_H + +#include <tqiconset.h> +#include <tqstring.h> +#include "widgetinterface.h" // up here for GCC 2.7.* compatibility +#include <private/qpluginmanager_p.h> + + +extern TQPluginManager<WidgetInterface> *widgetManager(); + +struct WidgetDatabaseRecord +{ + WidgetDatabaseRecord(); + ~WidgetDatabaseRecord(); + TQString iconSet, name, group, toolTip, whatsThis, includeFile; + uint isContainer : 1; + uint isForm : 1; + uint isCommon : 1; + uint isPlugin : 1; + TQIconSet *icon; + int nameCounter; +}; + +class WidgetDatabase : public TQt +{ +public: + WidgetDatabase(); + static void setupDataBase( int id ); + static void setupPlugins(); + + static int count(); + static int startCustom(); + + static TQIconSet iconSet( int id ); + static TQString className( int id ); + static TQString group( int id ); + static TQString toolTip( int id ); + static TQString whatsThis( int id ); + static TQString includeFile( int id ); + static bool isForm( int id ); + static bool isContainer( int id ); + static bool isCommon( int id ); + + static int idFromClassName( const TQString &name ); + static TQString createWidgetName( int id ); + + static WidgetDatabaseRecord *at( int index ); + static void insert( int index, WidgetDatabaseRecord *r ); + static void append( WidgetDatabaseRecord *r ); + + static TQString widgetGroup( const TQString &g ); + static TQString widgetGroup( int i ); + static int numWidgetGroups(); + static bool isGroupVisible( const TQString &g ); + static bool isGroupEmpty( const TQString &grp ); + + static int addCustomWidget( WidgetDatabaseRecord *r ); + static bool isCustomWidget( int id ); + static bool isCustomPluginWidget( int id ); + + static bool isWhatsThisLoaded(); + static void loadWhatsThis( const TQString &docPath ); + + static bool hasWidget( const TQString &name ); + static void customWidgetClassNameChanged( const TQString &oldName, const TQString &newName ); + +}; + +#endif diff --git a/pytquic3/widgetinterface.h b/pytquic3/widgetinterface.h new file mode 100644 index 0000000..50f8e6d --- /dev/null +++ b/pytquic3/widgetinterface.h @@ -0,0 +1,29 @@ + /********************************************************************** +** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef WIDGETINTERFACE_H +#define WIDGETINTERFACE_H + +#include <private/qwidgetinterface_p.h> + +#define WidgetInterface TQWidgetFactoryInterface +#define IID_Widget IID_QWidgetFactory + +#endif |