diff options
Diffstat (limited to 'puic')
-rw-r--r-- | puic/LICENSE.GPL | 280 | ||||
-rw-r--r-- | puic/Makefile.am | 33 | ||||
-rw-r--r-- | puic/Makefile.in | 699 | ||||
-rw-r--r-- | puic/TODO | 7 | ||||
-rw-r--r-- | puic/domtool.cpp | 453 | ||||
-rw-r--r-- | puic/domtool.h | 53 | ||||
-rw-r--r-- | puic/embed.cpp | 264 | ||||
-rw-r--r-- | puic/form.cpp | 1224 | ||||
-rw-r--r-- | puic/globaldefs.h | 45 | ||||
-rw-r--r-- | puic/main.cpp | 325 | ||||
-rw-r--r-- | puic/object.cpp | 768 | ||||
-rw-r--r-- | puic/parser.cpp | 66 | ||||
-rw-r--r-- | puic/parser.h | 33 | ||||
-rw-r--r-- | puic/puic.1 | 78 | ||||
-rw-r--r-- | puic/puic.pro | 28 | ||||
-rw-r--r-- | puic/stamp-h.in | 0 | ||||
-rw-r--r-- | puic/subclassing.cpp | 191 | ||||
-rw-r--r-- | puic/uic.cpp | 1101 | ||||
-rw-r--r-- | puic/uic.h | 195 | ||||
-rw-r--r-- | puic/widgetdatabase.cpp | 953 | ||||
-rw-r--r-- | puic/widgetdatabase.h | 90 | ||||
-rw-r--r-- | puic/widgetinterface.h | 29 |
22 files changed, 6915 insertions, 0 deletions
diff --git a/puic/LICENSE.GPL b/puic/LICENSE.GPL new file mode 100644 index 0000000..c7aea18 --- /dev/null +++ b/puic/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/puic/Makefile.am b/puic/Makefile.am new file mode 100644 index 0000000..d429dc7 --- /dev/null +++ b/puic/Makefile.am @@ -0,0 +1,33 @@ +AM_CPPFLAGS = -DUIC -DQT_INTERNAL_XML +AM_CXXFLAGS= $(KDE_CXXFLAGS) + +bin_PROGRAMS = puic + +puic_SOURCES = widgetdatabase.cpp uic.cpp subclassing.cpp parser.cpp object.cpp main.cpp form.cpp embed.cpp domtool.cpp +puic_LDADD = $(LIB_QT) $(LIBZ) + +man_MANS = puic.1 + +EXTRA_DIST = domtool.cpp domtool.h embed.cpp form.cpp globaldefs.h main.cpp object.cpp parser.cpp parser.h subclassing.cpp uic.cpp uic.h widgetdatabase.cpp widgetdatabase.h widgetinterface.h puic.1 + +# These paths are KDE specific : +# kde_bindir Where executables should go to. Use bin_PROGRAMS or bin_SCRIPTS. +# kde_libdir Where shared libraries should go to. Use lib_LTLIBRARIES. +# kde_moduledir Where modules (e.g. parts) should go to. Use kde_module_LTLIBRARIES. +# kde_styledir Where Qt/KDE widget styles should go to (new in KDE 3). +# kde_designerdir Where Qt Designer plugins should go to (new in KDE 3). + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + +METASOURCES = AUTO + +# the library search path. +puic_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +messages: + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/puic.pot; \ + fi + diff --git a/puic/Makefile.in b/puic/Makefile.in new file mode 100644 index 0000000..5caff94 --- /dev/null +++ b/puic/Makefile.in @@ -0,0 +1,699 @@ +# Makefile.in generated by automake 1.7.2 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision: 1.3 $ +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTODIRS = @AUTODIRS@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ +GL_CFLAGS = @GL_CFLAGS@ +GL_LIBS = @GL_LIBS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_HAVE_GL = @KDE_HAVE_GL@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ +KDE_MT_LIBS = @KDE_MT_LIBS@ +KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@ +KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@ +LDFLAGS = @LDFLAGS@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBRESOLV = @LIBRESOLV@ +LIBS = @LIBS@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBZ = @LIBZ@ +LIB_POLL = @LIB_POLL@ +LIB_QPE = @LIB_QPE@ +LIB_QT = @LIB_QT@ +LIB_X11 = @LIB_X11@ +LIB_XEXT = @LIB_XEXT@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MOC = @MOC@ +NOOPT_CFLAGS = @NOOPT_CFLAGS@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +QTE_NORTTI = @QTE_NORTTI@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RPATH = @USE_RPATH@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_qtver = @kde_qtver@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +qt_test_threshold = @qt_test_threshold@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ +AM_CPPFLAGS = -DUIC -DQT_INTERNAL_XML +AM_CXXFLAGS = $(KDE_CXXFLAGS) + +bin_PROGRAMS = puic + +puic_SOURCES = widgetdatabase.cpp uic.cpp subclassing.cpp parser.cpp object.cpp main.cpp form.cpp embed.cpp domtool.cpp +puic_LDADD = $(LIB_QT) $(LIBZ) + +man_MANS = puic.1 + +EXTRA_DIST = domtool.cpp domtool.h embed.cpp form.cpp globaldefs.h main.cpp object.cpp parser.cpp parser.h subclassing.cpp uic.cpp uic.h widgetdatabase.cpp widgetdatabase.h widgetinterface.h puic.1 + +# These paths are KDE specific : +# kde_bindir Where executables should go to. Use bin_PROGRAMS or bin_SCRIPTS. +# kde_libdir Where shared libraries should go to. Use lib_LTLIBRARIES. +# kde_moduledir Where modules (e.g. parts) should go to. Use kde_module_LTLIBRARIES. +# kde_styledir Where Qt/KDE widget styles should go to (new in KDE 3). +# kde_designerdir Where Qt Designer plugins should go to (new in KDE 3). + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +#>- METASOURCES = AUTO + +# the library search path. +puic_LDFLAGS = $(all_libraries) $(KDE_RPATH) +subdir = puic +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +bin_PROGRAMS = puic$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + +am_puic_OBJECTS = widgetdatabase.$(OBJEXT) uic.$(OBJEXT) \ + subclassing.$(OBJEXT) parser.$(OBJEXT) object.$(OBJEXT) \ + main.$(OBJEXT) form.$(OBJEXT) embed.$(OBJEXT) domtool.$(OBJEXT) +#>- puic_OBJECTS = $(am_puic_OBJECTS) +#>+ 6 +puic_final_OBJECTS = puic.all_cpp.o +puic_nofinal_OBJECTS = widgetdatabase.$(OBJEXT) uic.$(OBJEXT) \ + subclassing.$(OBJEXT) parser.$(OBJEXT) object.$(OBJEXT) \ + main.$(OBJEXT) form.$(OBJEXT) embed.$(OBJEXT) domtool.$(OBJEXT) +@KDE_USE_FINAL_FALSE@puic_OBJECTS = $(puic_nofinal_OBJECTS) +@KDE_USE_FINAL_TRUE@puic_OBJECTS = $(puic_final_OBJECTS) +puic_DEPENDENCIES = + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/admin/depcomp +am__depfiles_maybe = depfiles +#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/domtool.Po ./$(DEPDIR)/embed.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/form.Po ./$(DEPDIR)/main.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/object.Po ./$(DEPDIR)/parser.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/subclassing.Po ./$(DEPDIR)/uic.Po \ +#>- @AMDEP_TRUE@ ./$(DEPDIR)/widgetdatabase.Po +#>+ 11 +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/puic.all_cpp.P ./$(DEPDIR)/domtool.Po ./$(DEPDIR)/embed.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/form.Po ./$(DEPDIR)/main.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/object.Po ./$(DEPDIR)/parser.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/subclassing.Po ./$(DEPDIR)/uic.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/widgetdatabase.Po +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/domtool.Po ./$(DEPDIR)/embed.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/form.Po ./$(DEPDIR)/main.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/object.Po ./$(DEPDIR)/parser.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/subclassing.Po ./$(DEPDIR)/uic.Po \ +@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/widgetdatabase.Po + +#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 2 +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \ +#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ +#>- $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 3 +LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +CXXLD = $(CXX) +#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ +#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@ +#>+ 2 +CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(puic_SOURCES) + +NROFF = nroff +MANS = $(man_MANS) +DIST_COMMON = Makefile.am Makefile.in TODO +SOURCES = $(puic_SOURCES) + +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu puic/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu puic/Makefile + cd $(top_srcdir) && perl admin/am_edit PerlQt-3.008/puic/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +puic$(EXEEXT): $(puic_OBJECTS) $(puic_DEPENDENCIES) + @rm -f puic$(EXEEXT) + $(CXXLINK) $(puic_LDFLAGS) $(puic_OBJECTS) $(puic_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/domtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/embed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/form.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subclassing.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/widgetdatabase.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.cpp.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCXX_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +.cpp.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ +@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCXX_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` + +.cpp.lo: +@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCXX_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +man1dir = $(mandir)/man1 +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 4 +KDE_DIST=stamp-h.in puic.pro LICENSE.GPL + +DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) + + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +#>- clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am +#>+ 1 +clean-am: clean-final clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +install-man: install-man1 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man + +uninstall-man: uninstall-man1 + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-depend distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am info info-am install \ + install-am install-binPROGRAMS install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-man1 install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-info-am uninstall-man uninstall-man1 + + +messages: + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/puic.pot; \ + fi +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu puic/Makefile + cd $(top_srcdir) && perl admin/am_edit PerlQt-3.008/puic/Makefile.in + + +#>+ 9 +bcheck: bcheck-am + +bcheck-am: + test ! -r bchecktest.cc.class || mv -f bchecktest.cc.class bchecktest.cc.oldclass + @echo "int main() {return 0;}" > bchecktest.cc + for i in $(include_HEADERS); do echo "#include \"$$i\"" >> bchecktest.cc; done + test ! -s bchecktest.cc || $(CXXCOMPILE) --dump-class-hierarchy bchecktest.cc + test ! -s bchecktest.cc.oldclass || test ! -s bchecktest.cc.class || cmp -s bchecktest.cc.oldclass bchecktest.cc.class + +#>+ 11 +puic.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/widgetdatabase.cpp $(srcdir)/uic.cpp $(srcdir)/subclassing.cpp $(srcdir)/parser.cpp $(srcdir)/object.cpp $(srcdir)/main.cpp $(srcdir)/form.cpp $(srcdir)/embed.cpp $(srcdir)/domtool.cpp + @echo 'creating puic.all_cpp.cpp ...'; \ + rm -f puic.all_cpp.files puic.all_cpp.final; \ + echo "#define KDE_USE_FINAL 1" >> puic.all_cpp.final; \ + for file in widgetdatabase.cpp uic.cpp subclassing.cpp parser.cpp object.cpp main.cpp form.cpp embed.cpp domtool.cpp ; do \ + echo "#include \"$$file\"" >> puic.all_cpp.files; \ + test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> puic.all_cpp.final; \ + done; \ + cat puic.all_cpp.final puic.all_cpp.files > puic.all_cpp.cpp; \ + rm -f puic.all_cpp.final puic.all_cpp.files + +#>+ 3 +clean-final: + -rm -f puic.all_cpp.cpp + +#>+ 2 +final: + $(MAKE) puic_OBJECTS="$(puic_final_OBJECTS)" all-am +#>+ 2 +final-install: + $(MAKE) puic_OBJECTS="$(puic_final_OBJECTS)" install-am +#>+ 2 +no-final: + $(MAKE) puic_OBJECTS="$(puic_nofinal_OBJECTS)" all-am +#>+ 2 +no-final-install: + $(MAKE) puic_OBJECTS="$(puic_nofinal_OBJECTS)" install-am +#>+ 3 +cvs-clean: + $(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 3 +nmcheck: +nmcheck-am: nmcheck diff --git a/puic/TODO b/puic/TODO new file mode 100644 index 0000000..77702c9 --- /dev/null +++ b/puic/TODO @@ -0,0 +1,7 @@ + +- PNGs embedded in ui files and B&W pictures in external MimeSourceFactory remain untested + (and thus probably wrong) +- PerlQt does not handle subclassing yet, so don't use the -subimpl option +- database code needs more testing +- ... + diff --git a/puic/domtool.cpp b/puic/domtool.cpp new file mode 100644 index 0000000..492ce88 --- /dev/null +++ b/puic/domtool.cpp @@ -0,0 +1,453 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt 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 Qt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "domtool.h" + +#include <qsizepolicy.h> +#include <qcolor.h> +#include <qcursor.h> +#include <qdatetime.h> +#include <qrect.h> +#include <qsize.h> +#include <qfont.h> +#include <qdom.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() +*/ +QVariant DomTool::readProperty( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ) +{ + QDomElement 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 + */ +QVariant DomTool::readProperty( const QDomElement& e, const QString& name, const QVariant& defValue ) +{ + QString comment; + return readProperty( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines property \a name or not. + + \sa readProperty() + */ +bool DomTool::hasProperty( const QDomElement& e, const QString& name ) +{ + QDomElement 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; +} + +QStringList DomTool::propertiesOfType( const QDomElement& e, const QString& type ) +{ + QStringList result; + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + QDomElement n2 = n.firstChild().toElement(); + if ( n2.tagName() == type ) + result += n.attribute( "name" ); + } + } + return result; +} + + +QVariant DomTool::elementToVariant( const QDomElement& e, const QVariant& defValue ) +{ + QString dummy; + return elementToVariant( e, defValue, dummy ); +} + +/*! + Interprets element \a e as variant and returns the result of the interpretation. + */ +QVariant DomTool::elementToVariant( const QDomElement& e, const QVariant& defValue, QString &comment ) +{ + QVariant v; + if ( e.tagName() == "rect" ) { + QDomElement 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 = QVariant( QRect( x, y, w, h ) ); + } else if ( e.tagName() == "point" ) { + QDomElement 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 = QVariant( QPoint( x, y ) ); + } else if ( e.tagName() == "size" ) { + QDomElement 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 = QVariant( QSize( w, h ) ); + } else if ( e.tagName() == "color" ) { + v = QVariant( readColor( e ) ); + } else if ( e.tagName() == "font" ) { + QDomElement n3 = e.firstChild().toElement(); + QFont 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 = QVariant( f ); + } else if ( e.tagName() == "string" ) { + v = QVariant( e.firstChild().toText().data() ); + QDomElement n = e; + n = n.nextSibling().toElement(); + if ( n.tagName() == "comment" ) + comment = n.firstChild().toText().data(); + } else if ( e.tagName() == "cstring" ) { + v = QVariant( QCString( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "number" ) { + bool ok = TRUE; + v = QVariant( e.firstChild().toText().data().toInt( &ok ) ); + if ( !ok ) + v = QVariant( e.firstChild().toText().data().toDouble() ); + } else if ( e.tagName() == "bool" ) { + QString t = e.firstChild().toText().data(); + v = QVariant( t == "true" || t == "1", 0 ); + } else if ( e.tagName() == "pixmap" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "iconset" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "image" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "enum" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "set" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "sizepolicy" ) { + QDomElement n3 = e.firstChild().toElement(); + QSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (QSizePolicy::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 = QVariant( sp ); + } else if ( e.tagName() == "cursor" ) { + v = QVariant( QCursor( e.firstChild().toText().data().toInt() ) ); + } else if ( e.tagName() == "stringlist" ) { + QStringList lst; + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + lst << n.firstChild().toText().data(); + v = QVariant( lst ); + } else if ( e.tagName() == "date" ) { + QDomElement 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 = QVariant( QDate( y, m, d ) ); + } else if ( e.tagName() == "time" ) { + QDomElement 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 = QVariant( QTime( h, m, s ) ); + } else if ( e.tagName() == "datetime" ) { + QDomElement 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 = QVariant( QDateTime( QDate( y, mo, d ), QTime( h, mi, s ) ) ); + } + return v; +} + + +/*! Returns the color which is returned in the dom element \a e. + */ + +QColor DomTool::readColor( const QDomElement &e ) +{ + QDomElement 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 QColor( 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() + */ +QVariant DomTool::readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ) +{ + QDomElement 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 +*/ +QVariant DomTool::readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue ) +{ + QString comment; + return readAttribute( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines attribute \a name or not. + + \sa readAttribute() + */ +bool DomTool::hasAttribute( const QDomElement& e, const QString& name ) +{ + QDomElement 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 QString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +/*! + Convert Qt 2.x format to Qt 3.0 format if necessary +*/ +void DomTool::fixDocument( QDomDocument& doc ) +{ + QDomElement e; + QDomNode n; + QDomNodeList 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++ ) { + QDomElement el = nl.item(i).toElement(); + QString 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(); + QString name; + QDomElement 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(); + QString name; + QDomElement 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(); + QString name; + QDomElement 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(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "class" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "class", name ); + e.removeChild( n2 ); + } + } + +} + diff --git a/puic/domtool.h b/puic/domtool.h new file mode 100644 index 0000000..61b4269 --- /dev/null +++ b/puic/domtool.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt 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 Qt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DOMTOOL_H +#define DOMTOOL_H + +#include <qvariant.h> +#include <qnamespace.h> + +class QDomElement; +class QDomDocument; + +class DomTool : public Qt +{ +public: + static QVariant readProperty( const QDomElement& e, const QString& name, const QVariant& defValue ); + static QVariant readProperty( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ); + static bool hasProperty( const QDomElement& e, const QString& name ); + static QStringList propertiesOfType( const QDomElement& e, const QString& type ); + static QVariant elementToVariant( const QDomElement& e, const QVariant& defValue ); + static QVariant elementToVariant( const QDomElement& e, const QVariant& defValue, QString &comment ); + static QVariant readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue ); + static QVariant readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ); + static bool hasAttribute( const QDomElement& e, const QString& name ); + static QColor readColor( const QDomElement &e ); + static void fixDocument( QDomDocument& ); +}; + + +#endif // DOMTOOL_H diff --git a/puic/embed.cpp b/puic/embed.cpp new file mode 100644 index 0000000..aac9633 --- /dev/null +++ b/puic/embed.cpp @@ -0,0 +1,264 @@ +/********************************************************************** +** 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> +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt 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. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +**********************************************************************/ + +#include "uic.h" +#include <qfile.h> +#include <qimage.h> +#include <qstringlist.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +struct EmbedImage +{ + int width, height, depth; + int numColors; + QRgb* colorTable; + QString name; + QString cname; + bool alpha; +}; + +static QString convertToCIdentifier( const char *s ) +{ + QString 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 void embedData( QTextStream& out, const uchar* input, int nbytes ) +{ + static const char hexdigits[] = "0123456789abcdef"; + QString s; + for ( int i=0; i<nbytes; i++ ) + { + if ( (i%14) == 0 ) + { + s += "\n "; + out << (const char*)s; + s.truncate( 0 ); + } + uint v = input[i]; + s += "0x"; + s += hexdigits[(v >> 4) & 15]; + s += hexdigits[v & 15]; + if ( i < nbytes-1 ) + s += ", "; + else + s += "\n"; + } + if ( s.length() ) + out << (const char*)s; +} + +static void embedData( QTextStream& out, const QRgb* input, int n ) +{ + out << hex; + const QRgb *v = input; + for ( int i=0; i<n; i++ ) { + if ( (i%6) == 0 ) + out << endl << " "; + out << "0x"; + out << hex << *v++; + if ( i < n-1 ) + out << ", "; + else + out << ";" << endl; + } + out << dec; // back to decimal mode +} + +void Uic::embed( QTextStream& out, const char* project, const QStringList& images ) +{ + + QString cProject = convertToCIdentifier( project ); + + QStringList::ConstIterator it; + out << "# Image collection for project '" << project << "'." << endl; + out << "#" << endl; + out << "# Generated from reading image files: " << endl; + for ( it = images.begin(); it != images.end(); ++it ) + out << "# " << *it << endl; + out << "#" << endl; + out << "# Created: " << QDateTime::currentDateTime().toString() << endl; + out << "# by: The PerlQt User Interface Compiler (puic)" << endl; + out << "#" << endl; + out << "# WARNING! All changes made in this file will be lost!" << endl; + out << endl; + out << "use strict;" << endl; + out << "use utf8;" << endl; + out << endl; + + out << indent << "package DesignerMimeSourceFactory_" << cProject << ";" << endl; + out << indent << "use Qt;" << endl; + out << indent << "use Qt::isa qw(Qt::MimeSourceFactory);" << endl; + out << endl; + + QPtrList<EmbedImage> list_image; + int image_count = 0; + for ( it = images.begin(); it != images.end(); ++it ) { + QImage img; + if ( !img.load( *it ) ) { + fprintf( stderr, "puic: cannot load image file %s\n", (*it).latin1() ); + continue; + } + EmbedImage *e = new EmbedImage; + e->width = img.width(); + e->height = img.height(); + e->depth = img.depth(); + e->numColors = img.numColors(); + e->colorTable = new QRgb[e->numColors]; + e->alpha = img.hasAlphaBuffer(); + memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); + QFileInfo fi( *it ); + e->name = fi.fileName(); + e->cname = QString("$image_%1").arg( image_count++); + list_image.append( e ); + out << "# " << *it << endl; + QString s; + QString imgname = (const char *)e->cname; + + +//my $i0 = Qt::Image($image_0_data, 22, 22, 32, undef, &Qt::Image::BigEndian); +//$i0->setAlphaBuffer(1); +//my $image0 = Qt::Pixmap($i0); + + if ( e->depth == 32 ) { + out << indent << "my " << imgname << "_data = pack 'L*'," << endl; + embedData( out, (QRgb*)img.bits(), e->width*e->height ); + } else { + if ( e->depth == 1 ) + img = img.convertBitOrder(QImage::BigEndian); + out << indent << "my " << imgname << "_data = pack 'C*'," << endl; + embedData( out, img.bits(), img.numBytes() ); + } + out << endl; + if ( e->numColors ) { + out << indent << "my " << imgname << "_ctable = " << endl; + out << indent << "[" << endl; + embedData( out, e->colorTable, e->numColors ); + out << endl; + out << indent << "];" << endl; + } + } + + if ( !list_image.isEmpty() ) { + out << indent << "my %embed_images = (\n"; + ++indent; + EmbedImage *e = list_image.first(); + while ( e ) + { + out << indent << "\"" << e->name << "\"" << " => [" << e->cname << "_data, " + << e->width << ", " << e->height << ", " << e->depth << ", " + << (e->numColors ? e->cname + "_ctable" : QString::fromLatin1("undef") ) << ", " + << (e->alpha ? "1" : "0") << "]," << endl; + e = list_image.next(); + } + --indent; + out << indent << ");" << endl; + + out << endl; + out << indent << "my %images = ();" << endl; + out << endl; + out << endl; + out << indent << "sub uic_findImage" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "my $name = shift;" << endl; + out << indent << "return $images{$name} if exists $images{$name};" << endl; + out << indent << "return Qt::Image() unless exists $embed_images{$name};" << endl; + out << indent << endl; + out << indent << "my $img = Qt::Image(@{$embed_images{$name}}[0..4], &Qt::Image::BigEndian);" << endl; + out << indent << "${$embed_images{$name}}[5] && $img->setAlphaBuffer(1);" << endl; + out << indent << "$images{$name} = $img;" << endl; + out << indent << "return $img;" << endl; + --indent; + out << indent << "}" << endl; + out << endl; + out << indent << "sub data" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "my $abs_name = shift;" << endl; + out << indent << "my $img = uic_findImage($abs_name);" << endl; + out << indent << "if($img->isNull())" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "Qt::MimeSourceFactory::removeFactory(this);" << endl; + out << indent << "my $s = Qt::MimeSourceFactory::defaultFactory()->data($abs_name);" << endl; + out << indent << "Qt::MimeSourceFactory::addFactory(this);" << endl; + out << indent << "return $s;" << endl; + --indent; + out << indent << "}" << endl; + out << indent << "Qt::MimeSourceFactory::defaultFactory()->setImage($abs_name, $img);" << endl; + out << indent << "return Qt::MimeSourceFactory::defaultFactory()->data($abs_name);" << endl; + --indent; + out << indent << "}" << endl; + + out << endl; + out << endl; + + out << indent << "package staticImages;" << endl; + out << indent << "use Qt;" << endl; + out << indent << "use DesignerMimeSourceFactory_" << cProject << ";" << endl; + out << indent << "our %factories;" << endl; + out << indent << endl; + out << indent << "my $factory = DesignerMimeSourceFactory_" << cProject << ";" << endl; + out << indent << "Qt::MimeSourceFactory::defaultFactory()->addFactory($factory);" << endl; + out << indent << "$factories{'DesignerMimeSourceFactory_" << cProject << "'} = $factory;" << endl; + out << endl; + out << indent << "END" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "for( values %factories )" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "Qt::MimeSourceFactory::defaultFactory()->removeFactory($_);" << endl; + --indent; + out << indent << "}" << endl; + out << indent << "%factories = ();" << endl; + --indent; + out << indent << "}" << endl; + out << indent << "1;" << endl;; + out << endl; + } +} diff --git a/puic/form.cpp b/puic/form.cpp new file mode 100644 index 0000000..56f44c2 --- /dev/null +++ b/puic/form.cpp @@ -0,0 +1,1224 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt 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. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +**********************************************************************/ + +#include <iostream> +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qstringlist.h> +#include <qvaluelist.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qregexp.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#if( QT_VERSION < 0x030101 ) +# include <zlib.h> + +static QByteArray qUncompress( const uchar* data, int nbytes ) +{ + if ( !data ) { +#if defined(QT_CHECK_RANGE) + qWarning( "qUncompress: data is NULL." ); +#endif + return QByteArray(); + } + if ( nbytes <= 4 ) { +#if defined(QT_CHECK_RANGE) + if ( nbytes < 4 || ( data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0 ) ) + qWarning( "qUncompress: Input data is corrupted." ); +#endif + return QByteArray(); + } + ulong expectedSize = ( data[0] << 24 ) | ( data[1] << 16 ) | ( data[2] << 8 ) | data[3]; + ulong len = QMAX( expectedSize, 1 ); + QByteArray baunzip; + int res; + do { + baunzip.resize( len ); + res = ::uncompress( (uchar*)baunzip.data(), &len, + (uchar*)data+4, nbytes-4 ); + + switch ( res ) { + case Z_OK: + if ( len != baunzip.size() ) + baunzip.resize( len ); + break; + case Z_MEM_ERROR: +#if defined(QT_CHECK_RANGE) + qWarning( "qUncompress: Z_MEM_ERROR: Not enough memory." ); +#endif + break; + case Z_BUF_ERROR: + len *= 2; + break; + case Z_DATA_ERROR: +#if defined(QT_CHECK_RANGE) + qWarning( "qUncompress: Z_DATA_ERROR: Input data is corrupted." ); +#endif + break; + } + } while ( res == Z_BUF_ERROR ); + + if ( res != Z_OK ) + baunzip = QByteArray(); + + return baunzip; +} +#endif // QT_VERSION < 0x030101 + +using namespace std; + +static QByteArray unzipXPM( QString data, ulong& length ) +{ + 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; + } + // qUncompress() 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 ); + QByteArray baunzip = qUncompress( ba, baSize ); + delete[] ba; + return baunzip; +} +#if 0 +//- kept for diffs +#if QT_VERSION >= 0x030900 +#error Add this functionality to QDir (relativePathTo() maybe?) and \ +remove it from here and from moc +#endif + +QCString combinePath( const char *infile, const char *outfile ) +{ + QFileInfo inFileInfo( QDir::current(), QFile::decodeName(infile) ); + QFileInfo outFileInfo( QDir::current(), QFile::decodeName(outfile) ); + int numCommonComponents = 0; + + QStringList inSplitted = + QStringList::split( '/', inFileInfo.dir().canonicalPath(), TRUE ); + QStringList outSplitted = + QStringList::split( '/', outFileInfo.dir().canonicalPath(), TRUE ); + + while ( !inSplitted.isEmpty() && !outSplitted.isEmpty() && + inSplitted.first() == outSplitted.first() ) { + inSplitted.remove( inSplitted.begin() ); + outSplitted.remove( outSplitted.begin() ); + numCommonComponents++; + } + + if ( numCommonComponents < 2 ) { + /* + The paths don't have the same drive, or they don't have the + same root directory. Use an absolute path. + */ + return QFile::encodeName( inFileInfo.absFilePath() ); + } else { + /* + The paths have something in common. Use a path relative to + the output file. + */ + while ( !outSplitted.isEmpty() ) { + outSplitted.remove( outSplitted.begin() ); + inSplitted.prepend( ".." ); + } + inSplitted.append( inFileInfo.fileName() ); + return QFile::encodeName( inSplitted.join("/") ); + } +} +#endif + +/*! + Creates an implementation ( cpp-file ) for the form given in \a e + + \sa createFormDecl(), createObjectImpl() + */ +void Uic::createFormImpl( const QDomElement &e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + out << indent << "package " << nameOfClass << ";" << endl; + out << indent << "use Qt;" << endl; + + // generate local and local includes required + QStringList globalIncludes, localIncludes, useIncludes; + QStringList::Iterator it; + QStringList sqlClasses; + + QMap<QString, CustomInclude> customWidgetIncludes; + QMap<QString, QString> functionImpls; + QString uiPmInclude; + + // find additional slots + QStringList extraSlots; + QStringList extraSlotTyp; + + 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; + QString l = n.attribute( "language", "C++" ); + if ( l != "C++" && l != "Perl" ) //- mmh + continue; + QString slotName = n.firstChild().toText().data().stripWhiteSpace(); + if ( slotName.endsWith( ";" ) ) + slotName = slotName.left( slotName.length() - 1 ); + + extraSlots += Parser::cleanArgs(slotName); + extraSlotTyp += n.attribute( "returnType", "void" ); + } + + // find additional functions + QStringList extraFuncts; + QStringList extraFunctTyp; + + 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; + QString l = n.attribute( "language", "C++" ); + if ( l != "C++" && l != "Perl" ) //- mmh + continue; + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + extraFuncts += Parser::cleanArgs(functionName); + extraFunctTyp += n.attribute( "returnType", "void" ); + } + + // find signals + QStringList extraSignals; + nl = e.parentNode().toElement().elementsByTagName( "signal" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "signals" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + QString l = n.attribute( "language", "C++" ); + if ( l != "C++" && l != "Perl" ) //- mmh + continue; + QString sigName = n.firstChild().toText().data().stripWhiteSpace(); + if ( sigName.endsWith( ";" ) ) + sigName = sigName.left( sigName.length() - 1 ); + extraSignals += sigName; + } + +#if 0 + //- kept for diffs + QStringList customImages; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "customwidgets" ) { + nl = n.elementsByTagName( "pixmap" ); + for ( i = 0; i < (int) nl.length(); i++ ) + customImages += nl.item( i ).firstChild().toText().data(); + } + } +#endif + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "customwidgets" ) { + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "customwidget" ) { + QDomElement n3 = n2.firstChild().toElement(); + QString cl, header; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + while ( !n3.isNull() ) { + if ( n3.tagName() == "class" ) { + cl = n3.firstChild().toText().data(); + r->name = cl; + } else if ( n3.tagName() == "header" ) { + CustomInclude ci; + ci.header = n3.firstChild().toText().data(); + ci.location = n3.attribute( "location", "global" ); + r->includeFile = ci.header; + header = ci.header; + customWidgetIncludes.insert( cl, ci ); + } + WidgetDatabase::append( r ); + n3 = n3.nextSibling().toElement(); + } + + if (cl.isEmpty()) + cl = "UnnamedCustomClass"; + + int ext = header.findRev('.'); + + if (ext >= 0) + header.truncate(ext); + + if (header.isEmpty()) + header = cl.lower(); + + if (!nofwd) + out << "use " << cl << ";" << endl; // FIXME: what about header ? + } + n2 = n2.nextSibling().toElement(); + } + } + } + + out << indent << "use Qt::isa qw(" << objClass << ");" << endl; + + // PerlQt sig/slot declaration + if ( !extraSlots.isEmpty() ) { + out << indent << "use Qt::slots" << endl; + ++indent; + for ( it = extraSlots.begin(); it != extraSlots.end(); ++it ) + { + perlSlot( it ); + out << ( ((*it) == extraSlots.last()) ? ";":",") << endl; + } + --indent; + } + + // create signals + if ( !extraSignals.isEmpty() ) { + out << indent << "use Qt::signals" << endl; + ++indent; + for ( it = extraSignals.begin(); it != extraSignals.end(); ++it ) + { + perlSlot( it ); + out << ( ((*it) == extraSignals.last()) ? ";":",") << endl; + } + --indent; + } + + // PerlQt attributes + out << indent << "use Qt::attributes qw("<< endl; + ++indent; + + // children + if( !objectNames.isEmpty() ) + cerr << "WARNING : objectNames should be empty at form.cpp line" << __LINE__ << 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(); + createAttrDecl( n ); + } + objectNames.clear(); + + // additional attributes (from Designer) + QStringList publicVars, protectedVars, privateVars; + nl = e.parentNode().toElement().elementsByTagName( "variable" ); + for ( i = 0; i < (int)nl.length(); i++ ) { + n = nl.item( i ).toElement(); + // Because of compatibility the next lines have to be commented out. + // Someday it should be uncommented. + //if ( n.parentNode().toElement().tagName() != "variables" ) + // continue; + QString access = n.attribute( "access", "protected" ); + QString var = n.firstChild().toText().data().stripWhiteSpace(); + if ( var.endsWith( ";" ) ) + var.truncate(var.length() - 1); + if ( access == "public" ) + publicVars += var; + else if ( access == "private" ) + privateVars += var; + else + protectedVars += var; + } + + // for now, all member variables are public. + + if ( !publicVars.isEmpty() ) { + for ( it = publicVars.begin(); it != publicVars.end(); ++it ) + out << indent << *it << endl; + } + if ( !protectedVars.isEmpty() ) { + for ( it = protectedVars.begin(); it != protectedVars.end(); ++it ) + out << indent << *it << endl; + } + if ( !privateVars.isEmpty() ) { + for ( it = privateVars.begin(); it != privateVars.end(); ++it ) + out << indent << *it << endl; + } + + + // actions, toolbars, menus + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) + { + if ( n.tagName() == "actions" ) + { + for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createActionDecl( a ); + } + else if ( n.tagName() == "toolbars" ) + { + for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + { + if ( a.tagName() == "toolbar" ) + out << indent << getObjectName( a ) << endl; + } + + } + else if ( n.tagName() == "menubar" ) + { + out << indent << getObjectName( n ) << endl; + for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + { + if ( a.tagName() == "item" ) + out << indent << a.attribute( "name" ) << endl; + } + } + } + + // Databases Connection holders + + registerDatabases( e ); + dbConnections = unique( dbConnections ); + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)") { + out << indent << (*it) << "Connection" << endl; + } + } + + --indent; + out << indent << ");" << endl; + out << endl; + + + // additional includes (local or global ) and forward declaractions + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) { + if ( (s.right( 5 ) == ".ui.h" || s.right( 6 ) == ".ui.pm") && !QFile::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 + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( (s.right( 5 ) == ".ui.h" || s.right( 6 ) == ".ui.pm") && !QFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in declaration" ) == "in declaration" ) + { + useIncludes += s; + } + else if ( n2.attribute( "impldecl", "in implementation" ) == "in implementation" ) + { + localIncludes += s; + } + } + } + + // additional custom widget headers + nl = e.parentNode().toElement().elementsByTagName( "header" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) + globalIncludes += s; + else + localIncludes += s; + } + + // Output the "use" clauses for extra stuff in "Includes (In Declaration)" + // => in the perleditor plugin, this is content of the "Use clauses" list + for(QStringList::Iterator it = useIncludes.begin(); it != useIncludes.end(); ++it) + out << indent << (*it) << endl; + + // grab slots/funcs defined in ui.h files / ui.pm files + for(QStringList::Iterator it = localIncludes.begin(); it != localIncludes.end(); ++it) + { + if((*it).right( 5 ) == ".ui.h") + { + QFile f((*it)); + if( f.open( IO_ReadOnly ) ) + { + QRegExp re("^.*([a-zA-Z0-9_]+\\s*\\(.*\\))\\s*$"); + QRegExp re2("^\\}.*"); + QTextStream t( &f ); + QString s, s2, s3; + while ( !t.eof() ) + { + s = t.readLine(); + int pos = re.search(s); + if(pos == -1) + continue; + s2 = re.cap(1); + s2 = Parser::cleanArgs(s2); + s3 = QString::null; + while( !t.eof() ) + { + s = t.readLine(); + s3 += s + "\n"; + if(re2.search(s) != -1) + break; + } + functionImpls.insert( s2, s3 ); + if( t.eof() ) break; + } + f.close(); + } + } + else if((*it).right( 6 ) == ".ui.pm") + { + //QFileInfo fname( fileName ); //- FIXME: .ui files seem to require being in CWD? + //QString path = fname.absFilePath(); + //path = path.left( path.length() - fname.fileName().length() ); + QFile f(*it); + if( f.open( IO_ReadOnly ) ) + { + QTextStream t( &f ); + QString s; + bool skip = true; + int count = 0; + while ( !t.eof() ) + { + s = t.readLine(); + if( skip ) + { + if( s[0] == '#' ) + { + count++; + continue; + } + else + { + skip = false; + uiPmInclude += "# line " + QString::number( count+1 ) + " \"" + *it + "\"\n"; + } + } + uiPmInclude += s + "\n"; + } + f.close(); + } + } + + } + + // 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 + QString name = getClassName( nl.item(i).toElement() ); + if ( name == "Spacer" ) { + globalIncludes += "qlayout.h"; + globalIncludes += "qapplication.h"; + continue; + } + if ( name.mid( 4 ) == "ListView" ) + globalIncludes += "qheader.h"; + if ( name != objClass ) { + int wid = WidgetDatabase::idFromClassName( name.replace( QRegExp("^Qt::"), "Q" ) ); + QMap<QString, CustomInclude>::Iterator it = customWidgetIncludes.find( name ); + if ( it == customWidgetIncludes.end() ) + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + } + + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + sqlClasses += "Qt::SqlDatabase"; + if ( dbCursors.count() ) + sqlClasses += "Qt::SqlCursor"; + 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 += "Qt::SqlForm"; + sqlClasses += "Qt::SqlRecord"; + } + + if (globalIncludes.findIndex("qdatatable.h") >= 0) + sqlClasses += "Qt::DataTable"; + + if (globalIncludes.findIndex("qtableview.h") >= 0) + sqlClasses += "Qt::TableView"; + + if (globalIncludes.findIndex("qdatabrowser.h") >= 0) + sqlClasses += "Qt::DataBrowser"; + + out << endl; + + // find out what images are required + QStringList 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++ ) { + QDomNode 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 ); + + QStringList images; + QStringList 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++ ) + { + QString img = registerObject( nl.item(i).toElement().attribute( "name" ) ); + if ( !requiredImages.contains( img ) ) + continue; + QDomElement tmp = nl.item(i).firstChild().toElement(); + if ( tmp.tagName() != "data" ) + continue; + QString format = tmp.attribute("format", "PNG" ); + QString data = tmp.firstChild().toText().data(); + out << indent << "our $" << img << ";" << endl; + if ( format == "XPM.GZ" ) + { + xpmImages += img; + ulong length = tmp.attribute("length").toULong(); + QByteArray 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 << "our $" << img << "_data =\n["; + + while ( baunzip[a] != '\"' ) + a++; + for ( ; a < (int) length; a++ ) + { + char ch; + if ((ch = baunzip[a]) == '}') + { + out << "];\n" << endl; + + break; + } + out << ch; + } + } + else + { + images += img; + out << indent << "our $" << img << "_data = pack 'C*'," << endl; + ++indent; + int a ; + for ( a = 0; a < (int) (data.length()/2)-1; a++ ) { + out << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << ","; + if ( a % 12 == 11 ) + out << endl << " "; + else + out << " "; + } + out << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << ";" << endl; + --indent; + out << endl; + } + } + } + } + out << endl; + } + else if ( externPixmaps ) + { + pixmapLoaderFunction = "Qt::Pixmap::fromMimeSource"; + } + + + // constructor(s) + out << indent << "sub NEW" << endl; + out << indent << "{" << endl; + ++indent; + if ( objClass == "Qt::Dialog" || objClass == "Qt::Wizard" ) { + out << indent << "shift->SUPER::NEW(@_[0..3]);" << endl; + } else if ( objClass == "Qt::Widget") { + out << indent << "shift->SUPER::NEW(@_[0..2]);" << endl; + } else if ( objClass == "Qt::MainWindow" ) { + out << indent << "shift->SUPER::NEW(@_[0..2]);" << endl; + out << indent << "statusBar();" << endl; + isMainWindow = TRUE; + } else { + out << indent << "shift->SUPER::NEW(@_[0,1]);" << endl; + } + + out << endl; + + // create pixmaps for all images + if ( !images.isEmpty() ) { + QStringList::Iterator it; + for ( it = images.begin(); it != images.end(); ++it ) { + out << indent << "$" << (*it) << " = Qt::Pixmap();" << endl; + out << indent << "$" << (*it) << "->loadFromData($" << (*it) << "_data, length ($" << (*it) << "_data), \"PNG\");" << endl; + } + out << endl; + } + // create pixmaps for all images + if ( !xpmImages.isEmpty() ) { + for ( it = xpmImages.begin(); it != xpmImages.end(); ++it ) { + out << indent << "$" << (*it) << " = Qt::Pixmap($" << (*it) << "_data);" << endl; + } + out << endl; + } + + + // set the properties + QSize 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" ) ); + QString prop = n.attribute("name"); + QDomElement n2 = n.firstChild().toElement(); + QString value = setObjectProperty( objClass, QString::null, prop, n2, stdset ); + if ( value.isEmpty() ) + continue; + + if ( prop == "geometry" && n2.tagName() == "rect" ) { + QDomElement 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 { + QString call; + if ( stdset ) + call = mkStdSet( prop ) + "(" + value; + else + call = "setProperty(\"" + prop + "\", Qt::Variant(" + value + ")"; + call += " );"; + if ( n2.tagName() == "string" ) { + trout << indent << call << endl; + } else if ( prop == "name" ) { + out << indent << "if ( name() eq \"unnamed\" )" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << call << endl; + --indent; + out << indent << "}" << endl; + } else { + out << indent << call << endl; + } + } + } + } + + out << endl; + + // create all children, some forms have special requirements + + if ( objClass == "Qt::Wizard" ) + { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + { + if ( tags.contains( n.tagName() ) ) + { + QString page = createObjectImpl( n, objClass, "this" ); + QString comment; + QString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << "addPage( " << page << ", \"\" );" << endl; + trout << indent << "setTitle( " << page << ", " << trcall( label, comment ) << " );" << endl; + QVariant def( FALSE, 0 ); + if ( DomTool::hasAttribute( n, "backEnabled" ) ) + out << indent << "setBackEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "backEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "nextEnabled" ) ) + out << indent << "setNextEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "nextEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "finishEnabled" ) ) + out << indent << "setFinishEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "finishEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "helpEnabled" ) ) + out << indent << "setHelpEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "helpEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "finish" ) ) + out << indent << "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, "this" ); + } + } + + // 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 << (*it) << "Connection = Qt::SqlDatabase::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(); + QString s = getClassName( n ); + if ( (dbForm || subDbForms) && ( s == "Qt::DataBrowser" || s == "Qt::DataView" ) ) { + QString objName = getObjectName( n ); + QString tab = getDatabaseInfo( n, "table" ); + QString con = getDatabaseInfo( n, "connection" ); + out << indent << "my $" << objName << "Form = Qt::SqlForm(this, \"" << objName << "Form\");" << endl; + QDomElement n2; + for ( n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) + createFormImpl( n2, objName, con, tab ); + out << indent << 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(), "this" ); + 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 << indent << "languageChange();" << endl; + + // take minimumSizeHint() into account, for height-for-width widgets + if ( !geometry.isNull() ) { + out << indent << "my $resize = Qt::Size(" << geometry.width() << ", " + << geometry.height() << ");" << endl; + out << indent << "$resize = $resize->expandedTo(minimumSizeHint());" << endl; + out << indent << "resize( $resize );" << endl; + out << indent << "clearWState( &Qt::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++ ) { + QString sender, receiver, signal, slot; + for ( QDomElement 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; + else if ( sender[0] == '<' || + receiver[0] == '<' || + signal[0] == '<' || + slot[0] == '<' ) + continue; + sender = registeredName( sender ); + receiver = registeredName( receiver ); + + if ( sender == objName ) + sender = "this"; + if ( receiver == objName ) + receiver = "this"; + + out << indent << "Qt::Object::connect(" << sender + << ", SIGNAL \"" << signal << "\", "<< receiver << ", SLOT \"" << slot << "\");" << endl; + } + } else if ( n.tagName() == "tabstops" ) { + // setup tab order + out << endl; + QString lastName; + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "tabstop" ) { + QString name = n2.firstChild().toText().data(); + name = registeredName( name ); + if ( !lastName.isEmpty() ) + out << indent << "setTabOrder(" << lastName << ", " << name << ");" << endl; + lastName = name; + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // buddies + bool firstBuddy = TRUE; + for ( QValueList<Buddy>::Iterator buddy = buddies.begin(); buddy != buddies.end(); ++buddy ) { + if ( isObjectRegistered( (*buddy).buddy ) ) { + if ( firstBuddy ) { + out << endl; + } + out << indent << (*buddy).key << "->setBuddy(this->" << registeredName( (*buddy).buddy ) << ");" << endl; + firstBuddy = FALSE; + } + + } + if ( extraFuncts.find( "init()" ) != extraFuncts.end() || + extraSlots.find( "init()" ) != extraSlots.end() ) + out << endl << indent << "init();" << endl; + + // end of constructor + --indent; + out << indent << "}" << endl; + out << endl; + + if ( extraFuncts.find( "destroy()" ) != extraFuncts.end() || + extraSlots.find( "destroy()" ) != extraSlots.end() ) { + out << endl; + out << indent << "sub DESTROY" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "destroy();" << endl; + out << indent << "SUPER->DESTROY()" << endl; + --indent; + out << indent << "}" << endl; + } + + + // 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; + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "Qt::DataTable" || s == "Qt::DataBrowser" ) { + if ( !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) + continue; + if ( s == "Qt::DataTable" ) + needSqlTableEventHandler = TRUE; + if ( s == "Qt::DataBrowser" ) + needSqlDataBrowserEventHandler = TRUE; + } + if ( needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler ) + break; + } + +// PerlQt - TODO: is this needed ? +// Seems not.. let's ifzero for now... + + if ( 0 && needFontEventHandler ) { + // indent = "\t"; // increase indentation for if-clause below + out << endl; + out << "# Main event handler. Reimplemented to handle" << endl; + out << "# application font changes" << endl; + out << endl; + out << "sub event" << endl; + out << "{" << endl; + out << " my $ev = shift;" << endl; + out << " my $ret = SUPER->event( $ev ); " << endl; + if ( needFontEventHandler ) { + ++indent; + out << " if ( $ev->type() == &Qt::Event::ApplicationFontChange ) {" << endl; + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + QStringList 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 << "sub polish" << endl; + out << indent << "{" << endl; + ++indent; + if ( needSqlTableEventHandler ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "Qt::DataTable" ) { + n = nl.item(i).toElement(); + QString c = getObjectName( n ); + QString conn = getDatabaseInfo( n, "connection" ); + QString tab = getDatabaseInfo( n, "table" ); + if ( !( conn.isEmpty() || tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if(" << c << ")" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "my $cursor = " << c << "->sqlCursor();" << endl; + out << endl; + out << indent << "if(!$cursor)" << endl; + out << indent << "{" << endl; + ++indent; + if ( conn == "(default)" ) + out << indent << "$cursor = Qt::SqlCursor(\"" << tab << "\");" << endl; + else + out << indent << "$cursor = Qt::SqlCursor(\"" << tab << "\", 1, " << conn << "Connection);" << endl; + out << indent << "if ( " << c << "->isReadOnly() ) " << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "$cursor->setMode( &Qt::SqlCursor::ReadOnly )" << endl; + --indent; + out << indent << "}" << endl; + out << indent << c << "->setSqlCursor($cursor, 0, 1);" << endl; + --indent; + out << endl; + out << indent << "}" << endl; + out << indent << "if(!$cursor->isActive())" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << c << "->refresh( &Qt::DataTable::RefreshAll );" << endl; + --indent; + out << indent << "}" << endl; + --indent; + out << indent << "}" << endl; + } + } + } + } + if ( needSqlDataBrowserEventHandler ) { + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "Qt::DataBrowser" ) { + QString obj = getObjectName( nl.item(i).toElement() ); + QString tab = getDatabaseInfo( nl.item(i).toElement(), + "table" ); + QString conn = getDatabaseInfo( nl.item(i).toElement(), + "connection" ); + if ( !(tab).isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) { + out << indent << "if(" << obj << ")" << endl; + out << indent << "{" << endl; + ++indent; + out << indent << "if(!" << obj << "->sqlCursor())" << endl; + out << indent << "{" << endl; + ++indent; + if ( conn == "(default)" ) + out << indent << "my $cursor = Qt::SqlCursor(\"" << tab << "\");" << endl; + else + out << indent << "my $cursor = Qt::SqlCursor(\"" << tab << "\", 1, " << conn << "Connection);" << endl; + out << indent << obj << "->setSqlCursor($cursor, 1);" << endl; + out << indent << obj << "->refresh();" << endl; + out << indent << obj << "->first();" << endl; + --indent; + out << indent << "}" << endl; + --indent; + out << indent << "}" << endl; + } + } + } + } + out << indent << "SUPER->polish();" << endl; + --indent; + out << indent << "}" << endl; + } + + out << endl; + out << indent << "# Sets the strings of the subwidgets using the current" << endl; + out << indent << "# language." << endl; + out << endl; + out << indent << "sub languageChange" << endl; + out << indent << "{" << endl; + ++indent; + out << languageChangeBody; + --indent; + out << indent << "}" << endl; + out << endl; + + // create stubs for additional functs/slots if necessary + + for ( it = extraSlots.begin(); it != extraSlots.end(); ++it ) + extraFuncts << *it; + + if ( !extraFuncts.isEmpty() && writeFunctImpl && uiPmInclude.isNull() ) { + for ( it = extraFuncts.begin(); it != extraFuncts.end(); ++it ) { + out << endl; + int astart = (*it).find('('); + out << indent << "sub " << (*it).left(astart)<< endl; + out << indent << "{" << endl; + bool createWarning = TRUE; + QString fname = Parser::cleanArgs( *it ); + QMap<QString, QString>::Iterator fit = functionImpls.find( fname ); + if ( fit != functionImpls.end() ) { + int begin = (*fit).find( "{" ); + QString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 ); + createWarning = body.simplifyWhiteSpace().isEmpty(); + if ( !createWarning ) + out << body << endl; + } + if ( createWarning ) { + ++indent; + if ( *it != "init()" && *it != "destroy()" ) + out << indent << "print \"" << nameOfClass << "->" << (*it) << ": Not implemented yet.\\n\";" << endl; + --indent; + } + out << indent << "}" << endl; + + } + } + else if( !extraFuncts.isEmpty() && writeFunctImpl ) + { + ++indent; + for ( it = extraFuncts.begin(); it != extraFuncts.end(); ++it ) { + if ( *it == "init()" || *it == "destroy()" ) + continue; + int astart = (*it).find('('); + QRegExp r( "(\\nsub\\s+" + (*it).left(astart) + "(?:\\s*#\\s*SLOT:[^\\n]+|[ \t]+)?\\n\\{)(\\s*)(\\}\\n)" ); + r.setMinimal( true ); + uiPmInclude.replace( r, "\\1\n" + + indent + "print \"" + nameOfClass + "->" + (*it) + + ": Not implemented yet.\\n\";" + "\n\\3" ); + } + --indent; + + } + + if( !uiPmInclude.isNull() ) + out << uiPmInclude; + + out << endl; + out << "1;" << endl; // Perl modules must return true +} + + +/*! Creates form support implementation code for the widgets given + in \a e. + + Traverses recursively over all children. + */ + +void Uic::createFormImpl( const QDomElement& e, const QString& form, const QString& connection, const QString& table ) +{ + if ( e.tagName() == "widget" && + e.attribute( "class" ) != "Qt::DataTable" ) { + QString field = getDatabaseInfo( e, "field" ); + if ( !field.isEmpty() ) { + if ( isWidgetInTable( e, connection, table ) ) + out << indent << "$" << form << "Form->insert(" << getObjectName( e ) << ", " << fixString( field ) << ");" << endl; + } + } + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + createFormImpl( n, form, connection, table ); + } +} + + +// Generate a PerlQt signal/slot definition. + +void Uic::perlSlot(QStringList::Iterator &it) +{ + int astart = (*it).find('('); + out << indent << (*it).left(astart) << " => "; + QString args = (*it).mid(astart + 1,(*it).find(')') - astart - 1).stripWhiteSpace(); + out << "["; + if (!args.isEmpty()) + { + QStringList arglist = QStringList::split( QRegExp(","), args ); + out << "'" << arglist.join( "', '") << "'"; + } + out << "]"; +} diff --git a/puic/globaldefs.h b/puic/globaldefs.h new file mode 100644 index 0000000..cc6ed40 --- /dev/null +++ b/puic/globaldefs.h @@ -0,0 +1,45 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 <qcolor.h> + +#define BOXLAYOUT_DEFAULT_MARGIN 11 +#define BOXLAYOUT_DEFAULT_SPACING 6 + +#ifndef NO_STATIC_COLORS +static QColor *backColor1 = 0; +static QColor *backColor2 = 0; +static QColor *selectedBack = 0; + +static void init_colors() +{ + if ( backColor1 ) + return; + backColor1 = new QColor( 236, 245, 255 ); + backColor2 = new QColor( 250, 250, 250 ); + selectedBack = new QColor( 221, 221, 221 ); +} + +#endif + +#endif diff --git a/puic/main.cpp b/puic/main.cpp new file mode 100644 index 0000000..869702c --- /dev/null +++ b/puic/main.cpp @@ -0,0 +1,325 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt 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. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +**********************************************************************/ +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qapplication.h> +#include <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <stdio.h> +#include <stdlib.h> +#define PUIC_VERSION "0.70" + +void getDBConnections( Uic& uic, QString& s); + +int main( int argc, char * argv[] ) +{ + PyIndent indent; + bool execCode = FALSE; + bool subcl = FALSE; + bool imagecollection = FALSE; + bool imagecollection_tmpfile = FALSE; + QStringList images; + const char *error = 0; + const char* fileName = 0; + const char* className = 0; + QCString outputFile; + QCString image_tmpfile; + const char* projectName = 0; + const char* trmacro = 0; + bool nofwd = FALSE; + bool fix = FALSE; + QApplication app(argc, argv, FALSE); + QString uicClass; + + + for ( int n = 1; n < argc && error == 0; n++ ) { + QCString arg = argv[n]; + if ( arg[0] == '-' ) { // option + QCString opt = &arg[1]; + if ( opt[0] == 'o' ) { // output redirection + if ( opt[1] == '\0' ) { + if ( !(n < argc-2) ) { + 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-2) ) { + error = "Missing arguments."; + break; + } + projectName = argv[++n]; + } else { + projectName = &opt[1]; + } + if ( argc > n+1 && qstrcmp( argv[n+1], "-f" ) == 0 ) { + imagecollection_tmpfile = TRUE; + image_tmpfile = argv[n+2]; + n += 2; + } + } else if ( opt == "nofwd" ) { + nofwd = TRUE; + } else if ( opt == "subimpl" ) { + subcl = TRUE; + if ( !(n < argc-2) ) { + error = "Missing arguments."; + break; + } + className = argv[++n]; + } else if ( opt == "tr" ) { + if ( opt == "tr" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing tr function."; + break; + } + trmacro = argv[++n]; + } else { + trmacro = &opt[1]; + } + } else if ( opt == "version" ) { + fprintf( stderr, + "PerlQt User Interface Compiler v%s for Qt version %s\n", PUIC_VERSION, + QT_VERSION_STR ); + exit( 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 indent"; + break; + } + tabstop = QCString(argv[++n]).toUInt(&ok); + } else + tabstop = opt.mid(1).toUInt(&ok); + + if (ok) + indent.setTabStop(tabstop); + else + error = "Invalid indent"; + } else if ( opt == "x" ) { + execCode = TRUE; + } else { + error = QString( "Unrecognized option " + opt ).latin1(); + } + } else { + if ( imagecollection && !imagecollection_tmpfile ) + 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, "PerlQt user interface compiler.\n" ); + if ( error ) + fprintf( stderr, "puic: %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" + "or\n" + " %s [options] -embed <project> -f <file>\n" + "\t<project>\tproject name\n" + "\t<file>\t\ttemporary file containing image names\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 indent in spaces (0 to use a tab)\n" + "\t-nofwd\t\tOmit imports of custom widgets\n" + "\t-tr func\tUse func(...) rather than trUtf8(...) for i18n\n" + "\t-x\t\tGenerate extra code to test the class\n" + "\t-version\tDisplay version of puic\n" + "\t-help\t\tDisplay this information\n" + , argv[0], argv[0], argv[0], argv[0], argv[0] ); + return 1; + } + + if ( imagecollection_tmpfile ) { + QFile ifile( image_tmpfile ); + if ( ifile.open( IO_ReadOnly ) ) { + QTextStream ts( &ifile ); + QString s = ts.read(); + s = s.simplifyWhiteSpace(); + images = QStringList::split( ' ', s ); + for ( QStringList::Iterator it = images.begin(); it != images.end(); ++it ) + *it = (*it).simplifyWhiteSpace(); + } + } + + Uic::setIndent(indent); + + QFile fileOut; + if ( !outputFile.isEmpty() ) { + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) { + qWarning( "puic: Could not open output file '%s'", outputFile.data() ); + return 1; + } + } else { + fileOut.open( IO_WriteOnly, stdout ); + } + QTextStream out( &fileOut ); + + if ( imagecollection ) { + out.setEncoding( QTextStream::Latin1 ); + Uic::embed( out, projectName, images ); + return 0; + } + + + out.setEncoding( QTextStream::UnicodeUTF8 ); + + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + qWarning( "puic: Could not open file '%s' ", fileName ); + return 1; + } + + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &file, &errMsg, &errLine ) ) { + qWarning( QString("puic: Failed to parse %s: ") + errMsg + QString (" in line %d\n"), fileName, errLine ); + return 1; + } + + QDomElement e = doc.firstChild().toElement(); + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.2 ) { + qWarning( QString("puic: File generated with too recent version of Qt Designer (%s). Recent extensions won't be handled."), + e.attribute("version").latin1() ); + return 1; + } + + DomTool::fixDocument( doc ); + + if ( fix ) { + out << doc.toString(); + return 0; + } + + if ( !subcl ) { + out << "# Form implementation generated from reading ui file '" << fileName << "'" << endl; + out << "#" << endl; + out << "# Created: " << QDateTime::currentDateTime().toString() << endl; + out << "# by: The PerlQt User Interface Compiler (puic)" << endl; + out << "#" << endl; + out << "# WARNING! All changes made in this file will be lost!" << endl; + out << endl; + out << endl; + } + out << "use strict;" << endl; + out << "use utf8;" << endl; + out << endl; + out << endl; + + Uic uic( fileName, outputFile, out, doc, subcl, trmacro ? trmacro : "trUtf8", className, nofwd, uicClass ); + + if (execCode) { + out << endl; + out << endl; + out << indent << "package main;" << endl; + out << endl; + out << "use Qt;" << endl; + out << "use " << (subcl ? QString::fromLatin1(className) : uicClass) << ";" << endl; + out << endl; + out << indent << "my $a = Qt::Application(\\@ARGV);" << endl; + QString s; + getDBConnections( uic, s); + out << s; + out << indent << "my $w = " << (subcl? QString::fromLatin1(className) : uicClass) << ";" << endl; + out << indent << "$a->setMainWidget($w);" << endl; + out << indent << "$w->show;" << endl; + out << indent << "exit $a->exec;" << endl; + } + if ( fileOut.status() != IO_Ok ) { + qWarning( "uic: Error writing to file" ); + if ( !outputFile.isEmpty() ) + remove( outputFile ); + } + return 0; +} + +void getDBConnections( Uic& uic, QString& s) +{ + int num = 0; + for ( QStringList::Iterator it = uic.dbConnections.begin(); it != uic.dbConnections.end(); ++it ) { + if ( !(*it).isEmpty()) { + QString inc = (num ? QString::number(num+1) : QString::null); + s += "\n# Connection to database " + (*it) + "\n\n"; + s += "my $DRIVER" + inc + " =\t\t'QMYSQL3';" + (inc?"":" # appropriate driver") + "\n"; + s += "my $DATABASE" + inc + " =\t\t'foo';" + (inc?"":" # name of your database") + "\n"; + s += "my $USER" + inc + "=\t\t'john';" + (inc?"":" # username") + "\n"; + s += "my $PASSWORD" + inc + "=\t\t'ZxjGG34s';" + (inc?"":" # password for USER") + "\n"; + s += "my $HOST" + inc + "=\t\t'localhost';" + (inc?"":" # host on which the database is running") + "\n"; + s += "\n"; + s += "my $db" + inc + " = Qt::SqlDatabase::addDatabase( $DRIVER" + inc; + if (inc) + s+= ", '" + (*it) + "'"; + s += " );\n"; + s += " $db" + inc + "->setDatabaseName( $DATABASE" + inc + " );\n"; + s += " $db" + inc + "->setUserName( $USER" + inc + " );\n"; + s += " $db" + inc + "->setPassword( $PASSWORD" + inc + " );\n"; + s += " $db" + inc + "->setHostName( $HOST" + inc + " );\n"; + s += "\n"; + s += "if( !$db" + inc + "->open() )\n"; + s += "{\n"; + s += " Qt::MessageBox::information( undef, 'Unable to open database',\n"; + s += " $db" + inc + "->lastError()->databaseText() . \"\\n\");\n"; + s += " exit 1;\n"; + s += "}\n"; + s += "\n"; + num++; + } + } +} + diff --git a/puic/object.cpp b/puic/object.cpp new file mode 100644 index 0000000..a7eb0c4 --- /dev/null +++ b/puic/object.cpp @@ -0,0 +1,768 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 "widgetinterface.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qregexp.h> +#include <qsizepolicy.h> +#include <qstringlist.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> + +/*! + Creates a declaration for the object given in \a e. + + Children are not traversed recursively. + + \sa createObjectImpl() + */ +void Uic::createObjectDecl( const QDomElement& e ) +{ + if ( e.tagName() == "vbox" || e.tagName() == "hbox" || e.tagName() == "grid" ) { + out << indent << registerObject(getLayoutName(e) ) << endl; + } else { + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + // ignore QLayoutWidgets + if ( objClass == "Qt::LayoutWidget" ) + return; + + // register the object and unify its name + objName = registerObject( objName ); + out << indent << objName << endl; + } +} + +/*! + Creates a PerlQt attribute declaration for the object given in \a e. + + Children are not traversed recursively. + + */ +void Uic::createAttrDecl( const QDomElement& e ) +{ + if ( e.tagName() == "vbox" || e.tagName() == "hbox" || e.tagName() == "grid" ) { + out << indent << registerObject(getLayoutName(e) ) << endl; + } else { + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + // ignore QLayoutWidgets + if ( objClass == "Qt::LayoutWidget" ) + return; + // register the object and unify its name + objName = registerObject( objName ); + out << indent << objName << endl; + QDomElement n = getObjectProperty( e, "font"); + if ( !n.isNull() ) + out << indent << objName + "_font" << endl; + } +} + + +/*! + Creates an implementation for the object given in \a e. + + Traverses recursively over all children. + + Returns the name of the generated child object. + + \sa createObjectDecl() + */ + +static bool createdCentralWidget = FALSE; + +QString Uic::createObjectImpl( const QDomElement &e, const QString& parentClass, const QString& par, const QString& layout ) +{ + QString parent( par ); + if ( parent == "this" && isMainWindow ) { + if ( !createdCentralWidget ) + out << indent << "setCentralWidget(Qt::Widget(this, \"qt_central_widget\"));" << endl; + createdCentralWidget = TRUE; + parent = "centralWidget()"; + } + QDomElement n; + QString objClass, objName; + 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 ); + + QString definedName = objName; + bool isTmpObject = objName.isEmpty() || objClass == "Qt::LayoutWidget"; + if ( isTmpObject ) { + if ( objClass[0] == 'Q' ) + objName = "$" + objClass.mid( 4 ); + else + objName = "$" + objClass.lower(); + } + + bool isLine = objClass == "Line"; + if ( isLine ) + objClass = "Qt::Frame"; + + out << endl; + if ( objClass == "Qt::LayoutWidget" ) { + if ( layout.isEmpty() ) { + // register the object and unify its name + objName = registerObject( objName ); + out << indent << (isTmpObject ? QString::fromLatin1("my ") : QString::null) << objName << " = Qt::Widget(" << parent << ", '" << objName << "');" << endl; + } else { + // the layout widget is not necessary, hide it by creating its child in the parent + QString 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; + } + + } else if ( objClass != "Qt::ToolBar" && objClass != "Qt::MenuBar" ) { + // register the object and unify its name + objName = registerObject( objName ); + + // Temporary objects don't go into the class instance dictionary. + + out << indent << (isTmpObject ? QString("my ") : QString::null) << objName << " = " << createObjectInstance( objClass, parent, objName ) << ";" << endl; + } + + if ( objClass == "Qt::AxWidget" ) { + QString 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 << objName << "->setControl(\"" << controlId << "\");" << endl; + } + + lastItem = "undef"; + // 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" ) ); + QString prop = n.attribute( "name" ); + if ( prop == "database" ) + continue; + QString 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 = "&Qt::Frame::HLine"; + else + value = "&Qt::Frame::VLine"; + if ( !hadFrameShadow ) { + prop = "frameStyle"; + value += " | &Qt::Frame::Sunken"; + } + } + if ( prop == "buttonGroupId" ) { + if ( parentClass == "Qt::ButtonGroup" ) + out << indent << parent << "->insert( " << objName << "," << value << ");" << endl; + continue; + } + if ( prop == "frameworkCode" ) + continue; + if ( objClass == "Qt::MultiLineEdit" && + QRegExp("echoMode|hMargin|maxLength|maxLines|undoEnabled").exactMatch(prop) ) + continue; + + QString call = objName + "->"; + bool needClose = false; + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + } else { + call += "setProperty( \"" + prop + "\", Qt::Variant(" ; + needClose = true; + } + if ( prop == "accel" ) + call += "Qt::KeySequence( " + value + " )"+ (needClose ? " )": "") + " );"; + else + call += value + (needClose ? " )": "") + " );"; + + if ( n.firstChild().toElement().tagName() == "string" || + prop == "currentItem" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( n.tagName() == "item" ) { + QString call; + QString value; + + if ( objClass.mid( 4 ) == "ListBox" ) { + call = createListBoxItemImpl( n, objName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.mid( 4 ) == "ComboBox" ) { + call = createListBoxItemImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.mid( 4 ) == "IconView" ) { + call = createIconViewItemImpl( n, objName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.mid( 4 ) == "ListView" ) { + call = createListViewItemImpl( n, objName, QString::null ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << call << endl; + } + } + if ( !call.isEmpty() ) + numItems++; + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + QString call; + QString value; + + if ( objClass.mid( 4 ) == "ListView" ) { + call = createListViewColumnImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << objName << "->header()->setLabel( " + << numColumns++ << ", " << value << " );\n"; + } + } else if ( objClass == "Qt::Table" || objClass == "Qt::DataTable" ) { + bool isCols = ( n.tagName() == "column" ); + call = createTableRowColumnImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << objName << "->" + << ( isCols ? "horizontalHeader" : "verticalHeader" ) + << "()->setLabel( " + << ( isCols ? numColumns++ : numRows++ ) + << ", " << value << " );\n"; + } + } + } + } + + // create all children, some widgets have special requirements + + if ( objClass == "Qt::TabWidget" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + QString comment; + QString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << objName << "->insertTab( " << page << ", \"\" );" << endl; + trout << indent << objName << "->changeTab( " << page << ", " + << trcall( label, comment ) << " );" << endl; + } + } + } else if ( objClass == "Qt::WidgetStack" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + int id = DomTool::readAttribute( n, "id", "" ).toInt(); + out << indent << objName << "->addWidget( " << page << ", " << id << " );" << endl; + } + } + } else if ( objClass == "Qt::ToolBox" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + QString label = DomTool::readAttribute( n, "label", "" ).toString(); + out << indent << objName << "->addItem( " << page << ", \"" << label << "\" );" << endl; + } + } + } else if ( objClass != "Qt::ToolBar" && objClass != "Qt::MenuBar" ) { // standard widgets + WidgetInterface *iface = 0; + QString QtObjClass = objClass; + QtObjClass.replace( QRegExp("^Qt::"), "Q" ); + QtObjClass.replace( QRegExp("^KDE::"), "K" ); + widgetManager()->queryInterface( QtObjClass, &iface ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + int id = WidgetDatabase::idFromClassName( QtObjClass ); + if ( WidgetDatabase::isContainer( id ) && WidgetDatabase::isCustomPluginWidget( id ) && iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + bool supportsPages = iface2->supportsPages( QtObjClass ); + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + if ( supportsPages ) { + QString page = createObjectImpl( n, objClass, objName ); + QString comment; + QString label = DomTool::readAttribute( n, "label", "", comment ).toString(); + out << indent << iface2->createCode( objClass, objName, page, label ) << endl; + } else { + createObjectImpl( n, objClass, objName ); + } + } + } + iface2->release(); + } + iface->release(); + } else { +#endif + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objClass, objName ); + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } +#endif + } + + return objName; +} + + + +/*! + 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 QDomElement & e, const QString& exclusiveProp ) +{ + QDomElement n; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString 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" ) ); + QString prop = n.attribute( "name" ); + if ( prop != exclusiveProp ) + continue; + QString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + // we assume the property isn't of type 'string' + ++indent; + out << indent << objName << "->setProperty(\"" << prop << "\", Qt::Variant(" << value << "));" << endl; + --indent; + } + } +} + + +/*! Attention: this function has to be in sync with + Resource::saveProperty() and DomTool::elementToVariant. If you + change one, change all. + */ +QString Uic::setObjectProperty( const QString& objClass, const QString& obj, const QString &prop, const QDomElement &e, bool stdset ) +{ + QString v; + if ( e.tagName() == "rect" ) { + QDomElement 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 = "Qt::Rect(%1, %2, %3, %4)"; + v = v.arg(x).arg(y).arg(w).arg(h); + + } else if ( e.tagName() == "point" ) { + QDomElement 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 = "Qt::Point(%1, %2)"; + v = v.arg(x).arg(y); + } else if ( e.tagName() == "size" ) { + QDomElement 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 = "Qt::Size(%1, %2)"; + v = v.arg(w).arg(h); + } else if ( e.tagName() == "color" ) { + QDomElement 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 = "Qt::Color(%1, %2, %3)"; + v = v.arg(r).arg(g).arg(b); + } else if ( e.tagName() == "font" ) { + QDomElement n3 = e.firstChild().toElement(); + QString attrname = e.parentNode().toElement().attribute( "name", "font" ); + QString fontname; + if ( !obj.isEmpty() ) { + fontname = registerObject( "$" + obj + "_" + attrname ); + out << indent << "my " << fontname << " = Qt::Font(" << obj << "->font);" << endl; + } else { + fontname = "$" + registerObject( "font" ); + out << indent << "my " << fontname << " = Qt::Font(this->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 << obj << "->setFont(" << fontname << ");" << endl; + else + out << indent << "setFont(" << fontname << ");" << endl; + } else { + v = fontname; + } + } else if ( e.tagName() == "string" ) { + QString txt = e.firstChild().toText().data(); + QString com = getComment( e.parentNode() ); + + if ( prop == "toolTip" && objClass != "Qt::Action" && objClass != "Qt::ActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "Qt::ToolTip::add(" << obj << ", " + << trcall( txt, com ) << ");" << endl; + else + out << indent << "Qt::ToolTip::add( this, " + << trcall( txt, com ) << ");" << endl; + } else if ( prop == "whatsThis" && objClass != "Qt::Action" && objClass != "Qt::ActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "Qt::WhatsThis::add(" << obj << ", " + << trcall( txt, com ) << ");" << endl; + else + trout << indent << "Qt::WhatsThis::add( this," + << 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 = "int(%1)"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "bool" ) { + if ( stdset ) + v = "%1"; + else + v = "Qt::Variant(%1, 0)"; + v = v.arg( mkBool( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "pixmap" ) { + v = e.firstChild().toText().data(); + if( !externPixmaps ) + v.prepend( '$' ); + if ( !pixmapLoaderFunction.isEmpty() ) { + v.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + v.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } else if ( e.tagName() == "iconset" ) { + v = "Qt::IconSet(%1)"; + QString s = e.firstChild().toText().data(); + if( !externPixmaps ) + s.prepend( '$' ); + if ( !pixmapLoaderFunction.isEmpty() ) { + s.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + s.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + v = v.arg( s ); + } else if ( e.tagName() == "image" ) { + v = e.firstChild().toText().data() + "->convertToImage()"; + } else if ( e.tagName() == "enum" ) { + if ( stdset ) + v = "&%1::%2()"; + else + v = "\"%1\""; + QString oc = objClass; + QString ev = e.firstChild().toText().data(); + if ( oc == "Qt::ListView" && ev == "Manual" ) // #### workaround, rename QListView::Manual in 4.0 + oc = "Qt::ScrollView"; + if ( stdset ) + v = v.arg( oc ).arg( ev ); + else + v = v.arg( ev ); + } else if ( e.tagName() == "set" ) { + QString keys( e.firstChild().toText().data() ); + QStringList lst = QStringList::split( '|', keys ); + v = "int(&"; + QStringList::Iterator it = lst.begin(); + while ( it != lst.end() ) { + v += objClass + "::" + *it; + if ( it != lst.fromLast() ) + v += " | &"; + ++it; + } + v += ")"; + } else if ( e.tagName() == "sizepolicy" ) { + QDomElement n3 = e.firstChild().toElement(); + QSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (QSizePolicy::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(); + } + QString tmp = (obj.isEmpty() ? QString::fromLatin1("this") : obj) + "->"; + v = "Qt::SizePolicy(%1, %2, %3, %4, " + tmp + "sizePolicy()->hasHeightForWidth())"; + v = v.arg( (int)sp.horData() ).arg( (int)sp.verData() ).arg( sp.horStretch() ).arg( sp.verStretch() ); + } else if ( e.tagName() == "palette" ) { + QPalette pal; + bool no_pixmaps = e.elementsByTagName( "pixmap" ).count() == 0; + QDomElement n; + if ( no_pixmaps ) { + n = e.firstChild().toElement(); + while ( !n.isNull() ) { + QColorGroup 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 == QPalette( pal.active().button(), pal.active().background() ) ) { + v = "Qt::Palette(Qt::Color(%1,%2,%3), Qt::Color(%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 { + QString palette = "pal"; + if ( !pal_used ) { + out << indent << palette << " = Qt::Palette();" << endl; + pal_used = TRUE; + } + QString cg = "cg"; + if ( !cg_used ) { + out << indent << cg << " = Qt::ColorGroup();" << 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 = "Qt::Cursor(%1)"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "date" ) { + QDomElement 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 = "Qt::Date(%1,%2,%3)"; + v = v.arg(y).arg(m).arg(d); + } else if ( e.tagName() == "time" ) { + QDomElement 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 = "Qt::Time(%1, %2, %3)"; + v = v.arg(h).arg(m).arg(s); + } else if ( e.tagName() == "datetime" ) { + QDomElement 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 = "Qt::DateTime(Qt::Date(%1, %2, %3), Qt::Time(%4, %5, %6))"; + v = v.arg(y).arg(mo).arg(d).arg(h).arg(mi).arg(s); + } else if ( e.tagName() == "stringlist" ) { + QStringList l; + QDomElement n3 = e.firstChild().toElement(); + QString listname; + if ( !obj.isEmpty() ) { + listname = obj + "->{_strlist"; + listname = registerObject( listname ); + listname += "}"; + out << indent << listname << " = ["; + } else { + listname = registerObject( "$" + listname ); + out << indent << "my " << listname << " = ["; + } + int i = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "string" ) + { + out << "'" << n3.firstChild().toText().data().simplifyWhiteSpace() << "'"; + n3 = n3.nextSibling().toElement(); + if( n3.isNull() ) + break; + i++; + if( (i%3) == 0 ) + { + ++indent; + out << "," << endl << indent; + --indent; + } + else + out << ", "; + } + else + n3 = n3.nextSibling().toElement(); + } + out << "];" << endl; + v = listname; + } + return v; +} + + + + +/*! Extracts a named object property from \a e. + */ +QDomElement Uic::getObjectProperty( const QDomElement& e, const QString& name ) +{ + QDomElement 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/puic/parser.cpp b/puic/parser.cpp new file mode 100644 index 0000000..4fc13c5 --- /dev/null +++ b/puic/parser.cpp @@ -0,0 +1,66 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 <qobject.h> +#include <qstringlist.h> + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +QString Parser::cleanArgs( const QString &func ) +{ + QString slot( func ); + int begin = slot.find( "(" ) + 1; + QString args = slot.mid( begin ); + args = args.left( args.find( ")" ) ); + QStringList lst = QStringList::split( ',', args ); + QString res = slot.left( begin ); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( it != lst.begin() ) + res += ","; + QString 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(); + QStringList l = QStringList::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 QString::fromLatin1( NormalizeObject::normalizeSignalSlot( res.latin1() ) ); +} diff --git a/puic/parser.h b/puic/parser.h new file mode 100644 index 0000000..5a5671a --- /dev/null +++ b/puic/parser.h @@ -0,0 +1,33 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 <qstring.h> + +class Parser +{ +public: + static QString cleanArgs( const QString &func ); + +}; + +#endif diff --git a/puic/puic.1 b/puic/puic.1 new file mode 100644 index 0000000..a125a8d --- /dev/null +++ b/puic/puic.1 @@ -0,0 +1,78 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.TH "PUIC" "1" "August 21, 2003" "Lutz Badenheuer <lutz.badenheuer@t-online.de>" "" +.SH "NAME" +puic \- perl user interface compiler +.SH "SYNOPSIS" +.B puic [options] [mode] <uifile> + +.SH "DESCRIPTION" +This manual page documents briefly the +.B puic +command. +.PP +\fBpuic\fP is a program you can use to compile .ui and .ui.h +files (from Qt Designer) into perl (actually, PerlQt) code. This +enables you to draw your application using Qt Designer, compile +and then run it. + +PerlQt is an API for Perl to the Qt toolkit from Trolltech. With +PerlQt, you can use Qt widgets in perl code, thus giving a GUI to +your perl programs. +.SH "OPTIONS" +\fBGenerate implementation:\fR + puic [options] <uifile> + +\fBGenerate image collection:\fR + puic [options] \-embed <project> <image1> <image2> <image3> ... + <project> project name + <image[0..n]> image files + + +\fBGenerate subclass implementation:\fR + puic [options] \-subimpl <classname> <uifile> + <classname> name of the subclass to generate + + +.TP +.B Options: +.TP +.B \-o file +Write output to file rather than stdout +.TP +.B \-p indent +Set the indent in spaces (0 to use a tab) +.TP +.B \-nofwd +Omit imports of custom widgets +.TP +.B \-tr func +Use func(...) rather than trUtf8(...) for i18n +.TP +.B \-x +Generate extra code to test the class +.TP +.B \-version +Display version of puic +.TP +.B \-help +Show summary of options +.SH "SEE ALSO" +http://perlqt.sourceforge.net/ +.SH "AUTHOR" +This manual page was written by Lutz Badenheuer <Lutz.Badenheuer@t\-online.de>, +for the Debian project (but may be used by others). diff --git a/puic/puic.pro b/puic/puic.pro new file mode 100644 index 0000000..157ae59 --- /dev/null +++ b/puic/puic.pro @@ -0,0 +1,28 @@ + +TEMPLATE = app +INCLUDEPATH += . + +CONFIG += qt warn_on + +exists( $(QTDIR)/lib/libqt-mt* ) { + CONFIG += thread +} + +DEFINES += UIC QT_INTERNAL_XML + +# Input +HEADERS += domtool.h \ + globaldefs.h \ + parser.h \ + uic.h \ + widgetdatabase.h \ + widgetinterface.h +SOURCES += domtool.cpp \ + embed.cpp \ + form.cpp \ + main.cpp \ + object.cpp \ + parser.cpp \ + subclassing.cpp \ + uic.cpp \ + widgetdatabase.cpp diff --git a/puic/stamp-h.in b/puic/stamp-h.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/puic/stamp-h.in diff --git a/puic/subclassing.cpp b/puic/subclassing.cpp new file mode 100644 index 0000000..51a5e55 --- /dev/null +++ b/puic/subclassing.cpp @@ -0,0 +1,191 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.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 QDomElement &e, const QString& subClass ) +{ + QDomElement n; + QDomNodeList nl; + int i; + + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + out << indent << "package " << subClass << ";" << endl; + out << indent << "use Qt;" << endl; + out << indent << "use " << nameOfClass << ";" << endl; + out << indent << "use Qt::isa qw("<< nameOfClass << ");" << endl; + + out << endl; + + // constructor + out << indent << "sub NEW" << endl; + out << indent << "{" << endl; + ++indent; + if ( objClass == "Qt::Dialog" || objClass == "Qt::Wizard" ) { + out << indent << "shift->SUPER::NEW(@_[0..3]);" << endl; + } else if ( objClass == "Qt::Widget") { + out << indent << "shift->SUPER::NEW(@_[0..2]);" << endl; + } else if ( objClass == "Qt::MainWindow" ) { + out << indent << "shift->SUPER::NEW(@_[0..2]);" << endl; + out << indent << "statusBar();" << endl; + isMainWindow = TRUE; + } else { + out << indent << "shift->SUPER::NEW(@_[0,1]);" << endl; + } + --indent; + out << indent << "}" << endl; + out << endl; + + // find additional functions + QStringList publicSlots, protectedSlots, privateSlots; + QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + QStringList publicFuncts, protectedFuncts, privateFuncts; + QStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + QStringList 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; + QString l = n.attribute( "language", "C++" ); + if ( l != "C++" && l != "Perl" ) //- mmh + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString 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(); + QString fname = n.attribute( "name" ); + fname = Parser::cleanArgs( fname ); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + QString l = n.attribute( "language", "C++" ); + if ( l != "C++" && l != "Perl" ) //- mmh + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString 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; + } + } + + // FIXME PerlQt: distinguishing public/protected/private slots does not make any sense in the forseable future + // but nevermind, never forget somewhere far beyond the sky, Ashley Winters is furbishing *Plan 42* ! :) + + if ( !publicFuncts.isEmpty() ) + writeFunctionsSubImpl( publicFuncts, publicFunctRetTyp, publicFunctSpec, subClass, "public function" ); + + if ( !publicSlots.isEmpty() ) + writeFunctionsSubImpl( publicSlots, publicSlotTypes, publicSlotSpecifier, subClass, "public slot" ); + + if ( !protectedFuncts.isEmpty() ) + writeFunctionsSubImpl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec, subClass, "protected function" ); + + if ( !protectedSlots.isEmpty() ) + writeFunctionsSubImpl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier, subClass, "protected slot" ); + + if ( !privateFuncts.isEmpty() ) + writeFunctionsSubImpl( privateFuncts, privateFunctRetTyp, privateFunctSpec, subClass, "private function" ); + + if ( !privateSlots.isEmpty() ) + writeFunctionsSubImpl( privateSlots, privateSlotTypes, privateSlotSpecifier, subClass, "private slot" ); + + out << "1;" << endl; +} + +void Uic::writeFunctionsSubImpl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst, + const QString &subClass, const QString &descr ) +{ + QValueListConstIterator<QString> it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + out << endl; + int astart = (*it).find('('); + out << indent << "sub " << (*it).left(astart)<< endl; + out << indent << "{" << endl; + ++indent; + out << indent << "print \"" << subClass << "->" << (*it) << ": (Private) Not implemented yet.\\n\";" << endl; + --indent; + out << indent << "}" << endl; + } + out << endl; +} diff --git a/puic/uic.cpp b/puic/uic.cpp new file mode 100644 index 0000000..5d87918 --- /dev/null +++ b/puic/uic.cpp @@ -0,0 +1,1101 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt 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. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> + +bool Uic::isMainWindow = FALSE; +PyIndent Uic::indent; + + +// 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 += ' '; +} + + +QString Uic::getComment( const QDomNode& n ) +{ + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == "comment" ) + return child.toElement().firstChild().toText().data(); + child = child.nextSibling(); + } + return QString::null; +} + +QString Uic::mkBool( bool b ) +{ + return b? "1" : "0"; +} + +QString Uic::mkBool( const QString& s ) +{ + return mkBool( s == "true" || s == "1" ); +} + +bool Uic::toBool( const QString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +QString Uic::fixString( const QString &str, bool encode ) +{ + QString s; + if ( !encode ) { + s = str; + // PerlQt: we don't want to use replace( QString, QString ) because we support Qt 3.0 + s.replace( QRegExp("\\\\"), "\\\\" ); + s.replace( QRegExp("\""), "\\\"" ); + s.replace( QRegExp("\\r?\\n"), "\\n\" .\n" + indent + "\"" ); + } else { + QCString utf8 = str.utf8(); + const int l = utf8.length(); + for ( int i = 0; i < l; ++i ) + s += "\\x" + QString::number( (uchar)utf8[i], 16 ); + } + return "\"" + s + "\""; +} + +QString Uic::trcall( const QString& sourceText, const QString& comment ) +{ + if ( sourceText.isEmpty() && comment.isEmpty() ) + return "\"\""; + QString t = trmacro; + bool encode = FALSE; + if ( t.isNull() ) { + t = "tr"; + for ( int i = 0; i < (int) sourceText.length(); i++ ) { + if ( sourceText[i].unicode() >= 0x80 ) { + t = "trUtf8"; + encode = TRUE; + break; + } + } + } + + if ( comment.isEmpty() ) + return trmacro + "(" + fixString( sourceText, encode ) + ")"; + return trmacro + "(" + fixString( sourceText, encode ) + "," + fixString( comment, encode ) + ")"; +} + +QString Uic::mkStdSet( const QString& prop ) +{ + return QString( "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 QString &fn, const char *outputFn, QTextStream &outStream, + QDomDocument doc, bool subcl, const QString &trm, + const QString& subClass, bool omitForwardDecls, QString &uicClass ) + : out( outStream ), trout( &languageChangeBody ), + outputFileName( outputFn ), trmacro( trm ), nofwd( omitForwardDecls ) +{ + fileName = fn; + writeFunctImpl = TRUE; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + externPixmaps = FALSE; + + 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() ); + + stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") ); + + if ( doc.firstChild().isNull() || doc.firstChild().firstChild().isNull() ) + return; + QDomElement e = doc.firstChild().firstChild().toElement(); + QDomElement 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 ) { + QString buf = defSpacing.toString(); + defSpacing = buf.append( "()" ); + } + defMargin = e.attribute( "margin", defMargin.toString() ); + defMargin.toInt( &ok ); + if ( !ok ) { + QString buf = defMargin.toString(); + defMargin = buf.append( "()" ); + } + } + e = e.nextSibling().toElement(); + } + e = widget; + + if ( nameOfClass.isEmpty() ) + nameOfClass = getObjectName( e ); + namespaces = QStringList::split( "::", nameOfClass ); + bareNameOfClass = namespaces.last(); + namespaces.remove( namespaces.fromLast() ); + + uicClass = nameOfClass; + + if ( subcl ) { + createSubImpl( e, subClass ); + } else { + createFormImpl( e ); + } +} + +/*! Extracts a pixmap loader function from \a e + */ +QString Uic::getPixmapLoaderFunction( const QDomElement& e ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "pixmapfunction" ) + return n.firstChild().toText().data(); + } + return QString::null; +} + + +/*! Extracts the forms class name from \a e + */ +QString Uic::getFormClassName( const QDomElement& e ) +{ + QDomElement n; + QString cn; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "class" ) { + QString s = n.firstChild().toText().data(); + int i; + while ( ( i = s.find(' ' )) != -1 ) + s[i] = '_'; + cn = s; + } + } + return cn; +} + +/*! Extracts a Perl class name from \a e. + */ +QString Uic::getClassName( const QDomElement& e ) +{ + QString s = e.attribute( "class" ); + if ( s.isEmpty() && e.tagName() == "toolbar" ) + s = "Qt::ToolBar"; + else if ( s.isEmpty() && e.tagName() == "menubar" ) + s = "Qt::MenuBar"; + else if( WidgetDatabase::idFromClassName( s ) == -1) + return s; + else + { + QRegExp r("^([QK])(\\S+)"); + if( r.search( s ) != -1 ) + s = (r.cap(1) == 'K'?"KDE::":"Qt::") + r.cap(2); + } + return s; +} + + + +/*! Returns TRUE if database framework code is generated, else FALSE. +*/ + +bool Uic::isFrameworkCodeGenerated( const QDomElement& e ) +{ + QDomElement n = getObjectProperty( e, "frameworkCode" ); + if ( n.attribute("name") == "frameworkCode" && + !DomTool::elementToVariant( n.firstChild().toElement(), QVariant( TRUE, 0 ) ).toBool() ) + return FALSE; + return TRUE; +} + +/*! Extracts an object name from \a e. It's stored in the 'name' + property. + */ +QString Uic::getObjectName( const QDomElement& e ) +{ + QDomElement n = getObjectProperty( e, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) + return n.firstChild().toElement().firstChild().toText().data(); + return QString::null; +} + +/*! Extracts an layout name from \a e. It's stored in the 'name' + property of the preceeding sibling (the first child of a QLayoutWidget). + */ +QString Uic::getLayoutName( const QDomElement& e ) +{ + QDomElement p = e.parentNode().toElement(); + QString name; + + if ( getClassName(p) != "Qt::LayoutWidget" ) + name = "Layout"; + + QDomElement n = getObjectProperty( p, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) { + name.prepend( n.firstChild().toElement().firstChild().toText().data() ); + return QStringList::split( "::", name ).last(); + } + return e.tagName(); +} + + +QString Uic::getDatabaseInfo( const QDomElement& e, const QString& tag ) +{ + QDomElement n; + QDomElement 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 QString::null; + n = getObjectProperty( e, "database" ); + if ( n.firstChild().toElement().tagName() == "stringlist" ) { + // find correct stringlist entry + QDomElement n1 = n.firstChild().firstChild().toElement(); + for ( int i = 0; i < child && !n1.isNull(); ++i ) + n1 = n1.nextSibling().toElement(); + if ( n1.isNull() ) + return QString::null; + return n1.firstChild().toText().data(); + } + return QString::null; +} + + +void Uic::registerLayouts( const QDomElement &e ) +{ + if ( layouts.contains(e.tagName()) ) + createObjectDecl(e); + + QDomNodeList nl = e.childNodes(); + for ( int i = 0; i < (int) nl.length(); ++i ) + registerLayouts( nl.item(i).toElement() ); +} + + +/*! + Returns include file for class \a className or a null string. + */ +QString Uic::getInclude( const QString& className ) +{ + int wid = WidgetDatabase::idFromClassName( className ); + if ( wid != -1 ) + return WidgetDatabase::includeFile( wid ); + return QString::null; +} + +void Uic::createActionDecl( const QDomElement& e ) +{ + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + out << indent << objName << endl; + if ( e.tagName() == "actiongroup" ) { + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) + createActionDecl( n ); + } + } +} + +void Uic::createActionImpl( const QDomElement &n, const QString &parent ) +{ + for ( QDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) { + QString objName = registerObject( getObjectName( ae ) ); + if ( ae.tagName() == "action" ) + out << indent << objName << "= Qt::Action(" << parent << ", \"" << objName << "\");" << endl; + else if ( ae.tagName() == "actiongroup" ) + out << indent << objName << "= Qt::ActionGroup(" << parent << ", \"" << objName << "\");" << endl; + else + continue; + bool subActionsDone = FALSE; + for ( QDomElement 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" ) ); + QString prop = n2.attribute("name"); + if ( prop == "name" ) + continue; + QString value = setObjectProperty( "Qt::Action", objName, prop, n2.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + QString call = objName + "->"; + bool needClose = false; + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + } else { + call += "setProperty( \"" + prop + "\", Qt::Variant(" ; + needClose = true; + } + if ( prop == "accel" ) + call += "Qt::KeySequence( " + value + " )"+ (needClose ? " )": "") + " );"; + else + call += value + (needClose ? " )": "") + " );"; + + if ( n2.firstChild().toElement().tagName() == "string" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) { + createActionImpl( n2, objName ); + subActionsDone = TRUE; + } + } + } +} + +QString get_dock( const QString &d ) +{ + if ( d == "0" ) + return "&DockUnmanaged"; + if ( d == "1" ) + return "&DockTornOff"; + if ( d == "2" ) + return "&DockTop"; + if ( d == "3" ) + return "&DockBottom"; + if ( d == "4" ) + return "&DockRight"; + if ( d == "5" ) + return "&DockLeft"; + if ( d == "6" ) + return "&DockMinimized"; + return ""; +} + +void Uic::createToolbarImpl( const QDomElement &n, const QString &parentClass, const QString &parent ) +{ + QDomNodeList nl = n.elementsByTagName( "toolbar" ); + for ( int i = 0; i < (int) nl.length(); i++ ) { + QDomElement ae = nl.item( i ).toElement(); + QString dock = get_dock( ae.attribute( "dock" ) ); + QString objName = getObjectName( ae ); + out << indent << objName << " = Qt::ToolBar(\"\", this, " << dock << ");" << endl; + createObjectImpl( ae, parentClass, parent ); + for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "action" ) { + out << indent << n2.attribute( "name" ) << "->addTo(" << objName << ");" << endl; + } else if ( n2.tagName() == "separator" ) { + out << indent << objName << "->addSeparator;" << endl; + } else if ( n2.tagName() == "widget" ) { + if ( n2.attribute( "class" ) != "Spacer" ) { + createObjectImpl( n2, "Qt::ToolBar", objName ); + } else { + QString child = createSpacerImpl( n, parentClass, parent, objName ); + out << indent << "Qt::Application->sendPostedEvents( $" << objName + << ", &Qt::Event::ChildInserted);" << endl; + out << indent << "$" << objName << "->boxLayout()->addItem(" << child << ");" << endl; + } + } + } + } +} + +void Uic::createMenuBarImpl( const QDomElement &n, const QString &parentClass, const QString &parent ) +{ + QString objName = getObjectName( n ); + out << indent << objName << "= Qt::MenuBar( this, \"" << objName << "\");" << endl; + createObjectImpl( n, parentClass, parent ); + + QDomNodeList nl = n.elementsByTagName( "item" ); + int i = 0; + QDomElement c = n.firstChild().toElement(); + while ( !c.isNull() ) { + if ( c.tagName() == "item" ) { + QString itemName = c.attribute( "name" ); + out << endl; + out << indent << itemName << " = Qt::PopupMenu( this );" << endl; + createPopupMenuImpl( c, parentClass, itemName ); + out << indent << objName << "->insertItem( \"\", " << itemName << ", " << i << " );" << endl; + trout << indent << objName << "->findItem( " << i << " )->setText( " << trcall( c.attribute( "text" ) ) << " );" << endl; + } else if ( c.tagName() == "separator" ) { + out << endl; + out << indent << objName << "->insertSeparator( " << i << " );" << endl; + } + c = c.nextSibling().toElement(); + i++; + } +} + +void Uic::createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent ) +{ + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" ) { + QDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + QString itemName = n2.attribute( "name" ); + QString itemText = n2.attribute( "text" ); + out << indent << itemName << " = Qt::PopupMenu( this );" << endl; + out << indent << parent << "->setAccel( tr( \"" << n2.attribute( "accel" ) << "\" ), " << endl; + ++indent; + out << indent << parent << "->insertItem( " << n.attribute( "name" ) << "->iconSet(),"; + out << trcall( itemText ) << ", " << itemName << " ) );" << endl; + --indent; + createPopupMenuImpl( n2, parentClass, itemName ); + n = n2; + } else { + out << indent << n.attribute( "name" ) << "->addTo( " << parent << " );" << endl; + } + } else if ( n.tagName() == "separator" ) { + out << indent << parent << "->insertSeparator();" << endl; + } + } + } + +/*! + Creates implementation of an listbox item tag. +*/ + +QString Uic::createListBoxItemImpl( const QDomElement &e, const QString &parent, + QString *value ) + +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if( !pix.isEmpty() && !externPixmaps ) + pix.prepend( '$' ); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + if ( pix.isEmpty() ) { + return parent + "->insertItem( " + trcall( txt, com ) + " );"; + } else { + return parent + "->insertItem( " + pix + ", " + trcall( txt, com ) + " );"; + } + +} + +/*! + Creates implementation of an iconview item tag. +*/ + +QString Uic::createIconViewItemImpl( const QDomElement &e, const QString &parent ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if( !pix.isEmpty() && !externPixmaps ) + pix.prepend( '$' ); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( pix.isEmpty() ) + return "Qt::IconViewItem(" + parent + ", " + trcall( txt, com ) + ");"; + else + return "Qt::IconViewItem(" + parent + ", " + trcall( txt, com ) + ", " + pix + ");"; +} + +/*! + Creates implementation of an listview item tag. +*/ + +QString Uic::createListViewItemImpl( const QDomElement &e, const QString &parent, + const QString &parentItem ) +{ + QString s; + + QDomElement n = e.firstChild().toElement(); + + bool hasChildren = e.elementsByTagName( "item" ).count() > 0; + QString item; + + if ( hasChildren ) { + item = "$" + registerObject( "item" ); + s = indent + "my " + item + " = "; + } else { + item = "$item"; + if ( item_used ) + s = indent + item + " = "; + else + s = indent + "my " + item + " = "; + item_used = TRUE; + } + + if ( !parentItem.isEmpty() ) + s += "Qt::ListViewItem(" + parentItem + ", " + lastItem + ");\n"; + else + s += "Qt::ListViewItem(" + parent + ", " + lastItem + ");\n"; + + QStringList texts; + QStringList pixmaps; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + texts << v.toString(); + else if ( attrib == "pixmap" ) { + QString pix = v.toString(); + if( !pix.isEmpty() && !externPixmaps ) + pix.prepend( '$' ); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + pixmaps << pix; + } + } else if ( n.tagName() == "item" ) { + s += indent + 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 += indent + item + "->setText(" + QString::number( i ) + ", " + trcall( texts[ i ] ) + ");\n"; + if ( !pixmaps[ i ].isEmpty() ) + s += indent + item + "->setPixmap(" + QString::number( i ) + ", " + pixmaps[ i ] + ");\n"; + } + + lastItem = item; + return s; +} + +/*! + Creates implementation of an listview column tag. +*/ + +QString Uic::createListViewColumnImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + bool clickable = FALSE, resizable = FALSE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if( !pix.isEmpty() && !externPixmaps ) + pix.prepend( '$' ); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( 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 ); + + QString s; + s = indent + parent + "->addColumn(" + trcall( txt, com ) + ");\n"; + if ( !pix.isEmpty() ) + s += indent + parent + "->header()->setLabel(" + parent + "->header()->count() - 1," + 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; +} + +QString Uic::createTableRowColumnImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QString objClass = getClassName( e.parentNode().toElement() ); + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + QString field; + bool isRow = e.tagName() == "row"; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if( !pix.isEmpty() && !externPixmaps ) + pix.prepend( '$' ); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( 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 QDataTable has an API which makes this code pretty good + + QString 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, Qt::IconSet(" + + pix + " ), " + trcall( txt, com ) + ");\n"; + } else { + if ( objClass == "Qt::Table" ) { + 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, Qt::IconSet(" + + pix + " ), " + trcall( txt, com ) + ");\n"; + } else if ( objClass == "Qt::DataTable" ) { + 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 ) << ", Qt::IconSet(" << pix << "));" << endl; + } + } + } + return s; +} + +/*! + Creates the implementation of a layout tag. Called from createObjectImpl(). + */ +QString Uic::createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout ) +{ + QDomElement n; + QString objClass, objName; + objClass = e.tagName(); + + QString qlayout = "Qt::VBoxLayout"; + if ( objClass == "hbox" ) + qlayout = "Qt::HBoxLayout"; + else if ( objClass == "grid" ) + qlayout = "Qt::GridLayout"; + + bool isGrid = e.tagName() == "grid" ; + objName = registerObject( "$" + getLayoutName( e ) ); + layoutObjects += objName; + QString margin = DomTool::readProperty( e, "margin", defMargin ).toString(); + QString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString(); + QString resizeMode = DomTool::readProperty( e, "resizeMode", QString::null ).toString(); + + QString optcells; + if ( isGrid ) + optcells = "1, 1, "; + if ( (parentClass == "Qt::GroupBox" || parentClass == "Qt::ButtonGroup") && layout.isEmpty() ) { + // special case for group box + out << indent << parent << "->setColumnLayout( 0, &Vertical );" << endl; + out << indent << parent << "->layout()->setSpacing(" << spacing << ");" << endl; + out << indent << parent << "->layout()->setMargin(" << margin << ");" << endl; + out << indent << "my " << objName << " = " << qlayout << "(" << parent << "->layout() );" << endl; + out << indent << objName << "->setAlignment( &AlignTop );" << endl; + } else { + out << indent << "my " << objName << " = " << qlayout << "("; + if ( layout.isEmpty() ) + out << parent; + else { + out << "undef"; + if ( !DomTool::hasProperty( e, "margin" ) ) + margin = "0"; + } + out << ", " << optcells << margin << ", " << spacing << ", '" << objName << "');" << endl; + } + if ( !resizeMode.isEmpty() ) + out << indent << objName << "->setResizeMode( &Qt::Layout::" << resizeMode << " );" << endl; + + if ( !isGrid ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "spacer" ) { + QString child = createSpacerImpl( n, parentClass, parent, objName ); + out << indent << objName << "->addItem(" << child << ");" << endl; + } else if ( tags.contains( n.tagName() ) ) { + QString 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() ) { + QDomElement 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" ) { + QString 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() ) ) { + QString child = createObjectImpl( n, parentClass, parent, objName ); + out << endl; + QString 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; +} + + + +QString Uic::createSpacerImpl( const QDomElement &e, const QString& /*parentClass*/, const QString& /*parent*/, const QString& /*layout*/) +{ + QDomElement n; + QString objClass, objName; + objClass = e.tagName(); + objName = registerObject( "$spacer" ); + + QSize size = DomTool::readProperty( e, "sizeHint", QSize( 0, 0 ) ).toSize(); + QString 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 Qt 2.2 + QRect geom = DomTool::readProperty( e, "geometry", QRect(0,0,0,0) ).toRect(); + size = geom.size(); + } + + if ( isVspacer ) + out << indent << "my " << objName << " = Qt::SpacerItem(" + << size.width() << ", " << size.height() + << ", &Qt::SizePolicy::Minimum, &Qt::SizePolicy::" << sizeType << ");" << endl; + else + out << indent << "my " << objName << " = Qt::SpacerItem(" + << size.width() << ", " << size.height() + << ", &Qt::SizePolicy::" << sizeType << ", &Qt::SizePolicy::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 QString& name, const QDomElement& e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QString color; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + QColor col = DomTool::readColor( n ); + color = "Qt::Color(%1,%2,%3)"; + color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() ); + if ( col == white ) + color = "&white"; + else if ( col == black ) + color = "&black"; + if ( n.nextSibling().toElement().tagName() != "pixmap" ) { + out << indent << name << "->setColor(&Qt::ColorGroup::" << ColorRole[r] << ", " << color << ");" << endl; + } + } else if ( n.tagName() == "pixmap" ) { + QString pixmap = n.firstChild().toText().data(); + if( !pixmap.isEmpty() && !externPixmaps ) + pixmap.prepend( '$' ); + if ( !pixmapLoaderFunction.isEmpty() ) { + pixmap.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pixmap.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + out << indent << name << "->setBrush(&Qt::ColorGroup::" + << ColorRole[r] << ", Qt::Brush(" << color << ", " << pixmap << "));" << endl; + } + n = n.nextSibling().toElement(); + } +} + +/*! + Auxiliary function to load a color group. The colorgroup must not + contain pixmaps. + */ +QColorGroup Uic::loadColorGroup( const QDomElement &e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (QColorGroup::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 QDomElement& e, const QString& connection, const QString& table ) +{ + QString conn = getDatabaseInfo( e, "connection" ); + QString tab = getDatabaseInfo( e, "table" ); + if ( conn == connection && tab == table ) + return TRUE; + return FALSE; +} + +/*! + Registers all database connections, cursors and forms. +*/ + +void Uic::registerDatabases( const QDomElement& e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); ++i ) { + n = nl.item(i).toElement(); + QString conn = getDatabaseInfo( n, "connection" ); + QString tab = getDatabaseInfo( n, "table" ); + QString 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() + */ +QString Uic::registerObject( const QString& name ) +{ + if ( objectNames.isEmpty() ) { + // some temporary variables we need + objectNames += "img"; + objectNames += "item"; + objectNames += "cg"; + objectNames += "pal"; + } + + QString result = name; + int i; + while ( ( i = result.find(' ' )) != -1 ) { + result[i] = '_'; + } + + if ( objectNames.contains( result ) ) { + int i = 2; + while ( objectNames.contains( result + "_" + QString::number(i) ) ) + i++; + result += "_"; + result += QString::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() + */ +QString Uic::registeredName( const QString& 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 QString& name ) +{ + return objectMapper.contains( name ); +} + + +/*! + Unifies the entries in stringlist \a list. Should really be a QStringList feature. + */ +QStringList Uic::unique( const QStringList& list ) +{ + if ( list.isEmpty() ) + return list; + + QStringList result; + for ( QStringList::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 + */ +QString Uic::createObjectInstance( const QString& objClass, const QString& parent, const QString& objName ) +{ + + if ( objClass.mid( 4 ) == "ComboBox" ) { + return objClass + "(0, " + parent + ", \"" + objName + "\")"; + } + return objClass + "(" + parent + ", \"" + objName + "\")"; +} + +bool Uic::isLayout( const QString& name ) const +{ + return layoutObjects.contains( name ); +} diff --git a/puic/uic.h b/puic/uic.h new file mode 100644 index 0000000..20d07e2 --- /dev/null +++ b/puic/uic.h @@ -0,0 +1,195 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** +** This file is part of Qt 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 <qdom.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qtextstream.h> +#include <qpalette.h> +#include <qvariant.h> + +#ifndef Q_DUMMY_COMPARISON_OPERATOR +# warning "Defining Q_DUMMY_COMPARISON_OPERATOR" +# ifdef Q_FULL_TEMPLATE_INSTANTIATION +# define Q_DUMMY_COMPARISON_OPERATOR(C) \ + bool operator==( const C& ) const { \ + qWarning( #C"::operator==( const "#C"& ) got called." ); \ + return FALSE; \ + } +# else +# define Q_DUMMY_COMPARISON_OPERATOR(C) +# endif +#endif + +class PyIndent +{ +public: + PyIndent() : tabStop(4), current(0) {calc();} + + void setTabStop(uint n) {tabStop = n; calc();} + void operator++() {++current; calc();} + void operator--() {--current; calc();} + operator QString() {return indstr;} + +private: + uint tabStop; + uint current; + QString indstr; + + void calc(); +}; + + +class Uic : public Qt +{ +public: + Uic( const QString &fn, const char *outputFn, QTextStream& outStream, + QDomDocument doc, bool subcl, const QString &trm, + const QString& subClass, bool omitForwardDecls, QString &uicClass ); + + static void setIndent(const PyIndent &pyind) {indent = pyind;} + + void createFormImpl( const QDomElement &e ); + + void createSubImpl( const QDomElement &e, const QString& subclname ); + + void createObjectDecl( const QDomElement& e ); + void createAttrDecl( const QDomElement& e ); + void createActionDecl( const QDomElement& e ); + void createActionImpl( const QDomElement& e, const QString &parent ); + void createToolbarImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + void createMenuBarImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + void createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + QString createObjectImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + QString createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + QString createObjectInstance( const QString& objClass, const QString& parent, const QString& objName ); + QString createSpacerImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + void createExclusiveProperty( const QDomElement & e, const QString& exclusiveProp ); + QString createListBoxItemImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createIconViewItemImpl( const QDomElement &e, const QString &parent ); + QString createListViewColumnImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createTableRowColumnImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createListViewItemImpl( const QDomElement &e, const QString &parent, + const QString &parentItem ); + void createColorGroupImpl( const QString& cg, const QDomElement& e ); + QColorGroup loadColorGroup( const QDomElement &e ); + + QDomElement getObjectProperty( const QDomElement& e, const QString& name ); + QString getPixmapLoaderFunction( const QDomElement& e ); + QString getFormClassName( const QDomElement& e ); + QString getClassName( const QDomElement& e ); + QString getObjectName( const QDomElement& e ); + QString getLayoutName( const QDomElement& e ); + QString getInclude( const QString& className ); + + QString setObjectProperty( const QString& objClass, const QString& obj, const QString &prop, const QDomElement &e, bool stdset ); + + QString registerObject( const QString& name ); + QString registeredName( const QString& name ); + bool isObjectRegistered( const QString& name ); + QStringList unique( const QStringList& ); + + QString trcall( const QString& sourceText, const QString& comment = "" ); + + static void embed( QTextStream& out, const char* project, const QStringList& images ); + + friend void getDBConnections(Uic& uic, QString& s); + +private: + void registerLayouts ( const QDomElement& e ); + + QTextStream& out; + QTextOStream trout; + QString languageChangeBody; + QCString outputFileName; + QStringList objectNames; + QMap<QString,QString> objectMapper; + QStringList tags; + QStringList layouts; + QString formName; + QString lastItem; + QString trmacro; + + bool nofwd; + static PyIndent indent; + + struct Buddy + { + Buddy( const QString& k, const QString& b ) + : key( k ), buddy( b ) {} + Buddy(){} // for valuelist + QString key; + QString buddy; + bool operator==( const Buddy& other ) const + { return (key == other.key); } + }; + struct CustomInclude + { + QString header; + QString location; + Q_DUMMY_COMPARISON_OPERATOR(CustomInclude) + }; + QValueList<Buddy> buddies; + + QStringList layoutObjects; + bool isLayout( const QString& name ) const; + + uint item_used : 1; + uint cg_used : 1; + uint pal_used : 1; + uint stdsetdef : 1; + uint externPixmaps : 1; + + QString nameOfClass; + QStringList namespaces; + QString bareNameOfClass; + QString pixmapLoaderFunction; + + void registerDatabases( const QDomElement& e ); + bool isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table ); + bool isFrameworkCodeGenerated( const QDomElement& e ); + QString getDatabaseInfo( const QDomElement& e, const QString& tag ); + void createFormImpl( const QDomElement& e, const QString& form, const QString& connection, const QString& table ); + void writeFunctionsSubImpl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst, + const QString &subClass, const QString &descr ); + QStringList dbConnections; + QMap< QString, QStringList > dbCursors; + QMap< QString, QStringList > dbForms; + + static bool isMainWindow; + static QString mkBool( bool b ); + static QString mkBool( const QString& s ); + bool toBool( const QString& s ); + static QString fixString( const QString &str, bool encode = FALSE ); + static bool onlyAscii; + static QString mkStdSet( const QString& prop ); + static QString getComment( const QDomNode& n ); + QVariant defSpacing, defMargin; + QString fileName; + bool writeFunctImpl; + + void perlSlot(QStringList::Iterator &it); +}; + +#endif diff --git a/puic/widgetdatabase.cpp b/puic/widgetdatabase.cpp new file mode 100644 index 0000000..6c447d5 --- /dev/null +++ b/puic/widgetdatabase.cpp @@ -0,0 +1,953 @@ +/********************************************************************** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt 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 Qt 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 <qapplication.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qstrlist.h> +#include <qdict.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qcleanuphandler.h> +#include <qfeatures.h> + +#include <stdlib.h> + +const int dbsize = 300; +const int dbcustom = 200; +const int dbdictsize = 211; +static WidgetDatabaseRecord* db[ dbsize ]; +static QDict<int> *className2Id = 0; +static int dbcount = 0; +static int dbcustomcount = 200; +static QStrList *wGroups; +static QStrList *invisibleGroups; +static bool whatsThisLoaded = FALSE; +static QPluginManager<WidgetInterface> *widgetPluginManager = 0; +static bool plugins_set_up = FALSE; +static bool was_in_setup = FALSE; + +QCleanupHandler<QPluginManager<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 QStrList; + invisibleGroups = new QStrList; + invisibleGroups->append( "Forms" ); + invisibleGroups->append( "Temp" ); + className2Id = new QDict<int>( dbdictsize ); + className2Id->setAutoDelete( TRUE ); + + WidgetDatabaseRecord *r = 0; + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_pushbutton.png"; + r->name = "QPushButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Push Button"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_toolbutton.png"; + r->name = "QToolButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Tool Button"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_radiobutton.png"; + r->name = "QRadioButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Radio Button"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_checkbox.png"; + r->name = "QCheckBox"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Check Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_groupbox.png"; + r->name = "QGroupBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Group Box"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_buttongroup.png"; + r->name = "QButtonGroup"; + 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 = "QFrame"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Frame"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QTabWidget"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tabwidget"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_widgetstack.png"; + r->name = "QWidgetStack"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Widget Stack"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_toolbox.png"; + r->name = "QToolBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tool Box"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_listbox.png"; + r->name = "QListBox"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_listview.png"; + r->name = "QListView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List View"; + + append( r ); + +#if !defined(QT_NO_ICONVIEW) || defined(UIC) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_iconview.png"; + r->name = "QIconView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Icon View"; + + append( r ); +#endif + +#if !defined(QT_NO_TABLE) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_table.png"; + r->name = "QTable"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Table"; + + append( r ); +#endif + +#if !defined(QT_NO_SQL) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_datatable.png"; + r->includeFile = "qdatatable.h"; + r->name = "QDataTable"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Table"; + + append( r ); +#endif + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_lineedit.png"; + r->name = "QLineEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Line Edit"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_spinbox.png"; + r->name = "QSpinBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Spin Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_dateedit.png"; + r->name = "QDateEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_timeedit.png"; + r->name = "QTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Time Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_datetimeedit.png"; + r->name = "QDateTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date-Time Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_multilineedit.png"; + r->name = "QMultiLineEdit"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Multi Line Edit"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_richtextedit.png"; + r->name = "QTextEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Rich Text Edit"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_combobox.png"; + r->name = "QComboBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Combo Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_slider.png"; + r->name = "QSlider"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Slider"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_scrollbar.png"; + r->name = "QScrollBar"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Scrollbar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_dial.png"; + r->name = "QDial"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Dial"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_label.png"; + r->name = "QLabel"; + 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 = "QLCDNumber"; + 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 = "qframe.h"; + r->whatsThis = "The Line widget provides horizontal and vertical lines."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_progress.png"; + r->name = "QProgressBar"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Progress Bar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_textview.png"; + r->name = "QTextView"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Text View"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_textbrowser.png"; + r->name = "QTextBrowser"; + 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 = "QWidget"; + r->isForm = TRUE; + r->group = widgetGroup( "Forms" ); + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QDialog"; + r->group = widgetGroup( "Forms" ); + r->isForm = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QDesignerWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QLayoutWidget"; + r->group = widgetGroup( "Temp" ); + r->includeFile = ""; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QSplitter"; + r->group = widgetGroup( "Temp" ); + r->includeFile = "qsplitter.h"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QDesignerTabWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QDesignerWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QDesignerDialog"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QMainWindow"; + r->includeFile = "qmainwindow.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDesignerAction"; + r->includeFile = "qaction.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = FALSE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDesignerActionGroup"; + r->includeFile = "qaction.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = FALSE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QScrollView"; + r->includeFile = "qscrollview.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + +#ifndef QT_NO_SQL + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDataBrowser"; + r->includeFile = "qdatabrowser.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 = "QDataView"; + r->includeFile = "qdataview.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; + QStringList widgets = widgetManager()->featureList(); + for ( QStringList::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 + QIconSet icon = iface->iconSet( *it ); + if ( !icon.pixmap().isNull() ) + r->icon = new QIconSet( icon ); +#endif + QString 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. +*/ + +QIconSet WidgetDatabase::iconSet( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QIconSet(); +#if !defined(UIC) && !defined(RESOURCE) + if ( !r->icon ) { + if ( r->iconSet.isEmpty() ) + return QIconSet(); + QPixmap pix = QPixmap::fromMimeSource( r->iconSet ); + if ( pix.isNull() ) + pix = QPixmap( r->iconSet ); + r->icon = new QIconSet( pix ); + } + return *r->icon; +#else + return QIconSet(); +#endif +} + +/*! + Returns the classname of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::className( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->name; +} + +/*! + Returns the group the widget registered as \a id belongs to. +*/ + +QString WidgetDatabase::group( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->group; +} + +/*! + Returns the tooltip text of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::toolTip( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->toolTip; +} + +/*! + Returns the what's this? text of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::whatsThis( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->whatsThis; +} + +/*! + Returns the include file if the widget which is registered as \a id. +*/ + +QString WidgetDatabase::includeFile( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::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; +} + +QString WidgetDatabase::createWidgetName( int id ) +{ + setupDataBase( id ); + QString n = className( id ); + if ( n == "QLayoutWidget" ) + 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 += QString::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 QString &name ) +{ + setupDataBase( -1 ); + if ( name.isEmpty() ) + return 0; + int *i = className2Id->find( name ); + if ( i ) + return *i; + if ( name == "FormWindow" ) + return idFromClassName( "QLayoutWidget" ); +#ifdef UIC + setupDataBase( -2 ); + i = className2Id->find( name ); + if ( i ) + return *i; +#endif + return -1; +} + +bool WidgetDatabase::hasWidget( const QString &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 = QMAX( dbcount, index ); +} + +void WidgetDatabase::append( WidgetDatabaseRecord *r ) +{ + if ( !was_in_setup ) + setupDataBase( -1 ); + insert( dbcount++, r ); +} + +QString WidgetDatabase::widgetGroup( const QString &g ) +{ + if ( wGroups->find( g ) == -1 ) + wGroups->append( g ); + return g; +} + +bool WidgetDatabase::isGroupEmpty( const QString &grp ) +{ + WidgetDatabaseRecord *r = 0; + for ( int i = 0; i < dbcount; ++i ) { + if ( !( r = db[ i ] ) ) + continue; + if ( r->group == grp ) + return FALSE; + } + return TRUE; +} + +QString WidgetDatabase::widgetGroup( int i ) +{ + setupDataBase( -1 ); + if ( i >= 0 && i < (int)wGroups->count() ) + return wGroups->at( i ); + return QString::null; +} + +int WidgetDatabase::numWidgetGroups() +{ + setupDataBase( -1 ); + return wGroups->count(); +} + +bool WidgetDatabase::isGroupVisible( const QString &g ) +{ + setupDataBase( -1 ); + return invisibleGroups->find( g ) == -1; +} + +int WidgetDatabase::addCustomWidget( WidgetDatabaseRecord *r ) +{ + insert( dbcustomcount++, r ); + return dbcustomcount - 1; +} + +void WidgetDatabase::customWidgetClassNameChanged( const QString &oldName, + const QString &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 QString &docPath ) +{ + QString whatsthisFile = docPath + "/whatsthis"; + QFile f( whatsthisFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + while ( !ts.atEnd() ) { + QString s = ts.readLine(); + QStringList l = QStringList::split( " | ", s ); + int id = idFromClassName( l[ 1 ] ); + WidgetDatabaseRecord *r = at( id ); + if ( r ) + r->whatsThis = l[ 0 ]; + } + whatsThisLoaded = TRUE; +} + + +// ### Qt 3.1: make these publically accessible via QWidgetDatabase API +#if defined(UIC) +bool dbnounload = FALSE; +QStringList *dbpaths = 0; +#else +extern QString *qwf_plugin_dir; +#endif + + +QPluginManager<WidgetInterface> *widgetManager() +{ + if ( !widgetPluginManager ) { + QString pluginDir = "/designer"; +#if !defined(UIC) + if ( qwf_plugin_dir ) + pluginDir = *qwf_plugin_dir; +#endif + widgetPluginManager = new QPluginManager<WidgetInterface>( IID_Widget, QApplication::libraryPaths(), pluginDir ); + cleanup_manager.add( &widgetPluginManager ); +#if defined(UIC) + if ( dbnounload ) + widgetPluginManager->setAutoUnload( FALSE ); + if ( dbpaths ) { + QStringList::ConstIterator it = dbpaths->begin(); + for ( ; it != dbpaths->end(); ++it ) + widgetPluginManager->addLibraryPath( *it ); + } +#endif + } + return widgetPluginManager; +} diff --git a/puic/widgetdatabase.h b/puic/widgetdatabase.h new file mode 100644 index 0000000..dee809d --- /dev/null +++ b/puic/widgetdatabase.h @@ -0,0 +1,90 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 WIDGETDATABASE_H +#define WIDGETDATABASE_H + +#include <qiconset.h> +#include <qstring.h> +#include "widgetinterface.h" // up here for GCC 2.7.* compatibility +#include <private/qpluginmanager_p.h> + + +extern QPluginManager<WidgetInterface> *widgetManager(); + +struct WidgetDatabaseRecord +{ + WidgetDatabaseRecord(); + ~WidgetDatabaseRecord(); + QString iconSet, name, group, toolTip, whatsThis, includeFile; + uint isContainer : 1; + uint isForm : 1; + uint isCommon : 1; + uint isPlugin : 1; + QIconSet *icon; + int nameCounter; +}; + +class WidgetDatabase : public Qt +{ +public: + WidgetDatabase(); + static void setupDataBase( int id ); + static void setupPlugins(); + + static int count(); + static int startCustom(); + + static QIconSet iconSet( int id ); + static QString className( int id ); + static QString group( int id ); + static QString toolTip( int id ); + static QString whatsThis( int id ); + static QString includeFile( int id ); + static bool isForm( int id ); + static bool isContainer( int id ); + static bool isCommon( int id ); + + static int idFromClassName( const QString &name ); + static QString createWidgetName( int id ); + + static WidgetDatabaseRecord *at( int index ); + static void insert( int index, WidgetDatabaseRecord *r ); + static void append( WidgetDatabaseRecord *r ); + + static QString widgetGroup( const QString &g ); + static QString widgetGroup( int i ); + static int numWidgetGroups(); + static bool isGroupVisible( const QString &g ); + static bool isGroupEmpty( const QString &grp ); + + static int addCustomWidget( WidgetDatabaseRecord *r ); + static bool isCustomWidget( int id ); + static bool isCustomPluginWidget( int id ); + + static bool isWhatsThisLoaded(); + static void loadWhatsThis( const QString &docPath ); + + static bool hasWidget( const QString &name ); + static void customWidgetClassNameChanged( const QString &oldName, const QString &newName ); + +}; + +#endif diff --git a/puic/widgetinterface.h b/puic/widgetinterface.h new file mode 100644 index 0000000..bf6bcd5 --- /dev/null +++ b/puic/widgetinterface.h @@ -0,0 +1,29 @@ + /********************************************************************** +** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt 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 QWidgetFactoryInterface +#define IID_Widget IID_QWidgetFactory + +#endif |