diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch) | |
tree | acaf47eb0fa12142d3896416a69e74cbf5a72242 /kdevdesigner | |
download | tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdevdesigner')
434 files changed, 76909 insertions, 0 deletions
diff --git a/kdevdesigner/AUTHORS b/kdevdesigner/AUTHORS new file mode 100644 index 00000000..40d295ec --- /dev/null +++ b/kdevdesigner/AUTHORS @@ -0,0 +1,4 @@ +KDevDesigner: Alexander Dymo <adymo@mksat.net> +Qt Designer Copyright: (C) 2000-2003 Trolltech AS All Rights Reserved + + diff --git a/kdevdesigner/LICENSE.GPL b/kdevdesigner/LICENSE.GPL new file mode 100644 index 00000000..5b6e7c66 --- /dev/null +++ b/kdevdesigner/LICENSE.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/kdevdesigner/Makefile.am b/kdevdesigner/Makefile.am new file mode 100644 index 00000000..4cc5b44c --- /dev/null +++ b/kdevdesigner/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = shared uilib designer src +#plugins + +EXTRA_DIST = COPYING configure.in.in diff --git a/kdevdesigner/NEWS b/kdevdesigner/NEWS new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/kdevdesigner/NEWS @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/kdevdesigner/README b/kdevdesigner/README new file mode 100644 index 00000000..a9e2cf4b --- /dev/null +++ b/kdevdesigner/README @@ -0,0 +1,25 @@ +KDevDesigner is a port of Qt Designer (code taken from Qt 3.3 distribution) to KDE technologies: +1) XML GUI +2) KParts +3) KFileDialog +4) KIconLoader + +KDevDesigner consists of a part and a shell. +Part can be used in Konqueror and KDevelop to edit and view ui files and projects. +Shell loads a part with "in shell" argument so that the part can create projects and ui files. + +Other important notes: +KDevDesignerPart is Read/Write part which ignores readonly mode. +Designer Editor plugins are not loaded. +Available in system designer plugins are loaded if possible (tested with Qt 3.3 version). + +KDevDesignerPart integration: +KDevDesignerPart implements KInterfaceDesigner interface (defined in kdevelop/lib/external_interfaces). + +WARNING: +If you want to modify this code, try to introduce as few modifications to original Qt Designer code as possible. +Write your own classes and wrappers instead. The goal is to ease syncronization between the port and original Qt Designer. +Feel free to modify kdevdesigner_part.h(cpp) though. + +FUTURE: +Trolltech promises that Qt 4 will have easilly embeddable designer. If that happens, this port will be dropped for KDevelop 4. diff --git a/kdevdesigner/TODO b/kdevdesigner/TODO new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/kdevdesigner/TODO @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/kdevdesigner/designer/Makefile.am b/kdevdesigner/designer/Makefile.am new file mode 100644 index 00000000..5b8372f9 --- /dev/null +++ b/kdevdesigner/designer/Makefile.am @@ -0,0 +1,21 @@ +SUBDIRS = pics + +AM_CXXFLAGS=-DDESIGNER +KDE_CXXFLAGS=-UQT_NO_ASCII_CAST +INCLUDES = -I$(top_srcdir)/kdevdesigner/shared \ + -I$(top_srcdir)/lib/interfaces/external $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libkdevdesignerpart.la +libkdevdesignerpart_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries) +libkdevdesignerpart_la_LIBADD = \ + $(top_builddir)/kdevdesigner/uilib/libkdevqui.la $(top_builddir)/kdevdesigner/shared/libshared.la \ + $(top_builddir)/lib/interfaces/external/libkinterfacedesigner.la -lqassistantclient $(LIB_KFILE) $(LIB_KPARTS) +libkdevdesignerpart_la_SOURCES = kdevdesigner_part.cpp actiondnd.cpp actioneditorimpl.cpp actionlistview.cpp asciivalidator.cpp command.cpp connectionitems.cpp connectiontable.cpp customwidgeteditorimpl.cpp database.cpp dbconnectionimpl.cpp dbconnectionsimpl.cpp defs.cpp designerapp.cpp designerappiface.cpp editfunctionsimpl.cpp filechooser.cpp formfile.cpp formsettingsimpl.cpp formwindow.cpp hierarchyview.cpp iconvieweditorimpl.cpp layout.cpp listboxdnd.cpp listboxeditorimpl.cpp listboxrename.cpp listdnd.cpp listviewdnd.cpp listvieweditorimpl.cpp mainwindow.cpp mainwindowactions.cpp menubareditor.cpp metadatabase.cpp multilineeditorimpl.cpp newformimpl.cpp orderindicator.cpp outputwindow.cpp paletteeditoradvancedimpl.cpp paletteeditorimpl.cpp pixmapchooser.cpp pixmapcollection.cpp popupmenueditor.cpp previewframe.cpp previewwidgetimpl.cpp project.cpp projectsettingsimpl.cpp propertyeditor.cpp propertyobject.cpp qcompletionedit.cpp resource.cpp sizehandle.cpp sourceeditor.cpp sourcefile.cpp startdialogimpl.cpp styledbutton.cpp syntaxhighlighter_html.cpp tableeditorimpl.cpp timestamp.cpp variabledialogimpl.cpp widgetaction.cpp widgetfactory.cpp wizardeditorimpl.cpp workspace.cpp about.ui dbconnection.ui gotolinedialog.ui newform.ui previewwidget.ui variabledialog.ui actioneditor.ui dbconnectioneditor.ui iconvieweditor.ui paletteeditor.ui projectsettings.ui wizardeditor.ui configtoolboxdialog.ui dbconnections.ui listboxeditor.ui paletteeditoradvanced.ui replacedialog.ui connectiondialog.ui editfunctions.ui listeditor.ui pixmapcollectioneditor.ui richtextfontdialog.ui createtemplate.ui finddialog.ui listvieweditor.ui pixmapfunction.ui startdialog.ui customwidgeteditor.ui formsettings.ui multilineeditor.ui preferences.ui tableeditor.ui designeraction.cpp myiconloader.cpp +partrcdir = $(kde_datadir)/kdevdesignerpart +partdesktopdir = $(kde_servicesdir) +partdesktop_DATA = kdevdesigner_part.desktop +partrc_DATA = kdevdesigner_part.rc kdevdesigner_part_sh.rc +noinst_HEADERS = kdevdesigner_part.h designeraction.h myiconloader.h +picsdirdir = $(kde_datadir)/kdevdesignerpart/pics + +KDE_OPTIONS=nofinal diff --git a/kdevdesigner/designer/about.ui b/kdevdesigner/designer/about.ui new file mode 100644 index 00000000..68980df0 --- /dev/null +++ b/kdevdesigner/designer/about.ui @@ -0,0 +1,219 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AboutDialog</class> +<comment>********************************************************************* +** Copyright (C) 2001-2003 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>AboutDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>544</width> + <height>667</height> + </rect> + </property> + <property name="caption"> + <string>Qt Designer</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>aboutPixmap</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="pixmap"> + <pixmap>"designer_splash.png"</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + <property name="hAlign" stdset="0"> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>aboutVersion</cstring> + </property> + <property name="text"> + <string>Version 3.2</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + <property name="hAlign" stdset="0"> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>aboutCopyright</cstring> + </property> + <property name="text"> + <string>Copyright (C) 2000-2003 Trolltech AS. All Rights Reserved.</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + <property name="hAlign" stdset="0"> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>aboutLicense</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><p>Qt Commercial Edition license holders: This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution.</p><p></p><p>Qt Free Edition users: This program is licensed to you under the terms of the GNU General Public License Version 2. For details, see the file LICENSE.GPL that came with this software distribution.</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter|AlignLeft</set> + </property> + <property name="wordwrap" stdset="0"> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>AboutDialog</receiver> + <slot>accept()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/actiondnd.cpp b/kdevdesigner/designer/actiondnd.cpp new file mode 100644 index 00000000..071f0d4b --- /dev/null +++ b/kdevdesigner/designer/actiondnd.cpp @@ -0,0 +1,726 @@ +/********************************************************************** +** 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 "actiondnd.h" +#include "command.h" +#include "defs.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "widgetfactory.h" +#include "hierarchyview.h" + +#include <qaction.h> +#include <qapplication.h> +#include <qbitmap.h> +#include <qdragobject.h> +#include <qinputdialog.h> +#include <qlayout.h> +#include <qmainwindow.h> +#include <qmenudata.h> +#include <qmessagebox.h> +#include <qobjectlist.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qtimer.h> + +#include <klocale.h> + +QAction *ActionDrag::the_action = 0; + +ActionDrag::ActionDrag(QAction *action, QWidget *source) +: QStoredDrag("application/x-designer-actions", source) +{ + Q_ASSERT(the_action == 0); + the_action = action; +} + +ActionDrag::ActionDrag(QActionGroup *group, QWidget *source) +: QStoredDrag("application/x-designer-actiongroup", source) +{ + Q_ASSERT(the_action == 0); + the_action = group; +} + +ActionDrag::ActionDrag(const QString &type, QAction *action, QWidget *source) +: QStoredDrag(type, source) +{ + Q_ASSERT(the_action == 0); + the_action = action; +} + +bool ActionDrag::canDecode(QDropEvent *e) +{ + return e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-actiongroup" ) || + e->provides( "application/x-designer-separator" ); +} + +ActionDrag::~ActionDrag() +{ + the_action = 0; +} + +void QDesignerAction::init() +{ + MetaDataBase::addEntry( this ); + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( this ) ); + WidgetFactory::saveDefaultProperties( this, id ); + WidgetFactory::saveChangedProperties( this, id ); +} + +void QDesignerActionGroup::init() +{ + MetaDataBase::addEntry( this ); + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( this ) ); + WidgetFactory::saveDefaultProperties( this, id ); + WidgetFactory::saveChangedProperties( this, id ); +} + +bool QDesignerAction::addTo( QWidget *w ) +{ + if ( !widgetToInsert ) + return QAction::addTo( w ); + + if ( ::qt_cast<QPopupMenu*>(w) ) + return FALSE; + + widgetToInsert->reparent( w, QPoint( 0, 0 ), FALSE ); + widgetToInsert->show(); + addedTo( widgetToInsert, w ); + return TRUE; +} + +bool QDesignerAction::removeFrom( QWidget *w ) +{ + if ( !widgetToInsert ) + return QAction::removeFrom( w ); + + remove(); + return TRUE; +} + +void QDesignerAction::remove() +{ + if ( !widgetToInsert ) + return; + MainWindow::self->formWindow()->selectWidget( widgetToInsert, FALSE ); + widgetToInsert->reparent( 0, QPoint( 0, 0 ), FALSE ); +} + +QDesignerToolBarSeparator::QDesignerToolBarSeparator(Orientation o , QToolBar *parent, + const char* name ) + : QWidget( parent, name ) +{ + connect( parent, SIGNAL(orientationChanged(Orientation)), + this, SLOT(setOrientation(Orientation)) ); + setOrientation( o ); + setBackgroundMode( parent->backgroundMode() ); + setBackgroundOrigin( ParentOrigin ); + setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); +} + +void QDesignerToolBarSeparator::setOrientation( Orientation o ) +{ + orient = o; +} + +void QDesignerToolBarSeparator::styleChange( QStyle& ) +{ + setOrientation( orient ); +} + +QSize QDesignerToolBarSeparator::sizeHint() const +{ + int extent = style().pixelMetric( QStyle::PM_DockWindowSeparatorExtent, + this ); + if ( orient == Horizontal ) + return QSize( extent, 0 ); + else + return QSize( 0, extent ); +} + +void QDesignerToolBarSeparator::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + QStyle::SFlags flags = QStyle::Style_Default; + + if ( orientation() == Horizontal ) + flags |= QStyle::Style_Horizontal; + + style().drawPrimitive( QStyle::PE_DockWindowSeparator, &p, rect(), + colorGroup(), flags ); +} + + + +QSeparatorAction::QSeparatorAction( QObject *parent ) + : QAction( parent, "qt_designer_separator" ), wid( 0 ) +{ +} + +bool QSeparatorAction::addTo( QWidget *w ) +{ + if ( ::qt_cast<QToolBar*>(w) ) { + QToolBar *tb = (QToolBar*)w; + wid = new QDesignerToolBarSeparator( tb->orientation(), tb ); + return TRUE; + } else if ( ::qt_cast<QPopupMenu*>(w) ) { + idx = ( (QPopupMenu*)w )->count(); + ( (QPopupMenu*)w )->insertSeparator( idx ); + return TRUE; + } + return FALSE; +} + +bool QSeparatorAction::removeFrom( QWidget *w ) +{ + if ( ::qt_cast<QToolBar*>(w) ) { + delete wid; + return TRUE; + } else if ( ::qt_cast<QPopupMenu*>(w) ) { + ( (QPopupMenu*)w )->removeItemAt( idx ); + return TRUE; + } + return FALSE; +} + +QWidget *QSeparatorAction::widget() const +{ + return wid; +} + + + +QDesignerToolBar::QDesignerToolBar( QMainWindow *mw ) + : QToolBar( mw ), lastIndicatorPos( -1, -1 ) +{ + insertAnchor = 0; + afterAnchor = TRUE; + setAcceptDrops( TRUE ); + MetaDataBase::addEntry( this ); + lastIndicatorPos = QPoint( -1, -1 ); + indicator = new QDesignerIndicatorWidget( this ); + indicator->hide(); + installEventFilter( this ); + widgetInserting = FALSE; + findFormWindow(); + mw->setDockEnabled( DockTornOff, FALSE ); +} + +QDesignerToolBar::QDesignerToolBar( QMainWindow *mw, Dock dock ) + : QToolBar( QString::null, mw, dock), lastIndicatorPos( -1, -1 ) +{ + insertAnchor = 0; + afterAnchor = TRUE; + setAcceptDrops( TRUE ); + indicator = new QDesignerIndicatorWidget( this ); + indicator->hide(); + MetaDataBase::addEntry( this ); + installEventFilter( this ); + widgetInserting = FALSE; + findFormWindow(); + mw->setDockEnabled( DockTornOff, FALSE ); +} + +void QDesignerToolBar::findFormWindow() +{ + QWidget *w = this; + while ( w ) { + formWindow = ::qt_cast<FormWindow*>(w); + if ( formWindow ) + break; + w = w->parentWidget(); + } +} + +void QDesignerToolBar::addAction( QAction *a ) +{ + actionList.append( a ); + connect( a, SIGNAL( destroyed() ), this, SLOT( actionRemoved() ) ); + if ( ::qt_cast<QActionGroup*>(a) ) { + ( (QDesignerActionGroup*)a )->widget()->installEventFilter( this ); + actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a ); + } else if ( ::qt_cast<QSeparatorAction*>(a) ) { + ( (QSeparatorAction*)a )->widget()->installEventFilter( this ); + actionMap.insert( ( (QSeparatorAction*)a )->widget(), a ); + } else { + ( (QDesignerAction*)a )->widget()->installEventFilter( this ); + actionMap.insert( ( (QDesignerAction*)a )->widget(), a ); + } +} + +static void fixObject( QObject *&o ) +{ + while ( o && o->parent() && !::qt_cast<QDesignerToolBar*>(o->parent()) ) + o = o->parent(); +} + +bool QDesignerToolBar::eventFilter( QObject *o, QEvent *e ) +{ + if ( !o || !e || o->inherits( "QDockWindowHandle" ) || o->inherits( "QDockWindowTitleBar" ) ) + return QToolBar::eventFilter( o, e ); + + if ( o == this && e->type() == QEvent::MouseButtonPress && + ( ( QMouseEvent*)e )->button() == LeftButton ) { + mousePressEvent( (QMouseEvent*)e ); + return TRUE; + } + + if ( o == this ) + return QToolBar::eventFilter( o, e ); + + if ( e->type() == QEvent::MouseButtonPress ) { + QMouseEvent *ke = (QMouseEvent*)e; + fixObject( o ); + if ( !o ) + return FALSE; + buttonMousePressEvent( ke, o ); + return TRUE; + } else if(e->type() == QEvent::ContextMenu ) { + QContextMenuEvent *ce = (QContextMenuEvent*)e; + fixObject( o ); + if( !o ) + return FALSE; + buttonContextMenuEvent( ce, o ); + return TRUE; + } else if ( e->type() == QEvent::MouseMove ) { + QMouseEvent *ke = (QMouseEvent*)e; + fixObject( o ); + if ( !o ) + return FALSE; + buttonMouseMoveEvent( ke, o ); + return TRUE; + } else if ( e->type() == QEvent::MouseButtonRelease ) { + QMouseEvent *ke = (QMouseEvent*)e; + fixObject( o ); + if ( !o ) + return FALSE; + buttonMouseReleaseEvent( ke, o ); + return TRUE; + } else if ( e->type() == QEvent::DragEnter ) { + QDragEnterEvent *de = (QDragEnterEvent*)e; + if (ActionDrag::canDecode(de)) + de->accept(); + } else if ( e->type() == QEvent::DragMove ) { + QDragMoveEvent *de = (QDragMoveEvent*)e; + if (ActionDrag::canDecode(de)) + de->accept(); + } + + return QToolBar::eventFilter( o, e ); +} + +void QDesignerToolBar::paintEvent( QPaintEvent *e ) +{ + QToolBar::paintEvent( e ); + if ( e->rect() != rect() ) + return; + lastIndicatorPos = QPoint( -1, -1 ); +} + +void QDesignerToolBar::contextMenuEvent( QContextMenuEvent *e ) +{ + e->accept(); + QPopupMenu menu( 0 ); + menu.insertItem( i18n( "Delete Toolbar" ), 1 ); + int res = menu.exec( e->globalPos() ); + if ( res != -1 ) { + RemoveToolBarCommand *cmd = new RemoveToolBarCommand( i18n( "Delete Toolbar '%1'" ).arg( name() ), + formWindow, 0, this ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void QDesignerToolBar::mousePressEvent( QMouseEvent *e ) +{ + widgetInserting = FALSE; + if ( e->button() == LeftButton && + MainWindow::self->currentTool() != POINTER_TOOL && + MainWindow::self->currentTool() != ORDER_TOOL && + MainWindow::self->currentTool() != CONNECT_TOOL && + MainWindow::self->currentTool() != BUDDY_TOOL ) + widgetInserting = TRUE; +} + +void QDesignerToolBar::mouseReleaseEvent( QMouseEvent *e ) +{ + if ( widgetInserting ) + doInsertWidget( mapFromGlobal( e->globalPos() ) ); + widgetInserting = FALSE; +} + +void QDesignerToolBar::buttonMouseReleaseEvent( QMouseEvent *e, QObject *w ) +{ + if ( widgetInserting ) + doInsertWidget( mapFromGlobal( e->globalPos() ) ); + else if ( w->isWidgetType() && formWindow->widgets()->find( w ) ) { + formWindow->clearSelection( FALSE ); + formWindow->selectWidget( w ); + } + widgetInserting = FALSE; +} + +void QDesignerToolBar::buttonContextMenuEvent( QContextMenuEvent *e, QObject *o ) +{ + e->accept(); + QPopupMenu menu( 0 ); + const int ID_DELETE = 1; + const int ID_SEP = 2; + const int ID_DELTOOLBAR = 3; + QMap<QWidget*, QAction*>::Iterator it = actionMap.find( (QWidget*)o ); + if ( it != actionMap.end() && ::qt_cast<QSeparatorAction*>(*it) ) + menu.insertItem( i18n( "Delete Separator" ), ID_DELETE ); + else + menu.insertItem( i18n( "Delete Item" ), ID_DELETE ); + menu.insertItem( i18n( "Insert Separator" ), ID_SEP ); + menu.insertSeparator(); + menu.insertItem( i18n( "Delete Toolbar" ), ID_DELTOOLBAR ); + int res = menu.exec( e->globalPos() ); + if ( res == ID_DELETE ) { + QMap<QWidget*, QAction*>::Iterator it = actionMap.find( (QWidget*)o ); + if ( it == actionMap.end() ) + return; + QAction *a = *it; + int index = actionList.find( a ); + RemoveActionFromToolBarCommand *cmd = new RemoveActionFromToolBarCommand( + i18n( "Delete Action '%1' From Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( res == ID_SEP ) { + calcIndicatorPos( mapFromGlobal( e->globalPos() ) ); + QAction *a = new QSeparatorAction( 0 ); + int index = actionList.findRef( *actionMap.find( insertAnchor ) ); + if ( index != -1 && afterAnchor ) + ++index; + if ( !insertAnchor ) + index = 0; + + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( + i18n( "Add Separator to Toolbar '%1'" ). + arg( a->name() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( res == ID_DELTOOLBAR ) { + RemoveToolBarCommand *cmd = new RemoveToolBarCommand( i18n( "Delete Toolbar '%1'" ).arg( name() ), + formWindow, 0, this ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void QDesignerToolBar::buttonMousePressEvent( QMouseEvent *e, QObject * ) +{ + widgetInserting = FALSE; + + if ( e->button() == MidButton ) + return; + + if ( e->button() == LeftButton && + MainWindow::self->currentTool() != POINTER_TOOL && + MainWindow::self->currentTool() != ORDER_TOOL && + MainWindow::self->currentTool() != CONNECT_TOOL && + MainWindow::self->currentTool() != BUDDY_TOOL ) { + widgetInserting = TRUE; + return; + } + + dragStartPos = e->pos(); +} + +void QDesignerToolBar::removeWidget( QWidget *w ) +{ + QMap<QWidget*, QAction*>::Iterator it = actionMap.find( w ); + if ( it == actionMap.end() ) + return; + QAction *a = *it; + int index = actionList.find( a ); + RemoveActionFromToolBarCommand *cmd = + new RemoveActionFromToolBarCommand( i18n( "Delete Action '%1' From Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + QApplication::sendPostedEvents(); + adjustSize(); +} + +void QDesignerToolBar::buttonMouseMoveEvent( QMouseEvent *e, QObject *o ) +{ + if ( widgetInserting || ( e->state() & LeftButton ) == 0 ) + return; + if ( QABS( QPoint( dragStartPos - e->pos() ).manhattanLength() ) < QApplication::startDragDistance() ) + return; + QMap<QWidget*, QAction*>::Iterator it = actionMap.find( (QWidget*)o ); + if ( it == actionMap.end() ) + return; + QAction *a = *it; + if ( !a ) + return; + int index = actionList.find( a ); + RemoveActionFromToolBarCommand *cmd = + new RemoveActionFromToolBarCommand( i18n( "Delete Action '%1' From Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + QApplication::sendPostedEvents(); + adjustSize(); + + QString type = ::qt_cast<QActionGroup*>(a) ? QString( "application/x-designer-actiongroup" ) : + ::qt_cast<QSeparatorAction*>(a) ? QString( "application/x-designer-separator" ) : QString( "application/x-designer-actions" ); + QStoredDrag *drag = new ActionDrag( type, a, this ); + drag->setPixmap( a->iconSet().pixmap() ); + if ( ::qt_cast<QDesignerAction*>(a) ) { + if ( formWindow->widgets()->find( ( (QDesignerAction*)a )->widget() ) ) + formWindow->selectWidget( ( (QDesignerAction*)a )->widget(), FALSE ); + } + if ( !drag->drag() ) { + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Action '%1' to Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + lastIndicatorPos = QPoint( -1, -1 ); + indicator->hide(); +} + +#ifndef QT_NO_DRAGANDDROP + +void QDesignerToolBar::dragEnterEvent( QDragEnterEvent *e ) +{ + widgetInserting = FALSE; + lastIndicatorPos = QPoint( -1, -1 ); + if (ActionDrag::canDecode(e)) + e->accept(); +} + +void QDesignerToolBar::dragMoveEvent( QDragMoveEvent *e ) +{ + if (ActionDrag::canDecode(e)) { + e->accept(); + drawIndicator( calcIndicatorPos( e->pos() ) ); + } +} + +void QDesignerToolBar::dragLeaveEvent( QDragLeaveEvent * ) +{ + indicator->hide(); + insertAnchor = 0; + afterAnchor = TRUE; +} + +void QDesignerToolBar::dropEvent( QDropEvent *e ) +{ + if (!ActionDrag::canDecode(e)) + return; + + e->accept(); + + indicator->hide(); + QAction *a = 0; + int index = actionList.findRef( *actionMap.find( insertAnchor ) ); + if ( index != -1 && afterAnchor ) + ++index; + if ( !insertAnchor ) + index = 0; + if ( e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-separator" ) ) { + if ( e->provides( "application/x-designer-actions" ) ) + a = ::qt_cast<QDesignerAction*>(ActionDrag::action()); + else + a = ::qt_cast<QSeparatorAction*>(ActionDrag::action()); + } else { + a = ::qt_cast<QDesignerActionGroup*>(ActionDrag::action()); + } + + if ( actionList.findRef( a ) != -1 ) { + QMessageBox::warning( MainWindow::self, i18n( "Insert/Move Action" ), + i18n( "Action '%1' has already been added to this toolbar.\n" + "An Action may only occur once in a given toolbar." ). + arg( a->name() ) ); + return; + } + + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Action '%1' to Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + + lastIndicatorPos = QPoint( -1, -1 ); +} + +#endif + +void QDesignerToolBar::reInsert() +{ + QAction *a = 0; + actionMap.clear(); + clear(); + for ( a = actionList.first(); a; a = actionList.next() ) { + a->addTo( this ); + if ( ::qt_cast<QActionGroup*>(a) ) { + actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a ); + if ( ( (QDesignerActionGroup*)a )->widget() ) + ( (QDesignerActionGroup*)a )->widget()->installEventFilter( this ); + } else if ( ::qt_cast<QDesignerAction*>(a) ) { + actionMap.insert( ( (QDesignerAction*)a )->widget(), a ); + ( (QDesignerAction*)a )->widget()->installEventFilter( this ); + } else if ( ::qt_cast<QSeparatorAction*>(a) ) { + actionMap.insert( ( (QSeparatorAction*)a )->widget(), a ); + ( (QSeparatorAction*)a )->widget()->installEventFilter( this ); + } + } + QApplication::sendPostedEvents(); + adjustSize(); +} + +void QDesignerToolBar::actionRemoved() +{ + actionList.removeRef( (QAction*)sender() ); +} + +QPoint QDesignerToolBar::calcIndicatorPos( const QPoint &pos ) +{ + if ( orientation() == Horizontal ) { + QPoint pnt( width() - 2, 0 ); + insertAnchor = 0; + afterAnchor = TRUE; + if ( !children() ) + return pnt; + pnt = QPoint( 13, 0 ); + QObjectListIt it( *children() ); + QObject * obj; + while( (obj=it.current()) != 0 ) { + ++it; + if ( obj->isWidgetType() && + qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 ) { + QWidget *w = (QWidget*)obj; + if ( w->x() < pos.x() ) { + pnt.setX( w->x() + w->width() + 1 ); + insertAnchor = w; + afterAnchor = TRUE; + } + } + } + return pnt; + } else { + QPoint pnt( 0, height() - 2 ); + insertAnchor = 0; + afterAnchor = TRUE; + if ( !children() ) + return pnt; + pnt = QPoint( 0, 13 ); + QObjectListIt it( *children() ); + QObject * obj; + while( (obj=it.current()) != 0 ) { + ++it; + if ( obj->isWidgetType() && + qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 ) { + QWidget *w = (QWidget*)obj; + if ( w->y() < pos.y() ) { + pnt.setY( w->y() + w->height() + 1 ); + insertAnchor = w; + afterAnchor = TRUE; + } + } + } + return pnt; + } +} + +void QDesignerToolBar::drawIndicator( const QPoint &pos ) +{ + if ( lastIndicatorPos == pos ) + return; + bool wasVsisible = indicator->isVisible(); + if ( orientation() == Horizontal ) { + indicator->resize( 3, height() ); + if ( pos != QPoint( -1, -1 ) ) + indicator->move( pos.x() - 1, 0 ); + indicator->show(); + indicator->raise(); + lastIndicatorPos = pos; + } else { + indicator->resize( width(), 3 ); + if ( pos != QPoint( -1, -1 ) ) + indicator->move( 0, pos.y() - 1 ); + indicator->show(); + indicator->raise(); + lastIndicatorPos = pos; + } + if ( !wasVsisible ) + QApplication::sendPostedEvents(); +} + +void QDesignerToolBar::doInsertWidget( const QPoint &p ) +{ + if ( formWindow != MainWindow::self->formWindow() ) + return; + calcIndicatorPos( p ); + QWidget *w = WidgetFactory::create( MainWindow::self->currentTool(), this, 0, TRUE ); + installEventFilters( w ); + MainWindow::self->formWindow()->insertWidget( w, TRUE ); + QDesignerAction *a = new QDesignerAction( w, parent() ); + int index = actionList.findRef( *actionMap.find( insertAnchor ) ); + if ( index != -1 && afterAnchor ) + ++index; + if ( !insertAnchor ) + index = 0; + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( i18n( "Add Widget '%1' to Toolbar '%2'" ). + arg( w->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + MainWindow::self->resetTool(); +} + +void QDesignerToolBar::clear() +{ + for ( QAction *a = actionList.first(); a; a = actionList.next() ) { + if ( ::qt_cast<QDesignerAction*>(a) ) + ( (QDesignerAction*)a )->remove(); + } + QToolBar::clear(); +} + +void QDesignerToolBar::installEventFilters( QWidget *w ) +{ + if ( !w ) + return; + QObjectList *l = w->queryList( "QWidget" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( this ); + delete l; +} + +//#include "actiondnd.moc" diff --git a/kdevdesigner/designer/actiondnd.h b/kdevdesigner/designer/actiondnd.h new file mode 100644 index 00000000..fcf37fe9 --- /dev/null +++ b/kdevdesigner/designer/actiondnd.h @@ -0,0 +1,247 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef ACTIONDND_H +#define ACTIONDND_H + +#include <qaction.h> +#include <qdragobject.h> +#include <qmap.h> +#include <qmenubar.h> +#include <qpixmap.h> +#include <qpopupmenu.h> +#include <qptrlist.h> +#include <qtoolbar.h> +#include <qguardedptr.h> +#include "../shared/widgetdatabase.h" + +//class QDesignerPopupMenu; +class QDesignerIndicatorWidget; +class FormWindow; +class QPopupMenu; + +class QDesignerIndicatorWidget : public QWidget +{ + Q_OBJECT + +public: + QDesignerIndicatorWidget( QWidget *p ) + : QWidget( p, "qt_dockwidget_internal" ) { + setBackgroundColor( red ); + } + +}; + +class ActionDrag : public QStoredDrag +{ + Q_OBJECT + +public: + ActionDrag(const QString &type, QAction *action, QWidget *source); + ActionDrag(QAction *action, QWidget *source); + ActionDrag(QActionGroup *group, QWidget *source); + + ~ActionDrag(); + + static bool canDecode(QDropEvent *e); + + static QAction *action() + { + return the_action; + } + +private: + static QAction *the_action; +}; + +class QDesignerActionGroup : public QActionGroup +{ + Q_OBJECT + +public: + QDesignerActionGroup( QObject *parent ) + : QActionGroup( ::qt_cast<QActionGroup*>(parent) ? parent : 0 ), wid( 0 ), idx( -1 ) { init(); } + + void init(); + + QWidget *widget() const { return wid; } + QWidget *widget( QAction *a ) const { return *widgets.find( a ); } + int index() const { return idx; } + +protected: +#if !defined(Q_NO_USING_KEYWORD) + using QActionGroup::addedTo; +#endif + void addedTo( QWidget *w, QWidget * ) { + wid = w; + } + void addedTo( QWidget *w, QWidget *, QAction *a ) { + widgets.insert( a, w ); + } + void addedTo( int index, QPopupMenu * ) { + idx = index; + } + +private: + QWidget *wid; + QMap<QAction *, QWidget *> widgets; + int idx; + +}; + +class QDesignerAction : public QAction +{ + Q_OBJECT + +public: + QDesignerAction( QObject *parent ) + : QAction( ::qt_cast<QActionGroup*>(parent) ? parent : 0 ), wid( 0 ), idx( -1 ), widgetToInsert( 0 ) { init(); } + QDesignerAction( QWidget *w, QObject *parent ) + : QAction( ::qt_cast<QActionGroup*>(parent) ? parent : 0 ), wid( 0 ), idx( -1 ), widgetToInsert( w ) { init(); } + + void init(); + + QWidget *widget() const { return wid; } + int index() const { return idx; } + + bool addTo( QWidget *w ); + bool removeFrom( QWidget *w ); + + void remove(); + bool supportsMenu() const { return !widgetToInsert; } + +protected: + void addedTo( QWidget *w, QWidget * ) { + wid = w; + } + void addedTo( int index, QPopupMenu * ) { + idx = index; + } + +private: + QWidget *wid; + int idx; + QWidget *widgetToInsert; + +}; + +class QDesignerToolBarSeparator : public QWidget +{ + Q_OBJECT + +public: + QDesignerToolBarSeparator( Orientation, QToolBar *parent, const char* name=0 ); + + QSize sizeHint() const; + Orientation orientation() const { return orient; } +public slots: + void setOrientation( Orientation ); +protected: + void styleChange( QStyle& ); + void paintEvent( QPaintEvent * ); +private: + Orientation orient; +}; + + +class QSeparatorAction : public QAction +{ + Q_OBJECT + +public: + QSeparatorAction( QObject *parent ); + + bool addTo( QWidget *w ); + bool removeFrom( QWidget *w ); + QWidget *widget() const; + int index() const; + +private: + QWidget *wid; + int idx; + +}; + + +class QDesignerToolBar : public QToolBar +{ + Q_OBJECT + +public: + QDesignerToolBar( QMainWindow *mw ); + QDesignerToolBar( QMainWindow *mw, Dock dock ); + QPtrList<QAction> insertedActions() const { return actionList; } + void addAction( QAction *a ); + + void clear(); + void installEventFilters( QWidget *w ); + void insertAction( QWidget *w, QAction *a ) { actionMap.insert( w, a ); } + void insertAction( int index, QAction *a ) { actionList.insert( index, a ); } + void appendAction( QAction *a ) { actionList.append( a ); } + void removeAction( QAction *a ) { actionList.remove( a ); } + void reInsert(); + void removeWidget( QWidget *w ); + +protected: + bool eventFilter( QObject *, QEvent * ); + void paintEvent( QPaintEvent * ); +#ifndef QT_NO_DRAGANDDROP + void dragEnterEvent( QDragEnterEvent * ); + void dragMoveEvent( QDragMoveEvent * ); + void dragLeaveEvent( QDragLeaveEvent * ); + void dropEvent( QDropEvent * ); +#endif + void contextMenuEvent( QContextMenuEvent *e ); + void mousePressEvent( QMouseEvent *e ); + void mouseReleaseEvent( QMouseEvent *e ); + +private slots: + void actionRemoved(); + +private: + void drawIndicator( const QPoint &pos ); + QPoint calcIndicatorPos( const QPoint &pos ); + void buttonContextMenuEvent( QContextMenuEvent *e, QObject *o ); + void buttonMousePressEvent( QMouseEvent *e, QObject *o ); + void buttonMouseMoveEvent( QMouseEvent *e, QObject *o ); + void buttonMouseReleaseEvent( QMouseEvent *e, QObject *o ); + void doInsertWidget( const QPoint &p ); + void findFormWindow(); + +private: + QPoint lastIndicatorPos; + QWidget *insertAnchor; + bool afterAnchor; + QPtrList<QAction> actionList; + QMap<QWidget*, QAction*> actionMap; + QPoint dragStartPos; + QDesignerIndicatorWidget *indicator; + bool widgetInserting; + FormWindow *formWindow; + +}; + +#endif diff --git a/kdevdesigner/designer/actioneditor.ui b/kdevdesigner/designer/actioneditor.ui new file mode 100644 index 00000000..669c60e0 --- /dev/null +++ b/kdevdesigner/designer/actioneditor.ui @@ -0,0 +1,227 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ActionEditorBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QWidget"> + <property name="name"> + <cstring>ActionEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>206</width> + <height>227</height> + </rect> + </property> + <property name="caption"> + <string>Edit Actions</string> + </property> + <property name="layoutMargin" stdset="0"> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QToolButton"> + <property name="name"> + <cstring>buttonNewAction</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_filenew.png"</pixmap> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Create new Action</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>buttonDeleteAction</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Delete current Action</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>buttonConnect</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_connecttool.png"</pixmap> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Connect current Action</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="ActionListView"> + <property name="name"> + <cstring>listActions</cstring> + </property> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>ActionListView</class> + <header location="local">actionlistview.h</header> + <sizehint> + <width>200</width> + <height>200</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>7</hordata> + <verdata>7</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>"image0"</pixmap> + <signal>selectionChanged( QListViewItem * )</signal> + <signal>currentChanged( QListViewItem * )</signal> + <signal>clicked( QListViewItem * )</signal> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> + </image> +</images> +<connections> + <connection> + <sender>listActions</sender> + <signal>currentChanged( QListViewItem * )</signal> + <receiver>ActionEditorBase</receiver> + <slot>currentActionChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>listActions</sender> + <signal>clicked( QListViewItem * )</signal> + <receiver>ActionEditorBase</receiver> + <slot>currentActionChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>listActions</sender> + <signal>selectionChanged( QListViewItem * )</signal> + <receiver>ActionEditorBase</receiver> + <slot>currentActionChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>buttonNewAction</sender> + <signal>clicked()</signal> + <receiver>ActionEditorBase</receiver> + <slot>newAction()</slot> + </connection> + <connection> + <sender>buttonConnect</sender> + <signal>clicked()</signal> + <receiver>ActionEditorBase</receiver> + <slot>connectionsClicked()</slot> + </connection> + <connection> + <sender>buttonDeleteAction</sender> + <signal>clicked()</signal> + <receiver>ActionEditorBase</receiver> + <slot>deleteAction()</slot> + </connection> +</connections> +<forwards> + <forward>class QListViewItem;</forward> +</forwards> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">connectionsClicked()</slot> + <slot access="protected">currentActionChanged( QListViewItem * )</slot> + <slot access="protected">deleteAction()</slot> + <slot access="protected">newAction()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/actioneditorimpl.cpp b/kdevdesigner/designer/actioneditorimpl.cpp new file mode 100644 index 00000000..589525e4 --- /dev/null +++ b/kdevdesigner/designer/actioneditorimpl.cpp @@ -0,0 +1,320 @@ +/********************************************************************** +** 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 "actioneditorimpl.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "actionlistview.h" +#include "connectiondialog.h" +#include "mainwindow.h" +#include "hierarchyview.h" +#include "formfile.h" + +#include <qaction.h> +#include <qlineedit.h> +#include <qlabel.h> +#include <qtoolbutton.h> +#include <qlistview.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qpopupmenu.h> +#include <qobjectlist.h> + +#include <klocale.h> + +ActionEditor::ActionEditor( QWidget* parent, const char* name, WFlags fl ) + : ActionEditorBase( parent, name, fl ), currentAction( 0 ), formWindow( 0 ), + explicitlyClosed(false) +{ + listActions->addColumn( i18n( "Actions" ) ); + setEnabled( FALSE ); + buttonConnect->setEnabled( FALSE ); + + QPopupMenu *popup = new QPopupMenu( this ); + popup->insertItem( i18n( "New &Action" ), this, SLOT( newAction() ) ); + popup->insertItem( i18n( "New Action &Group" ), this, SLOT( newActionGroup() ) ); + popup->insertItem( i18n( "New &Dropdown Action Group" ), this, SLOT( newDropDownActionGroup() ) ); + buttonNewAction->setPopup( popup ); + buttonNewAction->setPopupDelay( 0 ); + + connect( listActions, SIGNAL( insertAction() ), this, SLOT( newAction() ) ); + connect( listActions, SIGNAL( insertActionGroup() ), this, SLOT( newActionGroup() ) ); + connect( listActions, SIGNAL( insertDropDownActionGroup() ), this, SLOT( newDropDownActionGroup() ) ); + connect( listActions, SIGNAL( deleteAction() ), this, SLOT( deleteAction() ) ); + connect( listActions, SIGNAL( connectAction() ), this, SLOT( connectionsClicked() ) ); +} + +void ActionEditor::closeEvent( QCloseEvent *e ) +{ + emit hidden(); + e->accept(); +} + +void ActionEditor::currentActionChanged( QListViewItem *i ) +{ + buttonConnect->setEnabled( i != 0 ); + if ( !i ) + return; + currentAction = ( (ActionItem*)i )->action(); + if ( !currentAction ) + currentAction = ( (ActionItem*)i )->actionGroup(); + if ( formWindow && currentAction ) + formWindow->setActiveObject( currentAction ); + MainWindow::self->objectHierarchy()->hierarchyList()->setCurrent( currentAction ); +} + +void ActionEditor::setCurrentAction( QAction *a ) +{ + QListViewItemIterator it( listActions ); + while ( it.current() ) { + if ( ( (ActionItem*)it.current() )->action() == a || ( (ActionItem*)it.current() )->actionGroup() == a ) { + listActions->setCurrentItem( it.current() ); + listActions->ensureItemVisible( it.current() ); + break; + } + ++it; + } +} + +QAction *ActionEditor::newActionEx() +{ + ActionItem *i = new ActionItem( listActions, (bool)FALSE ); + QAction *a = i->action(); + QObject::connect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + MetaDataBase::addEntry( i->action() ); + QString n = "Action"; + formWindow->unify( i->action(), n, TRUE ); + i->setText( 0, n ); + i->action()->setName( n ); + i->action()->setText( i->action()->name() ); + MetaDataBase::setPropertyChanged( i->action(), "text", TRUE ); + MetaDataBase::setPropertyChanged( i->action(), "name", TRUE ); + formWindow->actionList().append( i->action() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); + return i->action(); +} + +void ActionEditor::deleteAction() +{ + if ( !currentAction ) + return; + + QListViewItemIterator it( listActions ); + ActionItem *ai = 0; + while ( it.current() ) { + ai = (ActionItem*)it.current(); + if ( ai->action() == currentAction || ai->actionGroup() == currentAction ) { + emit removing( currentAction ); + formWindow->actionList().removeRef( currentAction ); + delete currentAction; + currentAction = 0; + delete it.current(); + break; + } + ++it; + } + if ( formWindow ) { + formWindow->setActiveObject( formWindow->mainContainer() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); + } +} + +void ActionEditor::newAction() +{ + ActionItem *actionParent = (ActionItem*)listActions->selectedItem(); + if ( actionParent ) { + if ( !::qt_cast<QActionGroup*>(actionParent->actionGroup()) ) + actionParent = (ActionItem*)actionParent->parent(); + } + + ActionItem *i = 0; + if ( actionParent ) + i = new ActionItem( actionParent ); + else + i = new ActionItem( listActions, (bool)FALSE ); + QAction *a = i->action(); + QObject::connect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + MetaDataBase::addEntry( i->action() ); + QString n = "Action"; + formWindow->unify( i->action(), n, TRUE ); + i->setText( 0, n ); + i->action()->setName( n ); + i->action()->setText( i->action()->name() ); + if ( actionParent && actionParent->actionGroup() && + actionParent->actionGroup()->usesDropDown() ) { + i->action()->setToggleAction( TRUE ); + MetaDataBase::setPropertyChanged( i->action(), "toggleAction", TRUE ); + } + MetaDataBase::setPropertyChanged( i->action(), "text", TRUE ); + MetaDataBase::setPropertyChanged( i->action(), "name", TRUE ); + listActions->setCurrentItem( i ); + if ( !actionParent ) + formWindow->actionList().append( i->action() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); +} + +void ActionEditor::newActionGroup() +{ + ActionItem *actionParent = (ActionItem*)listActions->selectedItem(); + if ( actionParent ) { + if ( !::qt_cast<QActionGroup*>(actionParent->actionGroup()) ) + actionParent = (ActionItem*)actionParent->parent(); + } + + ActionItem *i = 0; + if ( actionParent ) + i = new ActionItem( actionParent, TRUE ); + else + i = new ActionItem( listActions, TRUE ); + QAction *ag = i->actionGroup(); + QObject::connect( ag, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + MetaDataBase::addEntry( i->actionGroup() ); + MetaDataBase::setPropertyChanged( i->actionGroup(), "usesDropDown", TRUE ); + QString n = "ActionGroup"; + formWindow->unify( i->action(), n, TRUE ); + i->setText( 0, n ); + i->actionGroup()->setName( n ); + i->actionGroup()->setText( i->actionGroup()->name() ); + MetaDataBase::setPropertyChanged( i->actionGroup(), "text", TRUE ); + MetaDataBase::setPropertyChanged( i->actionGroup(), "name", TRUE ); + listActions->setCurrentItem( i ); + i->setOpen( TRUE ); + if ( !actionParent ) + formWindow->actionList().append( i->actionGroup() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); +} + +void ActionEditor::newDropDownActionGroup() +{ + newActionGroup(); + ( (ActionItem*)listActions->currentItem() )->actionGroup()->setUsesDropDown( TRUE ); +} + +void ActionEditor::setFormWindow( FormWindow *fw ) +{ + listActions->clear(); + formWindow = fw; + if ( !formWindow || + !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) { + setEnabled( FALSE ); + } else { + setEnabled( TRUE ); + for ( QAction *a = formWindow->actionList().first(); a; a = formWindow->actionList().next() ) { + ActionItem *i = 0; + if ( ::qt_cast<QAction*>(a->parent()) ) + continue; + i = new ActionItem( listActions, a ); + i->setText( 0, a->name() ); + i->setPixmap( 0, a->iconSet().pixmap() ); + // make sure we don't duplicate the connection + QObject::disconnect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject * ) ) ); + QObject::connect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + if ( ::qt_cast<QActionGroup*>(a) ) { + insertChildActions( i ); + } + } + if ( listActions->firstChild() ) { + listActions->setCurrentItem( listActions->firstChild() ); + listActions->setSelected( listActions->firstChild(), TRUE ); + } + } +} + +void ActionEditor::insertChildActions( ActionItem *i ) +{ + if ( !i->actionGroup() || !i->actionGroup()->children() ) + return; + QObjectListIt it( *i->actionGroup()->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast<QAction*>(o) ) + continue; + QAction *a = (QAction*)o; + ActionItem *i2 = new ActionItem( (QListViewItem*)i, a ); + i->setOpen( TRUE ); + i2->setText( 0, a->name() ); + i2->setPixmap( 0, a->iconSet().pixmap() ); + // make sure we don't duplicate the connection + QObject::disconnect( o, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject * ) ) ); + QObject::connect( o, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject * ) ) ); + if ( ::qt_cast<QActionGroup*>(a) ) + insertChildActions( i2 ); + } +} + +void ActionEditor::updateActionName( QAction *a ) +{ + QListViewItemIterator it( listActions ); + while ( it.current() ) { + if ( ( (ActionItem*)it.current() )->action() == a ) + ( (ActionItem*)it.current() )->setText( 0, a->name() ); + else if ( ( (ActionItem*)it.current() )->actionGroup() == a ) + ( (ActionItem*)it.current() )->setText( 0, a->name() ); + ++it; + } +} + +void ActionEditor::updateActionIcon( QAction *a ) +{ + QListViewItemIterator it( listActions ); + while ( it.current() ) { + if ( ( (ActionItem*)it.current() )->action() == a ) + ( (ActionItem*)it.current() )->setPixmap( 0, a->iconSet().pixmap() ); + else if ( ( (ActionItem*)it.current() )->actionGroup() == a ) + ( (ActionItem*)it.current() )->setPixmap( 0, a->iconSet().pixmap() ); + ++it; + } +} + +void ActionEditor::connectionsClicked() +{ + ConnectionDialog dlg( formWindow->mainWindow() ); + dlg.setDefault( currentAction, formWindow ); + dlg.addConnection(); + dlg.exec(); +} + +void ActionEditor::removeConnections( QObject *o ) +{ + QValueList<MetaDataBase::Connection> conns = + MetaDataBase::connections( formWindow, o ); + for ( QValueList<MetaDataBase::Connection>::Iterator it2 = conns.begin(); + it2 != conns.end(); ++it2 ) + MetaDataBase::removeConnection( formWindow, (*it2).sender, (*it2).signal, + (*it2).receiver, (*it2).slot ); +} diff --git a/kdevdesigner/designer/actioneditorimpl.h b/kdevdesigner/designer/actioneditorimpl.h new file mode 100644 index 00000000..439a8fb8 --- /dev/null +++ b/kdevdesigner/designer/actioneditorimpl.h @@ -0,0 +1,79 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef ACTIONEDITORIMPL_H +#define ACTIONEDITORIMPL_H + +#include "actioneditor.h" + +class QAction; +class FormWindow; +class ActionItem; + +class ActionEditor : public ActionEditorBase +{ + Q_OBJECT + +public: + ActionEditor( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + void setFormWindow( FormWindow *fw ); + void updateActionName( QAction *a ); + void updateActionIcon( QAction *a ); + FormWindow *form() const { return formWindow; } + + bool wantToBeShown() const { return !explicitlyClosed; } + void setWantToBeShown( bool b ) { explicitlyClosed = !b; } + + void setCurrentAction( QAction *a ); + QAction *newActionEx(); + +protected: + void closeEvent( QCloseEvent *e ); + +protected slots: + void currentActionChanged( QListViewItem * ); + void deleteAction(); + void newAction(); + void newActionGroup(); + void newDropDownActionGroup(); + void connectionsClicked(); + void removeConnections( QObject *o ); + +signals: + void hidden(); + void removing( QAction * ); + +private: + void insertChildActions( ActionItem *i ); + +private: + QAction *currentAction; + FormWindow *formWindow; + bool explicitlyClosed; + +}; + +#endif // ACTIONEDITORIMPL_H diff --git a/kdevdesigner/designer/actionlistview.cpp b/kdevdesigner/designer/actionlistview.cpp new file mode 100644 index 00000000..53c7e292 --- /dev/null +++ b/kdevdesigner/designer/actionlistview.cpp @@ -0,0 +1,110 @@ +/********************************************************************** +** 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 "actiondnd.h" +#include "actionlistview.h" +#include <qheader.h> + +#include <klocale.h> + +ActionListView::ActionListView( QWidget *parent, const char *name ) + : QListView( parent, name ) +{ + setShowSortIndicator( TRUE ); + setResizeMode( LastColumn ); + setRootIsDecorated( TRUE ); + connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ), + this, SLOT( rmbMenu( QListViewItem *, const QPoint & ) ) ); +} + +ActionItem::ActionItem( QListView *lv, QAction *ac ) + : QListViewItem( lv ), a( 0 ), g( 0 ) +{ + g = ::qt_cast<QDesignerActionGroup*>(ac); + if ( !g ) + a = ::qt_cast<QDesignerAction*>(ac); + setDragEnabled( TRUE ); +} + +ActionItem::ActionItem( QListViewItem *i, QAction *ac ) + : QListViewItem( i ), a( 0 ), g( 0 ) +{ + g = ::qt_cast<QDesignerActionGroup*>(ac); + if ( !g ) + a = ::qt_cast<QDesignerAction*>(ac); + setDragEnabled( TRUE ); + moveToEnd(); +} + +void ActionItem::moveToEnd() +{ + QListViewItem *i = this; + while ( i->nextSibling() ) + i = i->nextSibling(); + if ( i != this ) + moveItem( i ); +} + +QDragObject *ActionListView::dragObject() +{ + ActionItem *i = (ActionItem*)currentItem(); + if ( !i ) + return 0; + QStoredDrag *drag = 0; + if ( i->action() ) { + drag = new ActionDrag( i->action(), viewport() ); + drag->setPixmap( i->action()->iconSet().pixmap() ); + } else { + drag = new ActionDrag( i->actionGroup(), viewport() ); + drag->setPixmap( i->actionGroup()->iconSet().pixmap() ); + } + return drag; +} + +void ActionListView::rmbMenu( QListViewItem *i, const QPoint &p ) +{ + QPopupMenu *popup = new QPopupMenu( this ); + popup->insertItem( i18n( "New &Action" ), 0 ); + popup->insertItem( i18n( "New Action &Group" ), 1 ); + popup->insertItem( i18n( "New &Dropdown Action Group" ), 2 ); + if ( i ) { + popup->insertSeparator(); + popup->insertItem( i18n( "&Connect Action..." ), 3 ); + popup->insertSeparator(); + popup->insertItem( i18n( "Delete Action" ), 4 ); + } + int res = popup->exec( p ); + if ( res == 0 ) + emit insertAction(); + else if ( res == 1 ) + emit insertActionGroup(); + else if ( res == 2 ) + emit insertDropDownActionGroup(); + else if ( res == 3 ) + emit connectAction(); + else if ( res == 4 ) + emit deleteAction(); +} diff --git a/kdevdesigner/designer/actionlistview.h b/kdevdesigner/designer/actionlistview.h new file mode 100644 index 00000000..59c48b20 --- /dev/null +++ b/kdevdesigner/designer/actionlistview.h @@ -0,0 +1,81 @@ +/********************************************************************** +** 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 ACTIONLISTVIEW_H +#define ACTIONLISTVIEW_H + +#include <qlistview.h> +#include "actiondnd.h" + +class ActionItem : public QListViewItem +{ +public: + ActionItem( QListView *lv, bool group ) + : QListViewItem( lv ), + a( group ? 0 : new QDesignerAction( 0 ) ), + g( group ? new QDesignerActionGroup( 0 ) : 0 ) { setDragEnabled( TRUE ); } + ActionItem( QListView *lv, QAction *ac ); + ActionItem( QListViewItem *i, QAction *ac ); + ActionItem( ActionItem *parent, bool group = FALSE ) + : QListViewItem( parent ), + a( group ? 0 : new QDesignerAction( parent->actionGroup() ) ), + g( group ? new QDesignerActionGroup( parent->actionGroup() ) : 0 ) { setDragEnabled( TRUE ); moveToEnd(); } + + QDesignerAction *action() const { return a; } + QDesignerActionGroup *actionGroup() const { return g; } + +private: + void moveToEnd(); + +private: + QDesignerAction *a; + QDesignerActionGroup *g; + +}; + +class ActionListView : public QListView +{ + Q_OBJECT + +public: + ActionListView( QWidget *parent = 0, const char *name = 0 ); + +protected: + QDragObject *dragObject(); + +private slots: + void rmbMenu( QListViewItem *i, const QPoint &p ); + +signals: + void insertAction(); + void insertActionGroup(); + void insertDropDownActionGroup(); + void deleteAction(); + void connectAction(); + +}; + +#endif diff --git a/kdevdesigner/designer/asciivalidator.cpp b/kdevdesigner/designer/asciivalidator.cpp new file mode 100644 index 00000000..7642d47f --- /dev/null +++ b/kdevdesigner/designer/asciivalidator.cpp @@ -0,0 +1,94 @@ +/********************************************************************** +** 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 "asciivalidator.h" + +#include <qstring.h> + +AsciiValidator::AsciiValidator( QObject * parent, const char *name ) + : QValidator( parent, name ), functionName( FALSE ) +{ +} + +AsciiValidator::AsciiValidator( bool funcName, QObject * parent, const char *name ) + : QValidator( parent, name ), functionName( funcName ) +{ +} + +AsciiValidator::AsciiValidator( const QString &allow, QObject * parent, const char *name ) + : QValidator( parent, name ), functionName( FALSE ), allowedChars( allow ) +{ +} + +AsciiValidator::~AsciiValidator() +{ +} + +QValidator::State AsciiValidator::validate( QString &s, int & ) const +{ + bool inParen = FALSE; + bool outParen = FALSE; + if ( !s.isEmpty() && s[0].row() == 0 && s[0].cell() >= '0' && s[0].cell() <= '9' ) + s[0] = '_'; + for ( int i = 0, j = 0; i < (int) s.length(); i++ ) { + uchar r = s[i].row(); + uchar c = s[i].cell(); + + if ( outParen ) { // check if we have 'const' or 'volatile' + static const QString con = " const"; + static const QString vol = " volatile"; + QString mid = s.mid( j ); + if ( !( con.startsWith( mid ) || vol.startsWith( mid ) ) ) + return QValidator::Invalid; + } + + if ( inParen && c != ')' ) + continue; + + if ( r == 0 && ( ( c >= '0' && c <= '9' ) || + ( c >= 'a' && c <= 'z' ) || + ( c >= 'A' && c <= 'Z' ) ) ) + continue; + + if ( functionName ) { + if ( c == '(' ) { + inParen = TRUE; + continue; + } + if ( c == ')' ) { + outParen = TRUE; + j = i + 1; + continue; + } + } + + if ( allowedChars.find( s[ i ] ) != -1 ) + continue; + + s[i] = '_'; + } + return QValidator::Acceptable; +} diff --git a/kdevdesigner/designer/asciivalidator.h b/kdevdesigner/designer/asciivalidator.h new file mode 100644 index 00000000..2cdfe0cb --- /dev/null +++ b/kdevdesigner/designer/asciivalidator.h @@ -0,0 +1,52 @@ +/********************************************************************** +** 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 ASCIIVALIDATOR_H +#define ASCIIVALIDATOR_H + + +#include <qvalidator.h> + + +class AsciiValidator: public QValidator +{ + Q_OBJECT +public: + AsciiValidator( QObject * parent, const char *name = 0 ); + AsciiValidator( bool funcName, QObject * parent, const char *name = 0 ); + AsciiValidator( const QString &allow, QObject * parent, const char *name = 0 ); + ~AsciiValidator(); + + QValidator::State validate( QString &, int & ) const; + +private: + bool functionName; + QString allowedChars; + +}; + + +#endif diff --git a/kdevdesigner/designer/command.cpp b/kdevdesigner/designer/command.cpp new file mode 100644 index 00000000..83ec9a77 --- /dev/null +++ b/kdevdesigner/designer/command.cpp @@ -0,0 +1,2473 @@ +/********************************************************************** +** 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 "command.h" +#include "formwindow.h" +#include "widgetfactory.h" +#include "propertyeditor.h" +#include "metadatabase.h" +#include <widgetdatabase.h> +#include "mainwindow.h" +#include "hierarchyview.h" +#include "workspace.h" +#include "actioneditorimpl.h" +#include "actiondnd.h" +#include "formfile.h" +#include "../interfaces/languageinterface.h" +#include "menubareditor.h" +#include "popupmenueditor.h" + +#include <qfeatures.h> +#include <qwidget.h> +#include <qmetaobject.h> +#include <qapplication.h> +#include <qlayout.h> +#include <qmessagebox.h> +#include <qlistbox.h> +#include <qiconview.h> +#include <qtextedit.h> +#include <qptrstack.h> +#include <qheader.h> +#include <qsplitter.h> +#ifndef QT_NO_TABLE +#include <qtable.h> +#endif +#include <qaction.h> + +#include "kdevdesigner_part.h" + +#include <klocale.h> + +CommandHistory::CommandHistory( int s ) + : current( -1 ), steps( s ), savedAt( -1 ) +{ + history.setAutoDelete( TRUE ); + modified = FALSE; + compressedCommand = 0; +} + +void CommandHistory::addCommand( Command *cmd, bool tryCompress ) +{ + if ( tryCompress ) { + if ( !compressedCommand || + compressedCommand->type() != cmd->type() || + !compressedCommand->canMerge( cmd ) ) { + checkCompressedCommand(); + compressedCommand = 0; + } + + if ( compressedCommand ) { + compressedCommand->merge( cmd ); + modified = TRUE; + modificationChanged( modified ); + return; + } + compressedCommand = cmd; + } else { + checkCompressedCommand(); + } + + if ( current < (int)history.count() - 1 ) { + if ( current < savedAt ) + savedAt = -2; + + QPtrList<Command> commands; + commands.setAutoDelete( FALSE ); + + for( int i = 0; i <= current; ++i ) { + commands.insert( i, history.at( 0 ) ); + history.take( 0 ); + } + + commands.append( cmd ); + history.clear(); + history = commands; + history.setAutoDelete( TRUE ); + } else { + history.append( cmd ); + } + + if ( (int)history.count() > steps ) { + savedAt--; + history.removeFirst(); + } else { + ++current; + } + + emitUndoRedo(); + modified = TRUE; + modificationChanged( modified ); +} + +void CommandHistory::undo() +{ + checkCompressedCommand(); + compressedCommand = 0; + if ( current > -1 ) { + history.at( current )->unexecute(); + --current; + } + emitUndoRedo(); + modified = savedAt != current; + modificationChanged( modified ); +} + +void CommandHistory::redo() +{ + checkCompressedCommand(); + compressedCommand = 0; + if ( current > -1 ) { + if ( current < (int)history.count() - 1 ) { + ++current; + history.at( current )->execute(); + } + } else { + if ( history.count() > 0 ) { + ++current; + history.at( current )->execute(); + } + } + emitUndoRedo(); + modified = savedAt != current; + modificationChanged( modified ); +} + +void CommandHistory::emitUndoRedo() +{ + Command *undoCmd = 0; + Command *redoCmd = 0; + + if ( current >= 0 && current < (int)history.count() ) + undoCmd = history.at( current ); + if ( current + 1 >= 0 && current + 1 < (int)history.count() ) + redoCmd = history.at( current + 1 ); + + bool ua = (undoCmd != 0); + QString uc; + if ( ua ) + uc = undoCmd->name(); + bool ra = (redoCmd != 0); + QString rc; + if ( ra ) + rc = redoCmd->name(); + emit undoRedoChanged( ua, ra, uc, rc ); +} + +void CommandHistory::setModified( bool m ) +{ + modified = m; + if ( !modified ) + savedAt = current; + modificationChanged( modified ); +} + +bool CommandHistory::isModified() const +{ + return modified; +} + +void CommandHistory::checkCompressedCommand() +{ + if ( compressedCommand && compressedCommand->type() == Command::SetProperty ) { + Command *c = compressedCommand; + compressedCommand = 0; + if ( !( (SetPropertyCommand*)c )->checkProperty() ) { + history.remove( current ); + --current; + emitUndoRedo(); + } + } +} + +// ------------------------------------------------------------ + +Command::Command( const QString &n, FormWindow *fw ) + : cmdName( n ), formWin( fw ) +{ +} + +Command::~Command() +{ +} + +QString Command::name() const +{ + return cmdName; +} + +FormWindow *Command::formWindow() const +{ + return formWin; +} + +void Command::merge( Command * ) +{ +} + +bool Command::canMerge( Command * ) +{ + return FALSE; +} + +// ------------------------------------------------------------ + +ResizeCommand::ResizeCommand( const QString &n, FormWindow *fw, + QWidget *w, const QRect &oldr, const QRect &nr ) + : Command( n, fw ), widget( w ), oldRect( oldr ), newRect( nr ) +{ +} + +void ResizeCommand::execute() +{ + widget->setGeometry( newRect ); + formWindow()->updateSelection( widget ); + formWindow()->emitUpdateProperties( widget ); + if ( WidgetFactory::layoutType( widget ) != WidgetFactory::NoLayout ) + formWindow()->updateChildSelections( widget ); +} + +void ResizeCommand::unexecute() +{ + widget->setGeometry( oldRect ); + formWindow()->updateSelection( widget ); + formWindow()->emitUpdateProperties( widget ); + if ( WidgetFactory::layoutType( widget ) != WidgetFactory::NoLayout ) + formWindow()->updateChildSelections( widget ); +} + +// ------------------------------------------------------------ + +InsertCommand::InsertCommand( const QString &n, FormWindow *fw, + QWidget *w, const QRect &g ) + : Command( n, fw ), widget( w ), geometry( g ) +{ +} + +void InsertCommand::execute() +{ + if ( geometry.size() == QSize( 0, 0 ) ) { + widget->move( geometry.topLeft() ); + widget->adjustSize(); + } else { + QSize s = geometry.size().expandedTo( widget->minimumSize() ); + s = s.expandedTo( widget->minimumSizeHint() ); + QRect r( geometry.topLeft(), s ); + widget->setGeometry( r ); + } + widget->show(); + formWindow()->widgets()->insert( widget, widget ); + formWindow()->clearSelection( FALSE ); + formWindow()->selectWidget( widget ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( widget ); +} + +void InsertCommand::unexecute() +{ + widget->hide(); + formWindow()->selectWidget( widget, FALSE ); + formWindow()->widgets()->remove( widget ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( widget ); + } + +// ------------------------------------------------------------ + +MoveCommand::MoveCommand( const QString &n, FormWindow *fw, + const QWidgetList &w, + const QValueList<QPoint> op, + const QValueList<QPoint> np, + QWidget *opr, QWidget *npr ) + : Command( n, fw ), widgets( w ), oldPos( op ), newPos( np ), + oldParent( opr ), newParent( npr ) +{ + widgets.setAutoDelete( FALSE ); +} + +void MoveCommand::merge( Command *c ) +{ + MoveCommand *cmd = (MoveCommand*)c; + newPos = cmd->newPos; +} + +bool MoveCommand::canMerge( Command *c ) +{ + MoveCommand *cmd = (MoveCommand*)c; + return widgets == cmd->widgets; +} + + +void MoveCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) { + if ( newParent && oldParent && newParent != oldParent ) { + QPoint pos = newParent->mapFromGlobal( w->mapToGlobal( QPoint( 0,0 ) ) ); + w->reparent( newParent, pos, TRUE ); + formWindow()->raiseSelection( w ); + formWindow()->raiseChildSelections( w ); + formWindow()->widgetChanged( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( w ); + } + w->move( newPos[ widgets.at() ] ); + } + formWindow()->updateSelection( w ); + formWindow()->updateChildSelections( w ); + formWindow()->emitUpdateProperties( w ); + } +} + +void MoveCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) { + if ( newParent && oldParent && newParent != oldParent ) { + QPoint pos = oldParent->mapFromGlobal( w->mapToGlobal( QPoint( 0,0 ) ) ); + w->reparent( oldParent, pos, TRUE ); + formWindow()->raiseSelection( w ); + formWindow()->raiseChildSelections( w ); + formWindow()->widgetChanged( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( w ); + } + w->move( oldPos[ widgets.at() ] ); + } + formWindow()->updateSelection( w ); + formWindow()->updateChildSelections( w ); + formWindow()->emitUpdateProperties( w ); + } +} + +// ------------------------------------------------------------ + +DeleteCommand::DeleteCommand( const QString &n, FormWindow *fw, + const QWidgetList &wl ) + : Command( n, fw ), widgets( wl ) +{ + widgets.setAutoDelete( FALSE ); + QWidgetList copyOfWidgets = widgets; + copyOfWidgets.setAutoDelete(FALSE); + + // Include the children of the selected items when deleting + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + QObjectList *children = w->queryList( "QWidget" ); + for ( QWidget *c = (QWidget *)children->first(); c; c = (QWidget *)children->next() ) { + if ( copyOfWidgets.find( c ) == -1 && formWindow()->widgets()->find( c ) ) { + widgets.insert(widgets.at() + 1, c); + widgets.prev(); + copyOfWidgets.append(c); + } + } + delete children; + } +} + +void DeleteCommand::execute() +{ + formWindow()->setPropertyShowingBlocked( TRUE ); + connections.clear(); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->hide(); + QString s = w->name(); + s.prepend( "qt_dead_widget_" ); + w->setName( s ); + formWindow()->selectWidget( w, FALSE ); + formWindow()->widgets()->remove( w ); + QValueList<MetaDataBase::Connection> conns = MetaDataBase::connections( formWindow(), w ); + connections.insert( w, conns ); + QValueList<MetaDataBase::Connection>::Iterator it = conns.begin(); + for ( ; it != conns.end(); ++it ) { + MetaDataBase::removeConnection( formWindow(), (*it).sender, + (*it).signal, (*it).receiver, (*it).slot ); + } + } + formWindow()->setPropertyShowingBlocked( FALSE ); + formWindow()->emitShowProperties(); + formWindow()->mainWindow()->objectHierarchy()->widgetsRemoved( widgets ); + +} + +void DeleteCommand::unexecute() +{ + formWindow()->setPropertyShowingBlocked( TRUE ); + formWindow()->clearSelection( FALSE ); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->show(); + QString s = w->name(); + s.remove( 0, QString( "qt_dead_widget_" ).length() ); + w->setName( s ); + formWindow()->widgets()->insert( w, w ); + formWindow()->selectWidget( w ); + QValueList<MetaDataBase::Connection> conns = *connections.find( w ); + QValueList<MetaDataBase::Connection>::Iterator it = conns.begin(); + for ( ; it != conns.end(); ++it ) { + MetaDataBase::addConnection( formWindow(), (*it).sender, + (*it).signal, (*it).receiver, (*it).slot ); + } + } + formWindow()->setPropertyShowingBlocked( FALSE ); + formWindow()->emitShowProperties(); + formWindow()->mainWindow()->objectHierarchy()->widgetsInserted( widgets ); +} + +// ------------------------------------------------------------ + +SetPropertyCommand::SetPropertyCommand( const QString &n, FormWindow *fw, + QObject *w, PropertyEditor *e, + const QString &pn, const QVariant &ov, + const QVariant &nv, const QString &ncut, + const QString &ocut, bool reset ) + : Command( n, fw ), widget( w ), editor( e ), propName( pn ), + oldValue( ov ), newValue( nv ), oldCurrentItemText( ocut ), newCurrentItemText( ncut ), + wasChanged( TRUE ), isResetCommand( reset ) +{ + wasChanged = MetaDataBase::isPropertyChanged( w, propName ); + if ( oldCurrentItemText.isNull() ) + oldCurrentItemText = ""; + if ( newCurrentItemText.isNull() ) + newCurrentItemText = ""; +} + + +void SetPropertyCommand::execute() +{ + if ( !wasChanged ) + MetaDataBase::setPropertyChanged( widget, propName, TRUE ); + if ( isResetCommand ) { + MetaDataBase::setPropertyChanged( widget, propName, FALSE ); + if ( WidgetFactory::resetProperty( widget, propName ) ) { + if ( !formWindow()->isWidgetSelected( widget ) && formWindow() != (QObject *)widget ) + formWindow()->selectWidget( (QObject *)widget ); + if ( editor->widget() != widget ) + editor->setWidget( widget, formWindow() ); + editor->propertyList()->setCurrentProperty( propName ); + PropertyItem *i = (PropertyItem*)editor->propertyList()->currentItem(); + if ( !i ) + return; + i->setValue( widget->property( propName ) ); + i->setChanged( FALSE ); + editor->refetchData(); + editor->emitWidgetChanged(); + return; + } + } + setProperty( newValue, newCurrentItemText ); +} + +void SetPropertyCommand::unexecute() +{ + if ( !wasChanged ) + MetaDataBase::setPropertyChanged( widget, propName, FALSE ); + if ( isResetCommand ) + MetaDataBase::setPropertyChanged( widget, propName, TRUE ); + setProperty( oldValue, oldCurrentItemText ); +} + +bool SetPropertyCommand::canMerge( Command *c ) +{ + SetPropertyCommand *cmd = (SetPropertyCommand*)c; + if ( !widget ) + return FALSE; + const QMetaProperty *p = + widget->metaObject()->property( widget->metaObject()->findProperty( propName, TRUE ), TRUE ); + if ( !p ) { + if ( propName == "toolTip" || propName == "whatsThis" ) + return TRUE; + if ( ::qt_cast<CustomWidget*>((QObject *)widget) ) { + MetaDataBase::CustomWidget *cw = ((CustomWidget*)(QObject*)widget)->customWidget(); + if ( !cw ) + return FALSE; + for ( QValueList<MetaDataBase::Property>::Iterator it = cw->lstProperties.begin(); it != cw->lstProperties.end(); ++it ) { + if ( QString( (*it ).property ) == propName ) { + if ( (*it).type == "String" || (*it).type == "CString" || (*it).type == "Int" || (*it).type == "UInt" ) + return TRUE; + } + } + } + return FALSE; + } + QVariant::Type t = QVariant::nameToType( p->type() ); + return ( cmd->propName == propName && + t == QVariant::String || t == QVariant::CString || t == QVariant::Int || t == QVariant::UInt ); +} + +void SetPropertyCommand::merge( Command *c ) +{ + SetPropertyCommand *cmd = (SetPropertyCommand*)c; + newValue = cmd->newValue; + newCurrentItemText = cmd->newCurrentItemText; +} + +bool SetPropertyCommand::checkProperty() +{ + if ( propName == "name" /*|| propName == "itemName"*/ ) { // ### fix that + QString s = newValue.toString(); + if ( !formWindow()->unify( widget, s, FALSE ) ) { + QMessageBox::information( formWindow()->mainWindow(), + i18n( "Set 'name' Property" ), + i18n( "The name of a widget must be unique.\n" + "'%1' is already used in form '%2',\n" + "so the name has been reverted to '%3'." ). + arg( newValue.toString() ). + arg( formWindow()->name() ). + arg( oldValue.toString() )); + setProperty( oldValue, oldCurrentItemText, FALSE ); + return FALSE; + } + if ( s.isEmpty() ) { + QMessageBox::information( formWindow()->mainWindow(), + i18n( "Set 'name' Property" ), + i18n( "The name of a widget must not be null.\n" + "The name has been reverted to '%1'." ). + arg( oldValue.toString() )); + setProperty( oldValue, oldCurrentItemText, FALSE ); + return FALSE; + } + + if ( ::qt_cast<FormWindow*>(widget->parent()) ) + formWindow()->mainWindow()->formNameChanged( (FormWindow*)((QWidget*)(QObject*)widget)->parentWidget() ); + } + return TRUE; +} + +void SetPropertyCommand::setProperty( const QVariant &v, const QString ¤tItemText, bool select ) +{ + if ( !widget ) + return; + + if ( !formWindow()->isWidgetSelected( widget ) && !formWindow()->isMainContainer( widget ) && select ) + formWindow()->selectWidget( widget ); + if ( editor->widget() != widget && select ) + editor->setWidget( widget, formWindow() ); + if ( select ) + editor->propertyList()->setCurrentProperty( propName ); + const QMetaProperty *p = + widget->metaObject()->property( widget->metaObject()->findProperty( propName, TRUE ), TRUE ); + if ( !p ) { + if ( propName == "hAlign" ) { + p = widget->metaObject()->property( widget->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + int align = widget->property( "alignment" ).toInt(); + align &= ~( AlignHorizontal_Mask ); + align |= p->keyToValue( currentItemText ); + widget->setProperty( "alignment", QVariant( align ) ); + } else if ( propName == "vAlign" ) { + p = widget->metaObject()->property( widget->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + int align = widget->property( "alignment" ).toInt(); + align &= ~( AlignVertical_Mask ); + align |= p->keyToValue( currentItemText ); + widget->setProperty( "alignment", QVariant( align ) ); + } else if ( propName == "wordwrap" ) { + int align = widget->property( "alignment" ).toInt(); + align &= ~WordBreak; + if ( v.toBool() ) + align |= WordBreak; + widget->setProperty( "alignment", QVariant( align ) ); + } else if ( propName == "layoutSpacing" ) { + QVariant val = v; + if ( val.toString() == "default" ) + val = -1; + MetaDataBase::setSpacing( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ), val.toInt() ); + } else if ( propName == "layoutMargin" ) { + QVariant val = v; + if ( val.toString() == "default" ) + val = -1; + MetaDataBase::setMargin( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ), val.toInt() ); + } else if ( propName == "resizeMode" ) { + MetaDataBase::setResizeMode( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ), currentItemText ); + } else if ( propName == "toolTip" || propName == "whatsThis" || propName == "database" || propName == "frameworkCode" ) { + MetaDataBase::setFakeProperty( editor->widget(), propName, v ); + } else if ( ::qt_cast<CustomWidget*>(editor->widget()) ) { + MetaDataBase::CustomWidget *cw = ((CustomWidget *)(QObject *)widget)->customWidget(); + if ( cw ) { + MetaDataBase::setFakeProperty( editor->widget(), propName, v ); + } + } + editor->refetchData(); + editor->emitWidgetChanged(); + ( ( PropertyItem* )editor->propertyList()->currentItem() )->setChanged( MetaDataBase::isPropertyChanged( widget, propName ) ); +#ifndef QT_NO_SQL + if ( propName == "database" ) { + formWindow()->mainWindow()->objectHierarchy()->databasePropertyChanged( (QWidget*)((QObject *)widget), MetaDataBase::fakeProperty( widget, "database" ).toStringList() ); + } +#endif + return; + } + + if ( p->isSetType() ) { + QStrList strlst; + QStringList lst = QStringList::split( "|", currentItemText ); + QValueListConstIterator<QString> it = lst.begin(); + for ( ; it != lst.end(); ++it ) + strlst.append( (*it).latin1() ); + widget->setProperty( propName, p->keysToValue( strlst ) ); + } else if ( p->isEnumType() ) { + widget->setProperty( propName, p->keyToValue( currentItemText ) ); + } else if ( qstrcmp( p->name(), "buddy" ) == 0 ) { + widget->setProperty( propName, currentItemText ); + } else { + QVariant ov; + if ( propName == "name" || propName == "itemName" ) + ov = widget->property( propName ); + int oldSerNum = -1; + if ( v.type() == QVariant::Pixmap ) + oldSerNum = v.toPixmap().serialNumber(); + widget->setProperty( propName, v ); + if ( oldSerNum != -1 && oldSerNum != widget->property( propName ).toPixmap().serialNumber() ) + MetaDataBase::setPixmapKey( formWindow(), + widget->property( propName ).toPixmap().serialNumber(), + MetaDataBase::pixmapKey( formWindow(), oldSerNum ) ); + if ( propName == "cursor" ) { + MetaDataBase::setCursor( (QWidget*)((QObject *)widget), v.toCursor() ); + } + if ( propName == "name" && widget->isWidgetType() ) { + formWindow()->mainWindow()->objectHierarchy()->namePropertyChanged( ((QWidget*)(QObject *)widget), ov ); + if ( formWindow()->isMainContainer( widget ) ) + formWindow()->setName( v.toCString() ); + } + if ( propName == "name" && ::qt_cast<QAction*>((QObject *)widget) && ::qt_cast<QMainWindow*>(formWindow()->mainContainer()) ) { + formWindow()->mainWindow()->actioneditor()->updateActionName( (QAction*)(QObject *)widget ); + } + if ( propName == "iconSet" && ::qt_cast<QAction*>((QObject *)widget) && ::qt_cast<QMainWindow*>(formWindow()->mainContainer()) ) { + formWindow()->mainWindow()->actioneditor()->updateActionIcon( (QAction*)(QObject *)widget ); + } + if ( propName == "caption" ) { + if ( formWindow()->isMainContainer( widget ) ) + formWindow()->setCaption( v.toString() ); + } + if ( propName == "icon" ) { + if ( formWindow()->isMainContainer( widget ) ) + formWindow()->setIcon( v.toPixmap() ); + } + } + editor->refetchData(); + if ( editor->propertyList()->currentItem() && select ) { + ( ( PropertyItem* )editor->propertyList()->currentItem() )->showEditor(); + ( ( PropertyItem* )editor->propertyList()->currentItem() )->setChanged( MetaDataBase::isPropertyChanged( widget, propName ) ); + } + editor->emitWidgetChanged(); + formWindow()->killAccels( widget ); +} + +// ------------------------------------------------------------ + +LayoutHorizontalCommand::LayoutHorizontalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase ) +{ +} + +void LayoutHorizontalCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutHorizontalCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutHorizontalSplitCommand::LayoutHorizontalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase, TRUE, TRUE ) +{ +} + +void LayoutHorizontalSplitCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutHorizontalSplitCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutVerticalCommand::LayoutVerticalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase ) +{ +} + +void LayoutVerticalCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutVerticalCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutVerticalSplitCommand::LayoutVerticalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase, TRUE, TRUE ) +{ +} + +void LayoutVerticalSplitCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutVerticalSplitCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutGridCommand::LayoutGridCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl, int xres, int yres ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase, QSize( QMAX(5,xres), QMAX(5,yres) ) ) +{ +} + +void LayoutGridCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutGridCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +BreakLayoutCommand::BreakLayoutCommand( const QString &n, FormWindow *fw, + QWidget *layoutBase, const QWidgetList &wl ) + : Command( n, fw ), lb( layoutBase ), widgets( wl ) +{ + WidgetFactory::LayoutType lay = WidgetFactory::layoutType( layoutBase ); + spacing = MetaDataBase::spacing( layoutBase ); + margin = MetaDataBase::margin( layoutBase ); + layout = 0; + if ( lay == WidgetFactory::HBox ) + layout = new HorizontalLayout( wl, layoutBase, fw, layoutBase, FALSE, ::qt_cast<QSplitter*>(layoutBase) != 0 ); + else if ( lay == WidgetFactory::VBox ) + layout = new VerticalLayout( wl, layoutBase, fw, layoutBase, FALSE, ::qt_cast<QSplitter*>(layoutBase) != 0 ); + else if ( lay == WidgetFactory::Grid ) + layout = new GridLayout( wl, layoutBase, fw, layoutBase, QSize( QMAX( 5, fw->grid().x()), QMAX( 5, fw->grid().y()) ), FALSE ); +} + +void BreakLayoutCommand::execute() +{ + if ( !layout ) + return; + formWindow()->clearSelection( FALSE ); + layout->breakLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) + w->resize( QMAX( 16, w->width() ), QMAX( 16, w->height() ) ); +} + +void BreakLayoutCommand::unexecute() +{ + if ( !layout ) + return; + formWindow()->clearSelection( FALSE ); + layout->doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); + MetaDataBase::setSpacing( WidgetFactory::containerOfWidget( lb ), spacing ); + MetaDataBase::setMargin( WidgetFactory::containerOfWidget( lb ), margin ); +} + +// ------------------------------------------------------------ + +MacroCommand::MacroCommand( const QString &n, FormWindow *fw, + const QPtrList<Command> &cmds ) + : Command( n, fw ), commands( cmds ) +{ +} + +void MacroCommand::execute() +{ + for ( Command *c = commands.first(); c; c = commands.next() ) + c->execute(); +} + +void MacroCommand::unexecute() +{ + for ( Command *c = commands.last(); c; c = commands.prev() ) + c->unexecute(); +} + +// ------------------------------------------------------------ + +AddTabPageCommand::AddTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, const QString &label ) + : Command( n, fw ), tabWidget( tw ), tabLabel( label ) +{ + tabPage = new QDesignerWidget( formWindow(), tabWidget, "TabPage" ); + tabPage->hide(); + index = -1; + MetaDataBase::addEntry( tabPage ); +} + +void AddTabPageCommand::execute() +{ + if ( index == -1 ) + index = ( (QDesignerTabWidget*)tabWidget )->count(); + tabWidget->insertTab( tabPage, tabLabel, index ); + tabWidget->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +void AddTabPageCommand::unexecute() +{ + tabWidget->removePage( tabPage ); + tabPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +// ------------------------------------------------------------ + +MoveTabPageCommand::MoveTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget* page, const QString& label, int nIndex, int oIndex ) + : Command( n, fw ), tabWidget( tw ), tabPage( page ), tabLabel( label ) +{ + newIndex = nIndex; + oldIndex = oIndex; +} + +void MoveTabPageCommand::execute() +{ + ((QDesignerTabWidget*)tabWidget )->removePage( tabPage ); + ((QDesignerTabWidget*)tabWidget )->insertTab( tabPage, tabLabel, newIndex ); + ((QDesignerTabWidget*)tabWidget )->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +void MoveTabPageCommand::unexecute() +{ + ((QDesignerTabWidget*)tabWidget )->removePage( tabPage ); + ((QDesignerTabWidget*)tabWidget )->insertTab( tabPage, tabLabel, oldIndex ); + ((QDesignerTabWidget*)tabWidget )->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +// ------------------------------------------------------------ + +DeleteTabPageCommand::DeleteTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget *page ) + : Command( n, fw ), tabWidget( tw ), tabPage( page ) +{ + tabLabel = ( (QDesignerTabWidget*)tabWidget )->pageTitle(); + index = ( (QDesignerTabWidget*)tabWidget )->currentPage(); +} + +void DeleteTabPageCommand::execute() +{ + tabWidget->removePage( tabPage ); + tabPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +void DeleteTabPageCommand::unexecute() +{ + tabWidget->insertTab( tabPage, tabLabel, index ); + tabWidget->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +// ------------------------------------------------------------ + +AddWidgetStackPageCommand::AddWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws ) + : Command( n, fw ), widgetStack( ws ) +{ + stackPage = new QDesignerWidget( formWindow(), widgetStack, "WStackPage" ); + stackPage->hide(); + index = -1; + MetaDataBase::addEntry( stackPage ); +} + +void AddWidgetStackPageCommand::execute() +{ + index = widgetStack->insertPage( stackPage, index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( 0 ); +} + +void AddWidgetStackPageCommand::unexecute() +{ + index = widgetStack->removePage( stackPage ); + stackPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( 0 ); +} + +DeleteWidgetStackPageCommand::DeleteWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws, QWidget *page ) + : Command( n, fw), widgetStack( ws ), stackPage( page ) +{ + index = -1; +} + +void DeleteWidgetStackPageCommand::execute() +{ + index = widgetStack->removePage( stackPage ); + stackPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( stackPage ); +} + +void DeleteWidgetStackPageCommand::unexecute() +{ + index = widgetStack->insertPage( stackPage, index ); + widgetStack->raiseWidget( stackPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( stackPage ); +} + +// ------------------------------------------------------------ + +AddWizardPageCommand::AddWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, const QString &label, int i, bool s ) + : Command( n, fw ), wizard( w ), pageLabel( label ) +{ + page = new QDesignerWidget( formWindow(), wizard, "WizardPage" ); + page->hide(); + index = i; + show = s; + MetaDataBase::addEntry( page ); +} + +void AddWizardPageCommand::execute() +{ + if ( index == -1 ) + index = wizard->pageCount(); + wizard->insertPage( page, pageLabel, index ); + if ( show ) + ( (QDesignerWizard*)wizard )->setCurrentPage( ( (QDesignerWizard*)wizard )->pageNum( page ) ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void AddWizardPageCommand::unexecute() +{ + wizard->removePage( page ); + page->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +// ------------------------------------------------------------ + +DeleteWizardPageCommand::DeleteWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int i, bool s ) + : Command( n, fw ), wizard( w ), index( i ) +{ + show = s; +} + +void DeleteWizardPageCommand::execute() +{ + page = wizard->page( index ); + pageLabel = wizard->title( page ); + wizard->removePage( page ); + page->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void DeleteWizardPageCommand::unexecute() +{ + wizard->insertPage( page, pageLabel, index ); + if ( show ) + ( (QDesignerWizard*)wizard )->setCurrentPage( ( (QDesignerWizard*)wizard )->pageNum( page ) ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +// ------------------------------------------------------------ + +RenameWizardPageCommand::RenameWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int i, const QString& name ) + : Command( n, fw ), wizard( w ), index( i ), label( name ) +{ + +} + +void RenameWizardPageCommand::execute() +{ + page = wizard->page( index ); + QString oldLabel = wizard->title( page ); + + wizard->setTitle( page, label ); + label = oldLabel; + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); +} + +void RenameWizardPageCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +SwapWizardPagesCommand::SwapWizardPagesCommand( const QString &n, FormWindow *fw, QWizard *w, int i1, int i2 ) + : Command( n, fw ), wizard( w ), index1( i1 ), index2( i2 ) +{ +} + +void SwapWizardPagesCommand::execute() +{ + QWidget *page1 = wizard->page( index1 ); + QWidget *page2 = wizard->page( index2 ); + QString page1Label = wizard->title( page1 ); + QString page2Label = wizard->title( page2 ); + wizard->removePage( page1 ); + wizard->removePage( page2 ); + wizard->insertPage( page1, page1Label, index2 ); + wizard->insertPage( page2, page2Label, index1 ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void SwapWizardPagesCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +MoveWizardPageCommand::MoveWizardPageCommand( const QString &n, FormWindow *fw, QWizard *w, int i1, int i2 ) + : Command( n, fw ), wizard( w ), index1( i1 ), index2( i2 ) +{ +} + +void MoveWizardPageCommand::execute() +{ + QWidget *page = wizard->page( index1 ); + QString pageLabel = wizard->title( page ); + wizard->removePage( page ); + wizard->insertPage( page, pageLabel, index2 ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void MoveWizardPageCommand::unexecute() +{ + // ###FIX: index1 may be the wrong place + QWidget *page = wizard->page( index2 ); + QString pageLabel = wizard->title( page ); + wizard->removePage( page ); + wizard->insertPage( page, pageLabel, index1 ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +// ------------------------------------------------------------ + +AddConnectionCommand::AddConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ) + : Command( name, fw ), connection( c ) +{ +} + +void AddConnectionCommand::execute() +{ + MetaDataBase::addConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +void AddConnectionCommand::unexecute() +{ + MetaDataBase::removeConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +// ------------------------------------------------------------ + +RemoveConnectionCommand::RemoveConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ) + : Command( name, fw ), connection( c ) +{ +} + +void RemoveConnectionCommand::execute() +{ + MetaDataBase::removeConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +void RemoveConnectionCommand::unexecute() +{ + MetaDataBase::addConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +// ------------------------------------------------------------ + +AddFunctionCommand::AddFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, + const QString& spec, const QString &a, const QString &t, + const QString &l, const QString &rt ) + : Command( name, fw ), function( f ), specifier( spec ), access( a ), functionType( t ), language( l ), + returnType( rt ) +{ +} + +void AddFunctionCommand::execute() +{ + MetaDataBase::addFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + + //integration (add - execute) + KInterfaceDesigner::Function f; + f.returnType = returnType; + f.function = function; + f.specifier = specifier; + f.access = access; + f.type = (functionType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + formWindow()->clearSelection(false); + formWindow()->mainWindow()->part()->emitAddedFunction(formWindow()->fileName(), f); + + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void AddFunctionCommand::unexecute() +{ + MetaDataBase::removeFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + + //integration (add - unexecute) + KInterfaceDesigner::Function f; + f.returnType = returnType; + f.function = function; + f.specifier = specifier; + f.access = access; + f.type = (functionType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + formWindow()->mainWindow()->part()->emitRemovedFunction(formWindow()->fileName(), f); + + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +ChangeFunctionAttribCommand::ChangeFunctionAttribCommand( const QString &name, FormWindow *fw, MetaDataBase::Function f, + const QString &on, const QString &os, + const QString &oa, const QString &ot, const QString &ol, + const QString &ort ) + : Command( name, fw ), oldName( on ), oldSpec( os ), oldAccess( oa ), + oldType( ot ), oldLang( ol ), oldReturnType( ort ) +{ + newName = f.function; + newSpec = f.specifier; + newAccess = f.access; + newType = f.type; + newLang = f.language; + newReturnType = f.returnType; +} + +void ChangeFunctionAttribCommand::execute() +{ + MetaDataBase::changeFunctionAttributes( formWindow(), oldName, newName, newSpec, newAccess, + newType, newLang, newReturnType ); + formWindow()->formFile()->functionNameChanged( oldName, newName ); + formWindow()->formFile()->functionRetTypeChanged( newName, oldReturnType, newReturnType ); + formWindow()->mainWindow()->functionsChanged(); + + //integration (edit - execute) + KInterfaceDesigner::Function f; + f.returnType = newReturnType; + f.function = newName; + f.specifier = newSpec; + f.access = newAccess; + f.type = (newType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + KInterfaceDesigner::Function of; + f.returnType = oldReturnType; + f.function = oldName; + f.specifier = oldSpec; + f.access = oldAccess; + f.type = (oldType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + formWindow()->mainWindow()->part()->emitEditedFunction(formWindow()->fileName(), of, f); + + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void ChangeFunctionAttribCommand::unexecute() +{ + MetaDataBase::changeFunctionAttributes( formWindow(), newName, oldName, oldSpec, oldAccess, + oldType, oldLang, oldReturnType ); + formWindow()->formFile()->functionNameChanged( newName, oldName ); + formWindow()->formFile()->functionRetTypeChanged( oldName, newReturnType, oldReturnType ); + formWindow()->mainWindow()->functionsChanged(); + + //integration (edit - execute) + KInterfaceDesigner::Function f; + f.returnType = newReturnType; + f.function = newName; + f.specifier = newSpec; + f.access = newAccess; + f.type = (newType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + KInterfaceDesigner::Function of; + f.returnType = oldReturnType; + f.function = oldName; + f.specifier = oldSpec; + f.access = oldAccess; + f.type = (oldType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + formWindow()->mainWindow()->part()->emitEditedFunction(formWindow()->fileName(), f, of); + + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +RemoveFunctionCommand::RemoveFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, + const QString& spec, const QString &a, const QString &t, + const QString &l, const QString &rt ) + : Command( name, fw ), function( f ), specifier( spec ), access( a ), functionType( t ), language( l ), + returnType( rt ) +{ + if ( spec.isNull() ) { + QValueList<MetaDataBase::Function> lst = MetaDataBase::functionList( fw ); + for ( QValueList<MetaDataBase::Function>::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).function ) == + MetaDataBase::normalizeFunction( function ) ) { + specifier = (*it).specifier; + access = (*it).access; + functionType = (*it).type; + returnType = (*it).returnType; + language = (*it).language; + break; + } + } + } +} + +void RemoveFunctionCommand::execute() +{ + MetaDataBase::removeFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + + //integration (remove - execute) + KInterfaceDesigner::Function f; + f.returnType = returnType; + f.function = function; + f.specifier = specifier; + f.access = access; + f.type = (functionType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + formWindow()->mainWindow()->part()->emitRemovedFunction(formWindow()->fileName(), f); + + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void RemoveFunctionCommand::unexecute() +{ + if ( MetaDataBase::hasFunction( formWindow(), function ) ) + return; + MetaDataBase::addFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + + //integration (remove - unexecute) + KInterfaceDesigner::Function f; + f.returnType = returnType; + f.function = function; + f.specifier = specifier; + f.access = access; + f.type = (functionType == "slot") ? KInterfaceDesigner::ftQtSlot : KInterfaceDesigner::ftFunction ; + formWindow()->clearSelection(false); + formWindow()->mainWindow()->part()->emitAddedFunction(formWindow()->fileName(), f); + + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +AddVariableCommand::AddVariableCommand( const QString &name, FormWindow *fw, const QString &vn, const QString &a ) + : Command( name, fw ), varName( vn ), access( a ) +{ +} + +void AddVariableCommand::execute() +{ + MetaDataBase::addVariable( formWindow(), varName, access ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void AddVariableCommand::unexecute() +{ + MetaDataBase::removeVariable( formWindow(), varName ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +SetVariablesCommand::SetVariablesCommand( const QString &name, FormWindow *fw, + QValueList<MetaDataBase::Variable> lst ) + : Command( name, fw ), newList( lst ) +{ + oldList = MetaDataBase::variables( formWindow() ); +} + +void SetVariablesCommand::execute() +{ + MetaDataBase::setVariables( formWindow(), newList ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void SetVariablesCommand::unexecute() +{ + MetaDataBase::setVariables( formWindow(), oldList ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +RemoveVariableCommand::RemoveVariableCommand( const QString &name, FormWindow *fw, const QString &vn ) + : Command( name, fw ), varName( vn ) +{ + QValueList<MetaDataBase::Variable> lst = MetaDataBase::variables( fw ); + for ( QValueList<MetaDataBase::Variable>::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( (*it).varName == varName ) { + access = (*it).varAccess; + break; + } + } +} + +void RemoveVariableCommand::execute() +{ + MetaDataBase::removeVariable( formWindow(), varName ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void RemoveVariableCommand::unexecute() +{ + MetaDataBase::addVariable( formWindow(), varName, access ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +EditDefinitionsCommand::EditDefinitionsCommand( const QString &name, FormWindow *fw, LanguageInterface *lf, + const QString &n, const QStringList &nl ) + : Command( name, fw ), lIface( lf ), defName( n ), newList( nl ) +{ + oldList = lIface->definitionEntries( defName, formWindow()->mainWindow()->designerInterface() ); +} + +void EditDefinitionsCommand::execute() +{ + lIface->setDefinitionEntries( defName, newList, formWindow()->mainWindow()->designerInterface() ); + lIface->release(); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void EditDefinitionsCommand::unexecute() +{ + lIface->setDefinitionEntries( defName, oldList, formWindow()->mainWindow()->designerInterface() ); + lIface->release(); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +LowerCommand::LowerCommand( const QString &name, FormWindow *fw, const QWidgetList &w ) + : Command( name, fw ), widgets( w ) +{ +} + +void LowerCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->lower(); + formWindow()->raiseSelection( w ); + } + +} + +void LowerCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->raise(); + formWindow()->raiseSelection( w ); + } +} + +// ------------------------------------------------------------ + +RaiseCommand::RaiseCommand( const QString &name, FormWindow *fw, const QWidgetList &w ) + : Command( name, fw ), widgets( w ) +{ +} + +void RaiseCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->raise(); + formWindow()->raiseSelection( w ); + } + +} + +void RaiseCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->lower(); + formWindow()->raiseSelection( w ); + } +} + +// ------------------------------------------------------------ + +PasteCommand::PasteCommand( const QString &n, FormWindow *fw, + const QWidgetList &w ) + : Command( n, fw ), widgets( w ) +{ +} + +void PasteCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->show(); + formWindow()->selectWidget( w ); + formWindow()->widgets()->insert( w, w ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( w ); + } +} + +void PasteCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->hide(); + formWindow()->selectWidget( w, FALSE ); + formWindow()->widgets()->remove( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( w ); + } + } + +// ------------------------------------------------------------ + +TabOrderCommand::TabOrderCommand( const QString &n, FormWindow *fw, + const QWidgetList &ol, const QWidgetList &nl ) + : Command( n, fw ), oldOrder( ol ), newOrder( nl ) +{ +} + +void TabOrderCommand::merge( Command *c ) +{ + TabOrderCommand *cmd = (TabOrderCommand*)c; + newOrder = cmd->newOrder; +} + +bool TabOrderCommand::canMerge( Command * ) +{ + return TRUE; +} + +void TabOrderCommand::execute() +{ + MetaDataBase::setTabOrder( formWindow(), newOrder ); +} + +void TabOrderCommand::unexecute() +{ + MetaDataBase::setTabOrder( formWindow(), oldOrder ); +} + +// ------------------------------------------------------------ + +PopulateListBoxCommand::PopulateListBoxCommand( const QString &n, FormWindow *fw, + QListBox *lb, const QValueList<Item> &items ) + : Command( n, fw ), newItems( items ), listbox( lb ) +{ + QListBoxItem *i = 0; + for ( i = listbox->firstItem(); i; i = i->next() ) { + Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + oldItems.append( item ); + } +} + +void PopulateListBoxCommand::execute() +{ + listbox->clear(); + for ( QValueList<Item>::Iterator it = newItems.begin(); it != newItems.end(); ++it ) { + Item i = *it; + if ( !i.pix.isNull() ) + (void)new QListBoxPixmap( listbox, i.pix, i.text ); + else + (void)new QListBoxText( listbox, i.text ); + } + formWindow()->mainWindow()->propertyeditor()->refetchData(); +} + +void PopulateListBoxCommand::unexecute() +{ + listbox->clear(); + for ( QValueList<Item>::Iterator it = oldItems.begin(); it != oldItems.end(); ++it ) { + Item i = *it; + if ( !i.pix.isNull() ) + (void)new QListBoxPixmap( listbox, i.pix, i.text ); + else + (void)new QListBoxText( listbox, i.text ); + } + formWindow()->mainWindow()->propertyeditor()->refetchData(); +} + +// ------------------------------------------------------------ + +PopulateIconViewCommand::PopulateIconViewCommand( const QString &n, FormWindow *fw, + QIconView *iv, const QValueList<Item> &items ) + : Command( n, fw ), newItems( items ), iconview( iv ) +{ +#ifndef QT_NO_ICONVIEW + QIconViewItem *i = 0; + for ( i = iconview->firstItem(); i; i = i->nextItem() ) { + Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + oldItems.append( item ); + } +#endif +} + +void PopulateIconViewCommand::execute() +{ +#ifndef QT_NO_ICONVIEW + iconview->clear(); + for ( QValueList<Item>::Iterator it = newItems.begin(); it != newItems.end(); ++it ) { + Item i = *it; + (void)new QIconViewItem( iconview, i.text, i.pix ); + } +#endif +} + +void PopulateIconViewCommand::unexecute() +{ +#ifndef QT_NO_ICONVIEW + iconview->clear(); + for ( QValueList<Item>::Iterator it = oldItems.begin(); it != oldItems.end(); ++it ) { + Item i = *it; + (void)new QIconViewItem( iconview, i.text, i.pix ); + } +#endif +} + +// ------------------------------------------------------------ + +PopulateListViewCommand::PopulateListViewCommand( const QString &n, FormWindow *fw, + QListView *lv, QListView *from ) + : Command( n, fw ), listview( lv ) +{ + newItems = new QListView(); + newItems->hide(); + transferItems( from, newItems ); + oldItems = new QListView(); + oldItems->hide(); + transferItems( listview, oldItems ); +} + +void PopulateListViewCommand::execute() +{ + listview->clear(); + transferItems( newItems, listview ); +} + +void PopulateListViewCommand::unexecute() +{ + listview->clear(); + transferItems( oldItems, listview ); +} + +void PopulateListViewCommand::transferItems( QListView *from, QListView *to ) +{ + QHeader *header = to->header(); + while ( header->count() ) + to->removeColumn( 0 ); + QHeader *h2 = from->header(); + for ( int i = 0; i < h2->count(); ++i ) { + to->addColumn( h2->label( i ) ); + if ( h2->iconSet( i ) && !h2->iconSet( i )->pixmap().isNull() ) + header->setLabel( i, *h2->iconSet( i ), h2->label( i ) ); + header->setResizeEnabled( h2->isResizeEnabled( i ), i ); + header->setClickEnabled( h2->isClickEnabled( i ), i ); + } + + QListViewItemIterator it( from ); + QPtrStack<QListViewItem> fromParents, toParents; + fromParents.push( 0 ); + toParents.push( 0 ); + QPtrStack<QListViewItem> toLasts; + QListViewItem *fromLast = 0; + toLasts.push( 0 ); + int cols = from->columns(); + to->setSorting( -1 ); + from->setSorting( -1 ); + for ( ; it.current(); ++it ) { + QListViewItem *i = it.current(); + if ( i->parent() == fromParents.top() ) { + QListViewItem *pi = toParents.top(); + QListViewItem *ni = 0; + if ( pi ) + ni = new QListViewItem( pi, toLasts.top() ); + else + ni = new QListViewItem( to, toLasts.top() ); + for ( int c = 0; c < cols; ++c ) { + ni->setText( c, i->text( c ) ); + if ( i->pixmap( c ) ) + ni->setPixmap( c, *i->pixmap( c ) ); + } + toLasts.pop(); + toLasts.push( ni ); + if ( pi ) + pi->setOpen( TRUE ); + } else { + if ( i->parent() == fromLast ) { + fromParents.push( fromLast ); + toParents.push( toLasts.top() ); + toLasts.push( 0 ); + QListViewItem *pi = toParents.top(); + QListViewItem *ni = 0; + if ( pi ) + ni = new QListViewItem( pi ); + else + ni = new QListViewItem( to ); + for ( int c = 0; c < cols; ++c ) { + ni->setText( c, i->text( c ) ); + if ( i->pixmap( c ) ) + ni->setPixmap( c, *i->pixmap( c ) ); + } + toLasts.pop(); + toLasts.push( ni ); + if ( pi ) + pi->setOpen( TRUE ); + } else { + while ( fromParents.top() != i->parent() ) { + fromParents.pop(); + toParents.pop(); + toLasts.pop(); + } + + QListViewItem *pi = toParents.top(); + QListViewItem *ni = 0; + if ( pi ) + ni = new QListViewItem( pi, toLasts.top() ); + else + ni = new QListViewItem( to, toLasts.top() ); + for ( int c = 0; c < cols; ++c ) { + ni->setText( c, i->text( c ) ); + if ( i->pixmap( c ) ) + ni->setPixmap( c, *i->pixmap( c ) ); + } + if ( pi ) + pi->setOpen( TRUE ); + toLasts.pop(); + toLasts.push( ni ); + } + } + fromLast = i; + } +} + + + +// ------------------------------------------------------------ + +PopulateMultiLineEditCommand::PopulateMultiLineEditCommand( const QString &n, FormWindow *fw, + QTextEdit *mle, const QString &txt ) + : Command( n, fw ), newText( txt ), mlined( mle ) +{ + oldText = mlined->text(); + wasChanged = MetaDataBase::isPropertyChanged( mlined, "text" ); +} + +void PopulateMultiLineEditCommand::execute() +{ + mlined->setText( newText ); + MetaDataBase::setPropertyChanged( mlined, "text", TRUE ); + formWindow()->emitUpdateProperties( mlined ); +} + +void PopulateMultiLineEditCommand::unexecute() +{ + mlined->setText( oldText ); + MetaDataBase::setPropertyChanged( mlined, "text", wasChanged ); + formWindow()->emitUpdateProperties( mlined ); +} + +// ------------------------------------------------------------ + +PopulateTableCommand::PopulateTableCommand( const QString &n, FormWindow *fw, QTable *t, + const QValueList<Row> &rows, + const QValueList<Column> &columns ) + : Command( n, fw ), newRows( rows ), newColumns( columns ), table( t ) +{ +#ifndef QT_NO_TABLE + int i = 0; + QMap<QString, QString> columnFields = MetaDataBase::columnFields( table ); + for ( i = 0; i < table->horizontalHeader()->count(); ++i ) { + PopulateTableCommand::Column col; + col.text = table->horizontalHeader()->label( i ); + if ( table->horizontalHeader()->iconSet( i ) ) + col.pix = table->horizontalHeader()->iconSet( i )->pixmap(); + col.field = *columnFields.find( col.text ); + oldColumns.append( col ); + } + for ( i = 0; i < table->verticalHeader()->count(); ++i ) { + PopulateTableCommand::Row row; + row.text = table->verticalHeader()->label( i ); + if ( table->verticalHeader()->iconSet( i ) ) + row.pix = table->verticalHeader()->iconSet( i )->pixmap(); + oldRows.append( row ); + } +#endif +} + +void PopulateTableCommand::execute() +{ +#ifndef QT_NO_TABLE + QMap<QString, QString> columnFields; + table->setNumCols( newColumns.count() ); + int i = 0; + for ( QValueList<Column>::Iterator cit = newColumns.begin(); cit != newColumns.end(); ++cit, ++i ) { + table->horizontalHeader()->setLabel( i, (*cit).pix, (*cit).text ); + if ( !(*cit).field.isEmpty() ) + columnFields.insert( (*cit).text, (*cit).field ); + } + MetaDataBase::setColumnFields( table, columnFields ); + table->setNumRows( newRows.count() ); + i = 0; + for ( QValueList<Row>::Iterator rit = newRows.begin(); rit != newRows.end(); ++rit, ++i ) + table->verticalHeader()->setLabel( i, (*rit).pix, (*rit).text ); +#endif +} + +void PopulateTableCommand::unexecute() +{ +#ifndef QT_NO_TABLE + QMap<QString, QString> columnFields; + table->setNumCols( oldColumns.count() ); + int i = 0; + for ( QValueList<Column>::Iterator cit = oldColumns.begin(); cit != oldColumns.end(); ++cit, ++i ) { + table->horizontalHeader()->setLabel( i, (*cit).pix, (*cit).text ); + if ( !(*cit).field.isEmpty() ) + columnFields.insert( (*cit).text, (*cit).field ); + } + MetaDataBase::setColumnFields( table, columnFields ); + table->setNumRows( oldRows.count() ); + i = 0; + for ( QValueList<Row>::Iterator rit = oldRows.begin(); rit != oldRows.end(); ++rit, ++i ) + table->verticalHeader()->setLabel( i, (*rit).pix, (*rit).text ); +#endif +} + +// ------------------------------------------------------------ + +AddActionToToolBarCommand::AddActionToToolBarCommand( const QString &n, FormWindow *fw, + QAction *a, QDesignerToolBar *tb, int idx ) + : Command( n, fw ), action( a ), toolBar( tb ), index( idx ) +{ +} + +void AddActionToToolBarCommand::execute() +{ + action->addTo( toolBar ); + + if ( ::qt_cast<QDesignerAction*>(action) ) { + QString s = ( (QDesignerAction*)action )->widget()->name(); + if ( s.startsWith( "qt_dead_widget_" ) ) { + s.remove( 0, QString( "qt_dead_widget_" ).length() ); + ( (QDesignerAction*)action )->widget()->setName( s ); + } + toolBar->insertAction( ( (QDesignerAction*)action )->widget(), action ); + ( (QDesignerAction*)action )->widget()->installEventFilter( toolBar ); + } else if ( ::qt_cast<QDesignerActionGroup*>(action) ) { + if ( ( (QDesignerActionGroup*)action )->usesDropDown() ) { + toolBar->insertAction( ( (QDesignerActionGroup*)action )->widget(), action ); + ( (QDesignerActionGroup*)action )->widget()->installEventFilter( toolBar ); + } + } else if ( ::qt_cast<QSeparatorAction*>(action) ) { + toolBar->insertAction( ( (QSeparatorAction*)action )->widget(), action ); + ( (QSeparatorAction*)action )->widget()->installEventFilter( toolBar ); + } + if ( !::qt_cast<QActionGroup*>(action) || ( (QActionGroup*)action )->usesDropDown()) { + if ( index == -1 ) + toolBar->appendAction( action ); + else + toolBar->insertAction( index, action ); + toolBar->reInsert(); + QObject::connect( action, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } else { + if ( action->children() ) { + QObjectListIt it( *action->children() ); + int i = 0; + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast<QAction*>(o) ) + continue; + // ### fix it for nested actiongroups + if ( ::qt_cast<QDesignerAction*>(o) ) { + QDesignerAction *ac = (QDesignerAction*)o; + toolBar->insertAction( ac->widget(), ac ); + ac->widget()->installEventFilter( toolBar ); + if ( index == -1 ) + toolBar->appendAction( ac ); + else + toolBar->insertAction( index + (i++), ac ); + } + QObject::connect( o, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } + } + toolBar->reInsert(); + QObject::connect( action, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddActionToToolBarCommand::unexecute() +{ + if ( ::qt_cast<QDesignerAction*>(action) ) { + QString s = ( (QDesignerAction*)action )->widget()->name(); + s.prepend( "qt_dead_widget_" ); + ( (QDesignerAction*)action )->widget()->setName( s ); + } + + toolBar->removeAction( action ); + action->removeFrom( toolBar ); + QObject::disconnect( action, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + if ( !::qt_cast<QActionGroup*>(action) || ( (QActionGroup*)action )->usesDropDown()) { + action->removeEventFilter( toolBar ); + } else { + if ( action->children() ) { + QObjectListIt it( *action->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast<QAction*>(o) ) + continue; + if ( ::qt_cast<QDesignerAction*>(o) ) { + o->removeEventFilter( toolBar ); + toolBar->removeAction( (QAction*)o ); + } + QObject::disconnect( o, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } + } + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +AddToolBarCommand::AddToolBarCommand( const QString &n, FormWindow *fw, QMainWindow *mw ) + : Command( n, fw ), toolBar( 0 ), mainWindow( mw ) +{ +} + +void AddToolBarCommand::execute() +{ + if ( !toolBar ) { + toolBar = new QDesignerToolBar( mainWindow ); + QString n = "Toolbar"; + formWindow()->unify( toolBar, n, TRUE ); + toolBar->setName( n ); + mainWindow->addToolBar( toolBar, n ); + } else { + toolBar->show(); + QString s = toolBar->name(); + s.remove( 0, QString( "qt_dead_widget_" ).length() ); + toolBar->setName( s ); + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddToolBarCommand::unexecute() +{ + toolBar->hide(); + QString s = toolBar->name(); + s.prepend( "qt_dead_widget_" ); + toolBar->setName( s ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +#ifdef QT_CONTAINER_CUSTOM_WIDGETS +AddContainerPageCommand::AddContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, const QString &label ) + : Command( n, fw ), container( c ), index( -1 ), pageLabel( label ), page( 0 ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( container ), &iface ); + if ( !iface ) + return; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&wiface ); + if ( !wiface ) + return; + wClassName = WidgetFactory::classNameOf( container ); +} + +AddContainerPageCommand::~AddContainerPageCommand() +{ + if ( wiface ) + wiface->release(); +} + +void AddContainerPageCommand::execute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + if ( index == -1 ) + index = wiface->count( wClassName, container ); + if ( !page ) + page = wiface->addPage( wClassName, container, pageLabel, index ); + else + wiface->insertPage( wClassName, container, pageLabel, index, page ); + + MetaDataBase::addEntry( page ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +void AddContainerPageCommand::unexecute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + wiface->removePage( wClassName, container, index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +// ------------------------------------------------------------ + +DeleteContainerPageCommand::DeleteContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, int idx ) + : Command( n, fw ), container( c ), index( idx ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( container ), &iface ); + if ( !iface ) + return; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&wiface ); + if ( !wiface ) + return; + wClassName = WidgetFactory::classNameOf( container ); + page = wiface->page( wClassName, container, index ); + pageLabel = wiface->pageLabel( wClassName, container, index ); +} + +DeleteContainerPageCommand::~DeleteContainerPageCommand() +{ + if ( wiface ) + wiface->release(); +} + +void DeleteContainerPageCommand::execute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + + wiface->removePage( wClassName, container, index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +void DeleteContainerPageCommand::unexecute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + if ( index == -1 ) + index = wiface->count( wClassName, container ); + + wiface->insertPage( wClassName, container, pageLabel, index, page ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +// ------------------------------------------------------------ + +RenameContainerPageCommand::RenameContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, int idx, + const QString &label ) + : Command( n, fw ), container( c ), index( idx ), newLabel( label ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( container ), &iface ); + if ( !iface ) + return; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&wiface ); + if ( !wiface ) + return; + wClassName = WidgetFactory::classNameOf( container ); + oldLabel = wiface->pageLabel( wClassName, container, index ); +} + +RenameContainerPageCommand::~RenameContainerPageCommand() +{ + if ( wiface ) + wiface->release(); +} + +void RenameContainerPageCommand::execute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + wiface->renamePage( wClassName, container, index, newLabel ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +void RenameContainerPageCommand::unexecute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + wiface->renamePage( wClassName, container, index, oldLabel ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} +#endif // QT_CONTAINER_CUSTOM_WIDGETS +// ------------------------------------------------------------ + +AddActionToPopupCommand::AddActionToPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + PopupMenuEditorItem *i, + int idx ) + : Command( n, fw ), menu( m ), item( i ), index( idx ) +{ } + +void AddActionToPopupCommand::execute() +{ + menu->insert( item, index ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddActionToPopupCommand::unexecute() +{ + item->hideMenu(); + int i = menu->find( item->action() ); + menu->remove( i ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +RemoveActionFromPopupCommand::RemoveActionFromPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int idx ) + : AddActionToPopupCommand( n, fw, m, 0, idx ) +{ + item = menu->at( index ); +} + +void RemoveActionFromPopupCommand::execute() +{ + AddActionToPopupCommand::unexecute(); +} + +void RemoveActionFromPopupCommand::unexecute() +{ + AddActionToPopupCommand::execute(); +} + +// ------------------------------------------------------------ + +ExchangeActionInPopupCommand::ExchangeActionInPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int a, + int b ) + : Command( n, fw ), menu( m ), c( a ), d( b ) +{ } + +void ExchangeActionInPopupCommand::execute() +{ + menu->exchange( c, d ); +} + +void ExchangeActionInPopupCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +ActionEditor *ActionCommand::actionEditor() +{ + // FIXME: handle multiple action editors + return (ActionEditor *) formWindow()->mainWindow()->child( 0, "ActionEditor" ); +} + +// ------------------------------------------------------------ + +RenameActionCommand::RenameActionCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QString nm ) + : ActionCommand( n, fw, a ), menu( m ), newName( nm ) +{ + oldName = action->menuText(); +} + +void RenameActionCommand::execute() +{ + QString actionText = newName; + actionText.replace("&&", "&"); + QString menuText = newName; + action->setText( actionText ); + action->setMenuText( menuText ); + + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void RenameActionCommand::unexecute() +{ + action->setMenuText( oldName ); + action->setText( oldName ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +SetActionIconsCommand::SetActionIconsCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QIconSet &icons ) + : ActionCommand( n, fw, a ), menu( m ), newIcons( icons ) +{ + oldIcons = a->iconSet(); +} + +void SetActionIconsCommand::execute() +{ + action->setIconSet( newIcons ); + ActionEditor *ae = actionEditor(); + if ( ae ) + ae->updateActionIcon( action ); + MetaDataBase::setPropertyChanged( action, "iconSet", TRUE ); +} + +void SetActionIconsCommand::unexecute() +{ + action->setIconSet( oldIcons ); + ActionEditor *ae = actionEditor(); + if ( ae ) + ae->updateActionIcon( action ); + MetaDataBase::setPropertyChanged( action, "iconSet", TRUE ); +} + +// ------------------------------------------------------------ + +AddMenuCommand::AddMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + MenuBarEditorItem *i, + int idx ) + : Command( n, fw ), mb( b ), item( i ), name( 0 ), index( idx ) +{ } + +AddMenuCommand::AddMenuCommand( const QString &n, + FormWindow *fw, + QMainWindow *mw, + const QString &nm ) + : Command( n, fw ), mb( 0 ), item( 0 ), name( nm ), index( -1 ) +{ + if ( mw ) + mb = (MenuBarEditor *)mw->child( 0, "MenuBarEditor" ); +} + +void AddMenuCommand::execute() +{ + QString n; + QMainWindow *mw = (QMainWindow*)formWindow()->mainContainer(); + if ( !mb ) { + mb = new MenuBarEditor( formWindow(), mw ); + mb->setName( "MenuBarEditor" ); + formWindow()->insertWidget( mb, TRUE ); + } + if ( !item ) { + PopupMenuEditor *popup = new PopupMenuEditor( formWindow(), mw ); + popup->setName( "PopupMenuEditor" ); + formWindow()->insertWidget( popup, TRUE ); + mb->insertItem( name, popup, index ); + index = mb->findItem( popup ); + item = mb->item( index ); + } else { + PopupMenuEditor *popup = item->menu(); + popup->setName( item->menuText() ); + formWindow()->insertWidget( popup, TRUE ); + mb->insertItem( item, index ); + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddMenuCommand::unexecute() +{ + if ( !item ) { + qWarning( "The AddMenuCommand was created without a menu item." ); + return; + } + item->menu()->hide(); + int i = mb->findItem( item ); + formWindow()->removeWidget( item->menu() ); + mb->removeItemAt( i ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +RemoveMenuCommand::RemoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int idx ) + : AddMenuCommand( n, fw, b, 0, idx ) +{ + item = mb->item( index ); +} + +void RemoveMenuCommand::execute() +{ + mb->hideItem( index ); + AddMenuCommand::unexecute(); +} + +void RemoveMenuCommand::unexecute() +{ + AddMenuCommand::execute(); +} + +// ------------------------------------------------------------ + +ExchangeMenuCommand::ExchangeMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ) + : Command( n, fw ), bar( b ), k( i ), l( j ) +{ } + +void ExchangeMenuCommand::execute() +{ + bar->exchange( k, l ); +} + +void ExchangeMenuCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +MoveMenuCommand::MoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ) + : Command( n, fw ), bar( b ), from( i ), to( j ) +{ } + +void MoveMenuCommand::execute() +{ + bar->hideItem( from ); + MenuBarEditorItem * i = bar->item( from ); + bar->removeItemAt( from ); + int t = ( from > to ? to : to - 1 ); + bar->insertItem( i, t ); +} + +void MoveMenuCommand::unexecute() +{ + bar->hideItem( to ); + int t = ( from > to ? to : to - 1 ); + MenuBarEditorItem * i = bar->item( t ); + bar->removeItemAt( t ); + bar->insertItem( i, from ); +} + +// ------------------------------------------------------------ + +RenameMenuCommand::RenameMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + QString nm, + MenuBarEditorItem *i ) + : Command( n, fw ), bar( b ), item( i ), newName( nm ) +{ + oldName = item->menu()->name(); +} + +QString RenameMenuCommand::makeLegal( const QString &str ) +{ + // remove illegal characters + QString d; + char c = 0, i = 0; + while ( !str.at(i).isNull() ) { + c = str.at(i).latin1(); + if ( c == '-' || c == ' ' ) + d += '_'; + else if ( ( c >= '0' && c <= '9') || ( c >= 'A' && c <= 'Z' ) + || c == '_' || ( c >= 'a' && c <= 'z' ) ) + d += c; + ++i; + } + return d; +} + +void RenameMenuCommand::execute() +{ + PopupMenuEditor *popup = item->menu(); + item->setMenuText( newName ); + QString legal = makeLegal( newName ); + formWindow()->unify( popup, legal, TRUE ); + popup->setName( legal ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void RenameMenuCommand::unexecute() +{ + PopupMenuEditor *popup = item->menu(); + item->setMenuText( oldName ); + popup->setName( oldName ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +AddToolBoxPageCommand::AddToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, const QString &label ) + : Command( n, fw ), toolBox( tw ), toolBoxLabel( label ) +{ + toolBoxPage = new QDesignerWidget( formWindow(), toolBox, "page" ); + toolBoxPage->hide(); + index = -1; + MetaDataBase::addEntry( toolBoxPage ); +} + +void AddToolBoxPageCommand::execute() +{ + index = toolBox->insertItem( index, toolBoxPage, toolBoxLabel); + toolBox->setCurrentIndex( index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddToolBoxPageCommand::unexecute() +{ + toolBox->removeItem( toolBoxPage ); + toolBoxPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +DeleteToolBoxPageCommand::DeleteToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, QWidget *page ) + : Command( n, fw ), toolBox( tw ), toolBoxPage( page ) +{ + toolBoxLabel = toolBox->itemLabel( toolBox->currentIndex() ); + index = toolBox->currentIndex(); +} + +void DeleteToolBoxPageCommand::execute() +{ + toolBox->removeItem( toolBoxPage ); + toolBoxPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void DeleteToolBoxPageCommand::unexecute() +{ + index = toolBox->insertItem( index, toolBoxPage, toolBoxLabel ); + toolBox->setCurrentIndex( index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} diff --git a/kdevdesigner/designer/command.h b/kdevdesigner/designer/command.h new file mode 100644 index 00000000..ac5e9d5a --- /dev/null +++ b/kdevdesigner/designer/command.h @@ -0,0 +1,1259 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef COMMAND_H +#define COMMAND_H + +#include "metadatabase.h" +#include "layout.h" + +#include <qstring.h> +#include <qrect.h> +#include <qvaluelist.h> +#include <qvariant.h> +#include <qobject.h> +#include <qlistview.h> +#include <qptrlist.h> +#include <qmap.h> +#include <qiconset.h> + +class QWizard; +class QTabWidget; +class Command; +class QWidget; +class FormWindow; +class PropertyEditor; +class QListBox; +class QIconView; +class QTable; +class QAction; +class QDesignerToolBar; +class QMainWindow; +class QTextEdit; +struct LanguageInterface; +class QToolBox; + +class MenuBarEditor; +class MenuBarEditorItem; +class PopupMenuEditor; +class PopupMenuEditorItem; +class ActionEditor; + +class Command : public Qt +{ +public: + Command( const QString &n, FormWindow *fw ); + virtual ~Command(); + + enum Type { + Resize, + Insert, + Move, + Delete, + SetProperty, + LayoutHorizontal, + LayoutVertical, + LayoutHorizontalSplitter, + LayoutVerticalSplitter, + LayoutGrid, + BreakLayout, + Macro, + AddTabPage, + DeleteTabPage, + MoveTabPage, + AddWidgetStackPage, + DeleteWidgetStackPage, + AddWizardPage, + DeleteWizardPage, + SwapWizardPages, + MoveWizardPage, + RenameWizardPage, + AddConnection, + RemoveConnection, + Lower, + Raise, + Paste, + TabOrder, + PopulateListBox, + PopulateIconView, + PopulateListView, + PopulateMultiLineEdit, + PopulateTable, + AddActionToToolBar, + RemoveActionFromToolBar, + AddToolBar, + RemoveToolBar, + AddFunction, + ChangeFunctionAttrib, + RemoveFunction, + AddVariable, + SetVariables, + RemoveVariable, + EditDefinitions, + AddContainerPage, + DeleteContainerPage, + RenameContainerPage, + AddActionToPopup, + RemoveActionFromPopup, + ExchangeActionInPopup, + //MoveActionInPopup, + RenameAction, + SetActionIcons, + AddMenu, + RemoveMenu, + ExchangeMenu, + MoveMenu, + RenameMenu, + AddToolBoxPage, + DeleteToolBoxPage + }; + + QString name() const; + + virtual void execute() = 0; + virtual void unexecute() = 0; + virtual Type type() const = 0; + virtual void merge( Command *c ); + virtual bool canMerge( Command *c ); + + FormWindow *formWindow() const; + +private: + QString cmdName; + FormWindow *formWin; + +}; + +class CommandHistory : public QObject +{ + Q_OBJECT + +public: + CommandHistory( int s ); + + void addCommand( Command *cmd, bool tryCompress = FALSE ); + void undo(); + void redo(); + + void emitUndoRedo(); + + void setModified( bool m ); + bool isModified() const; + +public slots: + void checkCompressedCommand(); + +signals: + void undoRedoChanged( bool undoAvailable, bool redoAvailable, + const QString &undoCmd, const QString &redoCmd ); + void modificationChanged( bool m ); + +private: + QPtrList<Command> history; + int current, steps; + bool modified; + int savedAt; + Command *compressedCommand; + +}; + +class ResizeCommand : public Command +{ +public: + ResizeCommand( const QString &n, FormWindow *fw, + QWidget *w, const QRect &oldr, const QRect &nr ); + + void execute(); + void unexecute(); + Type type() const { return Resize; } + +private: + QWidget *widget; + QRect oldRect, newRect; + +}; + +class InsertCommand : public Command +{ +public: + InsertCommand( const QString &n, FormWindow *fw, QWidget *w, const QRect &g ); + + void execute(); + void unexecute(); + Type type() const { return Insert; } + +private: + QWidget *widget; + QRect geometry; + +}; + +class MoveCommand : public Command +{ +public: + MoveCommand( const QString &n, FormWindow *fw, + const QWidgetList &w, + const QValueList<QPoint> op, + const QValueList<QPoint> np, + QWidget *opr, QWidget *npr ); + void execute(); + void unexecute(); + Type type() const { return Move; } + void merge( Command *c ); + bool canMerge( Command *c ); + +private: + QWidgetList widgets; + QValueList<QPoint> oldPos, newPos; + QWidget *oldParent, *newParent; + +}; + +class DeleteCommand : public Command +{ +public: + DeleteCommand( const QString &n, FormWindow *fw, + const QWidgetList &w ); + void execute(); + void unexecute(); + Type type() const { return Delete; } + +private: + QWidgetList widgets; + QMap< QWidget*, QValueList<MetaDataBase::Connection> > connections; + +}; + +class SetPropertyCommand : public Command +{ +public: + SetPropertyCommand( const QString &n, FormWindow *fw, + QObject *w, PropertyEditor *e, + const QString &pn, const QVariant &ov, + const QVariant &nv, const QString &ncut, + const QString &ocut, + bool reset = FALSE ); + + void execute(); + void unexecute(); + Type type() const { return SetProperty; } + void merge( Command *c ); + bool canMerge( Command *c ); + bool checkProperty(); + +private: + void setProperty( const QVariant &v, const QString ¤tItemText, bool select = TRUE ); + + QGuardedPtr<QObject> widget; + PropertyEditor *editor; + QString propName; + QVariant oldValue, newValue; + QString oldCurrentItemText, newCurrentItemText; + bool wasChanged; + bool isResetCommand; + +}; + +class LayoutHorizontalCommand : public Command +{ +public: + LayoutHorizontalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutHorizontal; } + +private: + HorizontalLayout layout; + +}; + +class LayoutHorizontalSplitCommand : public Command +{ +public: + LayoutHorizontalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutHorizontalSplitter; } + +private: + HorizontalLayout layout; + +}; + +class LayoutVerticalCommand : public Command +{ +public: + LayoutVerticalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutVertical; } + +private: + VerticalLayout layout; + +}; + +class LayoutVerticalSplitCommand : public Command +{ +public: + LayoutVerticalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutVerticalSplitter; } + +private: + VerticalLayout layout; + +}; + +class LayoutGridCommand : public Command +{ +public: + LayoutGridCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl, int xres, int yres ); + + void execute(); + void unexecute(); + Type type() const { return LayoutGrid; } + +private: + GridLayout layout; + +}; + +class BreakLayoutCommand : public Command +{ +public: + BreakLayoutCommand( const QString &n, FormWindow *fw, + QWidget *layoutBase, const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return BreakLayout; } + +private: + Layout *layout; + int spacing; + int margin; + QWidget *lb; + QWidgetList widgets; + +}; + +class MacroCommand : public Command +{ +public: + MacroCommand( const QString &n, FormWindow *fw, + const QPtrList<Command> &cmds ); + + void execute(); + void unexecute(); + Type type() const { return Macro; } + +private: + QPtrList<Command> commands; + +}; + +class AddTabPageCommand : public Command +{ +public: + AddTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, const QString &label ); + + void execute(); + void unexecute(); + Type type() const { return AddTabPage; } + +private: + QTabWidget *tabWidget; + int index; + QWidget *tabPage; + QString tabLabel; + +}; + +class DeleteTabPageCommand : public Command +{ +public: + DeleteTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget *page ); + + void execute(); + void unexecute(); + Type type() const { return DeleteTabPage; } + +private: + QTabWidget *tabWidget; + int index; + QWidget *tabPage; + QString tabLabel; + +}; + +class MoveTabPageCommand : public Command +{ +public: + MoveTabPageCommand(const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget *page, const QString& label, int nIndex, int oIndex ); + + void execute(); + void unexecute(); + Type type() const { return MoveTabPage; } + +private: + QTabWidget *tabWidget; + int newIndex, oldIndex; + QWidget *tabPage; + QString tabLabel; + +}; +class QDesignerWidgetStack; +class AddWidgetStackPageCommand : public Command +{ +public: + AddWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws ); + + void execute(); + void unexecute(); + Type type() const { return AddWidgetStackPage; } + +private: + QDesignerWidgetStack *widgetStack; + int index; + QWidget *stackPage; +}; + +class DeleteWidgetStackPageCommand : public Command +{ +public: + DeleteWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws, QWidget *page ); + + void execute(); + void unexecute(); + Type type() const { return DeleteWidgetStackPage; } + +private: + QDesignerWidgetStack *widgetStack; + int index; + QWidget *stackPage; +}; + + + +class AddWizardPageCommand : public Command +{ +public: + AddWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, const QString &label, int index = -1, bool show = TRUE ); + + void execute(); + void unexecute(); + Type type() const { return AddWizardPage; } + +private: + QWizard *wizard; + int index; + bool show; + QWidget *page; + QString pageLabel; + +}; + +class DeleteWizardPageCommand : public Command +{ +public: + DeleteWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int index, bool show = TRUE ); + + void execute(); + void unexecute(); + Type type() const { return DeleteWizardPage; } + +private: + QWizard *wizard; + int index; + bool show; + QWidget *page; + QString pageLabel; + +}; + +class RenameWizardPageCommand : public Command +{ +public: + RenameWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int index, const QString& name ); + + void execute(); + void unexecute(); + Type type() const { return RenameWizardPage; } + +private: + QWizard *wizard; + int index; + QWidget *page; + QString label; + +}; + +class SwapWizardPagesCommand : public Command +{ +public: + SwapWizardPagesCommand( const QString &n, FormWindow *fw, + QWizard *w, int index1, int index2 ); + + void execute(); + void unexecute(); + Type type() const { return SwapWizardPages; } + +private: + QWizard *wizard; + int index1, index2; + +}; + +class MoveWizardPageCommand : public Command +{ +public: + MoveWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int index1, int index2 ); + + void execute(); + void unexecute(); + Type type() const { return MoveWizardPage; } + +private: + QWizard *wizard; + int index1, index2; + +}; + +class AddConnectionCommand : public Command +{ +public: + AddConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ); + + void execute(); + void unexecute(); + Type type() const { return AddConnection; } + +private: + MetaDataBase::Connection connection; + +}; + +class RemoveConnectionCommand : public Command +{ +public: + RemoveConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ); + + void execute(); + void unexecute(); + Type type() const { return RemoveConnection; } + +private: + MetaDataBase::Connection connection; + +}; + + +class AddFunctionCommand : public Command +{ +public: + AddFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, const QString& spec, + const QString &a, const QString &t, const QString &l, const QString &rt ); + + void execute(); + void unexecute(); + Type type() const { return AddFunction; } + +private: + QCString function; + QString specifier; + QString access; + QString functionType; + QString language; + QString returnType; +}; + +class ChangeFunctionAttribCommand : public Command +{ +public: + ChangeFunctionAttribCommand( const QString &name, FormWindow *fw, MetaDataBase::Function f, + const QString &on, const QString &os, const QString &oa, + const QString &ot, const QString &ol, const QString &ort ); + + void execute(); + void unexecute(); + Type type() const { return ChangeFunctionAttrib; } + +private: + QString oldName, newName; + QString oldSpec, newSpec; + QString oldAccess, newAccess; + QString oldType, newType; + QString oldLang, newLang; + QString oldReturnType, newReturnType; +}; + +class RemoveFunctionCommand : public Command +{ +public: + RemoveFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, const QString& spec, + const QString &a, const QString &t, const QString &l, const QString &rt ); + + void execute(); + void unexecute(); + Type type() const { return RemoveFunction; } + +private: + QCString function; + QString specifier; + QString access; + QString functionType; + QString language; + QString returnType; +}; + +class AddVariableCommand : public Command +{ +public: + AddVariableCommand( const QString &name, FormWindow *fw, const QString &vn, const QString &a ); + void execute(); + void unexecute(); + Type type() const { return AddVariable; } + +private: + QString varName; + QString access; +}; + +class SetVariablesCommand : public Command +{ +public: + SetVariablesCommand( const QString &name, FormWindow *fw, QValueList<MetaDataBase::Variable> lst ); + void execute(); + void unexecute(); + Type type() const { return SetVariables; } + +private: + QValueList<MetaDataBase::Variable> oldList, newList; +}; + +class RemoveVariableCommand : public Command +{ +public: + RemoveVariableCommand( const QString &name, FormWindow *fw, const QString &vn ); + void execute(); + void unexecute(); + Type type() const { return RemoveVariable; } + +private: + QString varName; + QString access; +}; + +class EditDefinitionsCommand : public Command +{ +public: + EditDefinitionsCommand( const QString &name, FormWindow *fw, LanguageInterface *lf, + const QString &n, const QStringList &l ); + void execute(); + void unexecute(); + Type type() const { return EditDefinitions; } + +private: + LanguageInterface *lIface; + QString defName; + QStringList newList, oldList; +}; + +class LowerCommand : public Command +{ +public: + LowerCommand( const QString &name, FormWindow *fw, const QWidgetList &w ); + + void execute(); + void unexecute(); + Type type() const { return Lower; } + +private: + QWidgetList widgets; + +}; + +class RaiseCommand : public Command +{ +public: + RaiseCommand( const QString &name, FormWindow *fw, const QWidgetList &w ); + + void execute(); + void unexecute(); + Type type() const { return Raise; } + +private: + QWidgetList widgets; + +}; + +class PasteCommand : public Command +{ +public: + PasteCommand( const QString &n, FormWindow *fw, const QWidgetList &w ); + + void execute(); + void unexecute(); + Type type() const { return Paste; } + +private: + QWidgetList widgets; + +}; + +class TabOrderCommand : public Command +{ +public: + TabOrderCommand( const QString &n, FormWindow *fw, const QWidgetList &ol, const QWidgetList &nl ); + + void execute(); + void unexecute(); + Type type() const { return TabOrder; } + void merge( Command *c ); + bool canMerge( Command *c ); + +private: + QWidgetList oldOrder, newOrder; + +}; + +class PopulateListBoxCommand : public Command +{ +public: + struct Item + { + QString text; + QPixmap pix; + Q_DUMMY_COMPARISON_OPERATOR( Item ) + }; + + PopulateListBoxCommand( const QString &n, FormWindow *fw, + QListBox *lb, const QValueList<Item> &items ); + void execute(); + void unexecute(); + Type type() const { return PopulateListBox; } + + bool operator==( const PopulateListBoxCommand & ) const; + +private: + QValueList<Item> oldItems, newItems; + QListBox *listbox; + +}; + +class PopulateIconViewCommand : public Command +{ +public: + struct Item + { + QString text; + QPixmap pix; + Q_DUMMY_COMPARISON_OPERATOR( Item ) + }; + + PopulateIconViewCommand( const QString &n, FormWindow *fw, + QIconView *iv, const QValueList<Item> &items ); + void execute(); + void unexecute(); + Type type() const { return PopulateIconView; } + + bool operator==( const PopulateIconViewCommand & ) const; + +private: + QValueList<Item> oldItems, newItems; + QIconView *iconview; + +}; + +class PopulateListViewCommand : public Command +{ +public: + PopulateListViewCommand( const QString &n, FormWindow *fw, + QListView *lv, QListView *from ); + void execute(); + void unexecute(); + Type type() const { return PopulateListView; } + static void transferItems( QListView *from, QListView *to ); + + bool operator==( const PopulateListViewCommand & ) const; + +private: + QListView *oldItems, *newItems; + QListView *listview; + +}; + +class PopulateMultiLineEditCommand : public Command +{ +public: + PopulateMultiLineEditCommand( const QString &n, FormWindow *fw, + QTextEdit *mle, const QString &txt ); + void execute(); + void unexecute(); + Type type() const { return PopulateMultiLineEdit; } + +private: + QString newText, oldText; + QTextEdit *mlined; + bool wasChanged; + +}; + +class PopulateTableCommand : public Command +{ +public: + struct Row + { + QString text; + QPixmap pix; + Q_DUMMY_COMPARISON_OPERATOR( Row ) + }; + + struct Column + { + QString text; + QPixmap pix; + QString field; + Q_DUMMY_COMPARISON_OPERATOR( Column ) + }; + + PopulateTableCommand( const QString &n, FormWindow *fw, QTable *t, + const QValueList<Row> &rows, + const QValueList<Column> &columns ); + + void execute(); + void unexecute(); + Type type() const { return PopulateTable; } + +private: + QValueList<Row> oldRows, newRows; + QValueList<Column> oldColumns, newColumns; + QTable *table; + +}; + +class AddActionToToolBarCommand : public Command +{ +public: + AddActionToToolBarCommand( const QString &n, FormWindow *fw, + QAction *a, QDesignerToolBar *tb, int idx ); + + void execute(); + void unexecute(); + Type type() const { return AddActionToToolBar; } + +private: + QAction *action; + QDesignerToolBar *toolBar; + int index; + +}; + +class RemoveActionFromToolBarCommand : public AddActionToToolBarCommand +{ +public: + RemoveActionFromToolBarCommand( const QString &n, FormWindow *fw, + QAction *a, QDesignerToolBar *tb, int idx ) + : AddActionToToolBarCommand( n, fw, a, tb, idx ) {} + + void execute() { AddActionToToolBarCommand::unexecute(); } + void unexecute() { AddActionToToolBarCommand::execute(); } + Type type() const { return RemoveActionFromToolBar; } + +}; + +// MenuCommands + +class AddToolBarCommand : public Command +{ +public: + AddToolBarCommand( const QString &n, FormWindow *fw, QMainWindow *mw ); + + void execute(); + void unexecute(); + Type type() const { return AddToolBar; } + +protected: + QDesignerToolBar *toolBar; + QMainWindow *mainWindow; + +}; + +class RemoveToolBarCommand : public AddToolBarCommand +{ +public: + RemoveToolBarCommand( const QString &n, FormWindow *fw, QMainWindow *mw, QDesignerToolBar *tb ) + : AddToolBarCommand( n, fw, mw ) { toolBar = tb; } + + void execute() { AddToolBarCommand::unexecute(); } + void unexecute() { AddToolBarCommand::execute(); } + Type type() const { return RemoveToolBar; } + +}; + +struct QWidgetContainerInterfacePrivate; + +class AddContainerPageCommand : public Command +{ +public: + AddContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, const QString &label ); + + ~AddContainerPageCommand(); + + void execute(); + void unexecute(); + Type type() const { return AddContainerPage; } + +private: + QString wClassName; + QWidget *container; + int index; + QString pageLabel; + QWidget *page; + QWidgetContainerInterfacePrivate *wiface; + +}; + +class DeleteContainerPageCommand : public Command +{ +public: + DeleteContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *container, int index ); + ~DeleteContainerPageCommand(); + + void execute(); + void unexecute(); + Type type() const { return DeleteContainerPage; } + +private: + QString wClassName; + QWidget *container; + int index; + QString pageLabel; + QWidget *page; + QWidgetContainerInterfacePrivate *wiface; + +}; + +class RenameContainerPageCommand : public Command +{ +public: + RenameContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *container, int index, + const QString &label ); + ~RenameContainerPageCommand(); + + void execute(); + void unexecute(); + Type type() const { return RenameContainerPage; } + +private: + QString wClassName; + QWidget *container; + int index; + QString oldLabel, newLabel; + QWidgetContainerInterfacePrivate *wiface; + +}; + +class AddActionToPopupCommand : public Command +{ +public: + AddActionToPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + PopupMenuEditorItem *i, + int idx = -1 ); + void execute(); + void unexecute(); + Type type() const { return AddActionToPopup; } +protected: + QString constructName() const; + PopupMenuEditor *menu; + PopupMenuEditorItem *item; + int index; +private: +}; + +class RemoveActionFromPopupCommand : public AddActionToPopupCommand +{ +public: + RemoveActionFromPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int idx ); + void execute(); + void unexecute(); + Type type() const { return RemoveActionFromPopup; } +protected: +private: +}; + +class ExchangeActionInPopupCommand : public Command +{ +public: + ExchangeActionInPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int a, + int b ); + void execute(); + void unexecute(); + Type type() const { return ExchangeActionInPopup; } +protected: +private: + PopupMenuEditor *menu; + int c; + int d; +}; +/* +class MoveActionInPopupCommand : public Command +{ +public: + MoveActionInPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int a, + int b ); + void execute(); + void unexecute(); + Type type() const { return MoveActionInPopup; } +protected: +private: + PopupMenuEditor *menu; + int from; + int to; +}; +*/ +class ActionCommand : public Command +{ +public: + ActionCommand( const QString &n, + FormWindow *fw, + QAction *a ) + : Command( n, fw ), action( a ) { } + virtual Type type() const = 0; +protected: + ActionEditor *actionEditor(); + QAction *action; +}; + +class RenameActionCommand : public ActionCommand +{ +public: + RenameActionCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QString nm ); + void execute(); + void unexecute(); + Type type() const { return RenameAction; } +private: + PopupMenuEditor *menu; + QString newName; + QString oldName; +}; + +class SetActionIconsCommand : public ActionCommand +{ +public: + SetActionIconsCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QIconSet &icons ); + void execute(); + void unexecute(); + Type type() const { return SetActionIcons; } +protected: + void updateActionEditorItem(); +private: + PopupMenuEditor *menu; + QIconSet newIcons; + QIconSet oldIcons; +}; + +class AddMenuCommand : public Command +{ +public: + AddMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + MenuBarEditorItem *i, + int idx = -1 ); + + AddMenuCommand( const QString &n, + FormWindow *fw, + QMainWindow *mw, + const QString &nm = "Menu" ); + + void execute(); + void unexecute(); + Type type() const { return AddMenu; } +protected: + MenuBarEditor *mb; + MenuBarEditorItem *item; + QString name; + int index; +private: +}; + +class RemoveMenuCommand : public AddMenuCommand +{ +public: + RemoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int idx ); + void execute(); + void unexecute(); + Type type() const { return RemoveMenu; } +protected: +private: +}; + +class ExchangeMenuCommand : public Command +{ +public: + ExchangeMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ); + void execute(); + void unexecute(); + Type type() const { return ExchangeMenu; } +protected: +private: + MenuBarEditor *bar; + int k; + int l; +}; + + +class MoveMenuCommand : public Command +{ +public: + MoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ); + void execute(); + void unexecute(); + Type type() const { return MoveMenu; } +protected: +private: + MenuBarEditor *bar; + int from; + int to; +}; + +class RenameMenuCommand : public Command +{ +public: + RenameMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *m, + QString nm, + MenuBarEditorItem *i ); + void execute(); + void unexecute(); + Type type() const { return RenameMenu; } + static QString makeLegal( const QString &str ); +private: + MenuBarEditor *bar; + MenuBarEditorItem *item; + QString newName; + QString oldName; +}; + +class AddToolBoxPageCommand : public Command +{ +public: + AddToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, const QString &label ); + + void execute(); + void unexecute(); + Type type() const { return AddToolBoxPage; } + +private: + QToolBox *toolBox; + int index; + QWidget *toolBoxPage; + QString toolBoxLabel; + +}; + +class DeleteToolBoxPageCommand : public Command +{ +public: + DeleteToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, QWidget *page ); + + void execute(); + void unexecute(); + Type type() const { return DeleteToolBoxPage; } + +private: + QToolBox *toolBox; + int index; + QWidget *toolBoxPage; + QString toolBoxLabel; + +}; + +#endif diff --git a/kdevdesigner/designer/configtoolboxdialog.ui b/kdevdesigner/designer/configtoolboxdialog.ui new file mode 100644 index 00000000..ac19357b --- /dev/null +++ b/kdevdesigner/designer/configtoolboxdialog.ui @@ -0,0 +1,326 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ConfigToolboxDialog</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ConfigToolboxDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>403</width> + <height>467</height> + </rect> + </property> + <property name="caption"> + <string>Configure Toolbox</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>342</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton3</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton4</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>buttonAdd</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>111</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QListView" row="0" column="0" rowspan="1" colspan="2"> + <column> + <property name="text"> + <string>Available Tools</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listViewTools</cstring> + </property> + <property name="selectionMode"> + <enum>Extended</enum> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="0"> + <property name="name"> + <cstring>buttonRemove</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <widget class="QListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Common Widgets Page</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listViewCommon</cstring> + </property> + <property name="selectionMode"> + <enum>Extended</enum> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QToolButton" row="1" column="3"> + <property name="name"> + <cstring>buttonDown</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>41</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QToolButton" row="1" column="2"> + <property name="name"> + <cstring>buttonUp</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonAdd</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>addTool()</slot> + </connection> + <connection> + <sender>buttonRemove</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>removeTool()</slot> + </connection> + <connection> + <sender>buttonUp</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>moveToolUp()</slot> + </connection> + <connection> + <sender>buttonDown</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>moveToolDown()</slot> + </connection> + <connection> + <sender>listViewTools</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>currentToolChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>listViewCommon</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>currentCommonToolChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>PushButton3</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>PushButton4</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>PushButton3</sender> + <signal>clicked()</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>ok()</slot> + </connection> + <connection> + <sender>listViewTools</sender> + <signal>doubleClicked(QListViewItem*)</signal> + <receiver>ConfigToolboxDialog</receiver> + <slot>addTool()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">configtoolboxdialog.ui.h</include> +</includes> +<slots> + <slot>addTool()</slot> + <slot>removeTool()</slot> + <slot>moveToolUp()</slot> + <slot>moveToolDown()</slot> + <slot>currentToolChanged( QListViewItem * i )</slot> + <slot>currentCommonToolChanged( QListViewItem * i )</slot> + <slot>ok()</slot> +</slots> +<functions> + <function access="private">init()</function> +</functions> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/configtoolboxdialog.ui.h b/kdevdesigner/designer/configtoolboxdialog.ui.h new file mode 100644 index 00000000..6b5d55b6 --- /dev/null +++ b/kdevdesigner/designer/configtoolboxdialog.ui.h @@ -0,0 +1,215 @@ +/********************************************************************** +** 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 "mainwindow.h" +#include "widgetaction.h" +#include "listviewdnd.h" +#include <qlistview.h> + +void ConfigToolboxDialog::init() +{ + listViewTools->setSorting( -1 ); + listViewCommon->setSorting( -1 ); + + ListViewDnd *toolsDnd = new ListViewDnd( listViewTools ); + toolsDnd->setDragMode( ListViewDnd::External | ListViewDnd::NullDrop | ListViewDnd::Flat ); + + ListViewDnd *commonDnd = new ListViewDnd( listViewCommon ); + commonDnd->setDragMode( ListViewDnd::Both | ListViewDnd::Move | ListViewDnd::Flat ); + + QObject::connect( toolsDnd, SIGNAL( dropped( QListViewItem * ) ), + commonDnd, SLOT( confirmDrop( QListViewItem * ) ) ); + QObject::connect( commonDnd, SIGNAL( dropped( QListViewItem * ) ), + commonDnd, SLOT( confirmDrop( QListViewItem * ) ) ); + + QDict<QListViewItem> groups; + QAction *a; + for ( a = MainWindow::self->toolActions.last(); + a; + a = MainWindow::self->toolActions.prev() ) { + QString grp = ( (WidgetAction*)a )->group(); + QListViewItem *parent = groups.find( grp ); + if ( !parent ) { + parent = new QListViewItem( listViewTools ); + parent->setText( 0, grp ); + parent->setOpen( TRUE ); + groups.insert( grp, parent ); + } + QListViewItem *i = new QListViewItem( parent ); + i->setText( 0, a->text() ); + i->setPixmap( 0, a->iconSet().pixmap() ); + } + for ( a = MainWindow::self->commonWidgetsPage.last(); a; + a = MainWindow::self->commonWidgetsPage.prev() ) { + QListViewItem *i = new QListViewItem( listViewCommon ); + i->setText( 0, a->text() ); + i->setPixmap( 0, a->iconSet().pixmap() ); + } + +} + + +void ConfigToolboxDialog::addTool() +{ + QListView *src = listViewTools; + + bool addKids = FALSE; + QListViewItem *nextSibling = 0; + QListViewItem *nextParent = 0; + QListViewItemIterator it = src->firstChild(); + for ( ; *it; it++ ) { + // Hit the nextSibling, turn of child processing + if ( (*it) == nextSibling ) + addKids = FALSE; + + if ( (*it)->isSelected() ) { + if ( (*it)->childCount() == 0 ) { + // Selected, no children + QListViewItem *i = new QListViewItem( listViewCommon, listViewCommon->lastItem() ); + i->setText( 0, (*it)->text(0) ); + i->setPixmap( 0, *((*it)->pixmap(0)) ); + listViewCommon->setCurrentItem( i ); + listViewCommon->ensureItemVisible( i ); + } else if ( !addKids ) { + // Children processing not set, so set it + // Also find the item were we shall quit + // processing children...if any such item + addKids = TRUE; + nextSibling = (*it)->nextSibling(); + nextParent = (*it)->parent(); + while ( nextParent && !nextSibling ) { + nextSibling = nextParent->nextSibling(); + nextParent = nextParent->parent(); + } + } + } else if ( ((*it)->childCount() == 0) && addKids ) { + // Leaf node, and we _do_ process children + QListViewItem *i = new QListViewItem( listViewCommon, listViewCommon->lastItem() ); + i->setText( 0, (*it)->text(0) ); + i->setPixmap( 0, *((*it)->pixmap(0)) ); + listViewCommon->setCurrentItem( i ); + listViewCommon->ensureItemVisible( i ); + } + } +} + + +void ConfigToolboxDialog::removeTool() +{ + QListViewItemIterator it = listViewCommon->firstChild(); + while ( *it ) { + if ( (*it)->isSelected() ) + delete (*it); + else + it++; + } +} + + +void ConfigToolboxDialog::moveToolUp() +{ + QListViewItem *next = 0; + QListViewItem *item = listViewCommon->firstChild(); + for ( int i = 0; i < listViewCommon->childCount(); ++i ) { + next = item->itemBelow(); + if ( item->isSelected() && (i > 0) && !item->itemAbove()->isSelected() ) + item->itemAbove()->moveItem( item ); + item = next; + } +} + + +void ConfigToolboxDialog::moveToolDown() +{ + int count = listViewCommon->childCount(); + QListViewItem *next = 0; + QListViewItem *item = listViewCommon->lastItem(); + for ( int i = 0; i < count; ++i ) { + next = item->itemAbove(); + if ( item->isSelected() && (i > 0) && !item->itemBelow()->isSelected() ) + item->moveItem( item->itemBelow() ); + item = next; + } + + // QListViewItem *item = listViewCommon->firstChild(); + // for ( int i = 0; i < listViewCommon->childCount(); ++i ) { + //if ( item == listViewCommon->currentItem() ) { + // item->moveItem( item->itemBelow() ); + // currentCommonToolChanged( item ); + // break; + //} + //item = item->itemBelow(); + // } +} + + +void ConfigToolboxDialog::currentToolChanged( QListViewItem *i ) +{ + bool canAdd = FALSE; + QListViewItemIterator it = listViewTools->firstChild(); + for ( ; *it; it++ ) { + if ( (*it)->isSelected() ) { + canAdd = TRUE; + break; + } + } + buttonAdd->setEnabled( canAdd || ( i && i->isSelected() ) ); +} + + +void ConfigToolboxDialog::currentCommonToolChanged( QListViewItem *i ) +{ + buttonUp->setEnabled( (bool) (i && i->itemAbove()) ); + buttonDown->setEnabled( (bool) (i && i->itemBelow()) ); + + bool canRemove = FALSE; + QListViewItemIterator it = listViewCommon->firstChild(); + for ( ; *it; it++ ) { + if ( (*it)->isSelected() ) { + canRemove = TRUE; + break; + } + } + buttonRemove->setEnabled( canRemove || ( i && i->isSelected() ) ); +} + + +void ConfigToolboxDialog::ok() +{ + MainWindow::self->commonWidgetsPage.clear(); + QListViewItem *item = listViewCommon->firstChild(); + for ( int j = 0; j < listViewCommon->childCount(); item = item->itemBelow(), ++j ) { + QAction *a = 0; + for ( a = MainWindow::self->toolActions.last(); + a; + a = MainWindow::self->toolActions.prev() ) { + if ( a->text() == item->text( 0 ) ) + break; + } + if ( a ) + MainWindow::self->commonWidgetsPage.insert( j, a ); + } +} diff --git a/kdevdesigner/designer/connectiondialog.ui b/kdevdesigner/designer/connectiondialog.ui new file mode 100644 index 00000000..c8cc9c4f --- /dev/null +++ b/kdevdesigner/designer/connectiondialog.ui @@ -0,0 +1,219 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ConnectionDialog</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ConnectionDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>365</height> + </rect> + </property> + <property name="caption"> + <string>View & Edit Connections</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&New</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Connections:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>connectionsTable</cstring> + </property> + </widget> + <widget class="QPushButton" row="2" column="1"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + </widget> + <widget class="QPushButton" row="6" column="1"> + <property name="name"> + <cstring>PushButton3</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <widget class="QPushButton" row="5" column="1"> + <property name="name"> + <cstring>PushButton7</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <spacer row="4" column="1"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="3" column="1"> + <property name="name"> + <cstring>buttonEditSlots</cstring> + </property> + <property name="text"> + <string>&Edit Slots...</string> + </property> + </widget> + <widget class="ConnectionTable" row="1" column="0" rowspan="6" colspan="1"> + <property name="name"> + <cstring>connectionsTable</cstring> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>ConnectionTable</class> + <header location="local">connectiontable.h</header> + <sizehint> + <width>50</width> + <height>50</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>7</hordata> + <verdata>7</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>"image0"</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="4830">789c9597c972e3480e40eff5158ec2ada203cd3549c6c41cbcc9b6bccabbddd1078014bdcb9b6449ee987f9f240072caac9e4357d6c1cf5812890490f4ef3f562e8ff6577efcfeed7d4ad3bb72a5bca5b7951fd5ece969f9c79ffffeebdbf7285a69fec7f14af4fdb76fdf47d39572e5e079326e00c10304f24ff8b9c7d463ee71d9e3aac7e31ed70d67dc2ce1cb9e7cd0e3c957863eaff778d4b3bfe8c97be781a71eaff5f8e82bf37ecfff4dc314364b58fdb966096ff6ecf77af6b70d1771b3841f1b8ef366099ff7ec17bdf8faf7970847cd12f9b2e344f8b563890f5e3a96fda0ea98c45fdc71299c765c354c67c249bb1fcd3a56ff271d8b3d9d1b271a0f1d742c725874acfe9d70eef3a9f65bc2e47fa3f16a7d55411d6a3e4e1b0e03bf349e8171144a7e49ceeb295239cb79c3384ccdff76c7b23f14c269e8ccdfa9716ef6b5b18f407857d88585e57bbf65b39f18971a0fc8fd7b6fc624f723e524f9e3d2b8d4f391d49ba74ae5bed585a3c8e49b1d6b7c929f701ca5e65feac10b9dd967c2519485a9dcaf33ce952110cea3caec23e53830f9863045b5ca79ae1c8741263cec58eb59ed390ecd3e378e8d651e44651c85527f20f51cd55eae5c1b27a1f823b9bf388c0b65b831a6b090fd24be384bc24098a6d65fb5ca29ed58fd5f35eccbaf34ff320f922819ab3e487e93d4b3d6eb9b711d4abda0f44352a685d5f39d709db2ca296c380dd2c238366ee5605c1acb3c96f2d3feff148ed25aeb0d1e955d60fd22f94a63178632df79d5d8fa95971d8b9cee5b8e647ec1d038567b40e1a4d567a9d73475b1f14ecb5a7f2cf94a9d4b343eba304e357e3814ce5c6afd22f33b2d5c6ee7295bb6fc4abda4e40af3f7d972a4f52df79bb223ebff79cb2a2736e650ce470fc2652b67b9cfb4726dff5d195776bead96adbf1e3bd67a9779928ebbfdc898357f34346ee7c3a0658d07359eba5922d7fbaebd3fdd6f6e3c567d96f9e4c22cb4780a63eb7f90f7c525596cf11c1a2791ce9bd8d869bd93e4dba55eaeefc781b1dd17ee1b9b3e4b3e9dcbfcc4107f9fc671a4ef9dcc139765763fa4f6943965947a7355b3c45eceebc65965fb851deb79655e662ecfcddf93716172999759966791f67f689ceb79e9a363951f1b9b3d1e76acf36fcf98544e529fdebc954b3f67d42ce1eb86f3465df3fb2e5c14a5d53b2b53a0f316773ad6f922f32c2fa9cd9fdc6f5e79d6f8768d13ebc79d96559fe47dcd6b8a63cdcfbb71126bfcd21f45e0f5f57dbb357691c63f342e2cbea063d597f7b808c9e6151e1993c573d1b2de0fc8fd1711151a1fdf187324f393671debfe92df22a134d67e93fb2a1cd93c05630ef4fe48f25d641c683de2b171a8f399ef3a56f989b1bd273c6dd9f697f7bcc85b7dca8da348be4f41fabf2838b1f7e9cc38d5f715e4fd2888439b9f53639ba72cf55a701b3f0c8cad3ff9de38b57c4bfd15a5678d6f646cfd87857166ef95f46b51f9fdf57c609cda7b756edcbee7ceb850a671c7faf7809e7fccb9d63b6c1b93d5f7ac63d5d7fcd41c245a8fabc685e68f1f8c49ef93e5bda4c0fbd7f9b16b4c5a9ff060ccf63e4b3d52c889c6433bc685da33195bbfc2bd31dbfc947aa5982bf37fddb1c623f39c7cbbda7c94f889cac4ea4df24f55c9367fe43da47159da3c907ea39ac74ebfdfe5fe39e0dac9f71f4abed87fb02993d42b475562effb5dcb36ff243fec3f3f327d4fd1384db5ffd68c9db1bc579cb6faf8619cdafe321f39f39f33721fb46bec4cfe699c19cf3bd6f3ad1ae7c6f2de71ce2549fe71a9dcc917c685324b7eb8aac6767ff27dc763cf92afd1b4590848c8586285e3deaafc6fd94b61346df5b1c61bbcc53bbcff9bf5808ff884136ff5acfadef70dbee02bbee13b4e71861f38c7052ef1d3af555cc375dcc04d1c6069fae47dbfe2166ee30e0e7117f7701f0ff0108f7084c77882a77886e7788197a6cf3e922baf7d8d018618618c895f293acc30c702478000403831fdd247f90e8c019450610c63a8e1066efd4f15dcc13d3cc0a3d77f8256bff2fa531cc233bcc02bbcc13b4c61061f3087052ce11356c5ff1aac9bfed8ebcf701736bc741306b005dbb00343d8853def611f0ee0d0eb1fc1e827fd0f38861338f5becfe01c2ee0d26b5ec13504de4708d12ffa7388bd2481141c64907bed020f0909604944fc8bfe924a4ca8a231d5e2fb956ee896eee8deeb3fd0e32ffa0b7ac29426f041fed4f442afdee28dde694a33faa0f9aff1d0829618d327add21aadd3066dfafd06b445dbb443c3be3eedd21eed7bfd033aa4231ad1319dd0299dd1395dd0255dfd8dff6b0a28c4042af27fcc907fafc879ed73ff199053f145bfc207463c666062e6d2dfd9d2db2db9a20b1e73cd377cfbe5be4a5fb1eb7cc7f7fcc08ffcc4137ee6177ee5377ee729cff883e7bcf8a91ed8d7f7069ef1923f7995d7789d37789307bc4557bccd3b3ce45ddefba9defc4fbebecfe1fffce305eff1fe4ff50c3ea2015e00f93dd7fcb9beae35ff5bf2da5dbf788b676f71891398c03a8c7a6b1d267effcbfff5e33fe8f7fffcebdb7f01520e2ea3</data> + </image> +</images> +<connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>ConnectionDialog</receiver> + <slot>addConnection()</slot> + </connection> + <connection> + <sender>PushButton7</sender> + <signal>clicked()</signal> + <receiver>ConnectionDialog</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>PushButton3</sender> + <signal>clicked()</signal> + <receiver>ConnectionDialog</receiver> + <slot>cancelClicked()</slot> + </connection> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>ConnectionDialog</receiver> + <slot>deleteClicked()</slot> + </connection> + <connection> + <sender>buttonEditSlots</sender> + <signal>clicked()</signal> + <receiver>ConnectionDialog</receiver> + <slot>editSlots()</slot> + </connection> +</connections> +<includes> + <include location="global" impldecl="in declaration">qptrlist.h</include> + <include location="local" impldecl="in declaration">connectionitems.h</include> + <include location="local" impldecl="in implementation">connectiondialog.ui.h</include> +</includes> +<variables> + <variable>QPtrList<ConnectionContainer> connections;</variable> + <variable>QObject *defaultSender;</variable> + <variable>QObject *defaultReceiver;</variable> +</variables> +<slots> + <slot>init()</slot> + <slot>addConnection()</slot> + <slot returnType="ConnectionContainer *">addConnection( QObject * sender, QObject * receiver, const QString & signal, const QString & slot )</slot> + <slot>updateConnectionState( ConnectionContainer * c )</slot> + <slot>okClicked()</slot> + <slot>cancelClicked()</slot> + <slot>deleteClicked()</slot> + <slot>editSlots()</slot> + <slot>setDefault( QObject * sender, QObject * receiver )</slot> + <slot>updateEditSlotsButton()</slot> + <slot>updateConnectionContainers()</slot> + <slot>ensureConnectionVisible()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/connectiondialog.ui.h b/kdevdesigner/designer/connectiondialog.ui.h new file mode 100644 index 00000000..3c6cd932 --- /dev/null +++ b/kdevdesigner/designer/connectiondialog.ui.h @@ -0,0 +1,318 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include "mainwindow.h" +#include "formwindow.h" +#include "editfunctionsimpl.h" + +static const char *valid_connection[] = { + "16 14 7 1", + ". c none", + "# c #00c000", + "a c #008000", + "b c #004000", + "c c #000000", + "d c #c0fcc0", + "e c #400000", + "...............d", + "..............d#", + ".............d#a", + "............d#ab", + "...........d#abc", + "..da......d#abc.", + ".d##a....d#abe..", + "cba##a..d#abc...", + ".cba##ad#abe....", + "..eba###abe.....", + "...cba#abc......", + "....cbabc.......", + ".....cec........", + "................" +}; + +static const char * invalid_connection[] = { + "17 18 7 1", + " c None", + ". c #000000", + "+ c #C3C3C3", + "@ c #FFFFFF", + "# c #C00000", + "$ c #FFC0C0", + "% c #FF0000", + " ", + " . ", + " ... ", + " .+.. ", + " ...+@+.. ", + "..+@@@+#.. ", + ".@@@@$#%#.. ", + ".@@$$#%##.. ", + " .$%%%##.... ", + " .%%%##. .. ", + " .%#.. .. ", + " .. .. ", + " .. ", + " .. ", + " .. ", + " .. ", + " ", + " " +}; + +static QPixmap *invalidConnection = 0; +static QPixmap *validConnection = 0; + +void ConnectionDialog::init() +{ + connect( connectionsTable, SIGNAL( currentChanged( int, int ) ), + this, SLOT( updateEditSlotsButton() ) ); + connect( connectionsTable, SIGNAL( resorted() ), + this, SLOT( updateConnectionContainers() ) ); + buttonEditSlots->setEnabled( FALSE ); + + if ( !invalidConnection ) { + invalidConnection = new QPixmap( invalid_connection ); + validConnection = new QPixmap( valid_connection ); + } + + QValueList<MetaDataBase::Connection> conns = + MetaDataBase::connections( MainWindow::self->formWindow() ); + for ( QValueList<MetaDataBase::Connection>::Iterator it = conns.begin(); + it != conns.end(); ++it ) { + ConnectionContainer *c = addConnection( (*it).sender, (*it).receiver, + (*it).signal, (*it).slot ); + c->setModified( FALSE ); + updateConnectionState( c ); + } + + defaultSender = defaultReceiver = 0; + connectionsTable->setCurrentCell( 0, 0 ); +} + +void ConnectionDialog::addConnection() +{ + addConnection( defaultSender, defaultReceiver, QString::null, QString::null ); + ensureConnectionVisible(); +} + +ConnectionContainer *ConnectionDialog::addConnection( QObject *sender, QObject *receiver, + const QString &signal, + const QString &slot ) +{ + connectionsTable->insertRows( connectionsTable->numRows() ); + + int row = connectionsTable->numRows() - 1; + SenderItem *se; + SignalItem *si; + ReceiverItem *re; + SlotItem *sl; + connectionsTable->setItem( row, 0, + ( se = new SenderItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + connectionsTable->setItem( row, 1, + ( si = new SignalItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + connectionsTable->setItem( row, 2, + ( re = new ReceiverItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + connectionsTable->setItem( row, 3, + ( sl = new SlotItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + + si->setSender( se ); + re->setSender( se ); + sl->setSender( se ); + se->setSender( se ); + + se->setSignal( si ); + re->setSignal( si ); + sl->setSignal( si ); + si->setSignal( si ); + + se->setReceiver( re ); + si->setReceiver( re ); + sl->setReceiver( re ); + re->setReceiver( re ); + + se->setSlot( sl ); + si->setSlot( sl ); + re->setSlot( sl ); + sl->setSlot( sl ); + + connect( re, SIGNAL( currentReceiverChanged( QObject * ) ), + this, SLOT( updateEditSlotsButton() ) ); + + ConnectionContainer *c = new ConnectionContainer( this, se, si, re, sl, row ); + connections.append( c ); + connect( c, SIGNAL( changed( ConnectionContainer * ) ), + this, SLOT( updateConnectionState( ConnectionContainer * ) ) ); + + connectionsTable->setCurrentCell( row, 0 ); + + connectionsTable->verticalHeader()->setLabel( row, *invalidConnection, QString::null ); + + if ( sender ) + se->setSenderEx( sender ); + defaultSender = sender; + if ( receiver ) + re->setReceiverEx( receiver ); + defaultReceiver = receiver; + + if ( !signal.isEmpty() && !slot.isEmpty() ) { + si->setCurrentItem( signal ); + sl->signalChanged( signal ); + sl->setCurrentItem( slot ); + } + + c->setModified( TRUE ); + return c; +} + +void ConnectionDialog::updateConnectionState( ConnectionContainer *c ) +{ + c->repaint(); + if ( c->isValid() ) + connectionsTable->verticalHeader()->setLabel( c->row(), + *validConnection, QString::null ); + else + connectionsTable->verticalHeader()->setLabel( c->row(), + *invalidConnection, QString::null ); +} + + +void ConnectionDialog::okClicked() +{ + QValueList<MetaDataBase::Connection> oldConnections = + MetaDataBase::connections( MainWindow::self->formWindow() ); + QPtrList<Command> newConnectionCmds; + QPtrList<Command> oldConnectionCmds; + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) { + MetaDataBase::Connection conn; + + // find sender widget + conn.sender = MainWindow::self->formWindow()->child( c->senderItem()->currentText() ); + if ( !conn.sender ) // if no sender widget, find sender action + conn.sender = MainWindow::self->formWindow()->findAction( c->senderItem()->currentText() ); + + // find receiver widget + conn.receiver = MainWindow::self->formWindow()->child( c->receiverItem()->currentText() ); + if ( !conn.receiver ) // if no receiver widget, find receiver action + conn.receiver = MainWindow::self->formWindow()->findAction( c->receiverItem()->currentText() ); + + conn.signal = c->signalItem()->currentText(); + conn.slot = c->slotItem()->currentText(); + AddConnectionCommand *cmd = new AddConnectionCommand( i18n( "Add Signal/Slot " + "Connection" ), + MainWindow::self->formWindow(), + conn ); + newConnectionCmds.append( cmd ); + } + + + QValueList<MetaDataBase::Connection> conns = + MetaDataBase::connections( MainWindow::self->formWindow() ); + for ( QValueList<MetaDataBase::Connection>::Iterator it = conns.begin(); + it != conns.end(); ++it ) { + RemoveConnectionCommand *cmd = new RemoveConnectionCommand( i18n( "Remove Signal/Slot " + "Connection" ), + MainWindow::self-> + formWindow(), *it ); + oldConnectionCmds.append( cmd ); + } + + MacroCommand *cmd1 = new MacroCommand( i18n( "Add Signal/Slot Connections" ), + MainWindow::self->formWindow(), + newConnectionCmds ); + MacroCommand *cmd2 = new MacroCommand( i18n( "Remove Signal/Slot Connections" ), + MainWindow::self->formWindow(), + oldConnectionCmds ); + QPtrList<Command> cmds; + cmds.append( cmd2 ); + cmds.append( cmd1 ); + MacroCommand *cmd = new MacroCommand( i18n( "Edit Signal/Slot Connections" ), + MainWindow::self->formWindow(), + cmds ); + MainWindow::self->formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + + accept(); +} + + +void ConnectionDialog::cancelClicked() +{ + reject(); +} + + +void ConnectionDialog::deleteClicked() +{ + int cr = connectionsTable->currentRow(); + connections.remove( cr ); + connectionsTable->removeRow( cr ); + int i = 0; + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) + c->setRow( i++ ); +} + + +void ConnectionDialog::editSlots() +{ + EditFunctions dlg( this, MainWindow::self->formWindow(), TRUE ); + dlg.exec(); + int currentCol = connectionsTable->currentColumn(); + connectionsTable->setCurrentCell( connectionsTable->currentRow(), 0 ); + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) { + if ( c->receiverItem()->currentText() != + QString( MainWindow::self->formWindow()->mainContainer()->name() ) ) + continue; + c->slotItem()->customSlotsChanged(); + } + connectionsTable->setCurrentCell( connectionsTable->currentRow(), currentCol ); +} + +void ConnectionDialog::setDefault( QObject *sender, QObject *receiver ) +{ + defaultSender = sender; + defaultReceiver = receiver; +} + +void ConnectionDialog::updateEditSlotsButton() +{ + if ( connectionsTable->currentRow() < 0 || + connectionsTable->currentRow() > (int)connections.count() - 1 ) + return; + ConnectionContainer *c = connections.at( connectionsTable->currentRow() ); + if ( !c || !c->receiverItem() ) + return; + buttonEditSlots->setEnabled( c->receiverItem()->currentText() == + QString( MainWindow::self->formWindow()-> + mainContainer()->name() ) ); +} + +void ConnectionDialog::updateConnectionContainers() +{ + QPtrList<ConnectionContainer> newContainers; + for ( int i = 0; i < connectionsTable->numRows(); ++i ) { + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) { + if ( c->senderItem() == connectionsTable->item( i, 0 ) ) { + newContainers.append( c ); + c->setRow( i ); + updateConnectionState(c); + break; + } + } + } + connections = newContainers; + updateEditSlotsButton(); +} + +void ConnectionDialog::ensureConnectionVisible() +{ + connectionsTable->ensureCellVisible( connectionsTable->numRows() - 1, 0 ); +} diff --git a/kdevdesigner/designer/connectionitems.cpp b/kdevdesigner/designer/connectionitems.cpp new file mode 100644 index 00000000..197eef65 --- /dev/null +++ b/kdevdesigner/designer/connectionitems.cpp @@ -0,0 +1,517 @@ +/********************************************************************** +** Copyright (C) 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 "connectionitems.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "widgetfactory.h" +#include "project.h" +#include <qpainter.h> +#include <qcombobox.h> +#include <qmetaobject.h> +#include <qcombobox.h> +#include <qlistbox.h> +#include <qaction.h> +#include <qdatabrowser.h> + +static const char* const ignore_slots[] = { + "destroyed()", + "setCaption(const QString&)", + "setIcon(const QPixmap&)", + "setIconText(const QString&)", + "setMouseTracking(bool)", + "clearFocus()", + "setUpdatesEnabled(bool)", + "update()", + "update(int,int,int,int)", + "update(const QRect&)", + "repaint()", + "repaint(bool)", + "repaint(int,int,int,int,bool)", + "repaint(const QRect&,bool)", + "repaint(const QRegion&,bool)", + "show()", + "hide()", + "iconify()", + "showMinimized()", + "showMaximized()", + "showFullScreen()", + "showNormal()", + "polish()", + "constPolish()", + "raise()", + "lower()", + "stackUnder(QWidget*)", + "move(int,int)", + "move(const QPoint&)", + "resize(int,int)", + "resize(const QSize&)", + "setGeometry(int,int,int,int)", + "setGeometry(const QRect&)", + "focusProxyDestroyed()", + "showExtension(bool)", + "setUpLayout()", + "showDockMenu(const QPoint&)", + "init()", + "destroy()", + "deleteLater()", + 0 +}; + +ConnectionItem::ConnectionItem( QTable *table, FormWindow *fw ) + : QComboTableItem( table, QStringList(), FALSE ), formWindow( fw ), conn( 0 ) +{ + setReplaceable( FALSE ); +} + +void ConnectionItem::senderChanged( QObject * ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::receiverChanged( QObject * ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::signalChanged( const QString & ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::slotChanged( const QString & ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::setSender( SenderItem *i ) +{ + connect( i, SIGNAL( currentSenderChanged( QObject * ) ), + this, SLOT( senderChanged( QObject * ) ) ); +} + +void ConnectionItem::setReceiver( ReceiverItem *i ) +{ + connect( i, SIGNAL( currentReceiverChanged( QObject * ) ), + this, SLOT( receiverChanged( QObject * ) ) ); +} + +void ConnectionItem::setSignal( SignalItem *i ) +{ + connect( i, SIGNAL( currentSignalChanged( const QString & ) ), + this, SLOT( signalChanged( const QString & ) ) ); +} + +void ConnectionItem::setSlot( SlotItem *i ) +{ + connect( i, SIGNAL( currentSlotChanged( const QString & ) ), + this, SLOT( slotChanged( const QString & ) ) ); +} + +void ConnectionItem::paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ) +{ + p->fillRect( 0, 0, cr.width(), cr.height(), + selected ? cg.brush( QColorGroup::Highlight ) + : cg.brush( QColorGroup::Base ) ); + + int w = cr.width(); + int h = cr.height(); + + int x = 0; + + if ( currentText()[0] == '<' ) + p->setPen( QObject::red ); + else if ( selected ) + p->setPen( cg.highlightedText() ); + else + p->setPen( cg.text() ); + + QFont f( p->font() ); + QFont oldf( p->font() ); + if ( conn && conn->isModified() ) { + f.setBold( TRUE ); + p->setFont( f ); + } + + p->drawText( x + 2, 0, w - x - 4, h, alignment(), currentText() ); + p->setFont( oldf ); +} + +void ConnectionItem::setConnection( ConnectionContainer *c ) +{ + conn = c; +} + +// ------------------------------------------------------------------ + +static void appendChildActions( QAction *action, QStringList &lst ) +{ + QObjectListIt it( *action->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast<QAction*>(o) ) + continue; + lst << o->name(); + if ( o->children() && ::qt_cast<QActionGroup*>(o) ) + appendChildActions( (QAction*)o, lst ); + } +} + +static QStringList flatActions( const QPtrList<QAction> &l ) +{ + QStringList lst; + + QPtrListIterator<QAction> it( l ); + while ( it.current() ) { + QAction *action = it.current(); + lst << action->name(); + if ( action->children() && ::qt_cast<QActionGroup*>(action) ) + appendChildActions( action, lst ); + ++it; + } + + return lst; +} + +// ------------------------------------------------------------------ + +SenderItem::SenderItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + + QPtrDictIterator<QWidget> it( *formWindow->widgets() ); + while ( it.current() ) { + if ( lst.find( it.current()->name() ) != lst.end() ) { + ++it; + continue; + } + if ( !QString( it.current()->name() ).startsWith( "qt_dead_widget_" ) && + !::qt_cast<QLayoutWidget*>(it.current()) && + !::qt_cast<Spacer*>(it.current()) && + !::qt_cast<SizeHandle*>(it.current()) && + qstrcmp( it.current()->name(), "central widget" ) != 0 ) { + lst << it.current()->name(); + } + ++it; + } + + lst += flatActions( formWindow->actionList() ); + + lst.prepend( "<No Sender>" ); + lst.sort(); + setStringList( lst ); +} + +QWidget *SenderItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SLOT( senderChanged( const QString & ) ) ); + return cb; +} + +void SenderItem::setSenderEx( QObject *sender ) +{ + setCurrentItem( sender->name() ); + emit currentSenderChanged( sender ); +} + +void SenderItem::senderChanged( const QString &sender ) +{ + QObject *o = formWindow->child( sender, "QObject" ); + if ( !o ) + o = formWindow->findAction( sender ); + if ( !o ) + return; + emit currentSenderChanged( o ); +} + + + +// ------------------------------------------------------------------ + +ReceiverItem::ReceiverItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + + QPtrDictIterator<QWidget> it( *formWindow->widgets() ); + while ( it.current() ) { + if ( lst.find( it.current()->name() ) != lst.end() ) { + ++it; + continue; + } + if ( !QString( it.current()->name() ).startsWith( "qt_dead_widget_" ) && + !::qt_cast<QLayoutWidget*>(it.current()) && + !::qt_cast<Spacer*>(it.current()) && + !::qt_cast<SizeHandle*>(it.current()) && + qstrcmp( it.current()->name(), "central widget" ) != 0 ) { + lst << it.current()->name(); + } + ++it; + } + + lst += flatActions( formWindow->actionList() ); + + lst.prepend( "<No Receiver>" ); + lst.sort(); + setStringList( lst ); +} + +QWidget *ReceiverItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SLOT( receiverChanged( const QString & ) ) ); + return cb; +} + +void ReceiverItem::setReceiverEx( QObject *receiver ) +{ + setCurrentItem( receiver->name() ); + emit currentReceiverChanged( receiver ); +} + +void ReceiverItem::receiverChanged( const QString &receiver ) +{ + QObject *o = formWindow->child( receiver, "QObject" ); + if ( !o ) + o = formWindow->findAction( receiver ); + if ( !o ) + return; + emit currentReceiverChanged( o ); +} + + + +// ------------------------------------------------------------------ + +SignalItem::SignalItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + lst << "<No Signal>"; + lst.sort(); + setStringList( lst ); +} + +void SignalItem::senderChanged( QObject *sender ) +{ + QStrList sigs = sender->metaObject()->signalNames( TRUE ); + sigs.remove( "destroyed()" ); + sigs.remove( "destroyed(QObject*)" ); + sigs.remove( "accessibilityChanged(int)" ); + sigs.remove( "accessibilityChanged(int,int)" ); + + QStringList lst = QStringList::fromStrList( sigs ); + + if ( ::qt_cast<CustomWidget*>(sender) ) { + MetaDataBase::CustomWidget *w = ( (CustomWidget*)sender )->customWidget(); + for ( QValueList<QCString>::Iterator it = w->lstSignals.begin(); + it != w->lstSignals.end(); ++it ) + lst << MetaDataBase::normalizeFunction( *it ); + } + + if ( sender == formWindow->mainContainer() ) { + QStringList extra = MetaDataBase::signalList( formWindow ); + if ( !extra.isEmpty() ) + lst += extra; + } + + lst.prepend( "<No Signal>" ); + + lst.sort(); + setStringList( lst ); + + ConnectionItem::senderChanged( sender ); +} + +QWidget *SignalItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SIGNAL( currentSignalChanged( const QString & ) ) ); + return cb; +} + +// ------------------------------------------------------------------ + +SlotItem::SlotItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + lst << "<No Slot>"; + lst.sort(); + setStringList( lst ); + + lastReceiver = 0; + lastSignal = "<No Signal>"; +} + +void SlotItem::receiverChanged( QObject *receiver ) +{ + lastReceiver = receiver; + updateSlotList(); + ConnectionItem::receiverChanged( receiver ); +} + +void SlotItem::signalChanged( const QString &signal ) +{ + lastSignal = signal; + updateSlotList(); + ConnectionItem::signalChanged( signal ); +} + +bool SlotItem::ignoreSlot( const char* slot ) const +{ +#ifndef QT_NO_SQL + if ( qstrcmp( slot, "update()" ) == 0 && + ::qt_cast<QDataBrowser*>(lastReceiver) ) + return FALSE; +#endif + + for ( int i = 0; ignore_slots[i]; i++ ) { + if ( qstrcmp( slot, ignore_slots[i] ) == 0 ) + return TRUE; + } + + if ( !formWindow->isMainContainer( (QWidget*)lastReceiver ) ) { + if ( qstrcmp( slot, "close()" ) == 0 ) + return TRUE; + } + + if ( qstrcmp( slot, "setFocus()" ) == 0 ) + if ( lastReceiver->isWidgetType() && + ( (QWidget*)lastReceiver )->focusPolicy() == QWidget::NoFocus ) + return TRUE; + + return FALSE; +} + +void SlotItem::updateSlotList() +{ + QStringList lst; + if ( !lastReceiver || lastSignal == "<No Signal>" ) { + lst << "<No Slot>"; + lst.sort(); + setStringList( lst ); + return; + } + + QString signal = MetaDataBase::normalizeFunction( lastSignal ); + int n = lastReceiver->metaObject()->numSlots( TRUE ); + QStringList slts; + + for( int i = 0; i < n; ++i ) { + // accept only public slots. For the form window, also accept protected slots + const QMetaData* md = lastReceiver->metaObject()->slot( i, TRUE ); + if ( ( (lastReceiver->metaObject()->slot( i, TRUE )->access == QMetaData::Public) || + (formWindow->isMainContainer( (QWidget*)lastReceiver ) && + lastReceiver->metaObject()->slot(i, TRUE)->access == + QMetaData::Protected) ) && + !ignoreSlot( md->name ) && + checkConnectArgs( signal.latin1(), lastReceiver, md->name ) ) + if ( lst.find( md->name ) == lst.end() ) + lst << MetaDataBase::normalizeFunction( md->name ); + } + + LanguageInterface *iface = + MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( !iface || iface->supports( LanguageInterface::ConnectionsToCustomSlots ) ) { + if ( formWindow->isMainContainer( (QWidget*)lastReceiver ) ) { + QValueList<MetaDataBase::Function> moreSlots = MetaDataBase::slotList( formWindow ); + if ( !moreSlots.isEmpty() ) { + for ( QValueList<MetaDataBase::Function>::Iterator it = moreSlots.begin(); + it != moreSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + s = MetaDataBase::normalizeFunction( s ); + if ( checkConnectArgs( signal.latin1(), lastReceiver, s ) ) { + if ( lst.find( (*it).function ) == lst.end() ) + lst << s; + } + } + } + } + } + + if ( ::qt_cast<CustomWidget*>(lastReceiver) ) { + MetaDataBase::CustomWidget *w = ( (CustomWidget*)lastReceiver )->customWidget(); + for ( QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.begin(); + it != w->lstSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + s = MetaDataBase::normalizeFunction( s ); + if ( checkConnectArgs( signal.latin1(), lastReceiver, s ) ) { + if ( lst.find( (*it).function ) == lst.end() ) + lst << s; + } + } + } + + lst.prepend( "<No Slot>" ); + lst.sort(); + setStringList( lst ); +} + +QWidget *SlotItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SIGNAL( currentSlotChanged( const QString & ) ) ); + return cb; +} + +void SlotItem::customSlotsChanged() +{ + QString currSlot = currentText(); + updateSlotList(); + setCurrentItem( "<No Slot>" ); + setCurrentItem( currSlot ); + emit currentSlotChanged( currentText() ); +} diff --git a/kdevdesigner/designer/connectionitems.h b/kdevdesigner/designer/connectionitems.h new file mode 100644 index 00000000..2442e475 --- /dev/null +++ b/kdevdesigner/designer/connectionitems.h @@ -0,0 +1,220 @@ +/********************************************************************** +** Copyright (C) 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. +** +**********************************************************************/ + +#ifndef CONNECTIONITEMS_H +#define CONNECTIONITEMS_H + +class FormWindow; + +#include <qtable.h> + +class SenderItem; +class ReceiverItem; +class SignalItem; +class SlotItem; +class ConnectionContainer; + + +class ConnectionItem : public QObject, + public QComboTableItem +{ + Q_OBJECT + +public: + ConnectionItem( QTable *table, FormWindow *fw ); + + void paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ); + + void setSender( SenderItem *i ); + void setReceiver( ReceiverItem *i ); + void setSignal( SignalItem *i ); + void setSlot( SlotItem *i ); + void setConnection( ConnectionContainer *c ); + +public slots: + virtual void senderChanged( QObject *sender ); + virtual void receiverChanged( QObject *receiver ); + virtual void signalChanged( const QString &sig ); + virtual void slotChanged( const QString &slot ); + +signals: + void changed(); + +protected: + FormWindow *formWindow; + +private: + ConnectionContainer *conn; + +}; + +// ------------------------------------------------------------------ + +class SenderItem : public ConnectionItem +{ + Q_OBJECT + +public: + SenderItem( QTable *table, FormWindow *fw ); + QWidget *createEditor() const; + void setSenderEx( QObject *sender ); + +signals: + void currentSenderChanged( QObject *sender ); + +private slots: + void senderChanged( const QString &sender ); + +}; + +// ------------------------------------------------------------------ + +class ReceiverItem : public ConnectionItem +{ + Q_OBJECT + +public: + ReceiverItem( QTable *table, FormWindow *fw ); + QWidget *createEditor() const; + void setReceiverEx( QObject *receiver ); + +signals: + void currentReceiverChanged( QObject *receiver ); + +private slots: + void receiverChanged( const QString &receiver ); + +}; + +// ------------------------------------------------------------------ + +class SignalItem : public ConnectionItem +{ + Q_OBJECT + +public: + SignalItem( QTable *table, FormWindow *fw ); + + void senderChanged( QObject *sender ); + QWidget *createEditor() const; + +signals: + void currentSignalChanged( const QString & ); + +}; + +// ------------------------------------------------------------------ + +class SlotItem : public ConnectionItem +{ + Q_OBJECT + +public: + SlotItem( QTable *table, FormWindow *fw ); + + void receiverChanged( QObject *receiver ); + void signalChanged( const QString &signal ); + QWidget *createEditor() const; + + void customSlotsChanged(); + +signals: + void currentSlotChanged( const QString & ); + +private: + void updateSlotList(); + bool ignoreSlot( const char* slot ) const; + +private: + QObject *lastReceiver; + QString lastSignal; + +}; + +// ------------------------------------------------------------------ + +class ConnectionContainer : public QObject +{ + Q_OBJECT + +public: + ConnectionContainer( QObject *parent, SenderItem *i1, SignalItem *i2, + ReceiverItem *i3, SlotItem *i4, int r ) + : QObject( parent ), mod( FALSE ), se( i1 ), si( i2 ), + re( i3 ), sl( i4 ), rw ( r ) { + i1->setConnection( this ); + i2->setConnection( this ); + i3->setConnection( this ); + i4->setConnection( this ); + connect( i1, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + connect( i2, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + connect( i3, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + connect( i4, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + } + + bool isModified() const { return mod; } + void setModified( bool b ) { mod = b; repaint(); } + bool isValid() const { + return se->currentText()[0] != '<' && + si->currentText()[0] != '<' && + re->currentText()[0] != '<' && + sl->currentText()[0] != '<'; + } + + void repaint() { + se->table()->updateCell( se->row(), se->col() ); + si->table()->updateCell( si->row(), si->col() ); + re->table()->updateCell( re->row(), re->col() ); + sl->table()->updateCell( sl->row(), sl->col() ); + } + + int row() const { return rw; } + void setRow( int r ) { rw = r; } + + SenderItem *senderItem() const { return se; } + SignalItem *signalItem() const { return si; } + ReceiverItem *receiverItem() const { return re; } + SlotItem *slotItem() const { return sl; } + +public slots: + void somethingChanged() { mod = TRUE; emit changed( this ); } + +signals: + void changed( ConnectionContainer *c ); + +private: + bool mod; + SenderItem *se; + SignalItem *si; + ReceiverItem *re; + SlotItem *sl; + int rw; + +}; + + +#endif diff --git a/kdevdesigner/designer/connectiontable.cpp b/kdevdesigner/designer/connectiontable.cpp new file mode 100644 index 00000000..7fed1b07 --- /dev/null +++ b/kdevdesigner/designer/connectiontable.cpp @@ -0,0 +1,56 @@ + /********************************************************************** +** 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 "connectiontable.h" + +#include <klocale.h> + +ConnectionTable::ConnectionTable( QWidget *parent, const char *name ) + : QTable( 0, 4, parent, name ) +{ + setSorting( TRUE ); + setShowGrid( FALSE ); + setFocusStyle( FollowStyle ); + setSelectionMode( SingleRow ); + horizontalHeader()->setLabel( 0, i18n( "Sender" ) ); + horizontalHeader()->setLabel( 1, i18n( "Signal" ) ); + horizontalHeader()->setLabel( 2, i18n( "Receiver" ) ); + horizontalHeader()->setLabel( 3, i18n( "Slot" ) ); + setColumnStretchable( 0, TRUE ); + setColumnStretchable( 1, TRUE ); + setColumnStretchable( 2, TRUE ); + setColumnStretchable( 3, TRUE ); +} + +void ConnectionTable::sortColumn( int col, bool ascending, bool ) +{ + horizontalHeader()->setSortIndicator( col, ascending ); + if ( isEditing() ) + endEdit( currEditRow(), currEditCol(), FALSE, FALSE ); + QTable::sortColumn( col, ascending, TRUE ); + setCurrentCell( 0, 0 ); + emit resorted(); +} diff --git a/kdevdesigner/designer/connectiontable.h b/kdevdesigner/designer/connectiontable.h new file mode 100644 index 00000000..288b544f --- /dev/null +++ b/kdevdesigner/designer/connectiontable.h @@ -0,0 +1,46 @@ + /********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef CONNECTIONTABLE_H +#define CONNECTIONTABLE_H + +#include <qtable.h> + +class ConnectionTable : public QTable +{ + Q_OBJECT + +public: + ConnectionTable( QWidget *parent, const char *name ); + + void sortColumn( int col, bool ascending, bool wholeRows ); + +signals: + void resorted(); + +}; + +#endif diff --git a/kdevdesigner/designer/createtemplate.ui b/kdevdesigner/designer/createtemplate.ui new file mode 100644 index 00000000..761873cc --- /dev/null +++ b/kdevdesigner/designer/createtemplate.ui @@ -0,0 +1,195 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CreateTemplate</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>CreateTemplate</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>347</width> + <height>248</height> + </rect> + </property> + <property name="caption"> + <string>Create Template</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Template &name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editName</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Name of the new template</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Enter the name of the new template</string> + </property> + </widget> + <widget class="QListBox" row="1" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>listClass</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Class of the new template</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Enter the name of the class which should be used as the template's base class</string> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCreate</cstring> + </property> + <property name="text"> + <string>C&reate</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Creates the new template</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Closes the Dialog</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>&Baseclass for template:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>listClass</cstring> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>buttonCreate</sender> + <signal>clicked()</signal> + <receiver>CreateTemplate</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>CreateTemplate</receiver> + <slot>reject()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/kdevdesigner/designer/customwidgeteditor.ui b/kdevdesigner/designer/customwidgeteditor.ui new file mode 100644 index 00000000..4d0e301a --- /dev/null +++ b/kdevdesigner/designer/customwidgeteditor.ui @@ -0,0 +1,1378 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>CustomWidgetEditorBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>CustomWidgetEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>712</width> + <height>386</height> + </rect> + </property> + <property name="caption"> + <string>Edit Custom Widgets</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Edit Custom Widgets</b><p>Add or delete custom widgets from <i>Qt Designer</i>'s database, and edit the properties of existing widgets.</p></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListBox" row="0" column="0" rowspan="5" colspan="1"> + <property name="name"> + <cstring>boxWidgets</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>The list of all custom widgets known to Qt Designer.</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>buttonNewWidget</cstring> + </property> + <property name="text"> + <string>&New Widget</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add new custom widget.</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Create an empty custom widget and add it to the list.</b><p>New custom widgets have a default name and header file, which must both be changed to appropriate values.</p></string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>buttonDeleteWidget</cstring> + </property> + <property name="text"> + <string>&Delete Widget</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete custom widget</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the selected custom widget.</b><p>You can only delete widgets that are not used in any open form.</p></string> + </property> + </widget> + <widget class="QLayoutWidget" row="5" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Closes the Dialog.</string> + </property> + </widget> + </hbox> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>Vertical Spacing1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="3" column="1"> + <property name="name"> + <cstring>buttonLoad</cstring> + </property> + <property name="text"> + <string>&Load Descriptions...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Loads widget description file</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Load Descriptions</b><p>Loads a file which contains descriptions of custom widgets, so that these custom widgets can be used in the Qt Designer.</p> +<p>Since it is a lot of work to type in all the information for custom widgets, you should consider using the createcw tool which is in $QTDIR/tools/designer/tools/createcw. Using createcw you can create custom widget description files for your custom widgets without the need to type in all the information manually. For more information about the README file in the createcw directory</p></string> + </property> + </widget> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>buttonSave</cstring> + </property> + <property name="text"> + <string>&Save Descriptions...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Saves widget description file</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Save Descriptions</b><p>Saves all the descriptions of the shown custom widgets to a file which can then be used to import the custom widgets elsewhere.</string> + </property> + </widget> + <widget class="QTabWidget" row="0" column="2" rowspan="5" colspan="1"> + <property name="name"> + <cstring>TabWidget1</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>Change the properties of the selected custom widget.</string> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget2</cstring> + </property> + <attribute name="title"> + <string>De&finition</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>previewPixmap</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonChoosePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a pixmap file.</b><p>The pixmap will be used to represent the widget in forms.</p></string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editHeader</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Enter filename</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the header file's name for the selected custom widget.</b><p>The header file will be included by forms using the widget.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonChooseHeader</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Choose headerfile</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Look for the header file using a file dialog.</string> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Global</string> + </property> + </item> + <item> + <property name="text"> + <string>Local</string> + </property> + </item> + <property name="name"> + <cstring>localGlobalCombo</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Select access</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change how the include file will be included.</b><p>Global include files will be included using &lt;&gt;-brackets, while local files will included using quotation marks.</p></string> + </property> + </widget> + </hbox> + </widget> + <widget class="KLineEdit" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>editClass</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change classname</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Enter the classname for the selected custom widget.</b><p>A class of that name must be defined in the header file.</p></string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label11</cstring> + </property> + <property name="text"> + <string>Heade&rfile:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editHeader</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>Label10</cstring> + </property> + <property name="text"> + <string>Cl&ass:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editClass</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>Label2</cstring> + </property> + <property name="text"> + <string>Pixmap:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>Label7</cstring> + </property> + <property name="text"> + <string>Si&ze hint:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinWidth</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>Size p&olicy:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sizeHor</cstring> + </property> + </widget> + <widget class="QComboBox" row="4" column="2"> + <item> + <property name="text"> + <string>Fixed</string> + </property> + </item> + <item> + <property name="text"> + <string>Minimum</string> + </property> + </item> + <item> + <property name="text"> + <string>Maximum</string> + </property> + </item> + <item> + <property name="text"> + <string>Preferred</string> + </property> + </item> + <item> + <property name="text"> + <string>MinimumExpanding</string> + </property> + </item> + <item> + <property name="text"> + <string>Expanding</string> + </property> + </item> + <property name="name"> + <cstring>sizeVer</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Vertical Sizepolicy</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose the Vertical size policy</string> + </property> + </widget> + <widget class="QSpinBox" row="3" column="1"> + <property name="name"> + <cstring>spinWidth</cstring> + </property> + <property name="maxValue"> + <number>32767</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>-1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Size hint width</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Set the size hint for the selected widget.</b><p>The size hint provides the recommended size for the widget. Enter a sizehint of -1/-1 if no size is recommended.</p></string> + </property> + </widget> + <widget class="QSpinBox" row="3" column="2"> + <property name="name"> + <cstring>spinHeight</cstring> + </property> + <property name="maxValue"> + <number>32767</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>-1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Size hint height</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Set the size hint for the selected widget.</b><p>The size hint provides the recommended size for the widget. Enter a sizehint of -1/-1 if no size is recommended.</p></string> + </property> + </widget> + <widget class="QComboBox" row="4" column="1"> + <item> + <property name="text"> + <string>Fixed</string> + </property> + </item> + <item> + <property name="text"> + <string>Minimum</string> + </property> + </item> + <item> + <property name="text"> + <string>Maximum</string> + </property> + </item> + <item> + <property name="text"> + <string>Preferred</string> + </property> + </item> + <item> + <property name="text"> + <string>MinimumExpanding</string> + </property> + </item> + <item> + <property name="text"> + <string>Expanding</string> + </property> + </item> + <property name="name"> + <cstring>sizeHor</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Horizontal Sizepolicy</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose the horizontal size policy for the widget</string> + </property> + </widget> + <spacer row="6" column="2"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="5" column="1"> + <property name="name"> + <cstring>checkContainer</cstring> + </property> + <property name="text"> + <string>Con&tainer widget</string> + </property> + <property name="toolTip" stdset="0"> + <string>Container Widget</string> + </property> + <property name="whatsThis" stdset="0"> + <string><p><b>Container Widget</b></p> +<p>If this custom widget is able to contain other widgets (children), check this checkbox.</p></string> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget3</cstring> + </property> + <attribute name="title"> + <string>Si&gnals</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListBox"> + <property name="name"> + <cstring>listSignals</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>The list of all the signals that the selected widget can emit.</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout40</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonAddSignal</cstring> + </property> + <property name="text"> + <string>N&ew Signal</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Add new signal</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Add a new signal for the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonRemoveSignal</cstring> + </property> + <property name="text"> + <string>Dele&te Signal</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Delete signal</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the signal.</b><p>All connections using this signal will also be deleted.</p></string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout38</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>S&ignal:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editSignal</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editSignal</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change signal name</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the name of the selected slot.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p></string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget4</cstring> + </property> + <attribute name="title"> + <string>S&lots</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Slot</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Access</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listSlots</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="showSortIndicator"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>The list of all the custom widget's slots.</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Sl&ot:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editSlot</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>editSlot</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change slot name</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the name of the selected slot.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p></string> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>&Access:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboAccess</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="3"> + <item> + <property name="text"> + <string>public</string> + </property> + </item> + <item> + <property name="text"> + <string>protected</string> + </property> + </item> + <property name="name"> + <cstring>comboAccess</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change slot access</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the slot's access policy.</b><p>You can only connect to the widget's public slots.</p></string> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>Layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonAddSlot</cstring> + </property> + <property name="text"> + <string>N&ew Slot</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Add new slot</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Add a new slot to the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonRemoveSlot</cstring> + </property> + <property name="text"> + <string>Dele&te Slot</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Delete slot</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the slot.</b><p>All connections using this slot will also be deleted.</p></string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget5</cstring> + </property> + <attribute name="title"> + <string>&Properties</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>Layout7_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonAddProperty</cstring> + </property> + <property name="text"> + <string>N&ew Property</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Add new property</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Add a new property to the current custom widget.</b><p>The properties must be implemented in the class using Qt's property system.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonRemoveProperty</cstring> + </property> + <property name="text"> + <string>Dele&te Property</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Delete property</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Deletes the selected property.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QComboBox" row="2" column="3"> + <item> + <property name="text"> + <string>String</string> + </property> + </item> + <item> + <property name="text"> + <string>CString</string> + </property> + </item> + <item> + <property name="text"> + <string>StringList</string> + </property> + </item> + <item> + <property name="text"> + <string>Bool</string> + </property> + </item> + <item> + <property name="text"> + <string>Int</string> + </property> + </item> + <item> + <property name="text"> + <string>UInt</string> + </property> + </item> + <item> + <property name="text"> + <string>Font</string> + </property> + </item> + <item> + <property name="text"> + <string>Color</string> + </property> + </item> + <item> + <property name="text"> + <string>Rect</string> + </property> + </item> + <item> + <property name="text"> + <string>Point</string> + </property> + </item> + <item> + <property name="text"> + <string>Size</string> + </property> + </item> + <item> + <property name="text"> + <string>Pixmap</string> + </property> + </item> + <item> + <property name="text"> + <string>Palette</string> + </property> + </item> + <item> + <property name="text"> + <string>Cursor</string> + </property> + </item> + <item> + <property name="text"> + <string>SizePolicy</string> + </property> + </item> + <property name="name"> + <cstring>comboType</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Select property type</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select the type of the property.</b><p>The property must be implemented in the class using Qt's property system.</p><p>You can use integer types to support enumeration properties in the property editor.</p></string> + </property> + </widget> + <widget class="QListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Property</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listProperties</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="showSortIndicator"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>The list of the current widget's properties.</b><p>The properties of the custom widget can be changed in the property editor.</p></string> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>editProperty</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change property name</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Enter a name for the property.</b><p>The properties must be implemented in the class using Qt's property system.</p></string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>P&roperty name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editProperty</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>TextLabel3_2</cstring> + </property> + <property name="text"> + <string>T&ype:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboType</cstring> + </property> + </widget> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>boxWidgets</sender> + <signal>selectionChanged(QListBoxItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentWidgetChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>boxWidgets</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentWidgetChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>buttonNewWidget</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>addWidgetClicked()</slot> + </connection> + <connection> + <sender>buttonDeleteWidget</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>deleteWidgetClicked()</slot> + </connection> + <connection> + <sender>editClass</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>classNameChanged(const QString&)</slot> + </connection> + <connection> + <sender>editHeader</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>headerFileChanged(const QString&)</slot> + </connection> + <connection> + <sender>spinWidth</sender> + <signal>valueChanged(int)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>widthChanged(int)</slot> + </connection> + <connection> + <sender>spinHeight</sender> + <signal>valueChanged(int)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>heightChanged(int)</slot> + </connection> + <connection> + <sender>buttonChoosePixmap</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>pixmapChoosen()</slot> + </connection> + <connection> + <sender>localGlobalCombo</sender> + <signal>highlighted(int)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>includePolicyChanged(int)</slot> + </connection> + <connection> + <sender>buttonChooseHeader</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>chooseHeader()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>closeClicked()</slot> + </connection> + <connection> + <sender>listSignals</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentSignalChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>listSignals</sender> + <signal>selectionChanged(QListBoxItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentSignalChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>buttonRemoveSignal</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>removeSignal()</slot> + </connection> + <connection> + <sender>editSignal</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>signalNameChanged(const QString&)</slot> + </connection> + <connection> + <sender>listSlots</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentSlotChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>listSlots</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentSlotChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>buttonRemoveSlot</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>removeSlot()</slot> + </connection> + <connection> + <sender>editSlot</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>slotNameChanged(const QString&)</slot> + </connection> + <connection> + <sender>comboAccess</sender> + <signal>activated(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>slotAccessChanged(const QString&)</slot> + </connection> + <connection> + <sender>listProperties</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentPropertyChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>listProperties</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>currentPropertyChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>buttonRemoveProperty</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>removeProperty()</slot> + </connection> + <connection> + <sender>editProperty</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>propertyNameChanged(const QString&)</slot> + </connection> + <connection> + <sender>comboType</sender> + <signal>activated(const QString&)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>propertyTypeChanged(const QString&)</slot> + </connection> + <connection> + <sender>buttonLoad</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>loadDescription()</slot> + </connection> + <connection> + <sender>buttonSave</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>saveDescription()</slot> + </connection> + <connection> + <sender>sizeHor</sender> + <signal>activated(int)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>horDataChanged(int)</slot> + </connection> + <connection> + <sender>sizeVer</sender> + <signal>activated(int)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>verDataChanged(int)</slot> + </connection> + <connection> + <sender>buttonAddProperty</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>addProperty()</slot> + </connection> + <connection> + <sender>checkContainer</sender> + <signal>toggled(bool)</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>widgetIsContainer(bool)</slot> + </connection> + <connection> + <sender>buttonAddSignal</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>addSignal()</slot> + </connection> + <connection> + <sender>buttonAddSlot</sender> + <signal>clicked()</signal> + <receiver>CustomWidgetEditorBase</receiver> + <slot>addSlot()</slot> + </connection> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> + <slot access="protected" language="C++" returnType="void">addProperty()</slot> + <slot access="public" language="C++" returnType="void">addSignal()</slot> + <slot access="protected" language="C++" returnType="void">addWidgetClicked()</slot> + <slot access="protected" language="C++" returnType="void">chooseHeader()</slot> + <slot access="protected" language="C++" returnType="void">classNameChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">closeClicked()</slot> + <slot access="protected" language="C++" returnType="void">currentPropertyChanged( QListViewItem * )</slot> + <slot access="protected" language="C++" returnType="void">currentSignalChanged( QListBoxItem * )</slot> + <slot access="protected" language="C++" returnType="void">currentSlotChanged( QListViewItem * )</slot> + <slot access="protected" language="C++" returnType="void">currentWidgetChanged( QListBoxItem * )</slot> + <slot access="protected" language="C++" returnType="void">deleteWidgetClicked()</slot> + <slot access="protected" language="C++" returnType="void">headerFileChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">heightChanged( int )</slot> + <slot access="protected" language="C++" returnType="void">horDataChanged(int)</slot> + <slot access="protected" language="C++" returnType="void">includePolicyChanged( int )</slot> + <slot access="public" language="C++" returnType="void">loadDescription()</slot> + <slot access="public" language="C++" returnType="void">addSlot()</slot> + <slot access="protected" language="C++" returnType="void">pixmapChoosen()</slot> + <slot access="protected" language="C++" returnType="void">propertyNameChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">propertyTypeChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">removeProperty()</slot> + <slot access="protected" language="C++" returnType="void">removeSignal()</slot> + <slot access="protected" language="C++" returnType="void">removeSlot()</slot> + <slot access="protected" language="C++" returnType="void">saveDescription()</slot> + <slot access="protected" language="C++" returnType="void">signalNameChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">slotAccessChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">slotNameChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">verDataChanged(int)</slot> + <slot access="protected" language="C++" returnType="void">widgetIsContainer(bool)</slot> + <slot access="protected" language="C++" returnType="void">widthChanged( int )</slot> +</connections> +<tabstops> + <tabstop>buttonCancel</tabstop> + <tabstop>boxWidgets</tabstop> + <tabstop>buttonNewWidget</tabstop> + <tabstop>buttonDeleteWidget</tabstop> + <tabstop>buttonLoad</tabstop> + <tabstop>buttonSave</tabstop> + <tabstop>TabWidget1</tabstop> + <tabstop>editClass</tabstop> + <tabstop>editHeader</tabstop> + <tabstop>buttonChooseHeader</tabstop> + <tabstop>localGlobalCombo</tabstop> + <tabstop>buttonChoosePixmap</tabstop> + <tabstop>spinWidth</tabstop> + <tabstop>spinHeight</tabstop> + <tabstop>sizeHor</tabstop> + <tabstop>sizeVer</tabstop> + <tabstop>checkContainer</tabstop> + <tabstop>helpButton</tabstop> + <tabstop>listSignals</tabstop> + <tabstop>buttonAddSignal</tabstop> + <tabstop>buttonRemoveSignal</tabstop> + <tabstop>editSignal</tabstop> + <tabstop>listSlots</tabstop> + <tabstop>buttonAddSlot</tabstop> + <tabstop>buttonRemoveSlot</tabstop> + <tabstop>editSlot</tabstop> + <tabstop>comboAccess</tabstop> + <tabstop>listProperties</tabstop> + <tabstop>buttonAddProperty</tabstop> + <tabstop>buttonRemoveProperty</tabstop> + <tabstop>editProperty</tabstop> + <tabstop>comboType</tabstop> +</tabstops> +</UI> diff --git a/kdevdesigner/designer/customwidgeteditorimpl.cpp b/kdevdesigner/designer/customwidgeteditorimpl.cpp new file mode 100644 index 00000000..dc0ed1a8 --- /dev/null +++ b/kdevdesigner/designer/customwidgeteditorimpl.cpp @@ -0,0 +1,842 @@ +/********************************************************************** +** 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 "customwidgeteditorimpl.h" +#include "defs.h" +#include "pixmapchooser.h" +#include "mainwindow.h" +#include "asciivalidator.h" +#include "resource.h" +#include "widgetfactory.h" +#include "widgetdatabase.h" + +#include <kfiledialog.h> +#include <klineedit.h> + +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qspinbox.h> +#include <qlabel.h> +#include <qmessagebox.h> +#include <qfiledialog.h> +#include <qmessagebox.h> +#include <qtimer.h> +#include <qapplication.h> +#include <qlistview.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qdom.h> +#include <qtextcodec.h> +#include <qcheckbox.h> + +#include <klocale.h> + +CustomWidgetEditor::CustomWidgetEditor( QWidget *parent, MainWindow *mw ) + : CustomWidgetEditorBase( parent, 0, TRUE ), mainWindow( mw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + checkTimer = new QTimer( this ); + connect( checkTimer, SIGNAL( timeout() ), + this, SLOT( checkWidgetName() ) ); + + editClass->setEnabled( FALSE ); + editHeader->setEnabled( FALSE ); + buttonChooseHeader->setEnabled( FALSE ); + buttonChoosePixmap->setEnabled( FALSE ); + spinWidth->setEnabled( FALSE ); + spinHeight->setEnabled( FALSE ); + sizeHor->setEnabled( FALSE ); + sizeVer->setEnabled( FALSE ); + checkContainer->setEnabled( FALSE ); + localGlobalCombo->setEnabled( FALSE ); + editClass->setValidator( new AsciiValidator( QString(":"), editClass ) ); + editSignal->setValidator( new AsciiValidator( TRUE, editSignal ) ); + editSlot->setValidator( new AsciiValidator( TRUE, editSignal ) ); + editProperty->setValidator( new AsciiValidator( editSignal ) ); + editSignal->setEnabled( FALSE ); + buttonRemoveSignal->setEnabled( FALSE ); + + setupDefinition(); + setupSignals(); + setupSlots(); + setupProperties(); +} + +void CustomWidgetEditor::setupDefinition() +{ + QPtrList<MetaDataBase::CustomWidget> *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + QListBoxItem *i; + if ( w->pixmap ) + i = new QListBoxPixmap( boxWidgets, *w->pixmap, w->className ); + else + i = new QListBoxText( boxWidgets, w->className ); + customWidgets.insert( i, w ); + } + + if ( boxWidgets->firstItem() ) { + boxWidgets->setCurrentItem( boxWidgets->firstItem() ); + boxWidgets->setSelected( boxWidgets->firstItem(), TRUE ); + } + oldItem = 0; +} + +void CustomWidgetEditor::setupSignals() +{ + editSignal->setEnabled( FALSE ); + buttonRemoveSignal->setEnabled( FALSE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w ) + return; + listSignals->clear(); + for ( QValueList<QCString>::Iterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + listSignals->insertItem( QString( *it ) ); + if ( listSignals->firstItem() ) { + listSignals->setCurrentItem( listSignals->firstItem() ); + listSignals->setSelected( listSignals->firstItem(), TRUE ); + } +} + +void CustomWidgetEditor::setupSlots() +{ + editSlot->setEnabled( FALSE ); + comboAccess->setEnabled( FALSE ); + buttonRemoveSlot->setEnabled( FALSE ); + + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w ) + return; + listSlots->clear(); + for ( QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) + (void)new QListViewItem( listSlots, (*it).function, (*it).access ); + + if ( listSlots->firstChild() ) { + listSlots->setCurrentItem( listSlots->firstChild() ); + listSlots->setSelected( listSlots->firstChild(), TRUE ); + } +} + +void CustomWidgetEditor::setupProperties() +{ + editProperty->setEnabled( FALSE ); + comboType->setEnabled( FALSE ); + buttonRemoveProperty->setEnabled( FALSE ); + + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w ) + return; + listProperties->clear(); + for ( QValueList<MetaDataBase::Property>::Iterator it = w->lstProperties.begin(); it != w->lstProperties.end(); ++it ) + (void)new QListViewItem( listProperties, (*it).property, (*it).type ); + + if ( listProperties->firstChild() ) { + listProperties->setCurrentItem( listProperties->firstChild() ); + listProperties->setSelected( listProperties->firstChild(), TRUE ); + } +} + +void CustomWidgetEditor::currentWidgetChanged( QListBoxItem *i ) +{ + checkTimer->stop(); + checkWidgetName(); + + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) { + buttonChooseHeader->setEnabled( FALSE ); + editClass->setEnabled( FALSE ); + editHeader->setEnabled( FALSE ); + buttonChoosePixmap->setEnabled( FALSE ); + spinWidth->setEnabled( FALSE ); + spinHeight->setEnabled( FALSE ); + localGlobalCombo->setEnabled( FALSE ); + sizeHor->setEnabled( FALSE ); + sizeVer->setEnabled( FALSE ); + checkContainer->setEnabled( FALSE ); + return; + } + + buttonChooseHeader->setEnabled( TRUE ); + editClass->setEnabled( TRUE ); + editHeader->setEnabled( TRUE ); + buttonChoosePixmap->setEnabled( TRUE ); + spinWidth->setEnabled( TRUE ); + spinHeight->setEnabled( TRUE ); + localGlobalCombo->setEnabled( TRUE ); + sizeHor->setEnabled( TRUE ); + sizeVer->setEnabled( TRUE ); + checkContainer->setEnabled( TRUE ); + + editClass->blockSignals( TRUE ); + editClass->setText( w->className ); + editClass->blockSignals( FALSE ); + editHeader->setText( w->includeFile ); + localGlobalCombo->setCurrentItem( (int)w->includePolicy ); + if ( w->pixmap ) + previewPixmap->setPixmap( *w->pixmap ); + else + previewPixmap->setText( "" ); + spinWidth->setValue( w->sizeHint.width() ); + spinHeight->setValue( w->sizeHint.height() ); + sizeHor->setCurrentItem( size_type_to_int( w->sizePolicy.horData() ) ); + sizeVer->setCurrentItem( size_type_to_int( w->sizePolicy.verData() ) ); + checkContainer->setChecked( w->isContainer ); + + setupSignals(); + setupSlots(); + setupProperties(); +} + +void CustomWidgetEditor::addWidgetClicked() +{ + oldItem = 0; + checkTimer->stop(); + checkWidgetName(); + + MetaDataBase::CustomWidget *w = new MetaDataBase::CustomWidget; + QString s = w->className; + if ( !MetaDataBase::addCustomWidget( w ) ) { + QMessageBox::information( this, i18n( "Adding Custom Widget" ), + i18n( "Custom widget names must be unique.\n" + "A custom widget called '%1' already exists, so it is not possible " + "to add another widget with this name." ).arg( s ) ); + return; + } + + QListBoxPixmap *i = new QListBoxPixmap( boxWidgets, *w->pixmap, w->className ); + customWidgets.insert( i, w ); + + boxWidgets->setCurrentItem( i ); + boxWidgets->setSelected( i, TRUE ); +} + +void CustomWidgetEditor::classNameChanged( const QString &s ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + WidgetDatabase::customWidgetClassNameChanged( w->className, s ); + + checkTimer->stop(); + boxWidgets->blockSignals( TRUE ); + oldName = w->className; + w->className = s; + QListBoxItem *old = i; + if ( w->pixmap ) + boxWidgets->changeItem( *w->pixmap, s, boxWidgets->currentItem() ); + else + boxWidgets->changeItem( s, boxWidgets->currentItem() ); + i = boxWidgets->item( boxWidgets->currentItem() ); + oldItem = i; + customWidgets.insert( i, w ); + customWidgets.remove( old ); + boxWidgets->blockSignals( FALSE ); + checkTimer->start( 1000, TRUE ); +} + +void CustomWidgetEditor::deleteWidgetClicked() +{ + oldItem = 0; + checkTimer->stop(); + checkWidgetName(); + + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + + if ( mainWindow->isCustomWidgetUsed( w ) ) { + QMessageBox::information( mainWindow, i18n( "Removing Custom Widget" ), + i18n( "The custom widget '%1' is in use, so it cannot be removed." ). + arg( w->className ) ); + return; + } + + if ( !i || !w ) + return; + + MetaDataBase::CustomWidget *cw = MetaDataBase::customWidget( mainWindow->currentTool() ); + if ( cw == w ) + mainWindow->resetTool(); + + MetaDataBase::removeCustomWidget( w ); + customWidgets.remove( i ); + delete i; + + i = boxWidgets->item( boxWidgets->currentItem() ); + if ( i ) { + boxWidgets->setCurrentItem( i ); + boxWidgets->setSelected( i, TRUE ); + } +} + +void CustomWidgetEditor::headerFileChanged( const QString &s ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->includeFile = s; +} + +void CustomWidgetEditor::heightChanged( int h ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->sizeHint.setHeight( h ); + updateCustomWidgetSizes(); +} + +void CustomWidgetEditor::includePolicyChanged( int p ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->includePolicy = (MetaDataBase::CustomWidget::IncludePolicy)p; +} + +void CustomWidgetEditor::pixmapChoosen() +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QPixmap pix = qChoosePixmap( this ); + if ( pix.isNull() ) + return; + delete w->pixmap; + w->pixmap = new QPixmap( pix ); + + boxWidgets->blockSignals( TRUE ); + QListBoxItem *old = i; + boxWidgets->changeItem( *w->pixmap, w->className, boxWidgets->currentItem() ); + i = boxWidgets->item( boxWidgets->currentItem() ); + customWidgets.insert( i, w ); + customWidgets.remove( old ); + boxWidgets->blockSignals( FALSE ); + previewPixmap->setPixmap( *w->pixmap ); +} + +void CustomWidgetEditor::widthChanged( int wid ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->sizeHint.setWidth( wid ); + updateCustomWidgetSizes(); +} + +MetaDataBase::CustomWidget *CustomWidgetEditor::findWidget( QListBoxItem *i ) +{ + if ( !i ) + return 0; + + QMap<QListBoxItem*, MetaDataBase::CustomWidget*>::Iterator it = customWidgets.find( i ); + if ( it == customWidgets.end() ) + return 0; + return *it; +} + +void CustomWidgetEditor::chooseHeader() +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QString h = KFileDialog::getOpenFileName( QString::null, i18n( "*.h *.h++ *.hxx *.hh|Header Files" ), this ); + if ( h.isEmpty() ) + return; + editHeader->setText( h ); + localGlobalCombo->setCurrentItem( (int)MetaDataBase::CustomWidget::Global ); +} + +void CustomWidgetEditor::checkWidgetName() +{ + QListBoxItem *i = oldItem ? oldItem : boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + oldItem = 0; + if ( !i || !w ) + return; + + if ( MetaDataBase::isWidgetNameUsed( w ) ) { + QString s = w->className; + w->className = oldName; + QMessageBox::information( this, i18n( "Renaming Custom Widget" ), + i18n( "Custom widget names must be unique.\n" + "A custom widget called '%1' already exists, so it is not possible " + "to rename this widget with this name." ).arg( s ) ); + if ( i != boxWidgets->item( boxWidgets->currentItem() ) ) { + boxWidgets->setCurrentItem( i ); + qApp->processEvents(); + } + editClass->setText( w->className ); + classNameChanged( w->className ); + } +} + +void CustomWidgetEditor::closeClicked() +{ + oldItem = 0; + checkTimer->stop(); + checkWidgetName(); + accept(); +} + +void CustomWidgetEditor::currentSignalChanged( QListBoxItem *i ) +{ + editSignal->blockSignals( TRUE ); + editSignal->setText( "" ); + editSignal->blockSignals( FALSE ); + + if ( !i ) { + editSignal->setEnabled( FALSE ); + buttonRemoveSignal->setEnabled( FALSE ); + return; + } + + editSignal->blockSignals( TRUE ); + editSignal->setEnabled( TRUE ); + buttonRemoveSignal->setEnabled( TRUE ); + editSignal->setText( i->text() ); + editSignal->blockSignals( FALSE ); +} + +void CustomWidgetEditor::addSignal() +{ + QListBoxItem *i = new QListBoxText( listSignals, "signal()" ); + listSignals->setCurrentItem( i ); + listSignals->setSelected( i, TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) + w->lstSignals.append( i->text().latin1() ); +} + +void CustomWidgetEditor::removeSignal() +{ + QString s = listSignals->currentText(); + delete listSignals->item( listSignals->currentItem() ); + if ( listSignals->currentItem() != -1 ) + listSignals->setSelected( listSignals->currentItem(), TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) + w->lstSignals.remove( s.latin1() ); +} + +void CustomWidgetEditor::signalNameChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || listSignals->currentItem() == -1 ) + return; + + QValueList<QCString>::Iterator it = w->lstSignals.find( listSignals->currentText().latin1() ); + if ( it != w->lstSignals.end() ) + w->lstSignals.remove( it ); + listSignals->blockSignals( TRUE ); + listSignals->changeItem( s, listSignals->currentItem() ); + listSignals->blockSignals( FALSE ); + w->lstSignals.append( s.latin1() ); +} + +void CustomWidgetEditor::slotAccessChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listSlots->currentItem() ) + return; + + MetaDataBase::Function slot; + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.find( slot ); + if ( it != w->lstSlots.end() ) + w->lstSlots.remove( it ); + listSlots->currentItem()->setText( 1, s ); + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + w->lstSlots.append( slot ); +} + +void CustomWidgetEditor::slotNameChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listSlots->currentItem() ) + return; + + MetaDataBase::Function slot; + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + slot.type = "slot"; + QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.find( slot ); + if ( it != w->lstSlots.end() ) + w->lstSlots.remove( it ); + listSlots->currentItem()->setText( 0, s ); + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + w->lstSlots.append( slot ); +} + +void CustomWidgetEditor::addSlot() +{ + QListViewItem *i = new QListViewItem( listSlots, "slot()", "public" ); + listSlots->setCurrentItem( i ); + listSlots->setSelected( i, TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) { + MetaDataBase::Function slot; + slot.function = "slot()"; + slot.access = "public"; + slot.type = "slot"; + w->lstSlots.append( slot ); + } +} + +void CustomWidgetEditor::removeSlot() +{ + MetaDataBase::Function slot; + slot.function = "1 2 3"; + if ( listSlots->currentItem() ) { + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + } + delete listSlots->currentItem(); + if ( listSlots->currentItem() ) + listSlots->setSelected( listSlots->currentItem(), TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w && slot.function != "1 2 3" ) + w->lstSlots.remove( slot ); +} + +void CustomWidgetEditor::currentSlotChanged( QListViewItem *i ) +{ + editSlot->blockSignals( TRUE ); + editSlot->setText( "" ); + editSignal->blockSignals( FALSE ); + + if ( !i ) { + editSlot->setEnabled( FALSE ); + comboAccess->setEnabled( FALSE ); + buttonRemoveSlot->setEnabled( FALSE ); + return; + } + + editSlot->setEnabled( TRUE ); + comboAccess->setEnabled( TRUE ); + buttonRemoveSlot->setEnabled( TRUE ); + editSlot->blockSignals( TRUE ); + comboAccess->blockSignals( TRUE ); + editSlot->setText( i->text( 0 ) ); + if ( i->text( 1 ) == i18n( "protected" ) ) + comboAccess->setCurrentItem( 1 ); + else + comboAccess->setCurrentItem( 0 ); + editSlot->blockSignals( FALSE ); + comboAccess->blockSignals( FALSE ); +} + +void CustomWidgetEditor::propertyTypeChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listProperties->currentItem() ) + return; + + MetaDataBase::Property property; + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + QValueList<MetaDataBase::Property>::Iterator it = w->lstProperties.find( property ); + if ( it != w->lstProperties.end() ) + w->lstProperties.remove( it ); + listProperties->currentItem()->setText( 1, s ); + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + w->lstProperties.append( property ); +} + +void CustomWidgetEditor::propertyNameChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listProperties->currentItem() ) + return; + + MetaDataBase::Property property; + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + QValueList<MetaDataBase::Property>::Iterator it = w->lstProperties.find( property ); + if ( it != w->lstProperties.end() ) + w->lstProperties.remove( it ); + listProperties->currentItem()->setText( 0, s ); + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + w->lstProperties.append( property ); +} + +void CustomWidgetEditor::addProperty() +{ + QListViewItem *i = new QListViewItem( listProperties, "property", "String" ); + listProperties->setCurrentItem( i ); + listProperties->setSelected( i, TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) { + MetaDataBase::Property prop; + prop.property = "property"; + prop.type = "String"; + w->lstProperties.append( prop ); + } +} + +void CustomWidgetEditor::removeProperty() +{ + MetaDataBase::Property property; + property.property = "1 2 3"; + if ( listProperties->currentItem() ) { + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + } + delete listProperties->currentItem(); + if ( listProperties->currentItem() ) + listProperties->setSelected( listProperties->currentItem(), TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w && property.property != "1 2 3" ) + w->lstProperties.remove( property ); +} + +void CustomWidgetEditor::currentPropertyChanged( QListViewItem *i ) +{ + editProperty->blockSignals( TRUE ); + editProperty->setText( "" ); + editSignal->blockSignals( FALSE ); + + if ( !i ) { + editProperty->setEnabled( FALSE ); + comboType->setEnabled( FALSE ); + buttonRemoveProperty->setEnabled( FALSE ); + return; + } + + editProperty->setEnabled( TRUE ); + comboType->setEnabled( TRUE ); + buttonRemoveProperty->setEnabled( TRUE ); + editProperty->blockSignals( TRUE ); + comboType->blockSignals( TRUE ); + editProperty->setText( i->text( 0 ) ); + + for ( int j = 0; j < comboType->count(); ++j ) { + if ( i->text( 1 ) == comboType->text( j ) ) { + comboType->setCurrentItem( j ); + break; + } + } + editProperty->blockSignals( FALSE ); + comboType->blockSignals( FALSE ); +} + +static QString makeIndent2( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} + +static QString entitize2( const QString &s ) +{ + QString s2 = s; + s2 = s2.replace( "\"", """ ); + s2 = s2.replace( "&", "&" ); + s2 = s2.replace( ">", ">" ); + s2 = s2.replace( "<", "<" ); + s2 = s2.replace( "'", "'" ); + return s2; +} + +void CustomWidgetEditor::saveDescription() +{ + QString fn = KFileDialog::getSaveFileName( QString::null, i18n( "*.cw|Custom-Widget Description\n*|All Files" ), this ); + if ( fn.isEmpty() ) + return; + + if ( QFileInfo( fn ).extension() != "cw" ) + fn += ".cw"; + QFile f( fn ); + if ( !f.open( IO_WriteOnly ) ) + return; + + QTextStream ts( &f ); + ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); + int indent = 0; + + ts << "<!DOCTYPE CW><CW>" << endl; + + ts << makeIndent2( indent ) << "<customwidgets>" << endl; + indent++; + + QPtrList<MetaDataBase::CustomWidget> *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + ts << makeIndent2( indent ) << "<customwidget>" << endl; + indent++; + ts << makeIndent2( indent ) << "<class>" << w->className << "</class>" << endl; + ts << makeIndent2( indent ) << "<header location=\"" + << ( w->includePolicy == MetaDataBase::CustomWidget::Local ? "local" : "global" ) + << "\">" << w->includeFile << "</header>" << endl; + ts << makeIndent2( indent ) << "<sizehint>" << endl; + indent++; + ts << makeIndent2( indent ) << "<width>" << w->sizeHint.width() << "</width>" << endl; + ts << makeIndent2( indent ) << "<height>" << w->sizeHint.height() << "</height>" << endl; + indent--; + ts << makeIndent2( indent ) << "</sizehint>" << endl; + ts << makeIndent2( indent ) << "<container>" << (int)w->isContainer << "</container>" << endl; + ts << makeIndent2( indent ) << "<sizepolicy>" << endl; + indent++; + ts << makeIndent2( indent ) << "<hordata>" << (int)w->sizePolicy.horData() << "</hordata>" << endl; + ts << makeIndent2( indent ) << "<verdata>" << (int)w->sizePolicy.verData() << "</verdata>" << endl; + indent--; + ts << makeIndent2( indent ) << "</sizepolicy>" << endl; + ts << makeIndent2( indent ) << "<pixmap>" << endl; + indent++; + Resource::saveImageData( w->pixmap->convertToImage(), ts, indent ); + indent--; + ts << makeIndent2( indent ) << "</pixmap>" << endl; + if ( !w->lstSignals.isEmpty() ) { + for ( QValueList<QCString>::Iterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + ts << makeIndent2( indent ) << "<signal>" << entitize2( *it ) << "</signal>" << endl; + } + if ( !w->lstSlots.isEmpty() ) { + for ( QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) + ts << makeIndent2( indent ) << "<slot access=\"" << (*it).access << "\">" << entitize2( (*it).function ) << "</slot>" << endl; + } + if ( !w->lstProperties.isEmpty() ) { + for ( QValueList<MetaDataBase::Property>::Iterator it = w->lstProperties.begin(); it != w->lstProperties.end(); ++it ) + ts << makeIndent2( indent ) << "<property type=\"" << (*it).type << "\">" << entitize2( (*it).property ) << "</property>" << endl; + } + indent--; + ts << makeIndent2( indent ) << "</customwidget>" << endl; + } + + indent--; + ts << makeIndent2( indent ) << "</customwidgets>" << endl; + ts << "</CW>" << endl; +} + +void CustomWidgetEditor::loadDescription() +{ + QString fn = KFileDialog::getOpenFileName( QString::null, i18n( "*.cw|Custom-Widget Description\n*|All Files" ), this ); + if ( fn.isEmpty() ) + return; + + QFile f( fn ); + if ( !f.open( IO_ReadOnly ) ) + return; + + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &f, &errMsg, &errLine ) ) { + qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine ); + return; + } + + QDomElement firstWidget = doc.firstChild().toElement().firstChild().toElement(); + + while ( firstWidget.tagName() != "customwidgets" ) + firstWidget = firstWidget.nextSibling().toElement(); + + Resource::loadCustomWidgets( firstWidget, 0 ); + boxWidgets->clear(); + setupDefinition(); + setupSignals(); + setupSlots(); + setupProperties(); +} + +void CustomWidgetEditor::updateCustomWidgetSizes() +{ + if ( cwLst.isEmpty() ) + cwLst = *mainWindow->queryList( "CustomWidget" ); + for ( QObject *o = cwLst.first(); o; o = cwLst.next() ) + ( (QWidget*)o )->updateGeometry(); +} + +void CustomWidgetEditor::horDataChanged( int a ) +{ + QSizePolicy::SizeType st = int_to_size_type( a ); + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QSizePolicy osp = w->sizePolicy; + w->sizePolicy.setHorData( st ); + if ( cwLst.isEmpty() ) + cwLst = *mainWindow->queryList( "CustomWidget" ); + for ( QObject *o = cwLst.first(); o; o = cwLst.next() ) { + CustomWidget *cw = (CustomWidget*)o; + if ( cw->realClassName() == boxWidgets->currentText() ) { + if ( cw->sizePolicy() == osp ) + cw->setSizePolicy( w->sizePolicy ); + } + } +} + +void CustomWidgetEditor::verDataChanged( int a ) +{ + QSizePolicy::SizeType st = int_to_size_type( a ); + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QSizePolicy osp = w->sizePolicy; + w->sizePolicy.setVerData( st ); + if ( cwLst.isEmpty() ) + cwLst = *mainWindow->queryList( "CustomWidget" ); + for ( QObject *o = cwLst.first(); o; o = cwLst.next() ) { + CustomWidget *cw = (CustomWidget*)o; + if ( cw->realClassName() == boxWidgets->currentText() ) { + if ( cw->sizePolicy() == osp ) + cw->setSizePolicy( w->sizePolicy ); + } + } +} + +void CustomWidgetEditor::widgetIsContainer( bool b ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->isContainer = b; + WidgetDatabaseRecord *r = WidgetDatabase::at( w->id ); + if ( r ) + r->isContainer = b; +} diff --git a/kdevdesigner/designer/customwidgeteditorimpl.h b/kdevdesigner/designer/customwidgeteditorimpl.h new file mode 100644 index 00000000..cdbf402f --- /dev/null +++ b/kdevdesigner/designer/customwidgeteditorimpl.h @@ -0,0 +1,98 @@ +/********************************************************************** +** 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 CUSTOMWIDGETEDITORIMPL_H +#define CUSTOMWIDGETEDITORIMPL_H + +#include "customwidgeteditor.h" +#include "metadatabase.h" + +#include <qmap.h> +#include <qobjectlist.h> + +class QTimer; +class QListBoxItem; +class MainWindow; + +class CustomWidgetEditor : public CustomWidgetEditorBase +{ + Q_OBJECT + +public: + CustomWidgetEditor( QWidget *parent , MainWindow *mw); + +protected slots: + void addWidgetClicked(); + void classNameChanged( const QString & ); + void currentWidgetChanged( QListBoxItem * ); + void deleteWidgetClicked(); + void headerFileChanged( const QString & ); + void heightChanged( int ); + void includePolicyChanged( int ); + void pixmapChoosen(); + void widthChanged( int ); + void chooseHeader(); + void checkWidgetName(); + void closeClicked(); + void currentSignalChanged( QListBoxItem *i ); + void addSignal(); + void removeSignal(); + void signalNameChanged( const QString &s ); + void slotAccessChanged( const QString & ); + void slotNameChanged( const QString & ); + void addSlot(); + void removeSlot(); + void currentSlotChanged( QListViewItem * ); + void propertyTypeChanged( const QString & ); + void propertyNameChanged( const QString & ); + void addProperty(); + void removeProperty(); + void currentPropertyChanged( QListViewItem * ); + void saveDescription(); + void loadDescription(); + void horDataChanged( int ); + void verDataChanged( int ); + void widgetIsContainer( bool ); + +private: + MetaDataBase::CustomWidget *findWidget( QListBoxItem *i ); + void setupDefinition(); + void setupSignals(); + void setupSlots(); + void setupProperties(); + void updateCustomWidgetSizes(); + +private: + QMap<QListBoxItem*, MetaDataBase::CustomWidget*> customWidgets; + QString oldName; + QTimer *checkTimer; + QListBoxItem *oldItem; + MainWindow *mainWindow; + QObjectList cwLst; + +}; + +#endif diff --git a/kdevdesigner/designer/database.cpp b/kdevdesigner/designer/database.cpp new file mode 100644 index 00000000..a92a04c8 --- /dev/null +++ b/kdevdesigner/designer/database.cpp @@ -0,0 +1,122 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#if defined(DESIGNER) +#include "database.h" +#else +#include "database2.h" +#endif + +#ifndef QT_NO_SQL + +#if defined(DESIGNER) +#include "formwindow.h" +#include "mainwindow.h" +#endif + +#include <qsqldatabase.h> +#include <qsqlform.h> +#include <qsqlcursor.h> +#include <qsqlrecord.h> + +DatabaseSupport::DatabaseSupport() +{ + con = 0; + frm = 0; + parent = 0; +} + +void DatabaseSupport::initPreview( const QString &connection, const QString &table, QObject *o, + const QMap<QString, QString> &databaseControls ) +{ + tbl = table; + dbControls = databaseControls; + parent = o; + + if ( connection != "(default)" ) + con = QSqlDatabase::database( connection ); + else + con = QSqlDatabase::database(); + frm = new QSqlForm( o, table ); + for ( QMap<QString, QString>::Iterator it = dbControls.begin(); it != dbControls.end(); ++it ) { + QObject *chld = parent->child( it.key(), "QWidget" ); + if ( !chld ) + continue; + frm->insert( (QWidget*)chld, *it ); + } +} + +QDesignerDataBrowser::QDesignerDataBrowser( QWidget *parent, const char *name ) + : QDataBrowser( parent, name ) +{ +} + +bool QDesignerDataBrowser::event( QEvent* e ) +{ + bool b = QDataBrowser::event( e ); +#if defined(DESIGNER) + if ( MainWindow::self->isPreviewing() ) { +#endif + if ( e->type() == QEvent::Show ) { + if ( con ) { + QSqlCursor* cursor = new QSqlCursor( tbl, TRUE, con ); + setSqlCursor( cursor, TRUE ); + setForm( frm ); + refresh(); + first(); + } + return TRUE; + } +#if defined(DESIGNER) + } +#endif + return b; +} + +QDesignerDataView::QDesignerDataView( QWidget *parent, const char *name ) + : QDataView( parent, name ) +{ +} + +bool QDesignerDataView::event( QEvent* e ) +{ + bool b = QDataView::event( e ); +#if defined(DESIGNER) + if ( MainWindow::self->isPreviewing() ) { +#endif + if ( e->type() == QEvent::Show ) { + setForm( frm ); + readFields(); + return TRUE; + } +#if defined(DESIGNER) + } +#endif + return b; +} + + +#endif diff --git a/kdevdesigner/designer/database.h b/kdevdesigner/designer/database.h new file mode 100644 index 00000000..530085fb --- /dev/null +++ b/kdevdesigner/designer/database.h @@ -0,0 +1,83 @@ +/********************************************************************** +** 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 DATABASE_H +#define DATABASE_H + +#include "qfeatures.h" + +#ifndef QT_NO_SQL +#include <qdataview.h> +#include <qdatabrowser.h> +#include <qsqlcursor.h> +#include <qstring.h> + +class QSqlDatabase; +class QSqlForm; + +class DatabaseSupport +{ +public: + DatabaseSupport(); + virtual ~DatabaseSupport() {} + + void initPreview( const QString &connection, const QString &table, QObject *o, + const QMap<QString, QString> &databaseControls ); + +protected: + QSqlDatabase* con; + QSqlForm* frm; + QString tbl; + QMap<QString, QString> dbControls; + QObject *parent; + +}; + +class QDesignerDataBrowser : public QDataBrowser, public DatabaseSupport +{ + Q_OBJECT + +public: + QDesignerDataBrowser( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); +}; + +class QDesignerDataView : public QDataView, public DatabaseSupport +{ + Q_OBJECT + +public: + QDesignerDataView( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); + +}; +#endif + +#endif diff --git a/kdevdesigner/designer/dbconnection.ui b/kdevdesigner/designer/dbconnection.ui new file mode 100644 index 00000000..19a0e216 --- /dev/null +++ b/kdevdesigner/designer/dbconnection.ui @@ -0,0 +1,222 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>DatabaseConnectionWidget</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QWidget"> + <property name="name"> + <cstring>DatabaseConnectionWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>199</width> + <height>185</height> + </rect> + </property> + <property name="caption"> + <string>Edit Database Connection</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>&Database name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editDatabase</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>TextLabel4</cstring> + </property> + <property name="text"> + <string>&Username:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editUsername</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>TextLabel4_2</cstring> + </property> + <property name="text"> + <string>&Password:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editPassword</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>D&river:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboDriver</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editName</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>TextLabel5</cstring> + </property> + <property name="text"> + <string>&Hostname:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editHostname</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>comboDriver</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="5" column="1"> + <property name="name"> + <cstring>editHostname</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="6" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>P&ort:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editPort</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>editUsername</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="KLineEdit" row="4" column="1"> + <property name="name"> + <cstring>editPassword</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>editDatabase</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QSpinBox" row="6" column="1"> + <property name="name"> + <cstring>editPort</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="specialValueText"> + <string>Default</string> + </property> + <property name="maxValue"> + <number>65535</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>-1</number> + </property> + </widget> + </grid> +</widget> +<connections> +</connections> +<tabstops> + <tabstop>editName</tabstop> + <tabstop>comboDriver</tabstop> + <tabstop>editDatabase</tabstop> + <tabstop>editUsername</tabstop> + <tabstop>editPassword</tabstop> + <tabstop>editHostname</tabstop> + <tabstop>editPort</tabstop> +</tabstops> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/dbconnectioneditor.ui b/kdevdesigner/designer/dbconnectioneditor.ui new file mode 100644 index 00000000..64b77387 --- /dev/null +++ b/kdevdesigner/designer/dbconnectioneditor.ui @@ -0,0 +1,147 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>DatabaseConnectionEditorBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>DatabaseConnectionEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>393</width> + <height>286</height> + </rect> + </property> + <property name="caption"> + <string>Connect</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>grp</cstring> + </property> + <property name="title"> + <string>Connection Details</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer row="0" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>DatabaseConnectionEditorBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>DatabaseConnectionEditorBase</receiver> + <slot>accept()</slot> + </connection> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> +</connections> +<tabstops> + <tabstop>PushButton1</tabstop> + <tabstop>PushButton2</tabstop> +</tabstops> +</UI> diff --git a/kdevdesigner/designer/dbconnectionimpl.cpp b/kdevdesigner/designer/dbconnectionimpl.cpp new file mode 100644 index 00000000..4867ed39 --- /dev/null +++ b/kdevdesigner/designer/dbconnectionimpl.cpp @@ -0,0 +1,80 @@ +/********************************************************************** +** 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 "dbconnectionimpl.h" +#include "dbconnection.h" +#include "project.h" +#include "asciivalidator.h" +#include <qgroupbox.h> +#include <qcombobox.h> +#include <qspinbox.h> +#include <klineedit.h> +#include <qlayout.h> +#include <qsqldatabase.h> + +DatabaseConnectionEditor::DatabaseConnectionEditor( DatabaseConnection* connection, QWidget* parent, + const char* name, bool modal, WFlags fl ) + : DatabaseConnectionEditorBase( parent, name, modal, fl ), conn( connection ) +{ + connectionWidget = new DatabaseConnectionWidget( grp ); + grpLayout->addWidget( connectionWidget, 0, 0 ); + init(); +} + +DatabaseConnectionEditor::~DatabaseConnectionEditor() +{ +} + +void DatabaseConnectionEditor::accept() +{ +#ifndef QT_NO_SQL + conn->setUsername( connectionWidget->editUsername->text() ); + conn->setPassword( connectionWidget->editPassword->text() ); + conn->setHostname( connectionWidget->editHostname->text() ); +#endif + DatabaseConnectionEditorBase::accept(); +} + +void DatabaseConnectionEditor::init() +{ + connectionWidget->editName->setEnabled( FALSE ); + connectionWidget->editName->setValidator( new AsciiValidator( connectionWidget->editName ) ); + connectionWidget->editName->setText( conn->name() ); + connectionWidget->comboDriver->setEnabled( FALSE ); + connectionWidget->comboDriver->lineEdit()->setText( conn->driver() ); + connectionWidget->editDatabase->setEnabled( FALSE ); + connectionWidget->editDatabase->setText( conn->database() ); + connectionWidget->editUsername->setEnabled( TRUE ); + connectionWidget->editUsername->setText( conn->username() ); + connectionWidget->editPassword->setEnabled( TRUE ); + connectionWidget->editPassword->setText( "" ); + connectionWidget->editHostname->setEnabled( TRUE ); + connectionWidget->editHostname->setText( conn->hostname() ); + connectionWidget->editPort->setEnabled( TRUE ); + connectionWidget->editPort->setValue( conn->port() ); + connectionWidget->editUsername->setFocus(); + connectionWidget->editUsername->selectAll(); +} diff --git a/kdevdesigner/designer/dbconnectionimpl.h b/kdevdesigner/designer/dbconnectionimpl.h new file mode 100644 index 00000000..daef2c21 --- /dev/null +++ b/kdevdesigner/designer/dbconnectionimpl.h @@ -0,0 +1,57 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef DBCONNECTIONIMPL_H +#define DBCONNECTIONIMPL_H + +#include "dbconnectioneditor.h" + +class DatabaseConnection; +class DatabaseConnectionWidget; +class QGridLayout; + +class DatabaseConnectionEditor : public DatabaseConnectionEditorBase +{ + Q_OBJECT + +public: + DatabaseConnectionEditor( DatabaseConnection* connection, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~DatabaseConnectionEditor(); + +public slots: + void accept(); +private: + void init(); + +private: + DatabaseConnection *conn; + QGridLayout* lay; + DatabaseConnectionWidget* connectionWidget; + +}; + +#endif // DBCONNECTIONIMPL_H diff --git a/kdevdesigner/designer/dbconnections.ui b/kdevdesigner/designer/dbconnections.ui new file mode 100644 index 00000000..847c00b1 --- /dev/null +++ b/kdevdesigner/designer/dbconnections.ui @@ -0,0 +1,321 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>DatabaseConnectionBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>DatabaseConnectionBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>512</width> + <height>309</height> + </rect> + </property> + <property name="caption"> + <string>Edit Database Connections</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>buttonNew</cstring> + </property> + <property name="text"> + <string>&New Connection</string> + </property> + </widget> + <widget class="QListBox" row="0" column="0" rowspan="5" colspan="1"> + <property name="name"> + <cstring>listConnections</cstring> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>buttonDelete</cstring> + </property> + <property name="text"> + <string>&Delete Connection</string> + </property> + </widget> + <widget class="QLayoutWidget" row="5" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonClose</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + <spacer row="2" column="1" rowspan="3" colspan="1"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="0" column="2" rowspan="3" colspan="1"> + <property name="name"> + <cstring>grp</cstring> + </property> + <property name="title"> + <string>Connection</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer row="0" column="0"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QLayoutWidget" row="3" column="2"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonConnect</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Connec&t</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer row="4" column="2"> + <property name="name"> + <cstring>Spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>buttonClose</sender> + <signal>clicked()</signal> + <receiver>DatabaseConnectionBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonNew</sender> + <signal>clicked()</signal> + <receiver>DatabaseConnectionBase</receiver> + <slot>newConnection()</slot> + </connection> + <connection> + <sender>buttonDelete</sender> + <signal>clicked()</signal> + <receiver>DatabaseConnectionBase</receiver> + <slot>deleteConnection()</slot> + </connection> + <connection> + <sender>buttonConnect</sender> + <signal>clicked()</signal> + <receiver>DatabaseConnectionBase</receiver> + <slot>doConnect()</slot> + </connection> + <connection> + <sender>listConnections</sender> + <signal>highlighted(const QString&)</signal> + <receiver>DatabaseConnectionBase</receiver> + <slot>currentConnectionChanged(const QString&)</slot> + </connection> + <connection> + <sender>listConnections</sender> + <signal>selected(const QString&)</signal> + <receiver>DatabaseConnectionBase</receiver> + <slot>currentConnectionChanged(const QString&)</slot> + </connection> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> + <slot access="protected" language="C++" returnType="void">currentConnectionChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">deleteConnection()</slot> + <slot access="protected" language="C++" returnType="void">newConnection()</slot> + <slot access="protected" language="C++" returnType="void">connectionNameChanged( const QString & )</slot> + <slot access="protected" language="C++" returnType="void">doConnect()</slot> +</connections> +<tabstops> + <tabstop>buttonClose</tabstop> + <tabstop>listConnections</tabstop> + <tabstop>buttonNew</tabstop> + <tabstop>buttonDelete</tabstop> + <tabstop>buttonConnect</tabstop> + <tabstop>buttonHelp</tabstop> +</tabstops> +</UI> diff --git a/kdevdesigner/designer/dbconnectionsimpl.cpp b/kdevdesigner/designer/dbconnectionsimpl.cpp new file mode 100644 index 00000000..6f059336 --- /dev/null +++ b/kdevdesigner/designer/dbconnectionsimpl.cpp @@ -0,0 +1,196 @@ +/********************************************************************** +** 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 "dbconnectionsimpl.h" +#include <qptrlist.h> +#include <qgroupbox.h> +#include <qlayout.h> +#include "project.h" +#include <qlistbox.h> +#include <qcombobox.h> +#include <qspinbox.h> +#include <klineedit.h> +#include <qpushbutton.h> +#include <qsqldatabase.h> +#include <qmessagebox.h> +#include <qapplication.h> +#include "mainwindow.h" +#include "asciivalidator.h" + +#include <klocale.h> + +static bool blockChanges = FALSE; + +/* + * Constructs a DatabaseConnectionsEditor which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +DatabaseConnectionsEditor::DatabaseConnectionsEditor( Project *pro, QWidget* parent, const char* name, bool modal, WFlags fl ) + : DatabaseConnectionBase( parent, name, modal, fl ), project( pro ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + connectionWidget = new DatabaseConnectionWidget( grp ); + grpLayout->addWidget( connectionWidget, 0, 0 ); +#ifndef QT_NO_SQL + QPtrList<DatabaseConnection> lst = project->databaseConnections(); + for ( DatabaseConnection *conn = lst.first(); conn; conn = lst.next() ) + listConnections->insertItem( conn->name() ); + connectionWidget->comboDriver->insertStringList( QSqlDatabase::drivers() ); +#endif + connectionWidget->editName->setValidator( new AsciiValidator( connectionWidget->editName ) ); + enableAll( FALSE ); +} + +DatabaseConnectionsEditor::~DatabaseConnectionsEditor() +{ +} + +void DatabaseConnectionsEditor::deleteConnection() +{ + if ( listConnections->currentItem() == -1 ) + return; + project->removeDatabaseConnection( listConnections->currentText() ); + delete listConnections->item( listConnections->currentItem() ); + if ( listConnections->count() ) { + listConnections->setCurrentItem( 0 ); + currentConnectionChanged( listConnections->currentText() ); + } else { + enableAll( FALSE ); + } + project->saveConnections(); +} + +void DatabaseConnectionsEditor::newConnection() +{ + blockChanges = TRUE; + enableAll( TRUE ); + QString n( "(default)" ); + if ( project->databaseConnection( n ) ) { + n = "connection"; + int i = 2; + while ( project->databaseConnection( n + QString::number( i ) ) ) + ++i; + n = n + QString::number( i ); + } + connectionWidget->editName->setText( n ); + listConnections->clearSelection(); + buttonConnect->setDefault( TRUE ); + connectionWidget->editName->setFocus(); + blockChanges = FALSE; +} + +void DatabaseConnectionsEditor::doConnect() +{ +#ifndef QT_NO_SQL + if ( listConnections->currentItem() == -1 || + !listConnections->item( listConnections->currentItem() )->isSelected() ) { // new connection + // ### do error checking for duplicated connection names + DatabaseConnection *conn = new DatabaseConnection( project ); + conn->setName( connectionWidget->editName->text() ); + conn->setDriver( connectionWidget->comboDriver->lineEdit()->text() ); + conn->setDatabase( connectionWidget->editDatabase->text() ); + conn->setUsername( connectionWidget->editUsername->text() ); + conn->setPassword( connectionWidget->editPassword->text() ); + conn->setHostname( connectionWidget->editHostname->text() ); + conn->setPort( connectionWidget->editPort->value() ); + if ( conn->refreshCatalog() ) { + project->addDatabaseConnection( conn ); + listConnections->insertItem( conn->name() ); + listConnections->setCurrentItem( listConnections->count() - 1 ); + project->saveConnections(); + } else { + QMessageBox::warning( MainWindow::self, i18n( "Connection" ), + i18n( "Could not connect to the database.\n" + "Please ensure that the database server is running " + "and that all the connection information is correct.\n" + "[ " + conn->lastError() + " ]" ) ); + delete conn; + } + } else { // sync // ### should this do something else? right now it just overwrites all info about the connection... + DatabaseConnection *conn = project->databaseConnection( listConnections->currentText() ); + conn->setName( connectionWidget->editName->text() ); + conn->setDriver( connectionWidget->comboDriver->lineEdit()->text() ); + conn->setDatabase( connectionWidget->editDatabase->text() ); + conn->setUsername( connectionWidget->editUsername->text() ); + conn->setPassword( connectionWidget->editPassword->text() ); + conn->setHostname( connectionWidget->editHostname->text() ); + conn->setPort( connectionWidget->editPort->value() ); + conn->refreshCatalog(); + project->saveConnections(); + } +#endif +} + +void DatabaseConnectionsEditor::currentConnectionChanged( const QString &s ) +{ +#ifndef QT_NO_SQL + DatabaseConnection *conn = project->databaseConnection( s ); + blockChanges = TRUE; + enableAll( conn != 0 ); + connectionWidget->editName->setEnabled( FALSE ); + blockChanges = FALSE; + if ( !conn ) + return; + blockChanges = TRUE; + connectionWidget->editName->setText( conn->name() ); + blockChanges = FALSE; + connectionWidget->comboDriver->lineEdit()->setText( conn->driver() ); + connectionWidget->editDatabase->setText( conn->database() ); + connectionWidget->editUsername->setText( conn->username() ); + connectionWidget->editPassword->setText( conn->password() ); + connectionWidget->editHostname->setText( conn->hostname() ); + connectionWidget->editPort->setValue( conn->port() ); +#endif +} + +void DatabaseConnectionsEditor::connectionNameChanged( const QString &s ) +{ + if ( listConnections->currentItem() == 0 || blockChanges ) + return; + listConnections->changeItem( s, listConnections->currentItem() ); +} + +void DatabaseConnectionsEditor::enableAll( bool b ) +{ + connectionWidget->editName->setEnabled( b ); + connectionWidget->editName->setText( "" ); + connectionWidget->comboDriver->setEnabled( b ); + connectionWidget->comboDriver->lineEdit()->setText( "" ); + connectionWidget->editDatabase->setEnabled( b ); + connectionWidget->editDatabase->setText( "" ); + connectionWidget->editUsername->setEnabled( b ); + connectionWidget->editUsername->setText( "" ); + connectionWidget->editPassword->setEnabled( b ); + connectionWidget->editPassword->setText( "" ); + connectionWidget->editHostname->setEnabled( b ); + connectionWidget->editHostname->setText( "" ); + connectionWidget->editPort->setEnabled( b ); + connectionWidget->editPort->setValue( -1 ); + buttonConnect->setEnabled( b ); +} diff --git a/kdevdesigner/designer/dbconnectionsimpl.h b/kdevdesigner/designer/dbconnectionsimpl.h new file mode 100644 index 00000000..fdb70427 --- /dev/null +++ b/kdevdesigner/designer/dbconnectionsimpl.h @@ -0,0 +1,60 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef DBCONNECTIONSIMPL_H +#define DBCONNECTIONSIMPL_H + +#include "dbconnections.h" +#include "dbconnection.h" + +class Project; + +class DatabaseConnectionsEditor : public DatabaseConnectionBase +{ + Q_OBJECT + +public: + DatabaseConnectionsEditor( Project *pro, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~DatabaseConnectionsEditor(); + +protected slots: + void deleteConnection(); + void newConnection(); + void doConnect(); + void currentConnectionChanged( const QString & ); + void connectionNameChanged( const QString &s ); + +private: + void enableAll( bool b ); + +private: + Project *project; + DatabaseConnectionWidget* connectionWidget; + +}; + +#endif // DBCONNECTIONSIMPL_H diff --git a/kdevdesigner/designer/defs.cpp b/kdevdesigner/designer/defs.cpp new file mode 100644 index 00000000..11b3dca0 --- /dev/null +++ b/kdevdesigner/designer/defs.cpp @@ -0,0 +1,84 @@ +/********************************************************************** +** 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 "defs.h" + +int size_type_to_int( QSizePolicy::SizeType t ) +{ + if ( t == QSizePolicy::Fixed ) + return 0; + if ( t == QSizePolicy::Minimum ) + return 1; + if ( t == QSizePolicy::Maximum ) + return 2; + if ( t == QSizePolicy::Preferred ) + return 3; + if ( t == QSizePolicy::MinimumExpanding ) + return 4; + if ( t == QSizePolicy::Expanding ) + return 5; + if ( t == QSizePolicy::Ignored ) + return 6; + return 0; +} + +QString size_type_to_string( QSizePolicy::SizeType t ) +{ + if ( t == QSizePolicy::Fixed ) + return "Fixed"; + if ( t == QSizePolicy::Minimum ) + return "Minimum"; + if ( t == QSizePolicy::Maximum ) + return "Maximum"; + if ( t == QSizePolicy::Preferred ) + return "Preferred"; + if ( t == QSizePolicy::MinimumExpanding ) + return "MinimumExpanding"; + if ( t == QSizePolicy::Expanding ) + return "Expanding"; + if ( t == QSizePolicy::Ignored ) + return "Ignored"; + return QString(); +} + +QSizePolicy::SizeType int_to_size_type( int i ) +{ + if ( i == 0 ) + return QSizePolicy::Fixed; + if ( i == 1 ) + return QSizePolicy::Minimum; + if ( i == 2 ) + return QSizePolicy::Maximum; + if ( i == 3 ) + return QSizePolicy::Preferred; + if ( i == 4 ) + return QSizePolicy::MinimumExpanding; + if ( i == 5 ) + return QSizePolicy::Expanding; + if ( i == 6 ) + return QSizePolicy::Ignored; + return QSizePolicy::Preferred; +} diff --git a/kdevdesigner/designer/defs.h b/kdevdesigner/designer/defs.h new file mode 100644 index 00000000..80a11671 --- /dev/null +++ b/kdevdesigner/designer/defs.h @@ -0,0 +1,42 @@ +/********************************************************************** +** 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 DEFS_H +#define DEFS_H + +#include <qsizepolicy.h> +#include <qstring.h> + +#define POINTER_TOOL 32000 +#define CONNECT_TOOL 32001 +#define ORDER_TOOL 32002 +#define BUDDY_TOOL 32004 + +int size_type_to_int( QSizePolicy::SizeType t ); +QString size_type_to_string( QSizePolicy::SizeType t ); +QSizePolicy::SizeType int_to_size_type( int i ); + +#endif diff --git a/kdevdesigner/designer/designer_pch.h b/kdevdesigner/designer/designer_pch.h new file mode 100644 index 00000000..6b53f984 --- /dev/null +++ b/kdevdesigner/designer/designer_pch.h @@ -0,0 +1,44 @@ +/* + * This is a precompiled header file for use in Xcode / Mac GCC / + * GCC >= 3.4 / VC to greatly speed the building of Qt Designer. It may + * also be of use to people developing their own project, but it is + * probably better to define your own header. Use of this header is + * currently UNSUPPORTED. + */ + +#if defined __cplusplus + +#include <private/qucomextra_p.h> +#include <qaction.h> +#include <qapplication.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qdialog.h> +#include <qheader.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qlistview.h> +#include <qmap.h> +#include <qmessagebox.h> +#include <qmetaobject.h> +#include <qobjectlist.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qpushbutton.h> +#include <qspinbox.h> +#include <qstring.h> +#include <qtooltip.h> +#include <qvariant.h> +#include <qwhatsthis.h> +#include <qwidget.h> + +#include "command.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "project.h" +#include "widgetfactory.h" + +#endif diff --git a/kdevdesigner/designer/designeraction.cpp b/kdevdesigner/designer/designeraction.cpp new file mode 100644 index 00000000..2cdcd5eb --- /dev/null +++ b/kdevdesigner/designer/designeraction.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "designeraction.h" + +DesignerAction::~DesignerAction() +{ +} + +void DesignerAction::setDisabled( bool d ) +{ + QAction::setEnabled(!d); + emit actionEnabled(!d); +} + +void DesignerAction::setEnabled( bool e ) +{ + QAction::setEnabled(e); + emit actionEnabled(e); +} + +#if QT_VERSION < 0x030300 +void DesignerAction::activate() +{ + if ( isToggleAction() ) { + return; + } + emit activated(); +} +#endif + +#include "designeraction.moc" diff --git a/kdevdesigner/designer/designeraction.h b/kdevdesigner/designer/designeraction.h new file mode 100644 index 00000000..db8f7901 --- /dev/null +++ b/kdevdesigner/designer/designeraction.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DESIGNERACTION_H +#define DESIGNERACTION_H + +#include <qaction.h> + +class DesignerAction : public QAction +{ +Q_OBJECT +public: + DesignerAction(QObject *parent = 0, const char *name = 0) + :QAction(parent, name) {} + DesignerAction ( const QString & menuText, QKeySequence accel, QObject * parent, const char * name = 0 ) + :QAction(menuText, accel, parent, name) {} + DesignerAction ( const QIconSet & icon, const QString & menuText, QKeySequence accel, QObject * parent, const char * name = 0 ) + :QAction(icon, menuText, accel, parent, name) {} + DesignerAction ( const QString & text, const QIconSet & icon, const QString & menuText, QKeySequence accel, QObject * parent, const char * name = 0, bool toggle = FALSE ) + :QAction(text, icon, menuText, accel, parent, name, toggle) {} + DesignerAction ( const QString & text, const QString & menuText, QKeySequence accel, QObject * parent, const char * name = 0, bool toggle = FALSE ) + :QAction(text, menuText, accel, parent, name, toggle) {} + DesignerAction ( QObject * parent, const char * name, bool toggle ) + :QAction(parent, name, toggle) {} + ~DesignerAction(); + + virtual void setEnabled(bool e); + virtual void setDisabled(bool d); +#if QT_VERSION < 0x030300 + virtual void activate(); +#endif + +signals: + void actionEnabled(bool e); + +}; + +#endif diff --git a/kdevdesigner/designer/designerapp.cpp b/kdevdesigner/designer/designerapp.cpp new file mode 100644 index 00000000..480bc65b --- /dev/null +++ b/kdevdesigner/designer/designerapp.cpp @@ -0,0 +1,176 @@ + /********************************************************************** +** 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 "designerappiface.h" +#include "designerapp.h" +#include "mainwindow.h" +#include "formwindow.h" + +#include <kiconloader.h> + +#include <qfile.h> +#include <qdir.h> +#include <qsettings.h> +#include <qsplashscreen.h> + +#ifdef Q_WS_WIN +#include <qt_windows.h> +#include <process.h> +#endif + +static QSplashScreen *splash = 0; + +void set_splash_status( const QString &txt ) +{ + if ( !splash ) + return; + QString splashText = "Licensed to " + + QString::fromLatin1( QT_PRODUCT_LICENSEE ) + "\n" + + txt; + splash->message( splashText, Qt::AlignRight|Qt::AlignTop ); +} + +DesignerApplication::DesignerApplication( int &argc, char **argv ) + : QApplication( argc, argv ) +{ +#if defined(Q_WS_WIN) + if ( winVersion() & Qt::WV_NT_based ) + DESIGNER_OPENFILE = RegisterWindowMessage((TCHAR*)"QT_DESIGNER_OPEN_FILE"); + else + DESIGNER_OPENFILE = RegisterWindowMessageA("QT_DESIGNER_OPEN_FILE"); +#endif +} + +QSplashScreen *DesignerApplication::showSplash() +{ + QRect screen = QApplication::desktop()->screenGeometry(); + QSettings config; + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + QRect mainRect; + QString keybase = settingsKey(); + bool show = config.readBoolEntry( keybase + "SplashScreen", TRUE ); + mainRect.setX( config.readNumEntry( keybase + "Geometries/MainwindowX", 0 ) ); + mainRect.setY( config.readNumEntry( keybase + "Geometries/MainwindowY", 0 ) ); + mainRect.setWidth( config.readNumEntry( keybase + "Geometries/MainwindowWidth", 500 ) ); + mainRect.setHeight( config.readNumEntry( keybase + "Geometries/MainwindowHeight", 500 ) ); + screen = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( mainRect.center() ) ); + + if ( show ) { + splash = new QSplashScreen( UserIcon("designer_splash.png") ); + splash->show(); + set_splash_status( "Initializing..." ); + } + + return splash; +} + +void DesignerApplication::closeSplash() +{ + splash->hide(); +} + +static QString *settings_key = 0; +static QString *old_settings_key = 0; + +QString DesignerApplication::settingsKey() +{ + if ( !settings_key ) + settings_key = new QString( "/Qt Designer/" + + QString::number( (QT_VERSION >> 16) & 0xff ) + + "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" ); + return *settings_key; +} + +QString DesignerApplication::oldSettingsKey() +{ + if ( !old_settings_key ) { + int majorVer = (QT_VERSION >> 16) & 0xff; + int minorVer = (QT_VERSION >> 8) & 0xff; + + // If minorVer is 0 (e.g. 4.0) then we don't want to read the + // old settings, too much might have changed. + if ( !minorVer == 0 ) + minorVer--; + + old_settings_key = new QString( "/Qt Designer/" + + QString::number( majorVer ) + + "." + QString::number( minorVer ) + "/" ); + } + return *old_settings_key; +} + +void DesignerApplication::setSettingsKey( const QString &key ) +{ + if ( !settings_key ) + settings_key = new QString( key ); + else + *settings_key = key; +} + +#if defined(Q_WS_WIN) +bool DesignerApplication::winEventFilter( MSG *msg ) +{ + if ( msg->message == DESIGNER_OPENFILE ) { + QFile f( QDir::homeDirPath() + "/.designerargs" ); + QFileInfo fi(f); + if ( fi.lastModified() == lastMod ) + return QApplication::winEventFilter( msg ); + lastMod = fi.lastModified(); + f.open( IO_ReadOnly ); + QString args; + f.readLine( args, f.size() ); + QStringList lst = QStringList::split( " ", args ); + + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + QString arg = (*it).stripWhiteSpace(); + if ( arg[0] != '-' ) { + QObjectList* l = MainWindow::self->queryList( "FormWindow" ); + FormWindow* fw = (FormWindow*) l->first(); + FormWindow* totop = 0; + bool haveit = FALSE; + while ( fw ) { + haveit = haveit || fw->fileName() == arg; + if ( haveit ) + totop = fw; + + fw = (FormWindow*) l->next(); + } + + if ( !haveit ) { + FlashWindow( MainWindow::self->winId(), TRUE ); + MainWindow::self->openFormWindow( arg ); + } else if ( totop ) { + totop->setFocus(); + } + delete l; + } + } + return TRUE; + } + return QApplication::winEventFilter( msg ); +} +#endif diff --git a/kdevdesigner/designer/designerapp.h b/kdevdesigner/designer/designerapp.h new file mode 100644 index 00000000..d78d55af --- /dev/null +++ b/kdevdesigner/designer/designerapp.h @@ -0,0 +1,58 @@ + /********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef DESIGNERAPP_H +#define DESIGNERAPP_H + +class QSplashScreen; + +#include <qapplication.h> + +class DesignerApplication : public QApplication +{ +public: + const char *className() const { return "DesignerApplication"; } + + DesignerApplication( int &argc, char **argv ); + + QSplashScreen *showSplash(); + static void closeSplash(); + + static QString settingsKey(); + static QString oldSettingsKey(); + static void setSettingsKey( const QString &key ); + +protected: + QDateTime lastMod; + +#if defined(Q_WS_WIN) + bool winEventFilter( MSG *msg ); + uint DESIGNER_OPENFILE; +#endif + +}; + +#endif diff --git a/kdevdesigner/designer/designerappiface.cpp b/kdevdesigner/designer/designerappiface.cpp new file mode 100644 index 00000000..798f45b6 --- /dev/null +++ b/kdevdesigner/designer/designerappiface.cpp @@ -0,0 +1,1093 @@ + /********************************************************************** +** 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 <qmenubar.h> +#include <qpopupmenu.h> +#include "designerappiface.h" +#include "mainwindow.h" +#include "project.h" +#include "formwindow.h" +#include "workspace.h" +#include "widgetfactory.h" +#include "command.h" +#include "outputwindow.h" +#include "../shared/widgetdatabase.h" +#include <qvariant.h> +#include <qlistview.h> +#include <qtextedit.h> +#include <qstatusbar.h> +#include "pixmapcollection.h" +#include "hierarchyview.h" +#include <stdlib.h> +#include <qmetaobject.h> +#include "popupmenueditor.h" +#include "menubareditor.h" + +DesignerInterfaceImpl::DesignerInterfaceImpl( MainWindow *mw ) + : mainWindow( mw ) +{ +} + +QRESULT DesignerInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + *iface = 0; + + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QComponentInformation ) + *iface = (QComponentInformationInterface*)this; + else if ( uuid == IID_Designer ) + *iface = (DesignerInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +DesignerProject *DesignerInterfaceImpl::currentProject() const +{ + return mainWindow->currProject()->iFace(); +} + +DesignerFormWindow *DesignerInterfaceImpl::currentForm() const +{ + if ( mainWindow->formWindow() ) + return mainWindow->formWindow()->iFace(); + return 0; +} + +DesignerSourceFile *DesignerInterfaceImpl::currentSourceFile() const +{ + if ( mainWindow->sourceFile() ) + return mainWindow->sourceFile()->iFace(); + return 0; +} + +QPtrList<DesignerProject> DesignerInterfaceImpl::projectList() const +{ + return mainWindow->projectList(); +} + +void DesignerInterfaceImpl::showStatusMessage( const QString &text, int ms ) const +{ + if ( text.isEmpty() ) { + mainWindow->statusBar()->clear(); + return; + } + if ( ms ) + mainWindow->statusMessage( text/*, ms*/ ); + else + mainWindow->statusMessage( text ); +} + +DesignerDock *DesignerInterfaceImpl::createDock() const +{ + return 0; +} + +DesignerOutputDock *DesignerInterfaceImpl::outputDock() const +{ + return mainWindow->outputWindow() ? mainWindow->outputWindow()->iFace() : 0; +} + +void DesignerInterfaceImpl::setModified( bool b, QWidget *window ) +{ + mainWindow->setModified( b, window ); +} + +void DesignerInterfaceImpl::updateFunctionList() +{ + mainWindow->updateFunctionList(); + if ( mainWindow->objectHierarchy()->sourceEditor() ) + mainWindow->objectHierarchy()->updateClassBrowsers(); +} + +void DesignerInterfaceImpl::onProjectChange( QObject *receiver, const char *slot ) +{ + QObject::connect( mainWindow, SIGNAL( projectChanged() ), receiver, slot ); +} + +void DesignerInterfaceImpl::onFormChange( QObject *receiver, const char *slot ) +{ + QObject::connect( mainWindow, SIGNAL( formWindowChanged() ), receiver, slot ); + QObject::connect( mainWindow, SIGNAL( editorChanged() ), receiver, slot ); +} + +bool DesignerInterfaceImpl::singleProjectMode() const +{ + return mainWindow->singleProjectMode(); +} + +void DesignerInterfaceImpl::showError( QWidget *widget, + int line, const QString &message ) +{ + mainWindow->showErrorMessage( widget, line, message ); +} + +void DesignerInterfaceImpl::runFinished() +{ + mainWindow->finishedRun(); +} + +void DesignerInterfaceImpl::showStackFrame( QWidget *w, int line ) +{ + mainWindow->showStackFrame( w, line ); +} + +void DesignerInterfaceImpl::showDebugStep( QWidget *w, int line ) +{ + mainWindow->showDebugStep( w, line ); +} + +void DesignerInterfaceImpl::runProjectPrecondition() +{ + mainWindow->runProjectPrecondition(); +} + +void DesignerInterfaceImpl::runProjectPostcondition( QObjectList *l ) +{ + mainWindow->runProjectPostcondition( l ); +} + +DesignerProjectImpl::DesignerProjectImpl( Project *pr ) + : project( pr ) +{ +} + +QPtrList<DesignerFormWindow> DesignerProjectImpl::formList() const +{ + QPtrList<DesignerFormWindow> list; + QObjectList *forms = project->formList(); + if ( !forms ) + return list; + + QPtrListIterator<QObject> it( *forms ); + while ( it.current() ) { + QObject *obj = it.current(); + ++it; + QWidget *par = ::qt_cast<FormWindow*>(obj->parent()); + if ( !obj->isWidgetType() || !par ) + continue; + + list.append( ((FormWindow*)par)->iFace() ); + } + + delete forms; + return list; +} + +QString DesignerProjectImpl::formFileName( const QString &form ) const +{ + for ( QPtrListIterator<FormFile> forms = project->formFiles(); + forms.current(); ++forms ) { + if ( QString( forms.current()->formName() ) == form ) + return forms.current()->fileName(); + } + return QString::null; +} + +QStringList DesignerProjectImpl::formNames() const +{ + QStringList l; + for ( QPtrListIterator<FormFile> forms = project->formFiles(); + forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->isFake() ) + continue; + l << f->formName(); + } + return l; +} + +void DesignerProjectImpl::addForm( DesignerFormWindow * ) +{ +} + +void DesignerProjectImpl::removeForm( DesignerFormWindow * ) +{ +} + +QString DesignerProjectImpl::fileName() const +{ + return project->fileName(); +} + +void DesignerProjectImpl::setFileName( const QString & ) +{ +} + +QString DesignerProjectImpl::projectName() const +{ + return project->projectName(); +} + +void DesignerProjectImpl::setProjectName( const QString & ) +{ +} + +QString DesignerProjectImpl::databaseFile() const +{ + return QString::null; +} + +void DesignerProjectImpl::setDatabaseFile( const QString & ) +{ +} + +void DesignerProjectImpl::setupDatabases() const +{ + MainWindow::self->editDatabaseConnections(); +} + +QPtrList<DesignerDatabase> DesignerProjectImpl::databaseConnections() const +{ + QPtrList<DesignerDatabase> lst; +#ifndef QT_NO_SQL + QPtrList<DatabaseConnection> conns = project->databaseConnections(); + for ( DatabaseConnection *d = conns.first(); d; d = conns.next() ) + lst.append( d->iFace() ); +#endif + return lst; +} + +void DesignerProjectImpl::addDatabase( DesignerDatabase * ) +{ +} + +void DesignerProjectImpl::removeDatabase( DesignerDatabase * ) +{ +} + +void DesignerProjectImpl::save() const +{ +} + +void DesignerProjectImpl::setLanguage( const QString &l ) +{ + project->setLanguage( l ); +} + +QString DesignerProjectImpl::language() const +{ + return project->language(); +} + +void DesignerProjectImpl::setCustomSetting( const QString &key, const QString &value ) +{ + project->setCustomSetting( key, value ); +} + +QString DesignerProjectImpl::customSetting( const QString &key ) const +{ + if ( key == "QTSCRIPT_PACKAGES" ) { + QString s = getenv( "QTSCRIPT_PACKAGES" ); + QString s2 = project->customSetting( "QUICK_PACKAGES" ); + if ( !s.isEmpty() && !s2.isEmpty() ) +#if defined(Q_OS_WIN32) + s += ";"; +#else + s += ":"; +#endif + s += s2; + return s; + } + return project->customSetting( key ); +} + +DesignerPixmapCollection *DesignerProjectImpl::pixmapCollection() const +{ + return project->pixmapCollection()->iFace(); +} + +void DesignerProjectImpl::breakPoints( QMap<QString, QValueList<uint> > &bps ) const +{ + MainWindow::self->saveAllBreakPoints(); + for ( QPtrListIterator<SourceFile> sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + bps.insert( project->makeRelative( f->fileName() ) + " <Source-File>", MetaDataBase::breakPoints( f ) ); + } + for ( QPtrListIterator<FormFile> forms = project->formFiles(); + forms.current(); ++forms ) { + if ( forms.current()->formWindow() ) + bps.insert( QString( forms.current()->formWindow()->name() ) + " <Form>", MetaDataBase::breakPoints( forms.current()->formWindow() ) ); + } +} + +QString DesignerProjectImpl::breakPointCondition( QObject *o, int line ) const +{ + return MetaDataBase::breakPointCondition( MainWindow::self->findRealObject( o ), line ); +} + +void DesignerProjectImpl::setBreakPointCondition( QObject *o, int line, const QString &condition ) +{ + MetaDataBase::setBreakPointCondition( MainWindow::self->findRealObject( o ), line, condition ); +} + +void DesignerProjectImpl::clearAllBreakpoints() const +{ + QValueList<uint> empty; + for ( QPtrListIterator<SourceFile> sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + MetaDataBase::setBreakPoints( f, empty ); + } + for ( QPtrListIterator<FormFile> forms = project->formFiles(); + forms.current(); ++forms ) { + if ( forms.current()->formWindow() ) + MetaDataBase::setBreakPoints( forms.current()->formWindow(), empty ); + MainWindow::self->resetBreakPoints(); + } +} + +void DesignerProjectImpl::setIncludePath( const QString &platform, const QString &path ) +{ + project->setIncludePath( platform, path ); +} + +void DesignerProjectImpl::setLibs( const QString &platform, const QString &path ) +{ + project->setLibs( platform, path ); +} + +void DesignerProjectImpl::setDefines( const QString &platform, const QString &path ) +{ + project->setDefines( platform, path ); +} + +void DesignerProjectImpl::setConfig( const QString &platform, const QString &config ) +{ + project->setConfig( platform, config ); +} + +void DesignerProjectImpl::setTemplate( const QString &t ) +{ + project->setTemplate( t ); +} + +QString DesignerProjectImpl::config( const QString &platform ) const +{ + return project->config( platform ); +} + +QString DesignerProjectImpl::libs( const QString &platform ) const +{ + return project->libs( platform ); +} + +QString DesignerProjectImpl::defines( const QString &platform ) const +{ + return project->defines( platform ); +} + +QString DesignerProjectImpl::includePath( const QString &platform ) const +{ + return project->includePath( platform ); +} + +QString DesignerProjectImpl::templte() const +{ + return project->templte(); +} + +bool DesignerProjectImpl::isGenericObject( QObject *o ) const +{ + return !!project->fakeFormFileFor( o ); +} + + + + + + + +#ifndef QT_NO_SQL +DesignerDatabaseImpl::DesignerDatabaseImpl( DatabaseConnection *d ) + : db( d ) +{ +} + +QString DesignerDatabaseImpl::name() const +{ + return db->name(); +} + +void DesignerDatabaseImpl::setName( const QString & ) +{ +} + +QString DesignerDatabaseImpl::driver() const +{ + return db->driver(); +} + +void DesignerDatabaseImpl::setDriver( const QString & ) +{ +} + +QString DesignerDatabaseImpl::database() const +{ + return db->database(); +} + +void DesignerDatabaseImpl::setDatabase( const QString & ) +{ +} + +QString DesignerDatabaseImpl::userName() const +{ + return db->username(); +} + +void DesignerDatabaseImpl::setUserName( const QString & ) +{ +} + +QString DesignerDatabaseImpl::password() const +{ + return db->password(); +} + +void DesignerDatabaseImpl::setPassword( const QString & ) +{ +} + +QString DesignerDatabaseImpl::hostName() const +{ + return db->hostname(); +} + +void DesignerDatabaseImpl::setHostName( const QString & ) +{ +} + +QStringList DesignerDatabaseImpl::tables() const +{ + return db->tables(); +} + +QMap<QString, QStringList> DesignerDatabaseImpl::fields() const +{ + return db->fields(); +} + +void DesignerDatabaseImpl::open( bool suppressDialog ) const +{ + db->open( suppressDialog ); +} + +void DesignerDatabaseImpl::close() const +{ + db->close(); +} + +void DesignerDatabaseImpl::setFields( const QMap<QString, QStringList> & ) +{ +} + +void DesignerDatabaseImpl::setTables( const QStringList & ) +{ +} + +QSqlDatabase* DesignerDatabaseImpl::connection() +{ + return db->connection(); +} +#endif + + + +DesignerPixmapCollectionImpl::DesignerPixmapCollectionImpl( PixmapCollection *coll ) + : pixCollection( coll ) +{ +} + +void DesignerPixmapCollectionImpl::addPixmap( const QPixmap &p, const QString &name, bool force ) +{ + PixmapCollection::Pixmap pix; + pix.pix = p; + pix.name = name; + pixCollection->addPixmap( pix, force ); + FormWindow *fw = MainWindow::self->formWindow(); + if ( fw ) + MetaDataBase::setPixmapKey( fw, p.serialNumber(), name ); +} + +QPixmap DesignerPixmapCollectionImpl::pixmap( const QString &name ) const +{ + return pixCollection->pixmap( name ); +} + + + +DesignerFormWindowImpl::DesignerFormWindowImpl( FormWindow *fw ) + : formWindow( fw ) +{ +} + +QString DesignerFormWindowImpl::name() const +{ + return formWindow->name(); + } + +void DesignerFormWindowImpl::setName( const QString &n ) +{ + formWindow->setName( n ); +} + +QString DesignerFormWindowImpl::fileName() const +{ + return formWindow->fileName(); +} + +void DesignerFormWindowImpl::setFileName( const QString & ) +{ +} + +void DesignerFormWindowImpl::save() const +{ +} + +bool DesignerFormWindowImpl::isModified() const +{ + return formWindow->commandHistory()->isModified(); +} + +void DesignerFormWindowImpl::insertWidget( QWidget * ) +{ +} + +QWidget *DesignerFormWindowImpl::create( const char *className, QWidget *parent, const char *name ) +{ + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( className ), parent, name ); + formWindow->insertWidget( w, TRUE ); + formWindow->killAccels( formWindow->mainContainer() ); + return w; +} + +void DesignerFormWindowImpl::removeWidget( QWidget * ) +{ +} + +QWidgetList DesignerFormWindowImpl::widgets() const +{ + return QWidgetList(); +} + +void DesignerFormWindowImpl::undo() +{ +} + +void DesignerFormWindowImpl::redo() +{ +} + +void DesignerFormWindowImpl::cut() +{ +} + +void DesignerFormWindowImpl::copy() +{ +} + +void DesignerFormWindowImpl::paste() +{ +} + +void DesignerFormWindowImpl::adjustSize() +{ +} + +void DesignerFormWindowImpl::editConnections() +{ +} + +void DesignerFormWindowImpl::checkAccels() +{ +} + +void DesignerFormWindowImpl::layoutH() +{ + formWindow->layoutHorizontal(); +} + +void DesignerFormWindowImpl::layoutV() +{ +} + +void DesignerFormWindowImpl::layoutHSplit() +{ +} + +void DesignerFormWindowImpl::layoutVSplit() +{ +} + +void DesignerFormWindowImpl::layoutG() +{ + formWindow->layoutGrid(); +} + +void DesignerFormWindowImpl::layoutHContainer( QWidget* w ) +{ + formWindow->layoutHorizontalContainer( w ); +} + +void DesignerFormWindowImpl::layoutVContainer( QWidget* w ) +{ + formWindow->layoutVerticalContainer( w ); +} + +void DesignerFormWindowImpl::layoutGContainer( QWidget* w ) +{ + formWindow->layoutGridContainer( w ); +} + +void DesignerFormWindowImpl::breakLayout() +{ +} + +void DesignerFormWindowImpl::selectWidget( QWidget * w ) +{ + formWindow->selectWidget( w, TRUE ); +} + +void DesignerFormWindowImpl::selectAll() +{ +} + +void DesignerFormWindowImpl::clearSelection() +{ + formWindow->clearSelection(); +} + +bool DesignerFormWindowImpl::isWidgetSelected( QWidget * ) const +{ + return FALSE; +} + +QWidgetList DesignerFormWindowImpl::selectedWidgets() const +{ + return formWindow->selectedWidgets(); +} + +QWidget *DesignerFormWindowImpl::currentWidget() const +{ + return formWindow->currentWidget(); +} + +QWidget *DesignerFormWindowImpl::form() const +{ + return formWindow; +} + + +void DesignerFormWindowImpl::setCurrentWidget( QWidget * ) +{ +} + +QPtrList<QAction> DesignerFormWindowImpl::actionList() const +{ + return QPtrList<QAction>(); +} + +QAction *DesignerFormWindowImpl::createAction( const QString& text, const QIconSet& icon, const QString& menuText, int accel, + QObject* parent, const char* name, bool toggle ) +{ + QDesignerAction *a = new QDesignerAction( parent ); + a->setName( name ); + a->setText( text ); + if ( !icon.isNull() && !icon.pixmap().isNull() ) + a->setIconSet( icon ); + a->setMenuText( menuText ); + a->setAccel( accel ); + a->setToggleAction( toggle ); + return a; +} + +void DesignerFormWindowImpl::addAction( QAction *a ) +{ + if ( formWindow->actionList().findRef( a ) != -1 ) + return; + formWindow->actionList().append( a ); + MetaDataBase::addEntry( a ); + setPropertyChanged( a, "name", TRUE ); + setPropertyChanged( a, "text", TRUE ); + setPropertyChanged( a, "menuText", TRUE ); + setPropertyChanged( a, "accel", TRUE ); + if ( !a->iconSet().isNull() && !a->iconSet().pixmap().isNull() ) + setPropertyChanged( a, "iconSet", TRUE ); +} + +void DesignerFormWindowImpl::removeAction( QAction *a ) +{ + formWindow->actionList().removeRef( a ); +} + +void DesignerFormWindowImpl::preview() const +{ +} + +void DesignerFormWindowImpl::addConnection( QObject *sender, const char *signal, QObject *receiver, const char *slot ) +{ + MetaDataBase::addConnection( formWindow, sender, signal, receiver, slot ); +} + +void DesignerFormWindowImpl::addFunction( const QCString &function, const QString &specifier, + const QString &access, const QString &type, + const QString &language, const QString &returnType ) +{ + MetaDataBase::addFunction( formWindow, function, specifier, access, type, language, returnType ); + formWindow->mainWindow()->functionsChanged(); +} + + + +void DesignerFormWindowImpl::setProperty( QObject *o, const char *property, const QVariant &value ) +{ + int id = o->metaObject()->findProperty( property, TRUE ); + const QMetaProperty* p = o->metaObject()->property( id, TRUE ); + if ( p && p->isValid() ) + o->setProperty( property, value ); + else + MetaDataBase::setFakeProperty( o, property, value ); +} + +QVariant DesignerFormWindowImpl::property( QObject *o, const char *prop ) const +{ + int id = o->metaObject()->findProperty( prop, TRUE ); + const QMetaProperty* p = o->metaObject()->property( id, TRUE ); + if ( p && p->isValid() ) + return o->property( prop ); + return MetaDataBase::fakeProperty( o, prop ); +} + +void DesignerFormWindowImpl::setPropertyChanged( QObject *o, const char *property, bool changed ) +{ + MetaDataBase::setPropertyChanged( o, property, changed ); +} + +bool DesignerFormWindowImpl::isPropertyChanged( QObject *o, const char *property ) const +{ + return MetaDataBase::isPropertyChanged( o, property ); +} + +void DesignerFormWindowImpl::setColumnFields( QObject *o, const QMap<QString, QString> &f ) +{ + MetaDataBase::setColumnFields( o, f ); +} + +QStringList DesignerFormWindowImpl::implementationIncludes() const +{ + QValueList<MetaDataBase::Include> includes = MetaDataBase::includes( formWindow ); + QStringList lst; + for ( QValueList<MetaDataBase::Include>::Iterator it = includes.begin(); it != includes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl != "in implementation" ) + continue; + QString s = inc.header; + if ( inc.location == "global" ) { + s.prepend( "<" ); + s.append( ">" ); + } else { + s.prepend( "\"" ); + s.append( "\"" ); + } + lst << s; + } + return lst; +} + +QStringList DesignerFormWindowImpl::declarationIncludes() const +{ + QValueList<MetaDataBase::Include> includes = MetaDataBase::includes( formWindow ); + QStringList lst; + for ( QValueList<MetaDataBase::Include>::Iterator it = includes.begin(); it != includes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl == "in implementation" ) + continue; + QString s = inc.header; + if ( inc.location == "global" ) { + s.prepend( "<" ); + s.append( ">" ); + } else { + s.prepend( "\"" ); + s.append( "\"" ); + } + lst << s; + } + return lst; +} + +void DesignerFormWindowImpl::setImplementationIncludes( const QStringList &lst ) +{ + QValueList<MetaDataBase::Include> oldIncludes = MetaDataBase::includes( formWindow ); + QValueList<MetaDataBase::Include> includes; + for ( QValueList<MetaDataBase::Include>::Iterator it = oldIncludes.begin(); it != oldIncludes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl == "in implementation" ) + continue; + includes << inc; + } + + for ( QStringList::ConstIterator sit = lst.begin(); sit != lst.end(); ++sit ) { + QString s = *sit; + if ( s.startsWith( "#include" ) ) + s.remove( (uint)0, 8 ); + s = s.simplifyWhiteSpace(); + if ( s[ 0 ] != '<' && s[ 0 ] != '"' ) { + s.prepend( "\"" ); + s.append( "\"" ); + } + if ( s[ 0 ] == '<' ) { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in implementation"; + inc.location = "global"; + includes << inc; + } else { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in implementation"; + inc.location = "local"; + includes << inc; + } + } + MetaDataBase::setIncludes( formWindow, includes ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +void DesignerFormWindowImpl::setDeclarationIncludes( const QStringList &lst ) +{ + QValueList<MetaDataBase::Include> oldIncludes = MetaDataBase::includes( formWindow ); + QValueList<MetaDataBase::Include> includes; + for ( QValueList<MetaDataBase::Include>::Iterator it = oldIncludes.begin(); it != oldIncludes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl == "in declaration" ) + continue; + includes << inc; + } + + for ( QStringList::ConstIterator sit = lst.begin(); sit != lst.end(); ++sit ) { + QString s = *sit; + if ( s.startsWith( "#include" ) ) + s.remove( (uint)0, 8 ); + s = s.simplifyWhiteSpace(); + if ( s[ 0 ] != '<' && s[ 0 ] != '"' ) { + s.prepend( "\"" ); + s.append( "\"" ); + } + if ( s[ 0 ] == '<' ) { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in declaration"; + inc.location = "global"; + includes << inc; + } else { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in declaration"; + inc.location = "local"; + includes << inc; + } + } + MetaDataBase::setIncludes( formWindow, includes ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +QStringList DesignerFormWindowImpl::forwardDeclarations() const +{ + return MetaDataBase::forwards( formWindow ); +} + +void DesignerFormWindowImpl::setForwardDeclarations( const QStringList &lst ) +{ + MetaDataBase::setForwards( formWindow, lst ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +QStringList DesignerFormWindowImpl::signalList() const +{ + return MetaDataBase::signalList( formWindow ); +} + +void DesignerFormWindowImpl::setSignalList( const QStringList &lst ) +{ + MetaDataBase::setSignalList( formWindow, lst ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +void DesignerFormWindowImpl::onModificationChange( QObject *receiver, const char *slot ) +{ + QObject::connect( formWindow, SIGNAL( modificationChanged( bool, FormWindow * ) ), receiver, slot ); +} + +void DesignerFormWindowImpl::addMenu( const QString &text, const QString &name ) +{ + if ( !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) + return; + + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + PopupMenuEditor *popup = new PopupMenuEditor( formWindow, mw ); + QString n = name; + formWindow->unify( popup, n, TRUE ); + popup->setName( n ); + MenuBarEditor *mb = (MenuBarEditor *)mw->child( 0, "MenuBarEditor" ); + if ( !mb ) { + mb = new MenuBarEditor( formWindow, mw ); + mb->setName( "MenuBar" ); + MetaDataBase::addEntry( mb ); + } + mb->insertItem( text, popup ); + MetaDataBase::addEntry( popup ); +} + +void DesignerFormWindowImpl::addMenuAction( const QString &menu, QAction *a ) +{ + if ( !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + if ( !mw->child( 0, "MenuBarEditor" ) ) + return; + PopupMenuEditor *popup = (PopupMenuEditor*)mw->child( menu, "PopupMenuEditor" ); + if ( !popup ) + return; + popup->insert( a ); +} + +void DesignerFormWindowImpl::addMenuSeparator( const QString &menu ) +{ + if ( !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + if ( !mw->child( 0, "MenuBarEditor" ) ) + return; + PopupMenuEditor *popup = (PopupMenuEditor*)mw->child( menu, "PopupMenuEditor" ); + if ( !popup ) + return; + QAction *a = new QSeparatorAction( 0 ); + popup->insert( a ); +} + +void DesignerFormWindowImpl::addToolBar( const QString &text, const QString &name ) +{ + if ( !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + QToolBar *tb = new QDesignerToolBar( mw ); + QString n = name; + formWindow->unify( tb, n, TRUE ); + tb->setName( n ); + mw->addToolBar( tb, text ); +} + +void DesignerFormWindowImpl::addToolBarAction( const QString &tbn, QAction *a ) +{ + if ( !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + QDesignerToolBar *tb = (QDesignerToolBar*)mw->child( tbn, "QDesignerToolBar" ); + if ( !tb ) + return; + a->addTo( tb ); + tb->addAction( a ); +} + +void DesignerFormWindowImpl::addToolBarSeparator( const QString &tbn ) +{ + if ( !::qt_cast<QMainWindow*>(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + QDesignerToolBar *tb = (QDesignerToolBar*)mw->child( tbn, "QDesignerToolBar" ); + if ( !tb ) + return; + QAction *a = new QSeparatorAction( 0 ); + a->addTo( tb ); + tb->addAction( a ); +} + +DesignerDockImpl::DesignerDockImpl() +{ +} + +QDockWindow *DesignerDockImpl::dockWindow() const +{ + return 0; +} + +DesignerOutputDockImpl::DesignerOutputDockImpl( OutputWindow *ow ) + : outWin( ow ) +{ +} + +QWidget *DesignerOutputDockImpl::addView( const QString &title ) +{ + QWidget *page = new QWidget( outWin ); + outWin->addTab( page, title ); + return page; +} + +void DesignerOutputDockImpl::appendDebug( const QString &s ) +{ + outWin->appendDebug( s ); +} + +void DesignerOutputDockImpl::clearDebug() +{ +} + +void DesignerOutputDockImpl::appendError( const QString &s, int l ) +{ + QStringList ls; + ls << s; + QValueList<uint> ll; + ll << l; + outWin->setErrorMessages( ls, ll, FALSE, QStringList(), QObjectList() ); +} + +void DesignerOutputDockImpl::clearError() +{ +} + +DesignerSourceFileImpl::DesignerSourceFileImpl( SourceFile *e ) + : ed( e ) +{ +} + +QString DesignerSourceFileImpl::fileName() const +{ + return ed->fileName(); +} diff --git a/kdevdesigner/designer/designerappiface.h b/kdevdesigner/designer/designerappiface.h new file mode 100644 index 00000000..a9eace16 --- /dev/null +++ b/kdevdesigner/designer/designerappiface.h @@ -0,0 +1,277 @@ + /********************************************************************** +** 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. +** +** 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 DESIGNERAPPIFACE_H +#define DESIGNERAPPIFACE_H + +#include "../interfaces/designerinterface.h" +#include "project.h" + +class FormWindow; +class MainWindow; +class Project; +class OutputWindow; +class SourceFile; + +class DesignerInterfaceImpl : public DesignerInterface +{ +public: + DesignerInterfaceImpl( MainWindow *mw ); + + DesignerProject *currentProject() const; + DesignerFormWindow *currentForm() const; + DesignerSourceFile *currentSourceFile() const; + QPtrList<DesignerProject> projectList() const; + void showStatusMessage( const QString &, int ms = 0 ) const; + DesignerDock *createDock() const; + DesignerOutputDock *outputDock() const; + void setModified( bool b, QWidget *window ); + void updateFunctionList(); + + void onProjectChange( QObject *receiver, const char *slot ); + void onFormChange( QObject *receiver, const char *slot ); + + bool singleProjectMode() const; + void showError( QWidget *widget, int line, const QString &message ); + void runFinished(); + void showStackFrame( QWidget *w, int line ); + void showDebugStep( QWidget *w, int line ); + void runProjectPrecondition(); + void runProjectPostcondition( QObjectList *l ); + + + QRESULT queryInterface( const QUuid &uuid, QUnknownInterface** iface ); + Q_REFCOUNT + +private: + MainWindow *mainWindow; + +}; + +class DesignerProjectImpl: public DesignerProject +{ +public: + DesignerProjectImpl( Project *pr ); + + QPtrList<DesignerFormWindow> formList() const; + QStringList formNames() const; + QString formFileName( const QString &form ) const; + void addForm( DesignerFormWindow * ); + void removeForm( DesignerFormWindow * ); + QString fileName() const; + void setFileName( const QString & ); + QString projectName() const; + void setProjectName( const QString & ); + QString databaseFile() const; + void setDatabaseFile( const QString & ); + void setupDatabases() const; + QPtrList<DesignerDatabase> databaseConnections() const; + void addDatabase( DesignerDatabase * ); + void removeDatabase( DesignerDatabase * ); + void save() const; + void setLanguage( const QString & ); + QString language() const; + void setCustomSetting( const QString &key, const QString &value ); + QString customSetting( const QString &key ) const; + DesignerPixmapCollection *pixmapCollection() const; + void breakPoints( QMap<QString, QValueList<uint> > &bps ) const; + QString breakPointCondition( QObject *o, int line ) const; + void setBreakPointCondition( QObject *o, int line, const QString &condition ); + void clearAllBreakpoints() const; + void setIncludePath( const QString &platform, const QString &path ); + void setLibs( const QString &platform, const QString &path ); + void setDefines( const QString &platform, const QString &path ); + void setConfig( const QString &platform, const QString &config ); + void setTemplate( const QString &t ); + QString config( const QString &platform ) const; + QString libs( const QString &platform ) const; + QString defines( const QString &platform ) const; + QString includePath( const QString &platform ) const; + QString templte() const; + bool isGenericObject( QObject *o ) const; + +private: + Project *project; + +}; + +#ifndef QT_NO_SQL +class QSqlDatabase; + +class DesignerDatabaseImpl: public DesignerDatabase +{ +public: + DesignerDatabaseImpl( DatabaseConnection *d ); + + QString name() const; + void setName( const QString & ); + QString driver() const; + void setDriver( const QString & ); + QString database() const; + void setDatabase( const QString & ); + QString userName() const; + void setUserName( const QString & ); + QString password() const; + void setPassword( const QString & ); + QString hostName() const; + void setHostName( const QString & ); + QStringList tables() const; + void setTables( const QStringList & ); + QMap<QString, QStringList> fields() const; + void setFields( const QMap<QString, QStringList> & ); + void open( bool suppressDialog = TRUE ) const; + void close() const; + QSqlDatabase* connection(); +private: + DatabaseConnection *db; + +}; +#endif + +class DesignerPixmapCollectionImpl : public DesignerPixmapCollection +{ +public: + DesignerPixmapCollectionImpl( PixmapCollection *coll ); + void addPixmap( const QPixmap &p, const QString &name, bool force ); + QPixmap pixmap( const QString &name ) const; + +private: + PixmapCollection *pixCollection; + +}; + +class DesignerFormWindowImpl: public DesignerFormWindow +{ +public: + DesignerFormWindowImpl( FormWindow *fw ); + + QString name() const; + void setName( const QString &n ); + QString fileName() const; + void setFileName( const QString & ); + void save() const; + bool isModified() const; + void insertWidget( QWidget * ); + QWidget *create( const char *className, QWidget *parent, const char *name ); + void removeWidget( QWidget * ); + QWidgetList widgets() const; + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void adjustSize(); + void editConnections(); + void checkAccels(); + void layoutH(); + void layoutV(); + void layoutHSplit(); + void layoutVSplit(); + void layoutG(); + void layoutHContainer( QWidget* w ); + void layoutVContainer( QWidget* w ); + void layoutGContainer( QWidget* w ); + void breakLayout(); + void selectWidget( QWidget * ); + void selectAll(); + void clearSelection(); + bool isWidgetSelected( QWidget * ) const; + QWidgetList selectedWidgets() const; + QWidget *currentWidget() const; + QWidget *form() const; + void setCurrentWidget( QWidget * ); + QPtrList<QAction> actionList() const; + QAction *createAction( const QString& text, const QIconSet& icon, const QString& menuText, int accel, + QObject* parent, const char* name = 0, bool toggle = FALSE ); + void addAction( QAction * ); + void removeAction( QAction * ); + void preview() const; + void addFunction( const QCString &function, const QString& specifier, const QString &access, + const QString &type, const QString &language, const QString &returnType ); + void addConnection( QObject *sender, const char *signal, QObject *receiver, const char *slot ); + void setProperty( QObject *o, const char *property, const QVariant &value ); + QVariant property( QObject *o, const char *property ) const; + void setPropertyChanged( QObject *o, const char *property, bool changed ); + bool isPropertyChanged( QObject *o, const char *property ) const; + void setColumnFields( QObject *o, const QMap<QString, QString> & ); + QStringList implementationIncludes() const; + QStringList declarationIncludes() const; + void setImplementationIncludes( const QStringList &lst ); + void setDeclarationIncludes( const QStringList &lst ); + QStringList forwardDeclarations() const; + void setForwardDeclarations( const QStringList &lst ); + QStringList signalList() const; + void setSignalList( const QStringList &lst ); + void addMenu( const QString &text, const QString &name ); + void addMenuAction( const QString &menu, QAction *a ); + void addMenuSeparator( const QString &menu ); + void addToolBar( const QString &text, const QString &name ); + void addToolBarAction( const QString &tb, QAction *a ); + void addToolBarSeparator( const QString &tb ); + + void onModificationChange( QObject *receiver, const char *slot ); + +private: + FormWindow *formWindow; + +}; + +class DesignerDockImpl: public DesignerDock +{ +public: + DesignerDockImpl(); + + QDockWindow *dockWindow() const; +}; + +class DesignerOutputDockImpl: public DesignerOutputDock +{ +public: + DesignerOutputDockImpl( OutputWindow *ow ); + + QWidget *addView( const QString &pageName ); + void appendDebug( const QString & ); + void clearDebug(); + void appendError( const QString &, int ); + void clearError(); + +private: + OutputWindow *outWin; + +}; + +class DesignerSourceFileImpl : public DesignerSourceFile +{ +public: + DesignerSourceFileImpl( SourceFile *e ); + QString fileName() const; + +private: + SourceFile *ed; + +}; + +#endif diff --git a/kdevdesigner/designer/editfunctions.ui b/kdevdesigner/designer/editfunctions.ui new file mode 100644 index 00000000..2cecdcb1 --- /dev/null +++ b/kdevdesigner/designer/editfunctions.ui @@ -0,0 +1,714 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>EditFunctionsBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>EditFunctionsBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>371</height> + </rect> + </property> + <property name="caption"> + <string>Edit Functions</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Edit Functions</b><p>Add, edit or delete the current form's slots or functions.</p><p>Click the <b>Add Function</b>-button to create a new function; enter a name, choose an access mode and specify if it should be a slot or normal function.</p><p>Select an entry from the list and click the <b>Delete Function</b>-button to remove a function; in case of a slot all connections using this slot will also be removed.</p></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Function</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Return Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Specifier</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Access</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>In Use</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>functionListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="showSortIndicator"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>This form's functions.</b><p>Select the function you want to change or delete.</p></string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>showOnlySlots</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="text"> + <string>Only d&isplay slots</string> + </property> + <property name="toolTip" stdset="0"> + <string>Change displaying mode for functions</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Check this button if only the slots should be displayed</b><p>Otherwise all functions, i.e. normal C++ functions and slots are displayed.</p> +</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Vertical Spacing1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>addFunction</cstring> + </property> + <property name="text"> + <string>&New Function</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add new function</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Add a new function.</b><p>New functions have a default name and public access.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>deleteFunction</cstring> + </property> + <property name="text"> + <string>&Delete Function</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete function</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the selected function.</b><p>All connections using this function are also removed.</p></string> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>boxProperties</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Function Properties</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout14</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>Label8</cstring> + </property> + <property name="text"> + <string>&Function:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>functionName</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>functionName</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Change function name</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the name of the selected function.</b><p>The name should include the argument list and must be syntactically correct.</p></string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>labelType</cstring> + </property> + <property name="text"> + <string>&Return type:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>editType</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editType</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Change the return type of the function</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the return type of the selected function.</b><p>Specifiy here the datatype which should be returned by the function.</p></string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout13</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>Label9_2</cstring> + </property> + <property name="text"> + <string>S&pecifier:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>functionSpecifier</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>non virtual</string> + </property> + </item> + <item> + <property name="text"> + <string>virtual</string> + </property> + </item> + <item> + <property name="text"> + <string>pure virtual</string> + </property> + </item> + <item> + <property name="text"> + <string>static</string> + </property> + </item> + <property name="name"> + <cstring>functionSpecifier</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Change function access</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the access policy of the function</b><p>All functions are created virtual and should be reimplemented in subclasses.</p></string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Access:</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>functionAccess</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>public</string> + </property> + </item> + <item> + <property name="text"> + <string>protected</string> + </property> + </item> + <item> + <property name="text"> + <string>private</string> + </property> + </item> + <property name="name"> + <cstring>functionAccess</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Change function access</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the access policy of the function</b><p>All functions are created virtual and should be reimplemented in subclasses.</p></string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>&Type:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>functionType</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>slot</string> + </property> + </item> + <item> + <property name="text"> + <string>function</string> + </property> + </item> + <property name="name"> + <cstring>functionType</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change function type</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the type of the function.</b><p>The type specifies if the function is either a slot or a normal C++ function.</p></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>EditFunctionsBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>EditFunctionsBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>deleteFunction</sender> + <signal>clicked()</signal> + <receiver>EditFunctionsBase</receiver> + <slot>functionRemove()</slot> + </connection> + <connection> + <sender>addFunction</sender> + <signal>clicked()</signal> + <receiver>EditFunctionsBase</receiver> + <slot>functionAdd()</slot> + </connection> + <connection> + <sender>functionName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>functionListView</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentItemChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>functionListView</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentItemChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>editType</sender> + <signal>textChanged(const QString&)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentReturnTypeChanged(const QString&)</slot> + </connection> + <connection> + <sender>functionSpecifier</sender> + <signal>activated(const QString&)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentSpecifierChanged(const QString&)</slot> + </connection> + <connection> + <sender>functionAccess</sender> + <signal>activated(const QString&)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentAccessChanged(const QString&)</slot> + </connection> + <connection> + <sender>functionType</sender> + <signal>activated(const QString&)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>currentTypeChanged(const QString&)</slot> + </connection> + <connection> + <sender>showOnlySlots</sender> + <signal>toggled(bool)</signal> + <receiver>EditFunctionsBase</receiver> + <slot>displaySlots(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>functionName</tabstop> + <tabstop>editType</tabstop> + <tabstop>functionSpecifier</tabstop> + <tabstop>functionAccess</tabstop> + <tabstop>functionType</tabstop> + <tabstop>helpButton</tabstop> + <tabstop>okButton</tabstop> + <tabstop>cancelButton</tabstop> + <tabstop>functionListView</tabstop> + <tabstop>showOnlySlots</tabstop> + <tabstop>addFunction</tabstop> + <tabstop>deleteFunction</tabstop> +</tabstops> +<slots> + <slot access="protected">currentItemChanged( QListViewItem * )</slot> + <slot access="protected">currentSpecifierChanged( const QString & )</slot> + <slot access="protected">currentTextChanged( const QString & )</slot> + <slot access="protected">currentReturnTypeChanged( const QString & )</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">init()</slot> + <slot access="protected">currentAccessChanged( const QString & )</slot> + <slot access="protected">currentTypeChanged( const QString & )</slot> + <slot access="protected">okClicked()</slot> + <slot access="protected">functionAdd()</slot> + <slot access="protected">functionRemove()</slot> + <slot access="protected">displaySlots( bool )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/editfunctionsimpl.cpp b/kdevdesigner/designer/editfunctionsimpl.cpp new file mode 100644 index 00000000..19506e22 --- /dev/null +++ b/kdevdesigner/designer/editfunctionsimpl.cpp @@ -0,0 +1,534 @@ +/********************************************************************** +** 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 "editfunctionsimpl.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "asciivalidator.h" +#include "mainwindow.h" +#include "hierarchyview.h" +#include "project.h" + +#include <kiconloader.h> +#include <klineedit.h> +#include "kdevdesigner_part.h" + +#include <qlistview.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qstrlist.h> +#include <qmessagebox.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qgroupbox.h> +#include <qheader.h> +#include <qcheckbox.h> + +#include <klocale.h> + +EditFunctions::EditFunctions( QWidget *parent, FormWindow *fw, bool justSlots ) + : EditFunctionsBase( parent, 0, TRUE ), formWindow( fw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + id = 0; + functList.clear(); + + QValueList<MetaDataBase::Function> functionList = MetaDataBase::functionList( fw ); + for ( QValueList<MetaDataBase::Function>::Iterator it = functionList.begin(); it != functionList.end(); ++it ) { + QListViewItem *i = new QListViewItem( functionListView ); + + i->setPixmap( 0, SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()) ); + i->setText( 0, (*it).function ); + i->setText( 1, (*it).returnType ); + i->setText( 2, (*it).specifier ); + i->setText( 3, (*it).access ); + i->setText( 4, (*it).type ); + + FunctItem fui; + fui.id = id; + fui.oldName = (*it).function; + fui.newName = fui.oldName; + fui.oldRetTyp = (*it).returnType; + fui.retTyp = fui.oldRetTyp; + fui.oldSpec = (*it).specifier; + fui.spec = fui.oldSpec; + fui.oldAccess = (*it).access; + fui.access = fui.oldAccess; + fui.oldType = (*it).type; + fui.type = fui.oldType; + functList.append( fui ); + + functionIds.insert( i, id ); + id++; + + if ( (*it).type == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, MetaDataBase::normalizeFunction( (*it).function ).latin1() ) ) + i->setText( 5, i18n( "Yes" ) ); + else + i->setText( 5, i18n( "No" ) ); + } else { + i->setText( 5, "---" ); + } + } + + boxProperties->setEnabled( FALSE ); + functionName->setValidator( new AsciiValidator( TRUE, functionName ) ); + + if ( functionListView->firstChild() ) + functionListView->setCurrentItem( functionListView->firstChild() ); + + showOnlySlots->setChecked( justSlots ); + lastType = "function"; + + // Enable rename for all QListViewItems + QListViewItemIterator lvit = functionListView->firstChild(); + for ( ; *lvit; lvit++ ) + (*lvit)->setRenameEnabled( 0, TRUE ); + + // Connect listview signal to signal-relay + QObject::connect( functionListView, + SIGNAL( itemRenamed( QListViewItem*, int, const QString & ) ), + this, + SLOT( emitItemRenamed(QListViewItem*, int, const QString&) ) ); + + // Connect signal-relay to QLineEdit "functionName" + QObjectList *l = parent->queryList( "QLineEdit", "functionName" ); + QObject *obj; + QObjectListIt itemsLineEditIt( *l ); + while ( (obj = itemsLineEditIt.current()) != 0 ) { + ++itemsLineEditIt; + QObject::connect( this, + SIGNAL( itemRenamed( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; +} + +void EditFunctions::okClicked() +{ + QValueList<MetaDataBase::Function> functionList = MetaDataBase::functionList( formWindow ); + QString n = i18n( "Add/Remove functions of '%1'" ).arg( formWindow->name() ); + QPtrList<Command> commands; + QValueList<MetaDataBase::Function>::Iterator fit; + if ( !functionList.isEmpty() ) { + for ( fit = functionList.begin(); fit != functionList.end(); ++fit ) { + bool functionFound = FALSE; + QValueList<FunctItem>::Iterator it = functList.begin(); + for ( ; it != functList.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).oldName ) == + MetaDataBase::normalizeFunction( (*fit).function ) ) { + functionFound = TRUE; + break; + } + } + if ( !functionFound ) + commands.append( new RemoveFunctionCommand( i18n( "Remove Function" ), + formWindow, (*fit).function, (*fit).specifier, + (*fit).access, + (*fit).type, + formWindow->project()->language(), + (*fit).returnType ) ); + } + } + + bool invalidFunctions = FALSE; + QValueList<FunctItem> invalidItems; + + if ( !functList.isEmpty() ) { + QStrList lst; + QValueList<FunctItem>::Iterator it = functList.begin(); + for ( ; it != functList.end(); ++it ) { + MetaDataBase::Function function; + function.function = (*it).newName; + function.returnType = (*it).retTyp; + function.specifier = (*it).spec; + function.access = (*it).access; + function.type = (*it).type; + function.language = formWindow->project()->language(); + if ( function.returnType.isEmpty() ) + function.returnType = "void"; + QString s = function.function; + s = s.simplifyWhiteSpace(); + bool startNum = s[ 0 ] >= '0' && s[ 0 ] <= '9'; + bool noParens = s.contains( '(' ) != 1 || s.contains( ')' ) != 1; + bool illegalSpace = s.find( ' ' ) != -1 && s.find( ' ' ) < s.find( '(' ); + + if ( startNum || noParens || illegalSpace || lst.find( function.function ) != -1 ) { + invalidFunctions = TRUE; + invalidItems.append( (*it) ); + continue; + } + bool functionFound = FALSE; + for ( fit = functionList.begin(); fit != functionList.end(); ++fit ) { + if ( MetaDataBase::normalizeFunction( (*fit).function ) == + MetaDataBase::normalizeFunction( (*it).oldName ) ) { + functionFound = TRUE; + break; + } + } + if ( !functionFound ) + commands.append( new AddFunctionCommand( i18n( "Add Function" ), + formWindow, function.function, function.specifier, + function.access, + function.type, formWindow->project()->language(), + function.returnType ) ); + if ( MetaDataBase::normalizeFunction( (*it).newName ) != MetaDataBase::normalizeFunction( (*it).oldName ) || + (*it).spec != (*it).oldSpec || (*it).access != (*it).oldAccess || (*it).type != (*it).oldType || + (*it).retTyp != (*it).oldRetTyp ) { + QString normalizedOldName = MetaDataBase::normalizeFunction( (*it).oldName ); + if ((*it).oldName.endsWith("const")) // make sure we get the 'const' when we remove the old name + normalizedOldName += " const"; + commands.append( new ChangeFunctionAttribCommand( i18n( "Change Function Attributes" ), + formWindow, function, normalizedOldName, + (*it).oldSpec, (*it).oldAccess, (*it).oldType, + formWindow->project()->language(), (*it).oldRetTyp ) ); + } + lst.append( function.function ); + } + } + + if ( invalidFunctions ) { + if ( QMessageBox::information( this, i18n( "Edit Functions" ), + i18n( "Some syntactically incorrect functions have been defined.\n" + "Remove these functions?" ), i18n( "&Yes" ), i18n( "&No" ) ) == 0 ) { + QValueList<FunctItem>::Iterator it = functList.begin(); + while ( it != functList.end() ) { + bool found = FALSE; + QValueList<FunctItem>::Iterator vit = invalidItems.begin(); + for ( ; vit != invalidItems.end(); ++vit ) { + if ( (*vit).newName == (*it).newName ) { + invalidItems.remove( vit ); + found = TRUE; + break; + } + } + if ( found ) { + int delId = (*it).id; + it = functList.remove( it ); + QMap<QListViewItem*, int>::Iterator fit = functionIds.begin(); + while ( fit != functionIds.end() ) { + if ( *fit == delId ) { + QListViewItem *litem = fit.key(); + functionIds.remove( fit ); + delete litem; + if ( functionListView->currentItem() ) + functionListView->setSelected( functionListView->currentItem(), TRUE ); + currentItemChanged( functionListView->currentItem() ); + break; + } + ++fit; + } + } + else + ++it; + } + if ( functionListView->firstChild() ) { + functionListView->setCurrentItem( functionListView->firstChild() ); + functionListView->setSelected( functionListView->firstChild(), TRUE ); + } + } + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + return; + } + + if ( !commands.isEmpty() ) { + MacroCommand *cmd = new MacroCommand( n, formWindow, commands ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + accept(); +} + +void EditFunctions::functionAdd( const QString &access, const QString &type ) +{ + QListViewItem *i = new QListViewItem( functionListView ); + i->setPixmap( 0, SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()) ); + i->setRenameEnabled( 0, TRUE ); + i->setText( 1, "void" ); + i->setText( 2, "virtual" ); + + if ( access.isEmpty() ) + i->setText( 3, "public" ); + else + i->setText( 3, access ); + + if( type.isEmpty() ) { + if ( showOnlySlots->isChecked() ) + i->setText( 4, "slot" ); + else { + i->setText( 4, lastType ); + } + } else { + i->setText( 4, type ); + } + + if ( i->text( 4 ) == "slot" ) { + i->setText( 0, "newSlot()" ); + if ( MetaDataBase::isSlotUsed( formWindow, "newSlot()" ) ) + i->setText( 5, i18n( "Yes" ) ); + else + i->setText( 5, i18n( "No" ) ); + } else { + i->setText( 0, "newFunction()" ); + i->setText( 5, "---" ); + } + + functionListView->setCurrentItem( i ); + functionListView->setSelected( i, TRUE ); + functionListView->ensureItemVisible( i ); + functionName->setFocus(); + functionName->selectAll(); + + FunctItem fui; + fui.id = id; + fui.oldName = i->text( 0 ); + fui.newName = fui.oldName; + fui.oldRetTyp = i->text( 1 ); + fui.retTyp = fui.oldRetTyp; + fui.oldSpec = i->text ( 2 ); + fui.spec = fui.oldSpec; + fui.oldAccess = i->text( 3 ); + fui.access = fui.oldAccess; + fui.oldType = i->text( 4 ); + fui.type = fui.oldType; + lastType = fui.oldType; + functList.append( fui ); + functionIds.insert( i, id ); + id++; +} + +void EditFunctions::functionRemove() +{ + if ( !functionListView->currentItem() ) + return; + + functionListView->blockSignals( TRUE ); + removedFunctions << MetaDataBase::normalizeFunction( functionListView->currentItem()->text( 0 ) ); + int delId = functionIds[ functionListView->currentItem() ]; + QValueList<FunctItem>::Iterator it = functList.begin(); + while ( it != functList.end() ) { + if ( (*it).id == delId ) { + functList.remove( it ); + break; + } + ++it; + } + functionIds.remove( functionListView->currentItem() ); + delete functionListView->currentItem(); + if ( functionListView->currentItem() ) + functionListView->setSelected( functionListView->currentItem(), TRUE ); + functionListView->blockSignals( FALSE ); + currentItemChanged( functionListView->currentItem() ); +} + +void EditFunctions::currentItemChanged( QListViewItem *i ) +{ + functionName->blockSignals( TRUE ); + functionName->setText( "" ); + functionAccess->setCurrentItem( 0 ); + functionName->blockSignals( FALSE ); + + if ( !i ) { + boxProperties->setEnabled( FALSE ); + return; + } + + functionName->blockSignals( TRUE ); + functionName->setText( i->text( 0 ) ); + editType->setText( i->text( 1 ) ); + QString specifier = i->text( 2 ); + QString access = i->text( 3 ); + QString type = i->text( 4 ); + if ( specifier == "pure virtual" ) + functionSpecifier->setCurrentItem( 2 ); + else if ( specifier == "non virtual" ) + functionSpecifier->setCurrentItem( 0 ); + else if ( specifier == "virtual" ) + functionSpecifier->setCurrentItem( 1 ); + else + functionSpecifier->setCurrentItem( 3 ); + if ( access == "private" ) + functionAccess->setCurrentItem( 2 ); + else if ( access == "protected" ) + functionAccess->setCurrentItem( 1 ); + else + functionAccess->setCurrentItem( 0 ); + if ( type == "slot" ) + functionType->setCurrentItem( 0 ); + else + functionType->setCurrentItem( 1 ); + + functionName->blockSignals( FALSE ); + boxProperties->setEnabled( TRUE ); +} + +void EditFunctions::currentTextChanged( const QString &txt ) +{ + if ( !functionListView->currentItem() ) + return; + + changeItem( functionListView->currentItem(), Name, txt ); + functionListView->currentItem()->setText( 0, txt ); + + if ( functionListView->currentItem()->text( 4 ) == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, MetaDataBase::normalizeFunction( txt.latin1() ).latin1() ) ) + functionListView->currentItem()->setText( 5, i18n( "Yes" ) ); + else + functionListView->currentItem()->setText( 5, i18n( "No" ) ); + } else { + functionListView->currentItem()->setText( 5, "---" ); + } +} + +void EditFunctions::currentSpecifierChanged( const QString& s ) +{ + if ( !functionListView->currentItem() ) + return; + + changeItem( functionListView->currentItem(), Specifier, s ); + functionListView->currentItem()->setText( 2, s ); +} + +void EditFunctions::currentAccessChanged( const QString& a ) +{ + if ( !functionListView->currentItem() ) + return; + changeItem( functionListView->currentItem(), Access, a ); + functionListView->currentItem()->setText( 3, a ); +} + + +void EditFunctions::currentReturnTypeChanged( const QString &type ) +{ + if ( !functionListView->currentItem() ) + return; + changeItem( functionListView->currentItem(), ReturnType, type ); + functionListView->currentItem()->setText( 1, type ); +} + +void EditFunctions::currentTypeChanged( const QString &type ) +{ + if ( !functionListView->currentItem() ) + return; + changeItem( functionListView->currentItem(), Type, type ); + lastType = type; + functionListView->currentItem()->setText( 4, type ); + if ( type == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, + MetaDataBase::normalizeFunction( functionListView->currentItem()->text( 0 ).latin1() ).latin1() ) ) + functionListView->currentItem()->setText( 5, i18n( "Yes" ) ); + else + functionListView->currentItem()->setText( 5, i18n( "No" ) ); + } else { + functionListView->currentItem()->setText( 5, "---" ); + } +} + +void EditFunctions::changeItem( QListViewItem *item, Attribute a, const QString &nV ) +{ + int itemId; + QMap<QListViewItem*, int>::Iterator fit = functionIds.find( item ); + if ( fit != functionIds.end() ) + itemId = *fit; + else + return; + + QValueList<FunctItem>::Iterator it = functList.begin(); + for ( ; it != functList.end(); ++it ) { + if ( (*it).id == itemId ) { + switch( a ) { + case Name: + (*it).newName = nV; + break; + case Specifier: + (*it).spec = nV; + break; + case Access: + (*it).access = nV; + break; + case ReturnType: + (*it).retTyp = nV; + break; + case Type: + (*it).type = nV; + break; + } + } + } +} + +void EditFunctions::setCurrentFunction( const QString &function ) +{ + QListViewItemIterator it( functionListView ); + while ( it.current() ) { + if ( MetaDataBase::normalizeFunction( it.current()->text( 0 ) ) == function ) { + functionListView->setCurrentItem( it.current() ); + functionListView->setSelected( it.current(), TRUE ); + currentItemChanged( it.current() ); + return; + } + ++it; + } +} + +void EditFunctions::displaySlots( bool justSlots ) +{ + functionIds.clear(); + functionListView->clear(); + for ( QValueList<FunctItem>::Iterator it = functList.begin(); it != functList.end(); ++it ) { + if ( (*it).type == "function" && justSlots ) + continue; + QListViewItem *i = new QListViewItem( functionListView ); + functionIds.insert( i, (*it).id ); + i->setPixmap( 0, SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()) ); + i->setText( 0, (*it).newName ); + i->setText( 1, (*it).retTyp ); + i->setText( 2, (*it).spec ); + i->setText( 3, (*it).access ); + i->setText( 4, (*it).type ); + + if ( (*it).type == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, MetaDataBase::normalizeFunction( (*it).newName ).latin1() ) ) + i->setText( 5, i18n( "Yes" ) ); + else + i->setText( 5, i18n( "No" ) ); + } else { + i->setText( 5, "---" ); + } + } + + if ( functionListView->firstChild() ) + functionListView->setSelected( functionListView->firstChild(), TRUE ); +} + +void EditFunctions::emitItemRenamed( QListViewItem *, int, const QString & text ) +{ + emit itemRenamed( text ); // Relay signal ( to QLineEdit ) +} diff --git a/kdevdesigner/designer/editfunctionsimpl.h b/kdevdesigner/designer/editfunctionsimpl.h new file mode 100644 index 00000000..f19f9d72 --- /dev/null +++ b/kdevdesigner/designer/editfunctionsimpl.h @@ -0,0 +1,94 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef EDITFUNCTIONSIMPL_H +#define EDITFUNCTIONSIMPL_H + +#include "editfunctions.h" +#include "hierarchyview.h" +#include "metadatabase.h" +#include <qmap.h> + +class FormWindow; +class QListViewItem; + +class EditFunctions : public EditFunctionsBase +{ + Q_OBJECT + +public: + EditFunctions( QWidget *parent, FormWindow *fw, bool showOnlySlots = FALSE ); + + void setCurrentFunction( const QString &function ); + void functionAdd( const QString &access = QString::null, + const QString &type = QString::null ); + void functionAdd() { functionAdd( "public" ); } + +signals: + void itemRenamed(const QString &); + +protected slots: + void okClicked(); + void functionRemove(); + void currentItemChanged( QListViewItem * ); + void currentTextChanged( const QString &txt ); + void currentSpecifierChanged( const QString &s ); + void currentAccessChanged( const QString &a ); + void currentReturnTypeChanged( const QString &type ); + void currentTypeChanged( const QString &type ); + void displaySlots( bool justSlots ); + void emitItemRenamed( QListViewItem *, int, const QString & ); + +private: + enum Attribute { Name, Specifier, Access, ReturnType, Type }; + struct FunctItem { + int id; + QString oldName; + QString newName; + QString oldRetTyp; + QString retTyp; + QString spec; + QString oldSpec; + QString access; + QString oldAccess; + QString type; + QString oldType; + + Q_DUMMY_COMPARISON_OPERATOR( FunctItem ) + }; + + void changeItem( QListViewItem *item, Attribute a, const QString &nV ); + + FormWindow *formWindow; + QMap<QListViewItem*, int> functionIds; + QStringList removedFunctions; + QValueList<MetaDataBase::Function> itemList; + QValueList<FunctItem> functList; + int id; + QString lastType; +}; + +#endif diff --git a/kdevdesigner/designer/filechooser.cpp b/kdevdesigner/designer/filechooser.cpp new file mode 100644 index 00000000..5a882b37 --- /dev/null +++ b/kdevdesigner/designer/filechooser.cpp @@ -0,0 +1,90 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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 "filechooser.h" +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qfiledialog.h> +#include <qlayout.h> + +#include <kfiledialog.h> + +FileChooser::FileChooser( QWidget *parent, const char *name ) + : QWidget( parent, name ), md( File ) +{ + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setMargin( 0 ); + + lineEdit = new QLineEdit( this, "filechooser_lineedit" ); + layout->addWidget( lineEdit ); + + connect( lineEdit, SIGNAL( textChanged( const QString & ) ), + this, SIGNAL( fileNameChanged( const QString & ) ) ); + + button = new QPushButton( "...", this, "filechooser_button" ); + button->setFixedWidth( button->fontMetrics().width( " ... " ) ); + layout->addWidget( button ); + + connect( button, SIGNAL( clicked() ), + this, SLOT( chooseFile() ) ); + + setFocusProxy( lineEdit ); +} + +void FileChooser::setMode( Mode m ) +{ + md = m; +} + +FileChooser::Mode FileChooser::mode() const +{ + return md; +} + +void FileChooser::setFileName( const QString &fn ) +{ + lineEdit->setText( fn ); +} + +QString FileChooser::fileName() const +{ + return lineEdit->text(); +} + +void FileChooser::chooseFile() +{ + QString fn; + if ( mode() == File ) + fn = KFileDialog::getOpenFileName( lineEdit->text(), QString::null, this ); + else + fn = KFileDialog::getExistingDirectory( lineEdit->text(),this ); + + if ( !fn.isEmpty() ) { + lineEdit->setText( fn ); + emit fileNameChanged( fn ); + } +} + diff --git a/kdevdesigner/designer/filechooser.h b/kdevdesigner/designer/filechooser.h new file mode 100644 index 00000000..6647a1d5 --- /dev/null +++ b/kdevdesigner/designer/filechooser.h @@ -0,0 +1,68 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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 FILECHOOSER_H +#define FILECHOOSER_H + +#include <qwidget.h> + +class QLineEdit; +class QPushButton; + +class FileChooser : public QWidget +{ + Q_OBJECT + + Q_ENUMS( Mode ) + Q_PROPERTY( Mode mode READ mode WRITE setMode ) + Q_PROPERTY( QString fileName READ fileName WRITE setFileName ) + +public: + FileChooser( QWidget *parent = 0, const char *name = 0); + + enum Mode { File, Directory }; + + QString fileName() const; + Mode mode() const; + +public slots: + void setFileName( const QString &fn ); + void setMode( Mode m ); + +signals: + void fileNameChanged( const QString & ); + +private slots: + void chooseFile(); + +private: + QLineEdit *lineEdit; + QPushButton *button; + Mode md; + +}; + +#endif diff --git a/kdevdesigner/designer/finddialog.ui b/kdevdesigner/designer/finddialog.ui new file mode 100644 index 00000000..3923d1ef --- /dev/null +++ b/kdevdesigner/designer/finddialog.ui @@ -0,0 +1,274 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>FindDialog</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>FindDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>285</width> + <height>189</height> + </rect> + </property> + <property name="caption"> + <string>Find Text</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>F&ind:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboFind</cstring> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>comboFind</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&Find</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QButtonGroup" row="1" column="1"> + <property name="name"> + <cstring>ButtonGroup2</cstring> + </property> + <property name="title"> + <string>Direction</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioForward</cstring> + </property> + <property name="text"> + <string>Forwar&d</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioBackward</cstring> + </property> + <property name="text"> + <string>Bac&kward</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup" row="1" column="0"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkWords</cstring> + </property> + <property name="text"> + <string>&Whole words only</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkCase</cstring> + </property> + <property name="text"> + <string>Case &sensitive</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBegin</cstring> + </property> + <property name="text"> + <string>Start at &beginning</string> + </property> + </widget> + </vbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>FindDialog</receiver> + <slot>doFind()</slot> + </connection> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>FindDialog</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>comboFind</tabstop> + <tabstop>checkWords</tabstop> + <tabstop>checkCase</tabstop> + <tabstop>checkBegin</tabstop> + <tabstop>radioForward</tabstop> + <tabstop>radioBackward</tabstop> + <tabstop>PushButton1</tabstop> + <tabstop>PushButton2</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">qlineedit.h</include> + <include location="local" impldecl="in implementation">../interfaces/editorinterface.h</include> + <include location="local" impldecl="in implementation">finddialog.ui.h</include> +</includes> +<forwards> + <forward>struct EditorInterface;</forward> +</forwards> +<variables> + <variable>EditorInterface *editor;</variable> + <variable>QObject *formWindow;</variable> +</variables> +<slots> + <slot>init()</slot> + <slot>destroy()</slot> + <slot>doFind()</slot> + <slot>setEditor( EditorInterface * e, QObject * fw )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/finddialog.ui.h b/kdevdesigner/designer/finddialog.ui.h new file mode 100644 index 00000000..c9b4f230 --- /dev/null +++ b/kdevdesigner/designer/finddialog.ui.h @@ -0,0 +1,61 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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. +** +**********************************************************************/ + +void FindDialog::init() +{ + editor = 0; + formWindow = 0; +} + +void FindDialog::destroy() +{ + if ( editor ) + editor->release(); +} + +void FindDialog::doFind() +{ + if ( !editor ) + return; + + if ( !editor->find( comboFind->currentText(), checkCase->isChecked(), + checkWords->isChecked(), radioForward->isChecked(), !checkBegin->isChecked() ) ) + checkBegin->setChecked( TRUE ); + else + checkBegin->setChecked( FALSE ); + +} + +void FindDialog::setEditor( EditorInterface * e, QObject * fw ) +{ + if ( fw != formWindow ) + checkBegin->setChecked( TRUE ); + formWindow = fw; + if ( editor ) + editor->release(); + editor = e; + editor->addRef(); +} diff --git a/kdevdesigner/designer/formfile.cpp b/kdevdesigner/designer/formfile.cpp new file mode 100644 index 00000000..cde7eb8b --- /dev/null +++ b/kdevdesigner/designer/formfile.cpp @@ -0,0 +1,905 @@ +/********************************************************************** +** 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 "formfile.h" +#include "timestamp.h" +#include "project.h" +#include "formwindow.h" +#include "command.h" +#include "sourceeditor.h" +#include "mainwindow.h" +#include "../interfaces/languageinterface.h" +#include "resource.h" +#include "workspace.h" +#include <qmessagebox.h> +#include <qfile.h> +#include <qstatusbar.h> +#include "propertyeditor.h" +#include <qworkspace.h> +#include <stdlib.h> +#include "designerappiface.h" +#include <qapplication.h> + +#include <kfiledialog.h> +#include <klocale.h> +#include "kdevdesigner_part.h" + +static QString make_func_pretty( const QString &s ) +{ + QString res = s; + if ( res.find( ")" ) - res.find( "(" ) == 1 ) + return res; + res.replace( "(", "( " ); + res.replace( ")", " )" ); + res.replace( "&", " &" ); + res.replace( "*", " *" ); + res.replace( ",", ", " ); + res.replace( ":", " : " ); + res = res.simplifyWhiteSpace(); + res.replace( " : : ", "::" ); + res.replace( ">>", "> >" ); + return res; +} + +FormFile::FormFile( const QString &fn, bool temp, Project *p, const char *name ) + : filename( fn ), fileNameTemp( temp ), pro( p ), fw( 0 ), ed( 0 ), + timeStamp( 0, fn + codeExtension() ), codeEdited( FALSE ), pkg( FALSE ), + cm( FALSE ), codeFileStat( None ) +{ + MetaDataBase::addEntry( this ); + fake = qstrcmp( name, "qt_fakewindow" ) == 0; + //codeFileStat = FormFile::None; + pro->addFormFile( this ); + loadCode(); + if ( !temp ) + checkFileName( FALSE ); + + connect(this, SIGNAL(somethingChanged(FormFile* )), this, SLOT(emitNewStatus(FormFile* ))); +} + +FormFile::~FormFile() +{ + pro->removeFormFile( this ); + if ( formWindow() ) + formWindow()->setFormFile( 0 ); +} + +void FormFile::setFormWindow( FormWindow *f ) +{ + if ( f == fw ) + return; + if ( fw ) + fw->setFormFile( 0 ); + fw = f; + if ( fw ) + fw->setFormFile( this ); + parseCode( cod, FALSE ); + QTimer::singleShot( 0, this, SLOT( notifyFormWindowChange() ) ); +} + +void FormFile::setEditor( SourceEditor *e ) +{ + ed = e; +} + +void FormFile::setFileName( const QString &fn ) +{ + if ( fn == filename ) + return; + if ( fn.isEmpty() ) { + fileNameTemp = TRUE; + if ( filename.find( "unnamed" ) != 0 ) + filename = createUnnamedFileName(); + return; + } else { + fileNameTemp = FALSE; + } + filename = fn; + timeStamp.setFileName( filename + codeExtension() ); + cod = ""; + loadCode(); +} + +void FormFile::setCode( const QString &c ) +{ + cod = c; +} + +FormWindow *FormFile::formWindow() const +{ + return fw; +} + +SourceEditor *FormFile::editor() const +{ + return ed; +} + +QString FormFile::fileName() const +{ + return filename; +} + +QString FormFile::absFileName() const +{ + return pro->makeAbsolute( filename ); +} + +QString FormFile::codeFile() const +{ + QString codeExt = codeExtension(); + if ( codeExt.isEmpty() ) + return ""; + return filename + codeExt; +} + +QString FormFile::code() +{ + return cod; +} + +bool FormFile::save( bool withMsgBox, bool ignoreModified ) +{ + if ( fileNameTemp ) + return saveAs(); + if ( !ignoreModified && !isModified() ) + return TRUE; + if ( ed ) + ed->save(); + + if ( formWindow() && isModified( WFormWindow ) ) { + if ( withMsgBox ) { + if ( !formWindow()->checkCustomWidgets() ) + return FALSE; + } + + if ( QFile::exists( pro->makeAbsolute( filename ) ) ) { + QString fn( pro->makeAbsolute( filename ) ); +#if defined(Q_OS_WIN32) + fn += ".bak"; +#else + fn += "~"; +#endif + QFile f( pro->makeAbsolute( filename ) ); + if ( f.open( IO_ReadOnly ) ) { + QFile f2( fn ); + if ( f2.open( IO_WriteOnly | IO_Translate ) ) { + QCString data( f.size() ); + f.readBlock( data.data(), f.size() ); + f2.writeBlock( data ); + } else { + QMessageBox::warning( MainWindow::self, i18n( "Save" ), + i18n( "The file %1 could not be saved" ).arg( codeFile() ) ); + } + } + } + } + + if ( isModified( WFormCode ) ) { + if ( QFile::exists( pro->makeAbsolute( codeFile() ) ) ) { + QString fn( pro->makeAbsolute( codeFile() ) ); +#if defined(Q_OS_WIN32) + fn += ".bak"; +#else + fn += "~"; +#endif + QFile f( pro->makeAbsolute( codeFile() ) ); + if ( f.open( IO_ReadOnly ) ) { + QFile f2( fn ); + if ( f2.open( IO_WriteOnly | IO_Translate) ) { + QCString data( f.size() ); + f.readBlock( data.data(), f.size() ); + f2.writeBlock( data ); + } else if ( qApp->type() != QApplication::Tty ) { + QMessageBox::warning( MainWindow::self, i18n( "Save" ), + i18n( "The file %1 could not be saved" ).arg( codeFile() ) ); + } + } + } + } + + if ( formWindow() ) { + Resource resource( MainWindow::self ); + resource.setWidget( formWindow() ); + bool formCodeOnly = isModified( WFormCode ) && !isModified( WFormWindow ); + if ( !resource.save( pro->makeAbsolute( filename ), formCodeOnly ) ) { + if ( MainWindow::self ) + MainWindow::self->statusMessage( i18n( "Failed to save file '%1'.").arg( formCodeOnly ? codeFile(): filename ) ); + if ( formCodeOnly ) + return FALSE; + return saveAs(); + } + if ( MainWindow::self ) + MainWindow::self->statusMessage( i18n( "'%1' saved."). + arg( formCodeOnly ? codeFile() : filename )); + } else { + if ( !Resource::saveFormCode(this, MetaDataBase::languageInterface(pro->language())) ) + return FALSE; + } + timeStamp.update(); + setModified( FALSE ); + return TRUE; +} + +bool FormFile::saveAs( bool ignoreModified ) +{ + QString f = pro->makeAbsolute( fileName() ); + if ( fileNameTemp && formWindow() ) { + f = QString( formWindow()->name() ).lower(); + f.replace( "::", "_" ); + f = pro->makeAbsolute( f + ".ui" ); + } + bool saved = FALSE; + if ( ignoreModified ) { + QString dir = QStringList::split( ':', pro->iFace()->customSetting( "QTSCRIPT_PACKAGES" ) ).first(); + f = QFileInfo( f ).fileName(); + f.prepend( dir + "/" ); + } + QString fn; + while ( !saved ) { + fn = KFileDialog::getSaveFileName( f, + i18n( "*.ui|Qt User-Interface Files" ) + "\n" + + i18n( "*|All Files" ), MainWindow::self, /*0,*/ + i18n( "Save Form '%1' As").arg( formName() )/*, + MainWindow::self ? &MainWindow::self->lastSaveFilter : 0*/ ); + if ( fn.isEmpty() ) + return FALSE; + QFileInfo fi( fn ); + if ( fi.extension() != "ui" ) + fn += ".ui"; + fileNameTemp = FALSE; + filename = pro->makeRelative( fn ); + QFileInfo relfi( filename ); + if ( relfi.exists() ) { + if ( QMessageBox::warning( MainWindow::self, i18n( "File Already Exists" ), + i18n( "The file already exists. Do you wish to overwrite it?" ), + QMessageBox::Yes, + QMessageBox::No ) == QMessageBox::Yes ) { + saved = TRUE; + } else { + filename = f; + } + + } else { + saved = TRUE; + } + } + if ( !checkFileName( TRUE ) ) { + filename = f; + return FALSE; + } + pro->setModified( TRUE ); + timeStamp.setFileName( pro->makeAbsolute( codeFile() ) ); + if ( ed && formWindow() ) + ed->setCaption( i18n( "Edit %1" ).arg( formWindow()->name() ) ); + setModified( TRUE ); + if ( pro->isDummy() ) + fw->mainWindow()->addRecentlyOpenedFile( fn ); + return save( TRUE, ignoreModified ); +} + +bool FormFile::close() +{ + if ( editor() ) { + editor()->save(); + editor()->close(); + } + if ( formWindow() ) + return formWindow()->close(); + return TRUE; +} + +bool FormFile::closeEvent() +{ + if ( !isModified() && fileNameTemp ) { + pro->removeFormFile( this ); + return TRUE; + } + + if ( !isModified() ) + return TRUE; + + if ( editor() ) + editor()->save(); + + switch ( QMessageBox::warning( MainWindow::self, i18n( "Save Form" ), + i18n( "Save changes to form '%1'?" ).arg( filename ), + i18n( "&Yes" ), i18n( "&No" ), i18n( "&Cancel" ), 0, 2 ) ) { + case 0: // save + if ( !save() ) + return FALSE; + case 1: // don't save + loadCode(); + if ( ed ) + ed->editorInterface()->setText( cod ); + if ( fileNameTemp ) + pro->removeFormFile( this ); + if ( MainWindow::self ) + MainWindow::self->workspace()->update(); + break; + case 2: // cancel + return FALSE; + default: + break; + } + + setModified( FALSE ); + if ( MainWindow::self ) + MainWindow::self->updateFunctionList(); + setCodeEdited( FALSE ); + return TRUE; +} + +void FormFile::setModified( bool m, int who ) +{ + if ( ( who & WFormWindow ) == WFormWindow ) + setFormWindowModified( m ); + if ( ( who & WFormCode ) == WFormCode ) + setCodeModified( m ); +} + +bool FormFile::isModified( int who ) +{ + if ( who == WFormWindow ) + return isFormWindowModified(); + if ( who == WFormCode ) + return isCodeModified(); + return isCodeModified() || isFormWindowModified(); +} + +bool FormFile::isFormWindowModified() const +{ + if ( !formWindow() || !formWindow()->commandHistory() ) + return FALSE; + return formWindow()->commandHistory()->isModified(); +} + +bool FormFile::isCodeModified() const +{ + if ( !editor() ) + return cm; + return editor()->isModified(); +} + +void FormFile::setFormWindowModified( bool m ) +{ + bool b = isFormWindowModified(); + if ( m == b ) + return; + if ( !formWindow() || !formWindow()->commandHistory() ) + return; + formWindow()->commandHistory()->setModified( m ); + emit somethingChanged( this ); +} + +void FormFile::setCodeModified( bool m ) +{ + bool b = isCodeModified(); + if ( m == b ) + return; + emit somethingChanged( this ); + cm = m; + if ( !editor() ) + return; + editor()->setModified( m ); +} + +void FormFile::showFormWindow() +{ + if ( !MainWindow::self ) + return; + if ( formWindow() ) { + if ( ( formWindow()->hasFocus() || + MainWindow::self->qWorkspace()->activeWindow() == formWindow() ) && + MainWindow::self->propertyeditor()->formWindow() != formWindow() ) { + MainWindow::self->propertyeditor()->setWidget( formWindow()->currentWidget(), formWindow() ); + MainWindow::self->objectHierarchy()->setFormWindow( formWindow(), + formWindow()->currentWidget() ); + } + formWindow()->setFocus(); + return; + } + MainWindow::self->openFormWindow( pro->makeAbsolute( filename ), TRUE, this ); +} + +bool FormFile::setupUihFile( bool askForUih ) +{ + if ( !pro->isCpp() || !askForUih ) { + if ( !hasFormCode() ) { + createFormCode(); + setModified( TRUE ); + } + codeFileStat = FormFile::Ok; + return TRUE; + } + if ( codeFileStat != FormFile::Ok && !ed ) { + if ( hasFormCode() ) { + int i = QMessageBox::information( MainWindow::self, i18n( "Using ui.h File" ), + i18n( "An \"ui.h\" file for this form already exists.\n" + "Do you want to use it or create a new one?" ), + i18n( "Use Existing" ), i18n( "Create New" ), + i18n( "Cancel" ), 2, 2 ); + if ( i == 2 ) + return FALSE; + if ( i == 1 ) + createFormCode(); + } else { + if ( QMessageBox::Yes != QMessageBox::information( MainWindow::self, i18n( "Creating ui.h file" ), + i18n( "Do you want to create an new \"ui.h\" file?" ), + QMessageBox::Yes, QMessageBox::No ) ) + return FALSE; + createFormCode(); + } + setModified( TRUE ); + } + codeFileStat = FormFile::Ok; + return TRUE; +} + +SourceEditor *FormFile::showEditor( bool askForUih ) +{ + if ( !MainWindow::self ) + return 0; + showFormWindow(); + //emit signal to the embedding IDE if there is one and return 0 because + //no source editing is possible + emit fw->mainWindow()->part()->emitEditSource(fw->fileName()); + return 0; +/* if ( !setupUihFile( askForUih ) ) + return 0; + return MainWindow::self->openSourceEditor();*/ +} + +static int ui_counter = 0; +QString FormFile::createUnnamedFileName() +{ + return QString( "unnamed" ) + QString::number( ++ui_counter ) + QString( ".ui" ); +} + +QString FormFile::codeExtension() const +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( iface ) + return iface->formCodeExtension(); + return ""; +} + +QString FormFile::codeComment() const +{ + return QString( "/****************************************************************************\n" + "** ui.h extension file, included from the uic-generated form implementation.\n" + "**\n" + "** If you want to add, delete, or rename functions or slots, use\n" + "** Qt Designer to update this file, preserving your code.\n" + "**\n" + "** You should not define a constructor or destructor in this file.\n" + "** Instead, write your code in functions called init() and destroy().\n" + "** These will automatically be called by the form's constructor and\n" + "** destructor.\n" + "*****************************************************************************/\n" ); +} + +bool FormFile::hasFormCode() const +{ + return !cod.isEmpty() && cod != QString( codeComment() ); +} + +int FormFile::codeFileState() const +{ + return hasFormCode() ? codeFileStat : None; +} + +void FormFile::setCodeFileState( UihState s ) +{ + codeFileStat = s; +} + +void FormFile::createFormCode() +{ + if ( !formWindow() ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + if ( pro->isCpp() ) + cod = codeComment(); + QValueList<MetaDataBase::Function> functionList = MetaDataBase::functionList( formWindow() ); + for ( QValueList<MetaDataBase::Function>::Iterator it = functionList.begin(); it != functionList.end(); ++it ) { + cod += (!cod.isEmpty() ? "\n\n" : "") + + iface->createFunctionStart( formWindow()->name(), make_func_pretty((*it).function), + (*it).returnType.isEmpty() ? + QString( "void" ) : + (*it).returnType, (*it).access ) + + "\n" + iface->createEmptyFunction(); + } + parseCode( cod, FALSE ); +} + +void FormFile::load() +{ + showFormWindow(); + code(); +} + +bool FormFile::loadCode() +{ + QFile f( pro->makeAbsolute( codeFile() ) ); + if ( !f.open( IO_ReadOnly ) ) { + cod = ""; + setCodeFileState( FormFile::None ); + return FALSE; + } + QTextStream ts( &f ); + cod = ts.read(); + parseCode( cod, FALSE ); + if ( hasFormCode() && codeFileStat != FormFile::Ok ) + setCodeFileState( FormFile::Deleted ); + timeStamp.update(); + return TRUE; +} + +bool FormFile::isCodeEdited() const +{ + return codeEdited; +} + +void FormFile::setCodeEdited( bool b ) +{ + codeEdited = b; +} + +void FormFile::parseCode( const QString &txt, bool allowModify ) +{ + if ( !formWindow() ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + QValueList<LanguageInterface::Function> functions; + QValueList<MetaDataBase::Function> newFunctions, oldFunctions; + oldFunctions = MetaDataBase::functionList( formWindow() ); + iface->functions( txt, &functions ); + QMap<QString, QString> funcs; + for ( QValueList<LanguageInterface::Function>::Iterator it = functions.begin(); + it != functions.end(); ++it ) { + bool found = FALSE; + for ( QValueList<MetaDataBase::Function>::Iterator fit = oldFunctions.begin(); + fit != oldFunctions.end(); ++fit ) { + QString f( (*fit).function ); + if ( MetaDataBase::normalizeFunction( f ) == + MetaDataBase::normalizeFunction( (*it).name ) ) { + found = TRUE; + MetaDataBase::Function function; + function.function = make_func_pretty( (*it).name ); + function.specifier = (*fit).specifier; + function.type = (*fit).type; + if ( !pro->isCpp() ) + function.access = (*it).access; + else + function.access = (*fit).access; + function.language = (*fit).language; + function.returnType = (*it).returnType; + newFunctions << function; + funcs.insert( (*it).name, (*it).body ); + oldFunctions.remove( fit ); + break; + } + } + if ( !found ) { + MetaDataBase::Function function; + function.function = make_func_pretty( (*it).name ); + function.specifier = "virtual"; + function.access = "public"; + function.language = pro->language(); + function.returnType = (*it).returnType; + if ( function.returnType == "void" ) + function.type = "slot"; + else + function.type = "function"; + if ( function.function == "init()" || function.function == "destroy()" ) { + function.type = "function"; + function.access = "private"; + function.specifier = "non virtual"; + } + newFunctions << function; + funcs.insert( (*it).name, (*it).body ); + if ( allowModify ) + setFormWindowModified( TRUE ); + } + } + + if ( allowModify && oldFunctions.count() > 0 ) + setFormWindowModified( TRUE ); + + MetaDataBase::setFunctionList( formWindow(), newFunctions ); +} + +void FormFile::syncCode() +{ + if ( !editor() ) + return; + parseCode( editor()->editorInterface()->text(), TRUE ); + cod = editor()->editorInterface()->text(); +} + +void FormFile::checkTimeStamp() +{ + if ( timeStamp.isUpToDate() ) + return; + timeStamp.update(); + if ( codeEdited ) { + if ( QMessageBox::information( MainWindow::self, i18n( "Qt Designer" ), + i18n( "File '%1' has been changed outside Qt Designer.\n" + "Do you want to reload it?" ).arg( timeStamp.fileName() ), + i18n( "&Yes" ), i18n( "&No" ) ) == 0 ) { + QFile f( timeStamp.fileName() ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + editor()->editorInterface()->setText( ts.read() ); + editor()->save(); + if ( MainWindow::self ) + MainWindow::self->functionsChanged(); + } + } + } else { + loadCode(); + } +} + +bool FormFile::isUihFileUpToDate() +{ + if ( timeStamp.isUpToDate() ) + return TRUE; + if ( !editor() ) { + MainWindow::self->editSource(); + qDebug( "parse Code" ); + parseCode( editor()->editorInterface()->text(), TRUE ); + } + checkTimeStamp(); + return FALSE; +} + +void FormFile::addFunctionCode( MetaDataBase::Function function ) +{ + if ( pro->isCpp() && !hasFormCode() && !codeEdited ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + + QValueList<LanguageInterface::Function> funcs; + iface->functions( cod, &funcs ); + bool hasFunc = FALSE; + for ( QValueList<LanguageInterface::Function>::Iterator it = funcs.begin(); + it != funcs.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).name ) == MetaDataBase::normalizeFunction( function.function ) ) { + hasFunc = TRUE; + break; + } + } + + if ( !hasFunc ) { + if ( !codeEdited && !timeStamp.isUpToDate() ) + loadCode(); + MetaDataBase::MetaInfo mi = MetaDataBase::metaInfo( formWindow() ); + QString cn; + if ( mi.classNameChanged ) + cn = mi.className; + if ( cn.isEmpty() ) + cn = formWindow()->name(); + QString body = "\n\n" + iface->createFunctionStart( cn, + make_func_pretty( function.function ), + function.returnType.isEmpty() ? + QString( "void" ) : + function.returnType, function.access ) + + "\n" + iface->createEmptyFunction(); + cod += body; + if ( codeEdited ) { + setModified( TRUE ); + emit somethingChanged( this ); + } + } +} + +void FormFile::removeFunctionCode( MetaDataBase::Function function ) +{ + if ( pro->isCpp() && !hasFormCode() && !codeEdited ) + return; + + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + + checkTimeStamp(); + QString sourceCode = code(); + if ( sourceCode.isEmpty() ) + return; + QValueList<LanguageInterface::Function> functions; + iface->functions( sourceCode, &functions ); + QString fu = MetaDataBase::normalizeFunction( function.function ); + for ( QValueList<LanguageInterface::Function>::Iterator fit = functions.begin(); fit != functions.end(); ++fit ) { + if ( MetaDataBase::normalizeFunction( (*fit).name ) == fu ) { + int line = 0; + int start = 0; + while ( line < (*fit).start - 1 ) { + start = sourceCode.find( '\n', start ); + if ( start == -1 ) + return; + start++; + line++; + } + if ( start == -1 ) + return; + int end = start; + while ( line < (*fit).end + 1 ) { + end = sourceCode.find( '\n', end ); + if ( end == -1 ) { + if ( line <= (*fit).end ) + end = sourceCode.length() - 1; + else + return; + } + end++; + line++; + } + if ( end < start ) + return; + sourceCode.remove( start, end - start ); + setCode( sourceCode ); + } + } +} + +void FormFile::functionNameChanged( const QString &oldName, const QString &newName ) +{ + if ( !cod.isEmpty() ) { + QString funcStart = QString( formWindow()->name() ) + QString( "::" ); + int i = cod.find( funcStart + oldName ); + if ( i != -1 ) { + cod.remove( i + funcStart.length(), oldName.length() ); + cod.insert( i + funcStart.length(), newName ); + } + } +} + +void FormFile::functionRetTypeChanged( const QString &fuName, const QString &oldType, const QString &newType ) +{ + if ( !cod.isEmpty() ) { + QString oldFunct = oldType + " " + QString( formWindow()->name() ) + "::" + fuName; + QString newFunct = newType + " " + QString( formWindow()->name() ) + "::" + fuName; + + int i = cod.find( oldFunct ); + if ( i != -1 ) { + cod.remove( i, oldFunct.length() ); + cod.insert( i, newFunct ); + } + } +} + +QString FormFile::formName() const +{ + FormFile* that = (FormFile*) this; + if ( formWindow() ) { + that->cachedFormName = formWindow()->name(); + return cachedFormName; + } + if ( !cachedFormName.isNull() ) + return cachedFormName; + QFile f( pro->makeAbsolute( filename ) ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + QString line; + QString className; + while ( !ts.eof() ) { + line = ts.readLine(); + if ( !className.isEmpty() ) { + int end = line.find( "</class>" ); + if ( end == -1 ) { + className += line; + } else { + className += line.left( end ); + break; + } + continue; + } + int start; + if ( ( start = line.find( "<class>" ) ) != -1 ) { + int end = line.find( "</class>" ); + if ( end == -1 ) { + className = line.mid( start + 7 ); + } else { + className = line.mid( start + 7, end - ( start + 7 ) ); + break; + } + } + } + that->cachedFormName = className; + } + if ( cachedFormName.isEmpty() ) + that->cachedFormName = filename; + return cachedFormName; +} + +void FormFile::formWindowChangedSomehow() +{ + emit somethingChanged( this ); +} + +bool FormFile::checkFileName( bool allowBreak ) +{ + FormFile *ff = pro->findFormFile( filename, this ); + if ( ff ) + QMessageBox::warning( MainWindow::self, i18n( "Invalid Filename" ), + i18n( "The project already contains a form with a\n" + "filename of '%1'. Please choose a new filename." ).arg( filename ) ); + while ( ff ) { + QString fn; + while ( fn.isEmpty() ) { + fn = KFileDialog::getSaveFileName( pro->makeAbsolute( fileName() ), + i18n( "*.ui|Qt User-Interface Files" ) + "\n" + + i18n( "*|All Files" ), MainWindow::self,/* 0,*/ + i18n( "Save Form '%1' As"). + arg( formWindow()->name() )/*, + MainWindow::self ? &MainWindow::self->lastSaveFilter : 0 */); + if ( allowBreak && fn.isEmpty() ) + return FALSE; + } + filename = pro->makeRelative( fn ); + ff = pro->findFormFile( filename, this ); + } + return TRUE; +} + +void FormFile::addConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ) +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( iface ) + iface->addConnection( sender, signal, receiver, slot, &cod ); + if ( ed ) + ed->editorInterface()->setText( cod ); +} + +void FormFile::removeConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ) +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( iface ) + iface->removeConnection( sender, signal, receiver, slot, &cod ); + if ( ed ) + ed->editorInterface()->setText( cod ); +} + +void FormFile::notifyFormWindowChange() +{ + if ( fw ) + pro->formOpened( fw ); +} + +void FormFile::emitNewStatus(FormFile *file) +{ + fw->mainWindow()->part()->emitNewStatus(fileName(), isModified()); +} diff --git a/kdevdesigner/designer/formfile.h b/kdevdesigner/designer/formfile.h new file mode 100644 index 00000000..65d0f389 --- /dev/null +++ b/kdevdesigner/designer/formfile.h @@ -0,0 +1,145 @@ +/********************************************************************** +** 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 FORMFILE_H +#define FORMFILE_H + +#include <qobject.h> +#include "timestamp.h" +#include "metadatabase.h" + +class Project; +class FormWindow; +class SourceEditor; + +class FormFile : public QObject +{ + Q_OBJECT + friend class SourceEditor; + +public: + enum Who { + WFormWindow = 1, + WFormCode = 2, + WAnyOrAll = WFormWindow | WFormCode + }; + + enum UihState { None, Ok, Deleted }; + + FormFile( const QString &fn, bool temp, Project *p, const char *name = 0 ); + ~FormFile(); + + void setFormWindow( FormWindow *f ); + void setEditor( SourceEditor *e ); + void setFileName( const QString &fn ); + void setCode( const QString &c ); + void setModified( bool m, int who = WAnyOrAll ); + void setCodeEdited( bool b ); + + FormWindow *formWindow() const; + SourceEditor *editor() const; + QString fileName() const; + QString absFileName() const; + + bool supportsCodeFile() const { return !codeExtension().isEmpty(); } + QString codeComment() const; + QString codeFile() const; + QString code(); + bool isCodeEdited() const; + + bool loadCode(); + void load(); + bool save( bool withMsgBox = TRUE, bool ignoreModified = FALSE ); + bool saveAs( bool ignoreModified = FALSE ); + bool close(); + bool closeEvent(); + bool isModified( int who = WAnyOrAll ); + bool hasFormCode() const; + void createFormCode(); + void syncCode(); + void checkTimeStamp(); + bool isUihFileUpToDate(); + void addFunctionCode( MetaDataBase::Function function ); + void removeFunctionCode( MetaDataBase::Function function ); + void functionNameChanged( const QString &oldName, const QString &newName ); + void functionRetTypeChanged( const QString &fuName, const QString &oldType, const QString &newType ); + + void showFormWindow(); + SourceEditor *showEditor( bool askForUih = TRUE ); + + static QString createUnnamedFileName(); + QString formName() const; + + bool isFake() const { return fake; } + + void parseCode( const QString &txt, bool allowModify ); + + void addConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ); + void removeConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ); + + bool hasTempFileName() const { return fileNameTemp; } + void setCodeFileState( UihState ); + int codeFileState() const; + bool setupUihFile( bool askForUih = TRUE ); + + Project *project() const { return pro; } + +signals: + void somethingChanged( FormFile* ); + +private slots: + void formWindowChangedSomehow(); + void notifyFormWindowChange(); + void emitNewStatus(FormFile* file); + +private: + bool isFormWindowModified() const; + bool isCodeModified() const; + void setFormWindowModified( bool m ); + void setCodeModified( bool m ); + QString codeExtension() const; + bool checkFileName( bool allowBreak ); + +private: + QString filename; + bool fileNameTemp; + Project *pro; + FormWindow *fw; + SourceEditor *ed; + QString cod; + TimeStamp timeStamp; + bool codeEdited; + QString cachedFormName; + bool fake; + bool pkg; + bool cm; + UihState codeFileStat; + +}; + +#endif diff --git a/kdevdesigner/designer/formsettings.ui b/kdevdesigner/designer/formsettings.ui new file mode 100644 index 00000000..c1d6be27 --- /dev/null +++ b/kdevdesigner/designer/formsettings.ui @@ -0,0 +1,549 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>FormSettingsBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>FormSettingsBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>597</width> + <height>458</height> + </rect> + </property> + <property name="caption"> + <string>Form Settings</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Form Settings</b><p>Change settings for the form. Settings like <b>Comment</b> and <b>Author</b> are for your own use and are not required.</p></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QButtonGroup" row="1" column="0"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>Pixmaps</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioPixmapInline</cstring> + </property> + <property name="text"> + <string>Save in&line</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Save pixmaps in the .ui files</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Save Inline</b><p>Saves the pixmaps as binary data in the .ui files. Pixmaps saved like this are not shared between forms. We recommend using Project image files instead.</string> + </property> + </widget> + <widget class="QRadioButton" row="2" column="0"> + <property name="name"> + <cstring>radioProjectImageFile</cstring> + </property> + <property name="text"> + <string>Project &image file</string> + </property> + <property name="toolTip" stdset="0"> + <string>Use the Project's Image file for pixmaps</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Use the Project's Image file for pixmaps</b> +<p>Each project may have a collection of pixmaps. If you use a project, we recommend that you use this option since it shares the images and is the fastest and most efficient way to use pixmaps in your forms.</p></string> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>editPixmapFunction</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Specify Pixmap-Loader function (only the function's name, no parentheses.)</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Specify Pixmap-Loader function</b><p>Specify the function which should be used for loading a pixmap in the generated code. <em>Only enter the function's name, without parentheses.</em></string> + </property> + </widget> + <widget class="QRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioPixmapFunction</cstring> + </property> + <property name="text"> + <string>Use &function:</string> + </property> + <property name="toolTip" stdset="0"> + <string>Use the given function for pixmaps</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Use a given function for pixmaps</b><p>If you choose this option you must define a function in the line edit at the right which will be used in the generated code for loading pixmaps. When choosing a pixmap in <i>Qt Designer</i> you will be asked to specify the arguments which will be passed to the function in the generated code.<p> This approach makes it possible to use your own icon-loader function for loading pixmaps. <i>Qt Designer</i> cannot preview the correct image if you use your own function.</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="title"> + <string>Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editClassName</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change class name</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Enter the name of the class that will be created.</b><p><em>classname.h</em> and <em>classname.cpp</em> will be generated as C++ output when it is compiled by uic.</p></string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>A&uthor:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editAuthor</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>editAuthor</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Enter your name</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Enter your name.</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Class &name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editClassName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Co&mment:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editComment</cstring> + </property> + </widget> + <widget class="QMultiLineEdit" row="1" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>editComment</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>Enter a comment about the form.</string> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="1"> + <property name="name"> + <cstring>GroupBox2</cstring> + </property> + <property name="title"> + <string>La&youts</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QSpinBox" row="0" column="2"> + <property name="name"> + <cstring>spinMargin</cstring> + </property> + <property name="value"> + <number>11</number> + </property> + </widget> + <spacer row="0" column="3"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + </spacer> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>D&efault spacing:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinSpacing</cstring> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>checkLayoutFunctions</cstring> + </property> + <property name="text"> + <string>Use func&tions:</string> + </property> + <property name="toolTip" stdset="0"> + <string>Use functions to get the margin and spacing</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Use a given function for margin and/or spacing</b><p>If you choose this option you must define functions in the line edit below which will be used in the generated code for getting the margin and spacing value. <i>Qt Designer</i> cannot preview the correct margin or spacing if you use your own function. Instead, the default values will be used for preview.</string> + </property> + </widget> + <widget class="QSpinBox" row="1" column="2"> + <property name="name"> + <cstring>spinSpacing</cstring> + </property> + <property name="value"> + <number>6</number> + </property> + </widget> + <spacer row="1" column="3"> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + </spacer> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>TextLabel1_3</cstring> + </property> + <property name="text"> + <string>Default mar&gin:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinMargin</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>spaFuLabel</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>S&pacing:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editSpacingFunction</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>marFuLabel</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Ma&rgin:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editMarginFunction</cstring> + </property> + </widget> + <spacer row="2" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + </spacer> + <widget class="KLineEdit" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>editSpacingFunction</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Specify spacing function (only the function's name, no parentheses.)</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Specify spacing function</b><p>Specify the function which should be used for getting the spacing in the generated code. <em>Only enter the function's name, without parentheses.</em></string> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>editMarginFunction</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Specify margin function (only the function's name, no parentheses.)</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Specify margin function</b><p>Specify the function which should be used for getting the margin in the generated code. <em>Only enter the function's name, without parentheses.</em></string> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>FormSettingsBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>FormSettingsBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>radioPixmapFunction</sender> + <signal>toggled(bool)</signal> + <receiver>editPixmapFunction</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkLayoutFunctions</sender> + <signal>toggled(bool)</signal> + <receiver>editSpacingFunction</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkLayoutFunctions</sender> + <signal>toggled(bool)</signal> + <receiver>editMarginFunction</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkLayoutFunctions</sender> + <signal>toggled(bool)</signal> + <receiver>marFuLabel</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkLayoutFunctions</sender> + <signal>toggled(bool)</signal> + <receiver>spaFuLabel</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>editClassName</tabstop> + <tabstop>editComment</tabstop> + <tabstop>editAuthor</tabstop> + <tabstop>radioPixmapInline</tabstop> + <tabstop>radioPixmapFunction</tabstop> + <tabstop>editPixmapFunction</tabstop> + <tabstop>radioProjectImageFile</tabstop> + <tabstop>spinMargin</tabstop> + <tabstop>spinSpacing</tabstop> + <tabstop>checkLayoutFunctions</tabstop> + <tabstop>editMarginFunction</tabstop> + <tabstop>editSpacingFunction</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>buttonHelp</tabstop> +</tabstops> +<slots> + <slot>okClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/formsettingsimpl.cpp b/kdevdesigner/designer/formsettingsimpl.cpp new file mode 100644 index 00000000..ce76dde7 --- /dev/null +++ b/kdevdesigner/designer/formsettingsimpl.cpp @@ -0,0 +1,118 @@ +/********************************************************************** +** 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 "formsettingsimpl.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "command.h" +#include "asciivalidator.h" +#include "mainwindow.h" +#include "project.h" + +#include <qmultilineedit.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qradiobutton.h> +#include <klineedit.h> +#include <qspinbox.h> +#include <qcheckbox.h> + +FormSettings::FormSettings( QWidget *parent, FormWindow *fw ) + : FormSettingsBase( parent, 0, TRUE ), formwindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + MetaDataBase::MetaInfo info = MetaDataBase::metaInfo( fw ); + if ( info.classNameChanged && !info.className.isEmpty() ) + editClassName->setText( info.className ); + else + editClassName->setText( fw->name() ); + editComment->setText( info.comment ); + editAuthor->setText( info.author ); + + editClassName->setValidator( new AsciiValidator( QString( ":" ), editClassName ) ); + editPixmapFunction->setValidator( new AsciiValidator( QString( ":" ), editPixmapFunction ) ); + + if ( formwindow->savePixmapInline() ) + radioPixmapInline->setChecked( TRUE ); + else if ( formwindow->savePixmapInProject() ) + radioProjectImageFile->setChecked( TRUE ); + else + radioPixmapFunction->setChecked( TRUE ); + editPixmapFunction->setText( formwindow->pixmapLoaderFunction() ); + radioProjectImageFile->setEnabled( !fw->project()->isDummy() ); + spinSpacing->setValue( formwindow->layoutDefaultSpacing() ); + spinMargin->setValue( formwindow->layoutDefaultMargin() ); + editSpacingFunction->setValidator( new AsciiValidator( QString( ":" ), editSpacingFunction ) ); + editMarginFunction->setValidator( new AsciiValidator( QString( ":" ), editMarginFunction ) ); + checkLayoutFunctions->setChecked( formwindow->hasLayoutFunctions() ); + editSpacingFunction->setText( formwindow->spacingFunction() ); + editMarginFunction->setText( formwindow->marginFunction() ); +} + +void FormSettings::okClicked() +{ + MetaDataBase::MetaInfo info; + info.className = editClassName->text(); + info.classNameChanged = info.className != QString( formwindow->name() ); + info.comment = editComment->text(); + info.author = editAuthor->text(); + MetaDataBase::setMetaInfo( formwindow, info ); + + formwindow->commandHistory()->setModified( TRUE ); + + if ( formwindow->savePixmapInline() ) { + MetaDataBase::clearPixmapArguments( formwindow ); + MetaDataBase::clearPixmapKeys( formwindow ); + } else if ( formwindow->savePixmapInProject() ) { + MetaDataBase::clearPixmapArguments( formwindow ); + } else { + MetaDataBase::clearPixmapKeys( formwindow ); + } + + if ( radioPixmapInline->isChecked() ) { + formwindow->setSavePixmapInline( TRUE ); + formwindow->setSavePixmapInProject( FALSE ); + } else if ( radioProjectImageFile->isChecked() ){ + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( TRUE ); + } else { + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( FALSE ); + } + + if ( checkLayoutFunctions->isChecked() ) + formwindow->hasLayoutFunctions( TRUE ); + else + formwindow->hasLayoutFunctions( FALSE ); + + formwindow->setPixmapLoaderFunction( editPixmapFunction->text() ); + formwindow->setLayoutDefaultSpacing( spinSpacing->value() ); + formwindow->setSpacingFunction( editSpacingFunction->text() ); + formwindow->setLayoutDefaultMargin( spinMargin->value() ); + formwindow->setMarginFunction( editMarginFunction->text() ); + + accept(); +} diff --git a/kdevdesigner/designer/formsettingsimpl.h b/kdevdesigner/designer/formsettingsimpl.h new file mode 100644 index 00000000..08750fbc --- /dev/null +++ b/kdevdesigner/designer/formsettingsimpl.h @@ -0,0 +1,49 @@ +/********************************************************************** +** 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 FORMSETTINGSIMPL_H +#define FORMSETTINGSIMPL_H + +#include "formsettings.h" + +class FormWindow; + +class FormSettings : public FormSettingsBase +{ + Q_OBJECT + +public: + FormSettings( QWidget *parent, FormWindow *fw ); + +protected slots: + void okClicked(); + +private: + FormWindow *formwindow; + +}; + +#endif diff --git a/kdevdesigner/designer/formwindow.cpp b/kdevdesigner/designer/formwindow.cpp new file mode 100644 index 00000000..d9de42cc --- /dev/null +++ b/kdevdesigner/designer/formwindow.cpp @@ -0,0 +1,2775 @@ +/********************************************************************** +** 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 "formwindow.h" +#include "defs.h" +#include "mainwindow.h" +#include "widgetfactory.h" +#include "sizehandle.h" +#include "metadatabase.h" +#include "resource.h" +#include "layout.h" +#include "connectiondialog.h" +#include <widgetdatabase.h> +#include "pixmapchooser.h" +#include "orderindicator.h" +#include "hierarchyview.h" +#include "designerappiface.h" +#include "menubareditor.h" +#define NO_STATIC_COLORS +#include "globaldefs.h" + +#include <stdlib.h> + +#include <kiconloader.h> +#include <klocale.h> +#include "kdevdesigner_part.h" + +#include <qevent.h> +#include <qpainter.h> +#include <qpen.h> +#include <qlabel.h> +#include <qobjectlist.h> +#include <qtimer.h> +#include <qapplication.h> +#include <qlayout.h> +#include <qspinbox.h> +#include <qstatusbar.h> +#include <qapplication.h> +#include <qpalette.h> +#include <qmessagebox.h> +#include <qpopupmenu.h> +#include <qsizegrip.h> +#include <qpushbutton.h> +#include <qwhatsthis.h> +#include <qmetaobject.h> +#include <qtooltip.h> +#include <qfeatures.h> +#include <qaccel.h> +#include <qpixmapcache.h> +#include <qbitmap.h> +#include <qsplitter.h> + +// FormWindow should be able to work to some limited degree +// (existance, loading) without a MainWindow. Functions which require +// a MainWindow in theory should never be called if no MainWindow +// exists. These macros are used to let us know if that happens anyway +// and to ensure that we don't crash +#define CHECK_MAINWINDOW Q_ASSERT( mainWindow() ); if ( !mainWindow() ) return +#define CHECK_MAINWINDOW_VALUE( v ) Q_ASSERT( mainWindow() ); if ( !mainWindow() ) return v + +static void setCursorToAll( const QCursor &c, QWidget *start ) +{ + start->setCursor( c ); + QObjectList *l = (QObjectList*)start->children(); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && !::qt_cast<SizeHandle*>(o) ) + setCursorToAll( c, ( (QWidget*)o ) ); + } + } +} + +static void restoreCursors( QWidget *start, FormWindow *fw ) +{ + if ( fw->widgets()->find( start ) ) + start->setCursor( MetaDataBase::cursor( start ) ); + else + start->setCursor( Qt::ArrowCursor ); + QObjectList *l = (QObjectList*)start->children(); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && !::qt_cast<SizeHandle*>(o) ) + restoreCursors( ( (QWidget*)o ), fw ); + } + } +} + +#if defined(Q_WS_WIN32) // #### needed for the workaround for repaint problem on windows +#include <qt_windows.h> +static void flickerfree_update( QWidget *w ) +{ + InvalidateRect( w->winId(), 0, FALSE ); +} +#endif + +/*! + \class FormWindow formwindow.h + \brief Editor window for a form + + The FormWindow is the widget which is used as editor for forms. It + handles inserting, deleting, moving, resizing, etc. of widgets. + + Normally multiple formwindows are used at the same time in the + Designer. So each formwindow has its own undo/redo buffer, etc. + + Also the formwindow has some signals to inform e.g. about selection + changes which is interesting for the PropertyEditor. + + For handling the events of the child widgets (moving, etc.) the + handleMousePress(), etc. functions are called from the application + event filter which is implemented in MainWindow::eventFilter(). +*/ + +FormWindow::FormWindow( FormFile *f, MainWindow *mw, QWidget *parent, const char *name ) + : QWidget( parent, name, WDestructiveClose ), mainwindow( mw ), + commands( 100 ), pixInline( TRUE ), pixProject( FALSE ) +{ + ff = f; + init(); + initSlots(); +} + +FormWindow::FormWindow( FormFile *f, QWidget *parent, const char *name ) + : QWidget( parent, name, WDestructiveClose ), mainwindow( 0 ), + commands( 100 ), pixInline( TRUE ) +{ + ff = f; + init(); +} + +void FormWindow::init() +{ + setWFlags(getWFlags() & Qt::WStyle_Maximize); + + fake = qstrcmp( name(), "qt_fakewindow" ) == 0; + MetaDataBase::addEntry( this ); + ff->setFormWindow( this ); + iface = 0; + proj = 0; + propertyWidget = 0; + toolFixed = FALSE; + checkedSelectionsForMove = FALSE; + mContainer = 0; + startWidget = endWidget = 0; + currTool = POINTER_TOOL; + unclippedPainter = 0; + widgetPressed = FALSE; + drawRubber = FALSE; + setFocusPolicy( ClickFocus ); + sizePreviewLabel = 0; + checkSelectionsTimer = new QTimer( this, "checkSelectionsTimer" ); + connect( checkSelectionsTimer, SIGNAL( timeout() ), + this, SLOT( invalidCheckedSelections() ) ); + updatePropertiesTimer = new QTimer( this ); + connect( updatePropertiesTimer, SIGNAL( timeout() ), + this, SLOT( updatePropertiesTimerDone() ) ); + showPropertiesTimer = new QTimer( this ); + //!!!! + connect( showPropertiesTimer, SIGNAL( timeout() ), + this, SLOT( showPropertiesTimerDone() ) ); + selectionChangedTimer = new QTimer( this ); + connect( selectionChangedTimer, SIGNAL( timeout() ), + this, SLOT( selectionChangedTimerDone() ) ); + windowsRepaintWorkaroundTimer = new QTimer( this ); + connect( windowsRepaintWorkaroundTimer, SIGNAL( timeout() ), + this, SLOT( windowsRepaintWorkaroundTimerTimeout() ) ); + insertParent = 0; + connect( &commands, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ), + this, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ) ); + propShowBlocked = FALSE; + + setIcon( SmallIcon( "designer_form.png" , KDevDesignerPartFactory::instance()) ); + + connect( &commands, SIGNAL( modificationChanged( bool ) ), + this, SLOT( modificationChanged( bool ) ) ); + buffer = 0; + + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QFrame" ), this ); + setMainContainer( w ); + propertyWidget = w; + targetContainer = 0; + hadOwnPalette = FALSE; + + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + hasLayoutFunc = FALSE; +} + +void FormWindow::setMainWindow( MainWindow *w ) +{ + mainwindow = w; + MetaDataBase::addEntry( this ); + initSlots(); +} + +void FormWindow::initSlots() +{ + if ( isFake() ) + return; + Q_ASSERT( project() || MainWindow::self ); + if ( !project() && !MainWindow::self ) + return; + Project *p = project() ? project() : MainWindow::self->currProject(); + if ( p && p->isCpp() ) { + QString code = formFile()->code(); + if ( code.isEmpty() ) + formFile()->setCode( formFile()->codeComment() ); + } +} + +FormWindow::~FormWindow() +{ + if ( MainWindow::self && MainWindow::self->objectHierarchy()->formWindow() == this ) + MainWindow::self->objectHierarchy()->setFormWindow( 0, 0 ); + + MetaDataBase::clear( this ); + if ( ff ) + ff->setFormWindow( 0 ); + delete iface; +} + +void FormWindow::closeEvent( QCloseEvent *e ) +{ + QGuardedPtr<FormWindow> that = this; + if ( ff->closeEvent() && ( !that || ( mainwindow && mainwindow->unregisterClient( this ) ) ) ) + e->accept(); + else + e->ignore(); +} + +void FormWindow::paintGrid( QWidget *w, QPaintEvent *e ) +{ + if ( !mainWindow() || !mainWindow()->showGrid() ) + return; + QPixmap grid; + QString grid_name; + grid_name.sprintf("FormWindowGrid_%d_%d", mainWindow()->grid().x(), mainWindow()->grid().y()); + if( !QPixmapCache::find( grid_name, grid ) ) { + grid = QPixmap( 350 + ( 350 % mainWindow()->grid().x() ), 350 + ( 350 % mainWindow()->grid().y() ) ); + grid.fill( colorGroup().color( QColorGroup::Foreground ) ); + QBitmap mask( grid.width(), grid.height() ); + mask.fill( color0 ); + QPainter p( &mask ); + p.setPen( color1 ); + for ( int y = 0; y < grid.width(); y += mainWindow()->grid().y()) { + for ( int x = 0; x < grid.height(); x += mainWindow()->grid().x() ) { + p.drawPoint( x, y ); + } + } + grid.setMask( mask ); + QPixmapCache::insert( grid_name, grid ); + } + QPainter p( w ); + p.setClipRegion( e->rect() ); + p.drawTiledPixmap( QRect( 0, 0, width(), height() ), grid ); +} + +/*! For operations like drawing a rubber band or drawing the rect + when inserting a new widget, a unclipped painter (which draws also + on child widgets) is needed. This method does all the initialization. +*/ + +void FormWindow::beginUnclippedPainter( bool doNot ) +{ + endUnclippedPainter(); + bool unclipped = testWFlags( WPaintUnclipped ); + setWFlags( WPaintUnclipped ); + unclippedPainter = new QPainter; + unclippedPainter->begin( this ); + if ( !unclipped ) + clearWFlags( WPaintUnclipped ); + if ( doNot ) { + unclippedPainter->setPen( QPen( color0, 2 ) ); + unclippedPainter->setRasterOp( NotROP ); + } +} + +/*! + Gets rid of an open unclipped painter. + + \sa beginUnclippedPainter() +*/ + +void FormWindow::endUnclippedPainter() +{ + if ( unclippedPainter ) + unclippedPainter->end(); + delete unclippedPainter; + unclippedPainter = 0; +} + +QPoint FormWindow::gridPoint( const QPoint &p ) +{ + return QPoint( ( p.x() / grid().x() ) * grid().x(), + ( p.y() / grid().y() ) * grid().y() ); +} + +void FormWindow::drawSizePreview( const QPoint &pos, const QString& text ) +{ + unclippedPainter->save(); + unclippedPainter->setPen( QPen( colorGroup().foreground(), 1 )); + unclippedPainter->setRasterOp( CopyROP ); + if ( !sizePreviewPixmap.isNull() ) + unclippedPainter->drawPixmap( sizePreviewPos, sizePreviewPixmap ); + if ( text.isNull() ) { + sizePreviewPixmap = QPixmap(); // set null again + unclippedPainter->restore(); + return; + } + QRect r = fontMetrics().boundingRect( 0, 0, 0, 0, AlignCenter, text ); + r = QRect( pos + QPoint( 10, 10 ), r.size() + QSize( 5, 5 ) ); + + checkPreviewGeometry( r ); + + sizePreviewPos = r.topLeft(); + sizePreviewPixmap = QPixmap::grabWindow( winId(), r.x(), r.y(), r.width(), r.height() ); + unclippedPainter->setBrush( QColor( 255, 255, 128 ) ); + unclippedPainter->drawRect( r ); + unclippedPainter->drawText( r, AlignCenter, text ); + unclippedPainter->restore(); +} + +void FormWindow::insertWidget() +{ + CHECK_MAINWINDOW; + if ( !insertParent ) + return; + + if ( currTool == POINTER_TOOL ) + return; + + bool useSizeHint = !oldRectValid || ( currRect.width() < 2 && currRect.height() < 2 ); + Orientation orient = Horizontal; + QString n = WidgetDatabase::className( currTool ); + if ( useSizeHint && ( n == "Spacer" || n == "QSlider" || n == "Line" || n == "QScrollBar" ) ) { + QPopupMenu m( mainWindow() ); + m.insertItem( i18n( "&Horizontal" ) ); + int ver = m.insertItem( i18n( "&Vertical" ) ); + int r = m.exec( QCursor::pos() ); + if ( r == ver ) + orient = Vertical; + } + + + QWidget *w = WidgetFactory::create( currTool, insertParent, 0, TRUE, &currRect, orient ); + if ( !w ) + return; + + if ( !savePixmapInline() && currTool == WidgetDatabase::idFromClassName( "PixmapLabel" ) ) { // ### what to do for pixmaps in project + QPixmap pix; + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( SmallIcon( "designer_image.png" , KDevDesignerPartFactory::instance()).convertToImage() ); + ( (QLabel*)w )->setPixmap( pix ); + } + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ); + if ( WidgetDatabase::isCustomWidget( id ) ) { + QWhatsThis::add( w, i18n("<b>A %1 (custom widget)</b> " + "<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> " + "menu to add and change custom widgets. You can add " + "properties as well as signals and slots to integrate custom widgets into " + "<i>Qt Designer</i>, and provide a pixmap which will be used to represent " + "the widget on the form.</p>") + .arg(WidgetDatabase::toolTip( id )) ); + QToolTip::add( w, i18n("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) ); + } else { + QString tt = WidgetDatabase::toolTip( id ); + QString wt = WidgetDatabase::whatsThis( id ); + if ( !wt.isEmpty() && !tt.isEmpty() ) + QWhatsThis::add( w, QString("<b>A %1</b><p>%2</p>").arg( tt ).arg( wt ) ); + } + + QString s = w->name(); + unify( w, s, TRUE ); + w->setName( s ); + insertWidget( w ); + QRect r( currRect ); + if ( !oldRectValid || + ( currRect.width() < 2 && currRect.height() < 2 ) ) + r = QRect( rectAnchor, QSize( 0, 0 ) ); + + QPoint p = r.topLeft(); + p = mapToGlobal( p ); + p = insertParent->mapFromGlobal( p ); + r = QRect( p, r.size() ); + + if ( useSizeHint ) { + if ( n == "Spacer" ) { + if ( orient == Vertical ) { + r.setWidth( 20 ); + r.setHeight( 40 ); + } else { + r.setWidth( 40 ); + r.setHeight( 20 ); + } + } else { + r.setWidth( w->sizeHint().width() ); + r.setHeight( w->sizeHint().height() ); + } + } + + if ( r.width() < 2 * grid().x() ) + r.setWidth( 2 * grid().x() ); + if ( r.height() < 2 * grid().y() ) + r.setHeight( 2 * grid().y() ); + + const QObjectList *l = insertParent->children(); + QObjectListIt it( *l ); + QWidgetList lst; + if ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + for ( ; it.current(); ) { + QObject *o = it.current(); + ++it; + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) && o != w ) { + QRect r2( ( (QWidget*)o )->pos(), + ( (QWidget*)o )->size() ); + if ( r.contains( r2 ) ) + lst.append( (QWidget*)o ); + } + } + } + + if ( !lst.isEmpty() ) { + QWidget *pw = WidgetFactory::containerOfWidget( w ); + if (pw) { + QValueList<QPoint> op, np; + for ( QWidget *i = lst.first(); i; i = lst.next() ) { + op.append( i->pos() ); + QPoint pos = pw->mapFromGlobal( i->mapToGlobal( QPoint( 0, 0 ) ) ); + pos -= r.topLeft(); + np.append( pos ); + } + + MoveCommand *mv = new MoveCommand( i18n( "Reparent Widgets" ), this, + lst, op, np, insertParent, pw ); + + if ( !toolFixed ) + mainwindow->resetTool(); + else + setCursorToAll( CrossCursor, w ); + + InsertCommand *cmd = new InsertCommand( i18n( "Insert %1" ).arg( w->name() ), this, w, r ); + + QPtrList<Command> commands; + commands.append( mv ); + commands.append( cmd ); + + MacroCommand *mc = new MacroCommand( i18n( "Insert %1" ).arg( w->name() ), this, commands ); + commandHistory()->addCommand( mc ); + mc->execute(); + } + } else { + if ( !toolFixed ) + mainwindow->resetTool(); + else + setCursorToAll( CrossCursor, w ); + + InsertCommand *cmd = new InsertCommand( i18n( "Insert %1" ).arg( w->name() ), this, w, r ); + commandHistory()->addCommand( cmd ); + cmd->execute(); + } + + TemplateWizardInterface *iface = mainWindow()->templateWizardInterface( w->className() ); + if ( iface ) { + iface->setup( w->className(), w, iFace(), mainWindow()->designerInterface() ); + iface->release(); + } +} + +void FormWindow::insertWidget( QWidget *w, bool checkName ) +{ + if ( !w ) + return; + if ( checkName ) { + QString s = w->name(); + unify( w, s, TRUE ); + w->setName( s ); + } + + MetaDataBase::addEntry( w ); + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ); + if ( WidgetDatabase::isCustomWidget( id ) ) { + QWhatsThis::add( w, i18n("<b>A %1 (custom widget)</b> " + "<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> " + "menu to add and change custom widgets. You can add " + "properties as well as signals and slots to integrate custom widgets into " + "<i>Qt Designer</i>, and provide a pixmap which will be used to represent " + "the widget on the form.</p>") + .arg(WidgetDatabase::toolTip( id )) ); + QToolTip::add( w, i18n("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) ); + } else { + QString tt = WidgetDatabase::toolTip( id ); + QString wt = WidgetDatabase::whatsThis( id ); + if ( !wt.isEmpty() && !tt.isEmpty() ) + QWhatsThis::add( w, QString("<b>A %1</b><p>%2</p>").arg( tt ).arg( wt ) ); + } + + restoreCursors( w, this ); + widgets()->insert( w, w ); + w->show(); +} + +void FormWindow::removeWidget( QWidget *w ) +{ + MetaDataBase::removeEntry( w ); + widgets()->take( w ); +} + +void FormWindow::handleContextMenu( QContextMenuEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + switch ( currTool ) { + case POINTER_TOOL: { + if ( !isMainContainer( w ) && qstrcmp( w->name(), "central widget" ) != 0 ) { // press on a child widget + raiseChildSelections( w ); // raise selections and select widget + selectWidget( w ); + // if widget is laid out, find the first non-laid out super-widget + QWidget *realWidget = w; // but store the original one + while ( w->parentWidget() && + ( WidgetFactory::layoutType( w->parentWidget()) != WidgetFactory::NoLayout || + !insertedWidgets.find(w) ) ) + w = w->parentWidget(); + if ( ::qt_cast<QMainWindow*>(mainContainer()) && ((QMainWindow*)mainContainer())->centralWidget() == realWidget ) { + e->accept(); + mainwindow->popupFormWindowMenu( e->globalPos(), this ); + } else { + e->accept(); + mainwindow->popupWidgetMenu( e->globalPos(), this, realWidget); + } + } else { + e->accept(); + clearSelection(); + mainwindow->popupFormWindowMenu( e->globalPos(), this ); + } + break; } + default: + break; + } +} + +void FormWindow::handleMousePress( QMouseEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + checkedSelectionsForMove = FALSE; + checkSelectionsTimer->stop(); + if ( !sizePreviewLabel ) { + sizePreviewLabel = new QLabel( this ); + sizePreviewLabel->hide(); + sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) ); + sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box ); + } + + switch ( currTool ) { + case POINTER_TOOL: + if ( !isMainContainer( w ) && qstrcmp( w->name(), "central widget" ) != 0 ) { // press on a child widget + // if the clicked widget is not in a layout, raise it + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) + w->raise(); + if ( ( e->state() & ControlButton ) ) { // with control pressed, always start rubber band selection + drawRubber = TRUE; + currRect = QRect( 0, 0, -1, -1 ); + startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); + break; + } + + bool sel = isWidgetSelected( w ); + if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { // control not pressed... + if ( !sel ) { // ...and widget no selectted: unselect all + clearSelection( FALSE ); + } else { // ...widget selected + // only if widget has a layout (it is a layout meta widget or a laid out container!), unselect its childs + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout ) { + QObjectList *l = w->queryList( "QWidget" ); + setPropertyShowingBlocked( TRUE ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( !o->isWidgetType() ) + continue; + if ( insertedWidgets.find( (QWidget*)o ) ) + selectWidget( (QWidget*)o, FALSE ); + } + setPropertyShowingBlocked( FALSE ); + delete l; + } + } + qApp->processEvents(); + } + if ( ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) && + sel && e->button() == LeftButton ) { // control pressed and selected, unselect widget + selectWidget( w, FALSE ); + break; + } + + raiseChildSelections( w ); // raise selections and select widget + selectWidget( w ); + + // if widget is laid out, find the first non-laid out super-widget + while ( w->parentWidget() && + ( WidgetFactory::layoutType( w->parentWidget()) != WidgetFactory::NoLayout || !insertedWidgets.find(w) ) ) + w = w->parentWidget(); + + if ( e->button() == LeftButton ) { // left button: store original geometry and more as the widget might start moving + widgetPressed = TRUE; + widgetGeom = QRect( w->pos(), w->size() ); + oldPressPos = w->mapFromGlobal( e->globalPos() ); + origPressPos = oldPressPos; + checkedSelectionsForMove = FALSE; + moving.clear(); + if ( w->parentWidget() && !isMainContainer( w->parentWidget() ) && !isCentralWidget( w->parentWidget() ) ) { + targetContainer = w->parentWidget(); + hadOwnPalette = w->parentWidget()->ownPalette(); + restorePalette = w->parentWidget()->palette(); + } + } + } else { // press was on the formwindow + if ( e->button() == LeftButton ) { // left button: start rubber selection and show formwindow properties + drawRubber = TRUE; + if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { + clearSelection( FALSE ); + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } + currRect = QRect( 0, 0, -1, -1 ); + startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); + } + } + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + if ( e->button() != LeftButton ) + break; + validForBuddy = FALSE; + if ( currTool == BUDDY_TOOL ) { + if ( !::qt_cast<QLabel*>(w) ) + break; + clearSelection( FALSE ); + validForBuddy = TRUE; + mainWindow()->statusMessage( i18n( "Set buddy for '%1' to..." ).arg( w->name() ) ); + } else { + mainWindow()->statusMessage( i18n( "Connect '%1' with..." ).arg( w->name() ) ); + } + saveBackground(); + startPos = mapFromGlobal( e->globalPos() ); + currentPos = startPos; + startWidget = designerWidget( w ); + endWidget = startWidget; + beginUnclippedPainter( FALSE ); + drawConnectionLine(); + break; + case ORDER_TOOL: + if ( !isMainContainer( w ) ) { // press on a child widget + orderedWidgets.removeRef( w ); + orderedWidgets.append( w ); + for ( QWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev() ) { + int i = stackedWidgets.findRef( wid ); + if ( i != -1 ) { + stackedWidgets.removeRef( wid ); + stackedWidgets.insert( 0, wid ); + } + } + QWidgetList oldl = MetaDataBase::tabOrder( this ); + TabOrderCommand *cmd = new TabOrderCommand( i18n( "Change Tab Order" ), this, oldl, stackedWidgets ); + cmd->execute(); + commandHistory()->addCommand( cmd, TRUE ); + updateOrderIndicators(); + } + break; + default: // any insert widget tool + if ( e->button() == LeftButton ) { + insertParent = WidgetFactory::containerOfWidget( mainContainer() ); // default parent for new widget is the formwindow + if ( !isMainContainer( w ) ) { // press was not on formwindow, check if we can find another parent + QWidget *wid = w; + for (;;) { + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( wid ) ); + if ( ( WidgetDatabase::isContainer( id ) || wid == mainContainer() ) && + !::qt_cast<QLayoutWidget*>(wid) && !::qt_cast<QSplitter*>(wid) ) { + insertParent = WidgetFactory::containerOfWidget( wid ); // found another parent, store it + break; + } else { + wid = wid->parentWidget(); + if ( !wid ) + break; + } + } + } + startRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert ); + } + break; + } +} + +void FormWindow::handleMouseDblClick( QMouseEvent *, QWidget *w ) +{ + CHECK_MAINWINDOW; + switch ( currTool ) { + case ORDER_TOOL: + if ( !isMainContainer( w ) ) { // press on a child widget + orderedWidgets.clear(); + orderedWidgets.append( w ); + for ( QWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev() ) { + int i = stackedWidgets.findRef( wid ); + if ( i != -1 ) { + stackedWidgets.removeRef( wid ); + stackedWidgets.insert( 0, wid ); + } + } + QWidgetList oldl = MetaDataBase::tabOrder( this ); + TabOrderCommand *cmd = new TabOrderCommand( i18n( "Change Tab Order" ), this, oldl, stackedWidgets ); + cmd->execute(); + commandHistory()->addCommand( cmd, TRUE ); + updateOrderIndicators(); + } + default: + if ( !WidgetFactory::isPassiveInteractor( w ) && + ( isMainContainer( w ) || w == this ) ) + mainWindow()->editSource(); + break; + } +} + +void FormWindow::handleMouseMove( QMouseEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + if ( ( e->state() & LeftButton ) != LeftButton ) + return; + + QWidget *newendWidget = endWidget, *oldendWidget = endWidget, *wid; + bool drawRecRect; + switch ( currTool ) { + case POINTER_TOOL: + if ( widgetPressed && allowMove( w ) ) { // we are prepated for a move + + // if widget is laid out, find the first non-laid out super-widget + while ( w->parentWidget() && + ( WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout || !insertedWidgets.find(w ) ) ) + w = w->parentWidget(); + + // calc correct position + QPoint pos = w->mapFromGlobal( e->globalPos() ); + +#if 0 + QPoint mpos = w->mapToParent( pos ); + // check if we are not outside the visible area, else correct coords + if ( mpos.x() < 0 ) + pos.setX( w->mapFromParent( QPoint( 0, mpos.y() ) ).x() ); + if ( mpos.y() < 0 ) + pos.setY( w->mapFromParent( QPoint( mpos.x(), 0 ) ).y() ); + if ( mpos.x() > w->parentWidget()->width() ) + pos.setX( w->mapFromParent( QPoint( w->parentWidget()->width(), mpos.y() ) ).x() ); + if ( mpos.y() > w->parentWidget()->height() ) + pos.setY( w->mapFromParent( QPoint( mpos.x(), w->parentWidget()->height() ) ).y() ); +#endif + + // calc move distance and store it + QPoint d = oldPressPos - pos; + if ( QABS( d.x() ) < grid().x() ) + d.setX( 0 ); + if ( QABS( d.y() ) < grid().y() ) + d.setY( 0 ); + if ( d.x() == 0 ) + pos.setX( oldPressPos.x() ); + if ( d.y() == 0 ) + pos.setY( oldPressPos.y() ); + oldPressPos = pos; + + // snap to grid + int x = widgetGeom.x() - d.x(); + widgetGeom.setX( x ); + x = ( x / grid().x() ) * grid().x(); + int y = widgetGeom.y() - d.y(); + widgetGeom.setY( y ); + y = ( y / grid().y() ) * grid().y(); + QPoint p = w->pos(); + + if ( x - p.x() != 0 || y - p.y() != 0 ) { // if we actually have to move + if ( !checkedSelectionsForMove ) { // if not checked yet, check if the correct widget are selected... + if ( !isWidgetSelected( w ) ) { // and unselect others. Only siblings can be moved at the same time + setPropertyShowingBlocked( TRUE ); + selectWidget( w ); + setPropertyShowingBlocked( FALSE ); + } + checkSelectionsForMove( w ); + } + + // check whether we would have to reparent the selection and highlight the possible new parent container + QMapConstIterator<QWidget*, QPoint> it = moving.begin(); + QWidget* wa = containerAt( e->globalPos(), it.key() ); + if ( wa && !isMainContainer( wa ) && !isCentralWidget( wa ) ) { + wa = WidgetFactory::containerOfWidget( wa ); + // ok, looks like we moved onto a container + + if ( wa != targetContainer ) { + if ( targetContainer ) { + if ( hadOwnPalette ) + targetContainer->setPalette( restorePalette ); + else + targetContainer->unsetPalette(); + } + targetContainer = wa; + hadOwnPalette = wa->ownPalette(); + restorePalette = wa->palette(); + wa->setPaletteBackgroundColor( wa->colorGroup().midlight() ); + } + } + else if ( targetContainer ) { + if( hadOwnPalette ) + targetContainer->setPalette( restorePalette ); + else + targetContainer->unsetPalette(); + targetContainer = 0; + } + + // finally move the selected widgets and show/update preview label + moveSelectedWidgets( x - p.x(), y - p.y() ); + sizePreviewLabel->setText( i18n( "%1/%2" ).arg( w->pos().x() ).arg( w->pos().y() ) ); + sizePreviewLabel->adjustSize(); + QRect lg( mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), sizePreviewLabel->size() ); + checkPreviewGeometry( lg ); + sizePreviewLabel->setGeometry( lg ); + sizePreviewLabel->raise(); + sizePreviewLabel->show(); +#if defined(Q_WS_WIN32) + windowsRepaintWorkaroundTimer->start( 100, TRUE ); +#endif + } else { // if we don't need to move, do some indication + QRect lg( mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), sizePreviewLabel->size() ); + checkPreviewGeometry( lg ); + sizePreviewLabel->move( lg.x(), lg.y() ); + } + + oldPressPos += ( p - w->pos() ); + } else if ( drawRubber ) { // draw rubber if we are in rubber-selection mode + continueRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); + } + break; + case CONNECT_TOOL: + restoreConnectionLine(); + wid = qApp->widgetAt( e->globalPos(), TRUE ); + if ( wid ) + wid = designerWidget( wid ); + if ( wid && ( isMainContainer( wid ) || insertedWidgets.find( wid ) ) && wid->isVisibleTo( this ) ) + newendWidget = wid; + if ( ::qt_cast<QLayoutWidget*>(newendWidget) || ::qt_cast<Spacer*>(newendWidget) ) + newendWidget = (QWidget*)endWidget; + drawRecRect = newendWidget != endWidget; + if ( newendWidget && + ( isMainContainer( newendWidget ) || insertedWidgets.find( newendWidget ) ) && !isCentralWidget( newendWidget ) ) + endWidget = newendWidget; + mainWindow()->statusMessage( i18n( "Connect '%1' to '%2'" ).arg( startWidget->name() ). + arg( endWidget->name() ) ); + currentPos = mapFromGlobal( e->globalPos() ); + qApp->processEvents(); + if ( drawRecRect ) + restoreRect( QRect( mapToForm( ( (QWidget*)oldendWidget )->parentWidget(), ( (QWidget*)oldendWidget )->pos() ), + ( (QWidget*)oldendWidget )->size() ) ); + drawConnectionLine(); + break; + case BUDDY_TOOL: + if ( !validForBuddy ) + break; + restoreConnectionLine(); + wid = qApp->widgetAt( e->globalPos(), TRUE ); + if ( wid ) + wid = designerWidget( wid ); + if ( wid && canBeBuddy( wid ) && wid->isVisibleTo( this ) ) + newendWidget = wid; + else + newendWidget = 0; + if ( ::qt_cast<QLayoutWidget*>(newendWidget) || ::qt_cast<Spacer*>(newendWidget) ) + newendWidget = (QWidget*)endWidget; + drawRecRect = newendWidget != endWidget; + if ( !newendWidget ) + endWidget = newendWidget; + else if ( insertedWidgets.find( newendWidget ) && !isCentralWidget( newendWidget ) ) + endWidget = newendWidget; + if ( endWidget ) + mainWindow()->statusMessage( i18n( "Set buddy '%1' to '%2'" ).arg( startWidget->name() ). + arg( endWidget->name() ) ); + else + mainWindow()->statusMessage( i18n( "Set buddy '%1' to ..." ).arg( startWidget->name() ) ); + currentPos = mapFromGlobal( e->globalPos() ); + qApp->processEvents(); + if ( drawRecRect && oldendWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)oldendWidget )->parentWidget(), ( (QWidget*)oldendWidget )->pos() ), + ( (QWidget*)oldendWidget )->size() ) ); + drawConnectionLine(); + break; + case ORDER_TOOL: + break; + default: // we are in an insert-widget tool + if ( insertParent ) // draw insert rect + continueRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert ); + break; + } +} + +void FormWindow::handleMouseRelease( QMouseEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + if ( e->button() != LeftButton ) + return; + + switch ( currTool ) { + case POINTER_TOOL: + if ( widgetPressed && allowMove( w ) ) { // we moved the widget + sizePreviewLabel->hide(); + + if ( moving.isEmpty() || w->pos() == *moving.find(w) ) + break; + + // restore targetContainer + if ( targetContainer ) { + if( hadOwnPalette ) + targetContainer->setPalette( restorePalette ); + else + targetContainer->unsetPalette(); + } + + // tell property editor to update + if ( propertyWidget && propertyWidget->isWidgetType() && !isMainContainer( propertyWidget ) ) + emitUpdateProperties( propertyWidget ); + + QMapConstIterator<QWidget*,QPoint> it = moving.begin(); + QWidget *oldParent = it.key()->parentWidget(); + QWidget *newParent = oldParent; + // check whether we have to reparent the selection + QWidget* wa = containerAt( e->globalPos(), it.key() ); + if ( wa ) { + wa = WidgetFactory::containerOfWidget( wa ); + // ok, looks like we moved onto a container + + // check whether we really have different parents. + if ( wa == it.key()->parentWidget() ) + goto make_move_command; + + // break layout if necessary + if ( WidgetFactory::layoutType( wa ) != WidgetFactory::NoLayout ) { + if ( QMessageBox::information( mainWindow(), i18n( "Inserting Widget" ), + i18n( "You tried to insert a widget into the " + "layout Container Widget '%1'.\n" + "This is not possible. " + "In order to insert the widget, the layout of '%1'\n" + "must first be broken.\n" + "Break the layout or cancel the operation?" ). + arg( wa->name() ). + arg( wa->name() ), i18n( "&Break Layout" ), i18n( "&Cancel" ) ) ) + goto make_move_command; // cancel + breakLayout( wa ); + } + + // doesn't need to be a command, the MoveCommand does reparenting too + bool emitSelChanged = FALSE; + for ( QMap<QWidget*, QPoint>::Iterator it = moving.begin(); it != moving.end(); ++it ) { + QWidget *i = it.key(); + if ( !emitSelChanged && ::qt_cast<QButton*>(i) ) { + if ( ::qt_cast<QButtonGroup*>(i->parentWidget()) || ::qt_cast<QButtonGroup*>(wa) ) + emitSelChanged = TRUE; + if ( !::qt_cast<QButtonGroup*>(wa) ) { + MetaDataBase::setPropertyChanged( i, "buttonGroupId", FALSE ); + if ( ::qt_cast<QButtonGroup*>(i->parentWidget()) ) + ( (QButtonGroup*)i->parentWidget() )->remove( (QButton*)i ); + } + } + QPoint pos = wa->mapFromGlobal( i->mapToGlobal( QPoint(0,0) ) ); + i->reparent( wa, pos, TRUE ); + raiseSelection( i ); + raiseChildSelections( i ); + widgetChanged( i ); + mainWindow()->objectHierarchy()->widgetRemoved( i ); + mainWindow()->objectHierarchy()->widgetInserted( i ); + } + if ( emitSelChanged ) { + emit showProperties( wa ); + emit showProperties( propertyWidget ); + } + newParent = wa; + } + + make_move_command: + QWidgetList widgets; // collect the widgets and its old and new positions which have been moved + QValueList<QPoint> oldPos, newPos; + for ( it = moving.begin(); it != moving.end(); ++it ) { + widgets.append( it.key() ); + oldPos.append( *it ); + newPos.append( it.key()->pos() ); + } + // add move command, don't execute it, this is just a summary of the operations we did during the move-event handling + commandHistory()->addCommand( new MoveCommand( i18n( "Move" ), + this, widgets, + oldPos, newPos, oldParent, newParent ) ); + } else if ( drawRubber ) { // we were drawing a rubber selection + endRectDraw(); // get rid of the rectangle + blockSignals( TRUE ); + selectWidgets(); // select widgets which intersect the rect + blockSignals( FALSE ); + emitSelectionChanged(); // inform about selection changes + if ( propertyWidget ) + emitShowProperties( propertyWidget ); + } + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + restoreConnectionLine(); + if ( startWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)startWidget )->parentWidget(), + ( (QWidget*)startWidget )->pos() ), + ((QWidget*)startWidget )->size() ) ); + if ( endWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)endWidget )->parentWidget(), + ( (QWidget*)endWidget )->pos() ), + ( (QWidget*)endWidget )->size() ) ); + endUnclippedPainter(); + qApp->processEvents(); + + if ( startWidget && endWidget ) { + if ( currTool == CONNECT_TOOL ) + editConnections(); + else if ( currTool == BUDDY_TOOL && validForBuddy && startWidget != endWidget ) { + QString oldBuddy = startWidget->property( "buddy" ).toString(); + if ( oldBuddy.isNull() ) + oldBuddy = ""; + SetPropertyCommand *cmd = new SetPropertyCommand( i18n( "Set Buddy for %1" ).arg( startWidget->name() ), + this, startWidget, mainWindow()->propertyeditor(), + "buddy", startWidget->property( "buddy" ), + endWidget->name(), endWidget->name(), + oldBuddy ); + commandHistory()->addCommand( cmd, TRUE ); + cmd->execute(); + emitUpdateProperties( startWidget ); + } + } + if ( !toolFixed ) + mainwindow->resetTool(); + startWidget = endWidget = 0; + mainWindow()->statusBar()->clear(); + break; + case ORDER_TOOL: + break; + default: // any insert widget tool is active + if ( insertParent ) { // we should insert the new widget now + endRectDraw(); + if ( WidgetFactory::layoutType( insertParent ) != WidgetFactory::NoLayout ) { + if ( QMessageBox::information( mainWindow(), i18n( "Inserting Widget" ), + i18n( "You tried to insert a widget into the " + "layout Container Widget '%1'.\n" + "This is not possible. " + "In order to insert the widget, the layout of '%1'\n" + "must first be broken.\n" + "Break the layout or cancel the operation?" ). + arg( insertParent->name() ). + arg( insertParent->name() ), i18n( "&Break Layout" ), i18n( "&Cancel" ) ) == 0 ) { + breakLayout( insertParent ); + } else { + if ( !toolFixed ) + mainWindow()->resetTool(); + break; + } + } + insertWidget(); // so do it + } + break; + } + widgetPressed = FALSE; + drawRubber = FALSE; + insertParent = 0; + delete buffer; + buffer = 0; +} + +void FormWindow::handleKeyPress( QKeyEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + e->ignore(); + checkSelectionsTimer->stop(); + if ( !checkedSelectionsForMove && + ( e->key() == Key_Left || + e->key() == Key_Right || + e->key() == Key_Up || + e->key() == Key_Down ) && + propertyWidget->isWidgetType() ) + checkSelectionsForMove( (QWidget*)propertyWidget ); + checkSelectionsTimer->start( 1000, TRUE ); + if ( e->key() == Key_Left || e->key() == Key_Right || + e->key() == Key_Up || e->key() == Key_Down ) { + QWidgetList widgets; + QValueList<QPoint> oldPos, newPos; + for ( WidgetSelection *s = selections.first(); s; s = selections.next() ) { + if ( s->isUsed() ) { + int dx = 0, dy = 0; + bool control = e->state() & ControlButton; + + switch ( e->key() ) { + case Key_Left: { + e->accept(); + if ( control ) + dx = -1; + else + dx = -grid().x(); + } break; + case Key_Right: { + e->accept(); + if ( control ) + dx = 1; + else + dx = grid().x(); + } break; + case Key_Up: { + e->accept(); + if ( control ) + dy = -1; + else + dy = -grid().y(); + } break; + case Key_Down: { + e->accept(); + if ( control ) + dy = 1; + else + dy = grid().y(); + } break; + default: + break; + } + + widgets.append( s->widget() ); + oldPos.append( s->widget()->pos() ); + newPos.append( s->widget()->pos() + QPoint( dx, dy ) ); + } + } + if ( !widgets.isEmpty() ) { + MoveCommand *cmd = new MoveCommand( i18n( "Move" ), this, + widgets, oldPos, newPos, 0, 0 ); + commandHistory()->addCommand( cmd, TRUE ); + cmd->execute(); + } + } + if ( !e->isAccepted() ) { + QObjectList *l = queryList( "QWidget" ); + if ( !l ) + return; + if ( l->find( w ) != -1 ) + e->accept(); + delete l; + } + +} + +void FormWindow::handleKeyRelease( QKeyEvent *e, QWidget * ) +{ + e->ignore(); +} + +void FormWindow::selectWidget( QObject *o, bool select ) +{ + CHECK_MAINWINDOW; + if ( !o->isWidgetType() ) { + // ########### do QObject stuff + return; + } + + QWidget *w = (QWidget*)o; + + if ( isMainContainer( w ) ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + emitShowProperties( propertyWidget ); + return; + } + + if ( ::qt_cast<QMainWindow*>(mainContainer()) && w == ( (QMainWindow*)mainContainer() )->centralWidget() ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + emitShowProperties( propertyWidget ); + return; + } + + if ( ::qt_cast<QDesignerToolBar*>(o) ) + return; + + if ( select ) { + QObject *opw = propertyWidget; + propertyWidget = w; + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + if ( !isPropertyShowingBlocked() ) + emitShowProperties( propertyWidget ); + WidgetSelection *s = usedSelections.find( w ); + if ( s ) { + s->show(); + return; + } + + for ( WidgetSelection *s2 = selections.first(); s2; s2 = selections.next() ) { + if ( !s2->isUsed() ) { + s = s2; + } + } + + if ( !s ) { + s = new WidgetSelection( this, &usedSelections ); + selections.append( s ); + } + + s->setWidget( w ); + emitSelectionChanged(); + } else { + WidgetSelection *s = usedSelections.find( w ); + if ( s ) + s->setWidget( 0 ); + QObject *opw = propertyWidget; + if ( !usedSelections.isEmpty() ) + propertyWidget = QPtrDictIterator<WidgetSelection>( usedSelections ).current()->widget(); + else + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + if ( !isPropertyShowingBlocked() ) + emitShowProperties( propertyWidget ); + emitSelectionChanged(); + } +} + +QPoint FormWindow::grid() const +{ + if ( !mainWindow() || !mainWindow()->snapGrid() ) + return QPoint( 1, 1 ); + return mainWindow()->grid(); +} + +void FormWindow::updateSelection( QWidget *w ) +{ + WidgetSelection *s = usedSelections.find( w ); + if ( !w->isVisibleTo( this ) ) + selectWidget( w, FALSE ); + else if ( s ) + s->updateGeometry(); +} + +void FormWindow::raiseSelection( QWidget *w ) +{ + WidgetSelection *s = usedSelections.find( w ); + if ( s ) + s->show(); +} + +void FormWindow::repaintSelection( QWidget *w ) +{ + WidgetSelection *s = usedSelections.find( w ); + if ( s ) + s->update(); +} + +void FormWindow::clearSelection( bool changePropertyDisplay ) +{ + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) + it.current()->setWidget( 0, FALSE ); + + usedSelections.clear(); + if ( changePropertyDisplay ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + emitShowProperties( propertyWidget ); + } + emitSelectionChanged(); +} + +void FormWindow::startRectDraw( const QPoint &p, const QPoint &global, QWidget *, RectType t ) +{ + QPoint pos( p ); + pos = mapFromGlobal( global ); + oldRectValid = FALSE; + beginUnclippedPainter( TRUE ); + if ( t == Rubber ) + unclippedPainter->setPen( QPen( color0, 1 ) ); + if ( t == Insert ) + rectAnchor = gridPoint( pos ); + else if ( t == Rubber ) + rectAnchor = pos; + currRect = QRect( rectAnchor, QPoint( 0, 0 ) ); + if ( t == Insert ) + drawSizePreview( pos, i18n("Use Size Hint") ); +} + +void FormWindow::continueRectDraw( const QPoint &p, const QPoint &global, QWidget *, RectType t ) +{ + QPoint pos =p; + pos = mapFromGlobal( global ); + QPoint p2; + if ( t == Insert ) + p2 = gridPoint( pos ); + else if ( t == Rubber ) + p2 = pos; + QRect r( rectAnchor, p2 ); + r = r.normalize(); + + if ( currRect == r ) { + QString t = i18n( "%1/%2" ); + t = t.arg( r.width() - 1 ).arg( r.height() - 1 ); + drawSizePreview( pos, t ); + return; + } + + if ( oldRectValid ) + unclippedPainter->drawRect( currRect ); + if ( r.width() > 1 || r.height() > 1 ) { + oldRectValid = TRUE; + currRect = r; + if ( t == Insert ) { + QString t = i18n( "%1/%2" ); + t = t.arg( r.width() - 1 ).arg( r.height() - 1 ); + drawSizePreview( pos, t ); + } + unclippedPainter->setClipRegion( QRegion( rect() ).subtract( QRect( sizePreviewPos, sizePreviewPixmap.size() ) ) ); + unclippedPainter->drawRect( currRect ); + unclippedPainter->setClipping( FALSE ); + } else { + oldRectValid = FALSE; + if ( t == Insert ) + drawSizePreview( pos, i18n("Use Size Hint") ); + } +} + +void FormWindow::endRectDraw() +{ + if ( !unclippedPainter ) + return; + + if ( oldRectValid ) + unclippedPainter->drawRect( currRect ); + drawSizePreview( QPoint(-1,-1), QString::null ); + endUnclippedPainter(); +} + +void FormWindow::selectWidgets() +{ + QObjectList *l = mainContainer()->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets[ (void*)o ] ) { + QPoint p = ( (QWidget*)o )->mapToGlobal( QPoint(0,0) ); + p = mapFromGlobal( p ); + QRect r( p, ( (QWidget*)o )->size() ); + if ( r.intersects( currRect ) && !r.contains( currRect ) ) + selectWidget( (QWidget*)o ); + } + } + delete l; + } + emitSelectionChanged(); +} + +bool FormWindow::isWidgetSelected( QObject *w ) +{ + if ( w->isWidgetType() ) + return usedSelections.find( (QWidget*)w ) != 0; + return FALSE; // #### do stuff for QObjects +} + +void FormWindow::moveSelectedWidgets( int dx, int dy ) +{ + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) { + WidgetSelection *s = it.current(); + QWidget *w = s->widget(); + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + continue; + w->move( w->x() + dx, w->y() + dy ); + s->updateGeometry(); + updateChildSelections( w ); + } +} + +CommandHistory *FormWindow::commandHistory() +{ + return &commands; +} + +void FormWindow::undo() +{ + commandHistory()->undo(); +} + +void FormWindow::redo() +{ + commandHistory()->redo(); +} + +void FormWindow::raiseChildSelections( QWidget *w ) +{ + QObjectList *l = w->queryList( "QWidget" ); + if ( !l || !l->first() ) { + delete l; + return; + } + + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) { + if ( l->findRef( it.current()->widget() ) != -1 ) + it.current()->show(); + } + delete l; +} + +void FormWindow::updateChildSelections( QWidget *w ) +{ + QObjectList *l = w->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + insertedWidgets.find( (QWidget*)o ) ) + updateSelection( (QWidget*)o ); + } + delete l; + } +} + +void FormWindow::checkSelectionsForMove( QWidget *w ) +{ + checkedSelectionsForMove = TRUE; + + QObjectList *l = w->parentWidget()->queryList( "QWidget", 0, FALSE, FALSE ); + moving.clear(); + if ( l ) { + QPtrDictIterator<WidgetSelection> it( usedSelections ); + WidgetSelection *sel; + while ( ( sel = it.current() ) != 0 ) { + if ( it.current()->widget() == mainContainer() ) + continue; + ++it; + if ( l->find( sel->widget() ) == -1 ) { + if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) + sel->setWidget( 0 ); + } else { + if ( WidgetFactory::layoutType( sel->widget()->parentWidget() ) == WidgetFactory::NoLayout ) { + moving.insert( sel->widget(), sel->widget()->pos() ); + sel->widget()->raise(); + raiseChildSelections( sel->widget() ); + raiseSelection( sel->widget() ); + } + } + } + delete l; + } +} + +void FormWindow::deleteWidgets() +{ + CHECK_MAINWINDOW; + QWidgetList widgets; + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) { + QWidget *tb = 0; + if ( !( tb = mainWindow()->isAToolBarChild( it.current()->widget() ) ) ) + widgets.append( it.current()->widget() ); + else + ( (QDesignerToolBar*)tb )->removeWidget( it.current()->widget() ); + } + + if ( widgets.isEmpty() ) + return; + + DeleteCommand *cmd = new DeleteCommand( i18n( "Delete" ), this, widgets ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::editAdjustSize() +{ + QPtrList<Command> commands; + QWidgetList widgets = selectedWidgets(); + if ( widgets.isEmpty() ) { + QRect oldr = geometry(); + mainContainer()->adjustSize(); + resize( mainContainer()->size() ); + // check whether our own size constraint hit us + if ( size() != mainContainer()->size() ) + mainContainer()->resize( size() ); + QRect nr = geometry(); + if ( oldr != nr ) { + ResizeCommand *cmd = new ResizeCommand( i18n( "Adjust Size" ), this, this, oldr, nr ); + commandHistory()->addCommand( cmd ); + } + return; + } + for ( QWidget* w = widgets.first(); w; w = widgets.next() ) { + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + continue; + QRect oldr = w->geometry(); + w->adjustSize(); + QRect nr = w->geometry(); + if ( oldr != nr ) + commands.append( new ResizeCommand( i18n("Adjust Size"), this, w, oldr, nr ) ); + } + + if ( commands.isEmpty() ) + return; + for ( WidgetSelection *s = selections.first(); s; s = selections.next() ) + s->updateGeometry(); + + MacroCommand *cmd = new MacroCommand( i18n( "Adjust Size" ), this, commands ); + commandHistory()->addCommand( cmd ); +} + + +QWidgetList FormWindow::selectedWidgets() const +{ + QWidgetList widgets; + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) + widgets.append( it.current()->widget() ); + return widgets; +} + +void FormWindow::widgetChanged( QObject *w ) +{ + if ( w->isWidgetType() ) + updateSelection( (QWidget*)w ); + // ########## do QObject stuff +} + +QLabel *FormWindow::sizePreview() const +{ + if ( !sizePreviewLabel ) { + ( (FormWindow*)this )->sizePreviewLabel = new QLabel( (FormWindow*)this ); + ( (FormWindow*)this )->sizePreviewLabel->hide(); + ( (FormWindow*)this )->sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) ); + ( (FormWindow*)this )->sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box ); + } + return sizePreviewLabel; +} + +void FormWindow::invalidCheckedSelections() +{ + checkedSelectionsForMove = FALSE; +} + +void FormWindow::checkPreviewGeometry( QRect &r ) +{ + if ( !rect().contains( r ) ) { + if ( r.left() < rect().left() ) + r.moveTopLeft( QPoint( 0, r.top() ) ); + if ( r.right() > rect().right() ) + r.moveBottomRight( QPoint( rect().right(), r.bottom() ) ); + if ( r.top() < rect().top() ) + r.moveTopLeft( QPoint( r.left(), rect().top() ) ); + if ( r.bottom() > rect().bottom() ) + r.moveBottomRight( QPoint( r.right(), rect().bottom() ) ); + } +} + +void FormWindow::focusInEvent( QFocusEvent * ){ + + if (ff) + ff->checkTimeStamp(); +} + +void FormWindow::focusOutEvent( QFocusEvent * ) +{ + if ( propertyWidget && !isMainContainer( propertyWidget ) && !isWidgetSelected( propertyWidget ) ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } +} + +void FormWindow::resizeEvent( QResizeEvent *e ) +{ + QWidget::resizeEvent( e ); + if ( currTool == ORDER_TOOL ) + repositionOrderIndicators(); + if ( isVisible() ) + formFile()->setModified( TRUE, FormFile::WFormWindow ); + +#if defined(Q_WS_WIN32) + windowsRepaintWorkaroundTimer->start( 100, TRUE ); +#endif +} + +void FormWindow::windowsRepaintWorkaroundTimerTimeout() +{ +#if defined(Q_WS_WIN32) + QObjectList *l = queryList( "QWidget" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + flickerfree_update( (QWidget*)o ); + } + flickerfree_update( this ); + delete l; +#endif +} + +QPtrDict<QWidget> *FormWindow::widgets() +{ + return &insertedWidgets; +} + +QWidget *FormWindow::designerWidget( QObject *o ) const +{ + if ( !o || !o->isWidgetType() ) + return 0; + QWidget *w = (QWidget*)o; + while ( w && !isMainContainer( w ) && !insertedWidgets[ (void*)w ] || isCentralWidget( w ) ) + w = (QWidget*)w->parent(); + return w; +} + +void FormWindow::emitShowProperties( QObject *w ) +{ + if ( w ) { + QObject *opw = propertyWidget; + propertyWidget = w; + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } + showPropertiesTimer->stop(); +// showPropertiesTimer->start( 0, TRUE ); + showPropertiesTimerDone(); +} + +void FormWindow::emitUpdateProperties( QObject *w ) +{ + if ( w == propertyWidget ) { + updatePropertiesTimer->stop(); + updatePropertiesTimer->start( 0, TRUE ); + } +} + +void FormWindow::emitSelectionChanged() +{ + selectionChangedTimer->stop(); + selectionChangedTimer->start( 0, TRUE ); +} + +void FormWindow::updatePropertiesTimerDone() +{ + CHECK_MAINWINDOW; + if ( propertyWidget && mainWindow()->formWindow() == this ) + emit updateProperties( propertyWidget ); +} + +void FormWindow::showPropertiesTimerDone() +{ + CHECK_MAINWINDOW; + if ( propertyWidget && mainWindow()->formWindow() == this ) + emit showProperties( propertyWidget ); +} + +void FormWindow::selectionChangedTimerDone() +{ + emit selectionChanged(); +} + +void FormWindow::currentToolChanged() +{ + CHECK_MAINWINDOW; + toolFixed = FALSE; + int t = mainwindow->currentTool(); + if ( currTool == t && t != ORDER_TOOL ) + return; + + // tool cleanup + switch ( currTool ) { + case ORDER_TOOL: + hideOrderIndicators(); + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + restoreConnectionLine(); + if ( startWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)startWidget )->parentWidget(), + ( (QWidget*)startWidget )->pos() ), + ( (QWidget*)startWidget )->size() ) ); + if ( endWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)endWidget )->parentWidget(), + ( (QWidget*)endWidget )->pos() ), + ( (QWidget*)endWidget )->size() ) ); + endUnclippedPainter(); + break; + case POINTER_TOOL: + break; + default: + if ( insertParent ) + endRectDraw(); + break; + } + + startWidget = endWidget = 0; + widgetPressed = FALSE; + drawRubber = FALSE; + insertParent = 0; + delete buffer; + buffer = 0; + + currTool = t; + + if ( hasFocus() ) + clearSelection( FALSE ); + + mainWindow()->statusBar()->clear(); + + // tool setup + switch ( currTool ) { + case POINTER_TOOL: + if ( propertyWidget && !isMainContainer( propertyWidget ) && !isWidgetSelected( propertyWidget ) ) + emitShowProperties( mainContainer() ); + restoreCursors( this, this ); + break; + case ORDER_TOOL: + if ( mainWindow()->formWindow() == this ) { + mainWindow()->statusMessage( i18n( "Click widgets to change the tab order...") ); + orderedWidgets.clear(); + showOrderIndicators(); + if ( mainWindow()->formWindow() == this ) + emitShowProperties( mainContainer() ); + setCursorToAll( ArrowCursor, this ); + } + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + if ( currTool == CONNECT_TOOL ) + mainWindow()->statusMessage( i18n( "Drag a line to create a connection...") ); + else + mainWindow()->statusMessage( i18n( "Drag a line to set a buddy...") ); + setCursorToAll( CrossCursor, this ); + if ( mainWindow()->formWindow() == this ) + emitShowProperties( mainContainer() ); + break; + default: + mainWindow()->statusMessage( i18n( "Click on the form to insert a %1..." ).arg( WidgetDatabase::toolTip( currTool ).lower() ) ); + setCursorToAll( CrossCursor, this ); + if ( mainWindow()->formWindow() == this ) + emitShowProperties( mainContainer() ); + break; + } +} + +void FormWindow::showOrderIndicators() +{ + hideOrderIndicators(); + orderIndicators.setAutoDelete( TRUE ); + QObjectList *l = mainContainer()->queryList( "QWidget" ); + stackedWidgets = MetaDataBase::tabOrder( this ); + if ( l ) { + int order = 1; + for ( QObject *o = l->first(); o; o = l->next() ) { + QWidget* w = (QWidget*) o; + if ( w->isShown() && + insertedWidgets[ (void*)w ] && + w->focusPolicy() != NoFocus ) { + OrderIndicator* ind = new OrderIndicator( order++, w, this ); + orderIndicators.append( ind ); + if ( stackedWidgets.findRef( w ) == -1 ) + stackedWidgets.append( w ); + } + } + delete l; + } + updateOrderIndicators(); +} + +void FormWindow::hideOrderIndicators() +{ + orderIndicators.clear(); +} + +void FormWindow::updateOrderIndicators() +{ + int order = 1; + for ( QWidget *w = stackedWidgets.first(); w; w = stackedWidgets.next() ) { + for ( OrderIndicator* i = orderIndicators.first(); i; i = orderIndicators.next() ) + i->setOrder( order, w ); + order++; + } +} + +void FormWindow::repositionOrderIndicators() +{ + for ( OrderIndicator* i = orderIndicators.first(); i; i = orderIndicators.next() ) + i->reposition(); +} + + +void FormWindow::updateUndoInfo() +{ + commandHistory()->emitUndoRedo(); +} + +bool FormWindow::checkCustomWidgets() +{ + QStringList missingCustomWidgets; + QPtrDictIterator<QWidget> it( insertedWidgets ); + for ( ; it.current(); ++it ) { + if ( it.current()->isA( "CustomWidget" ) ) { + QString className = WidgetFactory::classNameOf( it.current() ); + if ( !MetaDataBase::hasCustomWidget( className ) ) + missingCustomWidgets << className; + } + } + + if ( !missingCustomWidgets.isEmpty() ) { + QString txt = i18n( "The following custom widgets are used in '%1',\n" + "but are not known to Qt Designer:\n" ).arg( name() ); + for ( QStringList::Iterator sit = missingCustomWidgets.begin(); sit != missingCustomWidgets.end(); ++sit ) + txt += " " + *sit + "\n"; + txt += i18n( "If you save this form and generate code for it using uic, \n" + "the generated code will not compile.\n" + "Do you want to save this form now?" ); + if ( QMessageBox::information( mainWindow(), i18n( "Save Form" ), txt ) == 1 ) + return FALSE; + } + return TRUE; +} + +void FormWindow::setPropertyShowingBlocked( bool b ) +{ + propShowBlocked = b; +} + +bool FormWindow::isPropertyShowingBlocked() const +{ + return propShowBlocked; +} + +int FormWindow::numSelectedWidgets() const +{ + return usedSelections.count(); +} + +QString FormWindow::copy() +{ + CHECK_MAINWINDOW_VALUE( QString::null ); + Resource resource( mainWindow() ); + resource.setWidget( this ); + return resource.copy(); +} + +void FormWindow::lowerWidgets() +{ + QWidgetList widgets; + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) + widgets.append( it.current()->widget() ); + + LowerCommand *cmd = new LowerCommand( i18n( "Lower" ), this, widgets ); + cmd->execute(); + commandHistory()->addCommand( cmd ); +} + +void find_accel( const QString &txt, QMap<QChar, QWidgetList > &accels, QWidget *w ) +{ + int i = txt.find( "&" ); + if ( i == -1 ) + return; + QChar c = txt[ i + 1 ]; + if ( c.isNull() || c == '&' ) + return; + c = c.lower(); + QMap<QChar, QWidgetList >::Iterator it = accels.find( c ); + if ( it == accels.end() ) { + QWidgetList wl; + wl.append( w ); + accels.insert( c, wl ); + } else { + QWidgetList *wl = &*it; + wl->append( w ); + } +} + +void FormWindow::checkAccels() +{ + CHECK_MAINWINDOW; + QMap<QChar, QWidgetList > accels; + QObjectList *l = mainContainer()->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets[ (void*)o ] ) { + QWidget *w = (QWidget*)o; + const QMetaProperty* text = + w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE ); + const QMetaProperty* title = + w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE ); + const QMetaProperty* pageTitle = + w->metaObject()->property( w->metaObject()->findProperty( "pageTitle", TRUE ), TRUE ); + if ( text ) + find_accel( w->property( "text" ).toString(), accels, w ); + if ( title ) + find_accel( w->property( "title" ).toString(), accels, w ); + if ( pageTitle ) + find_accel( w->property( "pageTitle" ).toString(), accels, w ); + } else if ( ::qt_cast<MenuBarEditor*>(o) ) { + ((MenuBarEditor *)o)->checkAccels( accels ); + } + } + delete l; + } + + bool ok = TRUE; + QWidget *wid; + for ( QMap<QChar, QWidgetList >::Iterator it = accels.begin(); it != accels.end(); ++it ) { + if ( (*it).count() > 1 ) { + ok = FALSE; + switch ( QMessageBox::information( mainWindow(), i18n( "Check Accelerators" ), + i18n( "Accelerator '%1' is used once.", "Accelerator '%1' is used %n times.", (*it).count() + ).arg( it.key().upper() ), + i18n( "&Select" ), + i18n( "&Cancel" ), QString::null, 2 ) ) { + case 0: // select + clearSelection( FALSE ); + for ( wid = (*it).first(); wid; wid = (*it).next() ) + selectWidget( wid, TRUE ); + return; + case 1: // cancel + return; + } + } + } + + if ( ok ) + QMessageBox::information( mainWindow(), i18n( "Check Accelerators" ), + i18n( "No accelerator is used more than once." ) ); +} + +void FormWindow::raiseWidgets() +{ + QWidgetList widgets; + QPtrDictIterator<WidgetSelection> it( usedSelections ); + for ( ; it.current(); ++it ) + widgets.append( it.current()->widget() ); + + RaiseCommand *cmd = new RaiseCommand( i18n( "Raise" ), this, widgets ); + cmd->execute(); + commandHistory()->addCommand( cmd ); +} + +void FormWindow::paste( const QString &cb, QWidget *parent ) +{ + CHECK_MAINWINDOW; + Resource resource( mainWindow() ); + resource.setWidget( this ); + resource.paste( cb, parent ); +} + +void FormWindow::selectAll() +{ + checkedSelectionsForMove = FALSE; + blockSignals( TRUE ); + QObjectList *l = mainContainer()->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets[ (void*)o ] ) { + selectWidget( (QWidget*)o ); + } + } + delete l; + } + + blockSignals( FALSE ); + emitSelectionChanged(); + if ( propertyWidget ) + emitShowProperties( propertyWidget ); + emitSelectionChanged(); +} + +void FormWindow::layoutHorizontal() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand( i18n( "Lay Out Horizontally" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutVertical() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutVerticalCommand *cmd = new LayoutVerticalCommand( i18n( "Lay Out Vertically" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutHorizontalSplit() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutHorizontalSplitCommand *cmd = new LayoutHorizontalSplitCommand( i18n( "Lay Out Horizontally (in splitter)" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutVerticalSplit() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutVerticalSplitCommand *cmd = new LayoutVerticalSplitCommand( i18n( "Lay Out Vertically (in splitter)" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutGrid() +{ + int xres = grid().x(); + int yres = grid().y(); + + QWidgetList widgets( selectedWidgets() ); + LayoutGridCommand *cmd = new LayoutGridCommand( i18n( "Lay Out in a Grid" ), + this, mainContainer(), 0, widgets, xres, yres ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutHorizontalContainer( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children(); + if ( !l ) + return; + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand( i18n( "Lay Out Children Horizontally" ), + this, mainContainer(), w, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutVerticalContainer( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children(); + if ( !l ) + return; + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + LayoutVerticalCommand *cmd = new LayoutVerticalCommand( i18n( "Lay Out Children Vertically" ), + this, mainContainer(), w, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutGridContainer( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + int xres = grid().x(); + int yres = grid().y(); + + QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children(); + if ( !l ) + return; + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + LayoutGridCommand *cmd = new LayoutGridCommand( i18n( "Lay Out Children in a Grid" ), + this, mainContainer(), w, widgets, xres, yres ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::breakLayout( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + w = WidgetFactory::containerOfWidget( w ); + QPtrList<Command> commands; + + for (;;) { + if ( !w || w == this ) + break; + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout && + WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + Command *cmd = breakLayoutCommand( w ); + if ( cmd ) + commands.insert( 0, cmd ); + if ( !::qt_cast<QLayoutWidget*>(w) && !::qt_cast<QSplitter*>(w) ) + break; + } + w = w->parentWidget(); + } + + if ( commands.isEmpty() ) + return; + + clearSelection( FALSE ); + MacroCommand *cmd = new MacroCommand( i18n( "Break Layout" ), this, commands ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +BreakLayoutCommand *FormWindow::breakLayoutCommand( QWidget *w ) +{ + CHECK_MAINWINDOW_VALUE( 0 ); + QObjectList *l = (QObjectList*)w->children(); + if ( !l ) + return 0; + + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + !mainWindow()->isAToolBarChild( (QWidget*)o ) && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + return new BreakLayoutCommand( i18n( "Break Layout" ), this, WidgetFactory::widgetOfContainer( w ), widgets ); +} + +int FormWindow::numVisibleWidgets() const +{ + QPtrDictIterator<QWidget> it( insertedWidgets ); + int visible = 0; + for ( ; it.current(); ++it ) { + if ( it.current()->isVisibleTo( (FormWindow*)this ) ) + visible++; + } + return visible; +} + +bool FormWindow::hasInsertedChildren( QWidget *w ) const +{ + if ( !w ) + return FALSE; + w = WidgetFactory::containerOfWidget( w ); + if ( !w ) + return FALSE; + QObjectList *l = w->queryList( "QWidget" ); + if ( !l || !l->first() ) { + delete l; + return FALSE; + } + + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( (FormWindow*)this ) && + insertedWidgets.find( (QWidget*)o ) ) { + delete l; + return TRUE; + } + } + + delete l; + return FALSE; +} + +bool FormWindow::allowMove( QWidget *w ) +{ + w = w->parentWidget(); + while ( w ) { + if ( ( isMainContainer( w ) || insertedWidgets.find( w ) ) && WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) + return TRUE; + w = w->parentWidget(); + } + return FALSE; +} + + +void FormWindow::editConnections() +{ + CHECK_MAINWINDOW; + buffer = 0; + if ( !startWidget || !endWidget ) + return; + + ConnectionDialog dlg( mainwindow ); + mainWindow()->statusMessage( i18n( "Edit connections...") ); + dlg.addConnection( startWidget, endWidget, QString::null, QString::null ); + QTimer::singleShot( 0, &dlg, SLOT(ensureConnectionVisible()) ); + dlg.exec(); +} + +void FormWindow::saveBackground() +{ + if ( buffer ) + delete buffer; + buffer = new QPixmap( width(), height() ); + *buffer = QPixmap::grabWindow( winId() ); +} + +void FormWindow::restoreConnectionLine() +{ + if (!unclippedPainter || !buffer) // designer will occasionally crash if buffer is not tested to be non-zero + return; + + int a =QABS( startPos.x() - currentPos.x() ); + int b = QABS( startPos.y() - currentPos.y() ); + QRect r( startPos, currentPos ); + + if ( a < 32 || b < 32 ) { // special case: vertical or horizontal line + r = r.normalize(); + unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, + r.x() - 2, r.y() - 2, r.width() + 4, r.height() + 4 ); + return; + } + + if ( a <= 0 ) + a = 1; + if ( b <= 0 ) + b = 1; + int w, h; + if ( b > a ) { + h = 64; + w = ( a * h ) / b; + } else { + w = 64; + h = ( b * w ) / a; + } + + int dx = 2 * w / 3; + int dy = 2 * h / 3; + QPoint p( startPos ); + + if ( r.x() > r.right() ) { + dx = dx * -1; + p.setX( p.x() - 64 ); + r.moveBy( -64, 0 ); + } + if ( r.y() > r.bottom() ) { + dy = dy * -1; + p.setY( p.y() - 64 ); + r.moveBy( 0, -64 ); + } + + w = h = 64; + r = r.normalize(); + while ( r.contains( p ) ) { + unclippedPainter->drawPixmap( p, *buffer, QRect( p, QSize( w, h ) ) ); + unclippedPainter->setPen( red ); + p.setX( p.x() + dx ); + p.setY( p.y() + dy ); + } + + unclippedPainter->drawPixmap( startPos.x() - 10, startPos.y() - 10, *buffer, + startPos.x() - 10, startPos.y() - 10, 20, 20 ); +} + +void FormWindow::restoreRect( const QRect &rect ) +{ + if (!unclippedPainter || !buffer) + return; + + QRect r( rect ); + r = r.normalize(); + + r = QRect( r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4 ); + + unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, r.width() + 4, 4 ); + unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, 4, r.height() + 4 ); + unclippedPainter->drawPixmap( r.x() - 2, r.y() + r.height() - 3, *buffer, r.x() - 2, r.y() + r.height() - 3, r.width() + 4, 5 ); + unclippedPainter->drawPixmap( r.x() + r.width() - 2, r.y(), *buffer, r.x() + r.width() - 2, r.y(), 4, r.height() + 4 ); +} + +void FormWindow::drawConnectionLine() +{ + if ( !unclippedPainter ) + return; + + unclippedPainter->setPen( QPen( white, 2 ) ); + unclippedPainter->drawLine( startPos, currentPos ); + if ( validForBuddy ) + unclippedPainter->setPen( QPen( darkRed, 1 ) ); + else + unclippedPainter->setPen( QPen( darkCyan, 1 ) ); + unclippedPainter->drawLine( startPos, currentPos ); + + if ( validForBuddy ) + unclippedPainter->setPen( QPen( darkGreen, 1 ) ); + else + unclippedPainter->setPen( QPen( magenta, 1 ) ); + if ( startWidget ) { + QWidget *s = (QWidget*)startWidget; + QPoint p = mapToForm( s, QPoint(0,0) ); + unclippedPainter->drawRect( QRect( p + QPoint( 2, 2 ), s->size() - QSize( 4, 4 ) ) ); + } + if ( endWidget ) { + QWidget *e = (QWidget*)endWidget; + QPoint p = mapToForm( e, QPoint(0,0) ); + unclippedPainter->drawRect( QRect( p + QPoint( 2, 2 ), e->size() - QSize( 4, 4 ) ) ); + } +} + +QString FormWindow::fileName() const +{ + return ff->absFileName(); +} + +void FormWindow::setFileName( const QString &fn ) +{ + ff->setFileName( fn ); + emit fileNameChanged( ff->fileName(), this ); +} + +void FormWindow::modificationChanged( bool m ) +{ + emit modificationChanged( m, this ); + emit modificationChanged( m, ff->fileName() ); +} + +bool FormWindow::unify( QObject *w, QString &s, bool changeIt ) +{ + bool found = !isMainContainer( w ) && qstrcmp( name(), s.latin1() ) == 0; + if ( !found ) { + QString orig = s; + int num = 1; + QPtrDictIterator<QWidget> it( insertedWidgets ); + for ( ; it.current();) { + if ( it.current() != w && + qstrcmp( it.current()->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + it.toFirst(); + } else { + ++it; + } + } + if ( !found ) { + QPtrList<QAction> al; + QAction *a = 0; + for ( a = actions.first(); a; a = actions.next() ) { + QObjectList *l = a->queryList( "QAction" ); + al.append( a ); + for ( QObject *ao = l->first(); ao; ao = l->next() ) + al.append( (QAction*)ao ); + delete l; + } + for ( a = al.first(); a; a = al.next() ) { + if ( a != w && + qstrcmp( a->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + a = actions.first(); + } + } + } + if ( ::qt_cast<QMainWindow*>(mainContainer()) && !found ) { + QObjectList *l = mainContainer()->queryList( "PopupMenuEditor" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o != w && + qstrcmp ( o->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + o = l->first(); + } + } + delete l; + } + if ( ::qt_cast<QMainWindow*>(mainContainer()) ) { + if ( !found ) { + QObjectList *l = mainContainer()->queryList( "QDockWindow", 0, TRUE ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o != w && + qstrcmp( o->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + o = l->first(); + } + } + delete l; + } + } + } + + if ( !found ) + return TRUE; + return FALSE; +} + +bool FormWindow::isCustomWidgetUsed( MetaDataBase::CustomWidget *w ) +{ + QPtrDictIterator<QWidget> it( insertedWidgets ); + for ( ; it.current(); ++it ) { + if ( it.current()->isA( "CustomWidget" ) ) { + if ( qstrcmp( WidgetFactory::classNameOf( it.current() ), w->className.utf8() ) == 0 ) + return TRUE; + } + } + + return FALSE; +} + +bool FormWindow::isDatabaseWidgetUsed() const +{ +#ifndef QT_NO_SQL + QStringList dbClasses; + dbClasses << "QDataTable"; // add more here + QPtrDictIterator<QWidget> it( insertedWidgets ); + for ( ; it.current(); ++it ) { + QString c( it.current()->className() ); + if ( dbClasses.contains( c ) > 0 ) { + return TRUE; + } + } +#endif + return FALSE; +} + +bool FormWindow::isDatabaseAware() const +{ +#ifndef QT_NO_SQL + if ( QString(mContainer->className()) == "QDesignerDataBrowser" || QString(mContainer->className()) == "QDesignerDataView" ) + return TRUE; + return isDatabaseWidgetUsed(); +#else + return FALSE; +#endif +} + +void FormWindow::visibilityChanged() +{ + if ( currTool != ORDER_TOOL ) { + emitUpdateProperties( currentWidget() ); + } else { + updateOrderIndicators(); + repositionOrderIndicators(); + } +} + + +/*! + Maps \a pos in \a w's coordinates to the form's coordinate system. + + This is the equivalent to mapFromGlobal(w->mapToGlobal(pos) ) but + avoids the two roundtrips to the X-Server on Unix/X11. + */ +QPoint FormWindow::mapToForm( const QWidget* w, const QPoint& pos ) const +{ + QPoint p = pos; + const QWidget* i = w; + while ( i && !i->isTopLevel() && !isMainContainer( (QWidget*)i ) ) { + p = i->mapToParent( p ); + i = i->parentWidget(); + } + return mapFromGlobal( w->mapToGlobal( pos ) ); +} + +static int widgetDepth( QWidget *w ) +{ + int d = -1; + while ( w && !w->isTopLevel() ) { + d++; + w = w->parentWidget(); + } + + return d; +} + +static bool isChildOf( QWidget *c, QWidget *p ) +{ + while ( c && !c->isTopLevel() ) { + if ( c == p ) + return TRUE; + c = c->parentWidget(); + } + return FALSE; +} + +QWidget *FormWindow::containerAt( const QPoint &pos, QWidget *notParentOf ) +{ + QPtrDictIterator<QWidget> it( insertedWidgets ); + QWidget *container = 0; + int depth = -1; + QWidgetList selected = selectedWidgets(); + if ( rect().contains( mapFromGlobal( pos ) ) ) { + container = mainContainer(); + depth = widgetDepth( container ); + } + + for ( ; it.current(); ++it ) { + if ( ::qt_cast<QLayoutWidget*>(it.current()) + || ::qt_cast<QSplitter*>(it.current()) ) + continue; + if ( !it.current()->isVisibleTo( this ) ) + continue; + if ( selected.find( it.current() ) != -1 ) + continue; + if ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( it.current() ) ) ) && + it.current() != mainContainer() ) + continue; + + // the rectangles of all ancestors of the container must contain the insert position + QWidget *w = it.current(); + while ( w && !w->isTopLevel() ) { + if ( !w->rect().contains( ( w->mapFromGlobal( pos ) ) ) ) + break; + w = w->parentWidget(); + } + if ( !( w == 0 || w->isTopLevel() ) ) continue; // we did not get through the full while loop + + int wd = widgetDepth( it.current() ); + if ( wd == depth && container ) { + if ( ( (QObjectList*)it.current()->parentWidget()->children() )->find( it.current() ) > + ( (QObjectList*)container->parentWidget()->children() )->find( container ) ) + wd++; + } + if ( wd > depth && !isChildOf( it.current(), notParentOf ) ) { + depth = wd; + container = it.current(); + } + } + + return container; +} + +bool FormWindow::isMainContainer( QObject *w ) const +{ + return w && w->isWidgetType() && ( w == (QWidget*)this || w == mainContainer() ); +} + +void FormWindow::setMainContainer( QWidget *w ) +{ + bool resetPropertyWidget = isMainContainer( propertyWidget ); + if ( mContainer ) + insertedWidgets.remove( mContainer ); + if ( propertyWidget == mContainer ) + propertyWidget = 0; + delete mContainer; + mContainer = w; + insertedWidgets.insert( mContainer, mContainer ); + delete layout(); + QHBoxLayout *l = new QHBoxLayout( this ); + l->addWidget( w ); + if ( resetPropertyWidget ) { + QObject *opw = propertyWidget; + propertyWidget = mContainer; + if ( opw && opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } + if ( project() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( project()->language() ); + if ( iface && !project()->isCpp() && !isFake() ) { + if ( !MetaDataBase::hasFunction( this, "init()" ) ) + MetaDataBase::addFunction( this, "init()", "", "private", "function", + project()->language(), "void" ); + if ( !MetaDataBase::hasFunction( this, "destroy()" ) ) + MetaDataBase::addFunction( this, "destroy()", "", "private", "function", + project()->language(), "void" ); + if ( !MetaDataBase::hasConnection( this, mainContainer(), "shown()", mainContainer(), "init" ) ) + MetaDataBase::addConnection( this, mainContainer(), "shown()", mainContainer(), "init" ); + if ( !MetaDataBase::hasConnection( this, mainContainer(), "destroyed()", mainContainer(), "destroy" ) ) + MetaDataBase::addConnection( this, mainContainer(), "destroyed()", + mainContainer(), "destroy" ); + } + } +} + +bool FormWindow::savePixmapInline() const +{ + return pixInline; +} + +bool FormWindow::savePixmapInProject() const +{ + return pixProject; +} + +QString FormWindow::pixmapLoaderFunction() const +{ + return pixLoader; +} + +void FormWindow::setSavePixmapInline( bool b ) +{ + pixInline = b; + if ( b ) + pixProject = FALSE; +} + +void FormWindow::setSavePixmapInProject( bool b ) +{ + pixProject = b; + if ( b ) + pixInline = FALSE; +} + +void FormWindow::setPixmapLoaderFunction( const QString &func ) +{ + pixLoader = func; +} + +void FormWindow::setActiveObject( QObject *o ) +{ + emitShowProperties( o ); + propertyWidget = o; +} + +void FormWindow::setProject( Project *pro ) +{ + proj = pro; +} + +Project *FormWindow::project() const +{ + return proj; +} + +QAction *FormWindow::findAction( const QString &name ) +{ + for ( QAction *a = actionList().first(); a; a = actionList().next() ) { + if ( QString( a->name() ) == name ) + return a; + QAction *ac = (QAction*)a->child( name.latin1(), "QAction" ); + if ( ac ) + return ac; + } + return 0; +} + +void FormWindow::killAccels( QObject *top ) +{ + QObjectList *l = top->queryList( "QAccel" ); + if ( !l ) + return; + for ( QObject *o = l->first(); o; o = l->next() ) + ( (QAccel*)o )->setEnabled( FALSE ); + delete l; +} + +DesignerFormWindow *FormWindow::iFace() +{ + if ( !iface ) + iface = new DesignerFormWindowImpl( this ); + return iface; +} + +bool FormWindow::isCentralWidget( QObject *w ) const +{ + if ( !::qt_cast<QMainWindow*>(mainContainer()) ) + return FALSE; + return w == ( (QMainWindow*)mainContainer() )->centralWidget(); +} + +int FormWindow::layoutDefaultSpacing() const +{ + return defSpacing; +} + +int FormWindow::layoutDefaultMargin() const +{ + return defMargin; +} + +void FormWindow::setLayoutDefaultSpacing( int s ) +{ + defSpacing = s; +} + +void FormWindow::setLayoutDefaultMargin( int s ) +{ + defMargin = s; +} + +void FormWindow::setSpacingFunction( const QString &funct ) +{ + spacFunction = funct; +} + +QString FormWindow::spacingFunction() const +{ + return spacFunction; +} + +void FormWindow::hasLayoutFunctions( bool b ) +{ + hasLayoutFunc = b; +} + +bool FormWindow::hasLayoutFunctions() const +{ + return hasLayoutFunc; +} + +void FormWindow::setMarginFunction( const QString &funct ) +{ + margFunction = funct; +} + +QString FormWindow::marginFunction() const +{ + return margFunction; +} + +FormFile *FormWindow::formFile() const +{ + return ff; +} + +void FormWindow::setFormFile( FormFile *f ) +{ + ff = f; + if ( ff ) + connect( this, SIGNAL( modificationChanged(bool, const QString&) ), ff, SLOT( formWindowChangedSomehow() ) ); +} + +bool FormWindow::canBeBuddy( const QWidget *w ) const +{ + return w->focusPolicy() != QWidget::NoFocus; +} + +bool FormWindow::event( QEvent *e ) +{ + if (e->type() == QEvent::ShowMaximized) + { +#if QT_VERSION >= 0x030300 + if ( isMaximized() ) + setWindowState( windowState() & ~WindowMaximized | WindowActive); +#endif + return true; + } + return QWidget::event(e); +} diff --git a/kdevdesigner/designer/formwindow.h b/kdevdesigner/designer/formwindow.h new file mode 100644 index 00000000..782a26c3 --- /dev/null +++ b/kdevdesigner/designer/formwindow.h @@ -0,0 +1,322 @@ +/********************************************************************** +** 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 FORMWINDOW_H +#define FORMWINDOW_H + +#include "command.h" +#include "metadatabase.h" +#include "sizehandle.h" +#include "actiondnd.h" + +#include <qwidget.h> +#include <qptrdict.h> +#include <qpixmap.h> +#include <qwidgetlist.h> +#include <qmap.h> + +class QPaintEvent; +class QMouseEvent; +class QKeyEvent; +class QPainter; +class QLabel; +class MainWindow; +class QTimer; +class QFocusEvent; +class QCloseEvent; +class Resource; +class QResizeEvent; +class BreakLayoutCommand; +class QPixmap; +class QSizeGrip; +class Project; +struct DesignerFormWindow; +class FormFile; + +#if defined(Q_CC_MSVC) || defined(Q_FULL_TEMPLATE_INSTANTIATION) +#include "orderindicator.h" +#else +class OrderIndicator; +#endif + +class FormWindow : public QWidget +{ + Q_OBJECT + Q_PROPERTY( QString fileName READ fileName WRITE setFileName ) + +public: + FormWindow( FormFile *f, MainWindow *mw, QWidget *parent, const char *name = 0 ); + FormWindow( FormFile *f, QWidget *parent, const char *name = 0 ); + ~FormWindow(); + + void init(); + virtual void setMainWindow( MainWindow *w ); + + virtual QString fileName() const; + virtual void setFileName( const QString &fn ); + + virtual QPoint grid() const; + virtual QPoint gridPoint( const QPoint &p ); + + virtual CommandHistory *commandHistory(); + + virtual void undo(); + virtual void redo(); + virtual QString copy(); + virtual void paste( const QString &cb, QWidget *parent ); + virtual void lowerWidgets(); + virtual void raiseWidgets(); + virtual void checkAccels(); + + virtual void layoutHorizontal(); + virtual void layoutVertical(); + virtual void layoutHorizontalSplit(); + virtual void layoutVerticalSplit(); + virtual void layoutGrid(); + + virtual void layoutHorizontalContainer( QWidget *w ); + virtual void layoutVerticalContainer( QWidget *w ); + virtual void layoutGridContainer( QWidget *w ); + + virtual void breakLayout( QWidget *w ); + + virtual void selectWidget( QObject *w, bool select = TRUE ); + virtual void selectAll(); + virtual void updateSelection( QWidget *w ); + virtual void raiseSelection( QWidget *w ); + virtual void repaintSelection( QWidget *w ); + virtual void clearSelection( bool changePropertyDisplay = TRUE ); + virtual void selectWidgets(); + bool isWidgetSelected( QObject *w ); + virtual void updateChildSelections( QWidget *w ); + virtual void raiseChildSelections( QWidget *w ); + + virtual void emitUpdateProperties( QObject *w ); + virtual void emitShowProperties( QObject *w = 0 ); + virtual void emitSelectionChanged(); + + virtual void setPropertyShowingBlocked( bool b ); + bool isPropertyShowingBlocked() const; + + virtual QLabel *sizePreview() const; + virtual void checkPreviewGeometry( QRect &r ); + + virtual QPtrDict<QWidget> *widgets(); + virtual QWidgetList selectedWidgets() const; + + virtual QWidget *designerWidget( QObject *o ) const; + + virtual void handleContextMenu( QContextMenuEvent *e, QWidget *w ); + virtual void handleMousePress( QMouseEvent *e, QWidget *w ); + virtual void handleMouseRelease( QMouseEvent *e, QWidget *w ); + virtual void handleMouseDblClick( QMouseEvent *e, QWidget *w ); + virtual void handleMouseMove( QMouseEvent *e, QWidget *w ); + virtual void handleKeyPress( QKeyEvent *e, QWidget *w ); + virtual void handleKeyRelease( QKeyEvent *e, QWidget *w ); + + virtual void updateUndoInfo(); + + virtual MainWindow *mainWindow() const { return mainwindow; } + + bool checkCustomWidgets(); + virtual void insertWidget( QWidget *w, bool checkName = FALSE ); + virtual void removeWidget( QWidget *w ); + virtual void deleteWidgets(); + virtual void editAdjustSize(); + virtual void editConnections(); + + virtual int numSelectedWidgets() const; + virtual int numVisibleWidgets() const; + + virtual bool hasInsertedChildren( QWidget *w ) const; + + virtual QWidget *currentWidget() const { return propertyWidget && propertyWidget->isWidgetType() ? (QWidget*)propertyWidget : 0; } // ##### + virtual bool unify( QObject *w, QString &s, bool changeIt ); + + virtual bool isCustomWidgetUsed( MetaDataBase::CustomWidget *w ); + virtual bool isDatabaseWidgetUsed() const; + virtual bool isDatabaseAware() const; + + virtual QPoint mapToForm( const QWidget* w, const QPoint& ) const; + + bool isMainContainer( QObject *w ) const; + bool isCentralWidget( QObject *w ) const; + QWidget *mainContainer() const { return mContainer; } + void setMainContainer( QWidget *w ); + + void paintGrid( QWidget *w, QPaintEvent *e ); + + bool savePixmapInline() const; + QString pixmapLoaderFunction() const; + void setSavePixmapInline( bool b ); + void setPixmapLoaderFunction( const QString &func ); + + bool savePixmapInProject() const; + void setSavePixmapInProject( bool b ); + + void setToolFixed() { toolFixed = TRUE; } + + void setActiveObject( QObject *o ); + + QPtrList<QAction> &actionList() { return actions; } + QAction *findAction( const QString &name ); + + void setProject( Project *pro ); + Project *project() const; + + void killAccels( QObject *top ); + + DesignerFormWindow *iFace(); + + int layoutDefaultSpacing() const; + int layoutDefaultMargin() const; + void setLayoutDefaultSpacing( int s ); + void setLayoutDefaultMargin( int s ); + QString spacingFunction() const; + QString marginFunction() const; + void setSpacingFunction( const QString &func ); + void setMarginFunction( const QString &func ); + bool hasLayoutFunctions() const; + void hasLayoutFunctions( bool b ); + + void initSlots(); + FormFile *formFile() const; + void setFormFile( FormFile *f ); + + bool isFake() const { return fake; } + bool canBeBuddy( const QWidget* ) const; + +public slots: + virtual void widgetChanged( QObject *w ); + virtual void currentToolChanged(); + virtual void visibilityChanged(); + virtual void modificationChanged( bool m ); + +signals: + void showProperties( QObject *w ); + void updateProperties( QObject *w ); + void undoRedoChanged( bool undoAvailable, bool redoAvailable, + const QString &undoCmd, const QString &redoCmd ); + void selectionChanged(); + void modificationChanged( bool m, FormWindow *fw ); + void modificationChanged( bool m, const QString &s ); + void fileNameChanged( const QString &s, FormWindow *fw ); + +protected: + virtual void closeEvent( QCloseEvent *e ); + virtual void focusInEvent( QFocusEvent *e ); + virtual void focusOutEvent( QFocusEvent *e ); + virtual void resizeEvent( QResizeEvent *e ); + void mouseDoubleClickEvent( QMouseEvent *e ) { handleMouseDblClick( e, mainContainer() ); } + virtual bool event( QEvent *e ); + +private: + enum RectType { Insert, Rubber }; + + void beginUnclippedPainter( bool doNot ); + void endUnclippedPainter(); + void drawConnectionLine(); + void drawSizePreview( const QPoint &pos, const QString& text ); + + void insertWidget(); + void moveSelectedWidgets( int dx, int dy ); + + void startRectDraw( const QPoint &p, const QPoint &global, QWidget *w, RectType t ); + void continueRectDraw( const QPoint &p, const QPoint &global, QWidget *w, RectType t ); + void endRectDraw(); + + void checkSelectionsForMove( QWidget *w ); + BreakLayoutCommand *breakLayoutCommand( QWidget *w ); + + bool allowMove( QWidget *w ); + + void saveBackground(); + void restoreConnectionLine(); + void restoreRect( const QRect &rect ) ; + + void showOrderIndicators(); + void updateOrderIndicators(); + void repositionOrderIndicators(); + void hideOrderIndicators(); + + QWidget *containerAt( const QPoint &pos, QWidget *notParentOf ); + +private slots: + void invalidCheckedSelections(); + void updatePropertiesTimerDone(); + void showPropertiesTimerDone(); + void selectionChangedTimerDone(); + void windowsRepaintWorkaroundTimerTimeout(); + +private: + int currTool; + bool oldRectValid, widgetPressed, drawRubber, checkedSelectionsForMove; + bool validForBuddy; + QRect currRect; + QPoint rectAnchor; + QPainter *unclippedPainter; + QPoint sizePreviewPos; + QPixmap sizePreviewPixmap; + MainWindow *mainwindow; + QPtrList<WidgetSelection> selections; + QPtrDict<WidgetSelection> usedSelections; + QRect widgetGeom, rubber; + QPoint oldPressPos, origPressPos; + CommandHistory commands; + QMap<QWidget*, QPoint> moving; + QWidget *insertParent; + QObject *propertyWidget; + QLabel *sizePreviewLabel; + QTimer *checkSelectionsTimer; + QPtrDict<QWidget> insertedWidgets; + bool propShowBlocked; + QTimer* updatePropertiesTimer, *showPropertiesTimer, *selectionChangedTimer, + *windowsRepaintWorkaroundTimer; + QPoint startPos, currentPos; + QWidget *startWidget, *endWidget; + QPixmap *buffer; + QPtrList<OrderIndicator> orderIndicators; + QWidgetList orderedWidgets; + QWidgetList stackedWidgets; + QWidget *mContainer; + bool pixInline, pixProject; + QString pixLoader; + bool toolFixed; + QPtrList<QAction> actions; + Project *proj; + DesignerFormWindow *iface; + QWidget* targetContainer; + QPalette restorePalette; + bool hadOwnPalette; + int defSpacing, defMargin; + QString spacFunction, margFunction; + bool hasLayoutFunc; + FormFile *ff; + bool fake; + +}; + +#endif diff --git a/kdevdesigner/designer/gotolinedialog.ui b/kdevdesigner/designer/gotolinedialog.ui new file mode 100644 index 00000000..f2acf011 --- /dev/null +++ b/kdevdesigner/designer/gotolinedialog.ui @@ -0,0 +1,169 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>GotoLineDialog</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<include location="local" impldecl="in implementation">../interfaces/editorinterface.h</include> +<include location="local" implDecl="in declaration">gotolinedialog.ui.h</include> +<forward>struct EditorInterface;</forward> +<variable>EditorInterface *editor;</variable> +<layoutdefaults spacing="6" margin="11"/> +<widget class="QDialog"> + <property name="name"> + <cstring>GotoLineDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>243</width> + <height>85</height> + </rect> + </property> + <property name="caption"> + <string>Goto Line</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Line:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinLine</cstring> + </property> + </widget> + <widget class="QSpinBox" row="0" column="1"> + <property name="name"> + <cstring>spinLine</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Goto</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </hbox> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection language="C++"> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>GotoLineDialog</receiver> + <slot>reject()</slot> + </connection> + <connection language="C++"> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>GotoLineDialog</receiver> + <slot>gotoLine()</slot> + </connection> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> + <slot access="public" language="C++" returnType="void">gotoLine()</slot> + <slot access="public" language="C++" returnType="void">setEditor( EditorInterface * e )</slot> +</connections> +</UI> diff --git a/kdevdesigner/designer/gotolinedialog.ui.h b/kdevdesigner/designer/gotolinedialog.ui.h new file mode 100644 index 00000000..9ee0ef39 --- /dev/null +++ b/kdevdesigner/designer/gotolinedialog.ui.h @@ -0,0 +1,50 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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. +** +**********************************************************************/ + +void GotoLineDialog::init() +{ + editor = 0; +} + +void GotoLineDialog::destroy() +{ + if ( editor ) + editor->release(); +} + +void GotoLineDialog::gotoLine() +{ + if ( editor ) + editor->gotoLine( spinLine->value() - 1 ); + accept(); +} + +void GotoLineDialog::setEditor( EditorInterface *e ) +{ + editor = e; + editor->addRef(); +} + diff --git a/kdevdesigner/designer/hierarchyview.cpp b/kdevdesigner/designer/hierarchyview.cpp new file mode 100644 index 00000000..8c204ac3 --- /dev/null +++ b/kdevdesigner/designer/hierarchyview.cpp @@ -0,0 +1,1508 @@ +/********************************************************************** +** 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. +** +** 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 "hierarchyview.h" +#include "formwindow.h" +#include "globaldefs.h" +#include "mainwindow.h" +#include "command.h" +#include "widgetfactory.h" +#include "widgetdatabase.h" +#include "project.h" +#include "sourceeditor.h" +#include "propertyeditor.h" +#include "editfunctionsimpl.h" +#include "listeditor.h" +#include "actiondnd.h" +#include "actioneditorimpl.h" +#include "variabledialogimpl.h" +#include "popupmenueditor.h" +#include "menubareditor.h" + +#include <kiconloader.h> +#include "kdevdesigner_part.h" +#include <klocale.h> + +#include <qpalette.h> +#include <qobjectlist.h> +#include <qheader.h> +#include <qpopupmenu.h> +#include <qtabwidget.h> +#include <qwizard.h> +#include <qwidgetstack.h> +#include <qtabbar.h> +#include <qfeatures.h> +#include <qapplication.h> +#include <qtimer.h> +#include "../interfaces/languageinterface.h" +#include <qworkspace.h> +#include <qaccel.h> +#include <qmessagebox.h> + +#include <stdlib.h> + +QListViewItem *newItem = 0; + +static QPluginManager<ClassBrowserInterface> *classBrowserInterfaceManager = 0; + +HierarchyItem::HierarchyItem( Type type, QListViewItem *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ) + : QListViewItem( parent, after, txt1, txt2, txt3 ), typ( type ) +{ +} + +HierarchyItem::HierarchyItem( Type type, QListView *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ) + : QListViewItem( parent, after, txt1, txt2, txt3 ), typ( type ) +{ +} + +void HierarchyItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + g.setColor( QColorGroup::Foreground, Qt::black ); + g.setColor( QColorGroup::Text, Qt::black ); + QString txt = text( 0 ); + if ( rtti() == Function && + MainWindow::self->currProject()->isCpp() && + ( txt == "init()" || txt == "destroy()" ) ) { + listView()->setUpdatesEnabled( FALSE ); + if ( txt == "init()" ) + setText( 0, txt + " " + "(Constructor)" ); + else + setText( 0, txt + " " + "(Destructor)" ); + QListViewItem::paintCell( p, g, column, width, align ); + setText( 0, txt ); + listView()->setUpdatesEnabled( TRUE ); + } else { + QListViewItem::paintCell( p, g, column, width, align ); + } + p->save(); + p->setPen( QPen( cg.dark(), 1 ) ); + if ( column == 0 ) + p->drawLine( 0, 0, 0, height() - 1 ); + if ( listView()->firstChild() != this ) { + if ( nextSibling() != itemBelow() && itemBelow()->depth() < depth() ) { + int d = depth() - itemBelow()->depth(); + p->drawLine( -listView()->treeStepSize() * d, height() - 1, 0, height() - 1 ); + } + } + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); +} + +QColor HierarchyItem::backgroundColor() +{ + updateBackColor(); + return backColor; +} + +void HierarchyItem::updateBackColor() +{ + if ( listView()->firstChild() == this ) { + backColor = *backColor1; + return; + } + + QListViewItemIterator it( this ); + --it; + if ( it.current() ) { + if ( ( ( HierarchyItem*)it.current() )->backColor == *backColor1 ) + backColor = *backColor2; + else + backColor = *backColor1; + } else { + backColor = *backColor1; + } +} + +void HierarchyItem::setObject( QObject *o ) +{ + obj = o; +} + +QObject *HierarchyItem::object() const +{ + return obj; +} + +void HierarchyItem::okRename( int col ) +{ + if ( newItem == this ) + newItem = 0; + QListViewItem::okRename( col ); +} + +void HierarchyItem::cancelRename( int col ) +{ + if ( newItem == this ) { + newItem = 0; + QListViewItem::cancelRename( col ); + delete this; + return; + } + QListViewItem::cancelRename( col ); +} + + + + +HierarchyList::HierarchyList( QWidget *parent, FormWindow *fw, bool doConnects ) + : QListView( parent ), formWindow( fw ) +{ + DesignerFormPix = SmallIcon( "designer_form.png" , KDevDesignerPartFactory::instance()); + DesignerLayoutPix = SmallIcon( "designer_layout.png" , KDevDesignerPartFactory::instance()); + DesignerFolderPix = SmallIcon( "designer_folder.png" , KDevDesignerPartFactory::instance()); + DesignerEditSlotsPix = SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()); + + init_colors(); + + setDefaultRenameAction( Accept ); + header()->setMovingEnabled( FALSE ); + header()->setStretchEnabled( TRUE ); + normalMenu = 0; + tabWidgetMenu = 0; + addColumn( i18n( "Name" ) ); + addColumn( i18n( "Class" ) ); + QPalette p( palette() ); + p.setColor( QColorGroup::Base, QColor( *backColor2 ) ); + (void)*selectedBack; // hack + setPalette( p ); + disconnect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( changeSortColumn( int ) ) ); + setSorting( -1 ); + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + if ( doConnects ) { + connect( this, SIGNAL( clicked( QListViewItem * ) ), + this, SLOT( objectClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( objectDoubleClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( returnPressed( QListViewItem * ) ), + this, SLOT( objectClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint&, int ) ), + this, SLOT( showRMBMenu( QListViewItem *, const QPoint & ) ) ); + } + deselect = TRUE; + setColumnWidthMode( 1, Manual ); +} + +void HierarchyList::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Shift || e->key() == Key_Control ) + deselect = FALSE; + else + deselect = TRUE; + QListView::keyPressEvent( e ); +} + +void HierarchyList::keyReleaseEvent( QKeyEvent *e ) +{ + deselect = TRUE; + QListView::keyReleaseEvent( e ); +} + +void HierarchyList::viewportMousePressEvent( QMouseEvent *e ) +{ + if ( e->state() & ShiftButton || e->state() & ControlButton ) + deselect = FALSE; + else + deselect = TRUE; + QListView::viewportMousePressEvent( e ); +} + +void HierarchyList::viewportMouseReleaseEvent( QMouseEvent *e ) +{ + QListView::viewportMouseReleaseEvent( e ); +} + +QObject *HierarchyList::handleObjectClick( QListViewItem *i ) +{ + if ( !i ) + return 0; + + QObject *o = findObject( i ); + if ( !o ) + return 0; + if ( formWindow == o ) { + if ( deselect ) + formWindow->clearSelection( FALSE ); + formWindow->emitShowProperties( formWindow ); + return 0; + } + if ( o->isWidgetType() ) { + QWidget *w = (QWidget*)o; + if ( !formWindow->widgets()->find( w ) ) { + if ( ::qt_cast<QWidgetStack*>(w->parent()) ) { + if (::qt_cast<QTabWidget*>(w->parent()->parent()) ) { + ((QTabWidget*)w->parent()->parent())->showPage( w ); + o = (QWidget*)w->parent()->parent(); + formWindow->emitUpdateProperties( formWindow->currentWidget() ); + } else if ( ::qt_cast<QWizard*>(w->parent()->parent()) ) { + ((QDesignerWizard*)w->parent()->parent())-> + setCurrentPage( ( (QDesignerWizard*)w->parent()->parent() )->pageNum( w ) ); + o = (QWidget*)w->parent()->parent(); + formWindow->emitUpdateProperties( formWindow->currentWidget() ); + } else { + ( (QWidgetStack*)w->parent() )->raiseWidget( w ); + if ( (QWidgetStack*)w->parent()->isA( "QDesignerWidgetStack" ) ) + ( (QDesignerWidgetStack*)w->parent() )->updateButtons(); + } + } else if ( ::qt_cast<QMenuBar*>(w) || ::qt_cast<QDockWindow*>(w) ) { + formWindow->setActiveObject( w ); + } else if ( ::qt_cast<QPopupMenu*>(w) ) { + return 0; // ### we could try to find our menu bar and change the currentMenu to our index + } else { + return 0; + } + } + } else if ( ::qt_cast<QAction*>(o) ) { + MainWindow::self->actioneditor()->setCurrentAction( (QAction*)o ); + deselect = TRUE; + } + + if ( deselect ) + formWindow->clearSelection( FALSE ); + + return o; +} + + +void HierarchyList::objectDoubleClicked( QListViewItem *i ) +{ + QObject *o = handleObjectClick( i ); + if ( !o ) + return; + if ( o->isWidgetType() && ( (QWidget*)o )->isVisibleTo( formWindow ) ) { + QWidget *w = (QWidget*)o; + if ( !w->parentWidget() || + WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) + w->raise(); + formWindow->selectWidget( w, TRUE ); + } +} + +void HierarchyList::objectClicked( QListViewItem *i ) +{ + QObject *o = handleObjectClick( i ); + if ( !o ) + return; + if ( o->isWidgetType() && ( (QWidget*)o )->isVisibleTo( formWindow ) ) { + QWidget *w = (QWidget*)o; + formWindow->selectWidget( w, TRUE ); + } +} + +QObject *HierarchyList::findObject( QListViewItem *i ) +{ + return ( (HierarchyItem*)i )->object(); +} + +QListViewItem *HierarchyList::findItem( QObject *o ) +{ + QListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (HierarchyItem*)it.current() )->object() == o ) + return it.current(); + ++it; + } + return 0; +} + +QObject *HierarchyList::current() const +{ + if ( currentItem() ) + return ( (HierarchyItem*)currentItem() )->object(); + return 0; +} + +void HierarchyList::changeNameOf( QObject *o, const QString &name ) +{ + QListViewItem *item = findItem( o ); + if ( !item ) + return; + item->setText( 0, name ); +} + + +void HierarchyList::changeDatabaseOf( QObject *o, const QString &info ) +{ +#ifndef QT_NO_SQL + if ( !formWindow->isDatabaseAware() ) + return; + QListViewItem *item = findItem( o ); + if ( !item ) + return; + item->setText( 2, info ); +#endif +} + +static QPtrList<QWidgetStack> *widgetStacks = 0; + +void HierarchyList::setup() +{ + if ( !formWindow || formWindow->isFake() ) + return; + clear(); + QWidget *w = formWindow->mainContainer(); +#ifndef QT_NO_SQL + if ( formWindow->isDatabaseAware() ) { + if ( columns() == 2 ) { + addColumn( i18n( "Database" ) ); + header()->resizeSection( 0, 1 ); + header()->resizeSection( 1, 1 ); + header()->resizeSection( 2, 1 ); + header()->adjustHeaderSize(); + } + } else { + if ( columns() == 3 ) { + removeColumn( 2 ); + } + } +#endif + if ( !widgetStacks ) + widgetStacks = new QPtrList<QWidgetStack>; + if ( w ) + insertObject( w, 0 ); + widgetStacks->clear(); +} + +void HierarchyList::setOpen( QListViewItem *i, bool b ) +{ + QListView::setOpen( i, b ); +} + +void HierarchyList::insertObject( QObject *o, QListViewItem *parent ) +{ + if ( QString( o->name() ).startsWith( "qt_dead_widget_" ) ) + return; + bool fakeMainWindow = FALSE; + if ( ::qt_cast<QMainWindow*>(o) ) { + QObject *cw = ( (QMainWindow*)o )->centralWidget(); + if ( cw ) { + o = cw; + fakeMainWindow = TRUE; + } + } + QListViewItem *item = 0; + QString className = WidgetFactory::classNameOf( o ); + if ( ::qt_cast<QLayoutWidget*>(o) ) { + switch ( WidgetFactory::layoutType( (QWidget*)o ) ) { + case WidgetFactory::HBox: + className = "HBox"; + break; + case WidgetFactory::VBox: + className = "VBox"; + break; + case WidgetFactory::Grid: + className = "Grid"; + break; + default: + break; + } + } + + QString dbInfo; +#ifndef QT_NO_SQL + dbInfo = MetaDataBase::fakeProperty( o, "database" ).toStringList().join("."); +#endif + + QString name = o->name(); + if ( ::qt_cast<QWidgetStack*>(o->parent()) ) { + if ( ::qt_cast<QTabWidget*>(o->parent()->parent()) ) + name = ( (QTabWidget*)o->parent()->parent() )->tabLabel( (QWidget*)o ); + else if ( ::qt_cast<QWizard*>(o->parent()->parent()) ) + name = ( (QWizard*)o->parent()->parent() )->title( (QWidget*)o ); + } + + QToolBox *tb; + if ( o->parent() && o->parent()->parent() && + (tb = ::qt_cast<QToolBox*>(o->parent()->parent()->parent())) ) + name = tb->itemLabel( tb->indexOf((QWidget*)o) ); + + if ( fakeMainWindow ) { + name = o->parent()->name(); + className = "QMainWindow"; + } + + if ( !parent ) + item = new HierarchyItem( HierarchyItem::Widget, this, 0, name, className, dbInfo ); + else + item = new HierarchyItem( HierarchyItem::Widget, parent, 0, name, className, dbInfo ); + item->setOpen( TRUE ); + if ( !parent ) + item->setPixmap( 0, DesignerFormPix ); + else if ( ::qt_cast<QLayoutWidget*>(o) ) + item->setPixmap( 0, DesignerLayoutPix ); + else + item->setPixmap( 0, WidgetDatabase::iconSet( + WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( o ) ) ). + pixmap( QIconSet::Small, QIconSet::Normal ) ); + if ( ::qt_cast<QAction*>(o) ) + item->setPixmap( 0, ( (QAction*)o )->iconSet().pixmap() ); + + ( (HierarchyItem*)item )->setObject( o ); + const QObjectList *l = o->children(); + if ( ::qt_cast<QDesignerToolBar*>(o) ) + l = 0; + if ( l ) { + QObjectListIt it( *l ); + it.toLast(); + for ( ; it.current(); --it ) { + if ( !it.current()->isWidgetType() || + ( (QWidget*)it.current() )->isHidden() ) + continue; + if ( !formWindow->widgets()->find( (QWidget*)it.current() ) ) { + if ( ::qt_cast<QWidgetStack*>(it.current()->parent()) || + ::qt_cast<QWidgetStack*>(it.current()) ) { + QObject *obj = it.current(); + QDesignerTabWidget *tw = ::qt_cast<QDesignerTabWidget*>(it.current()->parent()); + QDesignerWizard *dw = ::qt_cast<QDesignerWizard*>(it.current()->parent()); + QWidgetStack *stack = 0; + if ( dw || tw || ::qt_cast<QWidgetStack*>(obj) ) + stack = (QWidgetStack*)obj; + else + stack = (QWidgetStack*)obj->parent(); + if ( widgetStacks->findRef( stack ) != -1 ) + continue; + widgetStacks->append( stack ); + QObjectList *l2 = stack->queryList( "QWidget", 0, TRUE, FALSE ); + for ( obj = l2->last(); obj; obj = l2->prev() ) { + if ( qstrcmp( obj->className(), + "QWidgetStackPrivate::Invisible" ) == 0 || + ( tw && !tw->tabBar()->tab( stack->id( (QWidget*)obj ) ) ) || + ( dw && dw->isPageRemoved( (QWidget*)obj ) ) ) + continue; + if ( qstrcmp( obj->name(), "designer_wizardstack_button" ) == 0 ) + continue; + if ( stack->id( (QWidget*)obj ) == -1 ) + continue; + insertObject( obj, item ); + } + delete l2; + } else if ( ::qt_cast<QToolBox*>(it.current()->parent()) ) { + if ( !::qt_cast<QScrollView*>(it.current()) ) + continue; + QToolBox *tb = (QToolBox*)it.current()->parent(); + for ( int i = tb->count() - 1; i >= 0; --i ) + insertObject( tb->item( i ), item ); + } + continue; + } + insertObject( it.current(), item ); + } + } + + if ( fakeMainWindow ) { + QObjectList *l = o->parent()->queryList( "QDesignerToolBar" ); + QObject *obj; + for ( obj = l->first(); obj; obj = l->next() ) + insertObject( obj, item ); + delete l; + l = o->parent()->queryList( "MenuBarEditor" ); + for ( obj = l->first(); obj; obj = l->next() ) + insertObject( obj, item ); + delete l; + } else if ( ::qt_cast<QDesignerToolBar*>(o) || ::qt_cast<PopupMenuEditor*>(o) ) { + QPtrList<QAction> actions; + if ( ::qt_cast<QDesignerToolBar*>(o) ) + actions = ( (QDesignerToolBar*)o )->insertedActions(); + else + ( (PopupMenuEditor*)o )->insertedActions( actions ); + + QPtrListIterator<QAction> it( actions ); + it.toLast(); + while ( it.current() ) { + QAction *a = it.current(); + if ( ::qt_cast<QDesignerAction*>(a) ) { + QDesignerAction *da = (QDesignerAction*)a; + if ( da->supportsMenu() ) + insertObject( da, item ); + else + insertObject( da->widget(), item ); + } else if ( ::qt_cast<QDesignerActionGroup*>(a) ) { + insertObject( a, item ); + } + --it; + } + } else if ( ::qt_cast<QDesignerActionGroup*>(o) && o->children() ) { + QObjectList *l = (QObjectList*)o->children(); + for ( QObject *obj = l->last(); obj; obj = l->prev() ) { + if ( ::qt_cast<QDesignerAction*>(obj) ) { + QDesignerAction *da = (QDesignerAction*)obj; + if ( da->supportsMenu() ) + insertObject( da, item ); + else + insertObject( da->widget(), item ); + } else if ( ::qt_cast<QDesignerActionGroup*>(obj) ) { + insertObject( obj, item ); + } + } + } else if ( ::qt_cast<MenuBarEditor*>(o) ) { + MenuBarEditor *mb = (MenuBarEditor*)o; + for ( int i = mb->count() -1; i >= 0; --i ) { + MenuBarEditorItem *md = mb->item( i ); + if ( !md || !md->menu() ) + continue; + insertObject( md->menu(), item ); + } + } +} + +void HierarchyList::setCurrent( QObject *o ) +{ + QListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (HierarchyItem*)it.current() )->object() == o ) { + blockSignals( TRUE ); + setCurrentItem( it.current() ); + ensureItemVisible( it.current() ); + blockSignals( FALSE ); + return; + } + ++it; + } +} + +void HierarchyList::showRMBMenu( QListViewItem *i, const QPoint & p ) +{ + if ( !i ) + return; + + QObject *o = findObject( i ); + if ( !o ) + return; + + if ( !o->isWidgetType() || + ( o != formWindow && !formWindow->widgets()->find( (QWidget*)o ) ) ) + return; + + QWidget *w = (QWidget*)o; + if ( w->isVisibleTo( formWindow ) ) { + if ( !::qt_cast<QTabWidget*>(w) && !::qt_cast<QWizard*>(w) ) { + if ( !normalMenu ) + normalMenu = formWindow->mainWindow()->setupNormalHierarchyMenu( this ); + normalMenu->popup( p ); + } else { + if ( !tabWidgetMenu ) + tabWidgetMenu = + formWindow->mainWindow()->setupTabWidgetHierarchyMenu( + this, SLOT( addTabPage() ), + SLOT( removeTabPage() ) ); + tabWidgetMenu->popup( p ); + } + } +} + +void HierarchyList::addTabPage() +{ + QObject *o = current(); + if ( !o || !o->isWidgetType() ) + return; + QWidget *w = (QWidget*)o; + if ( ::qt_cast<QTabWidget*>(w) ) { + QTabWidget *tw = (QTabWidget*)w; + AddTabPageCommand *cmd = new AddTabPageCommand( i18n( "Add Page to %1" ). + arg( tw->name() ), formWindow, + tw, "Tab" ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( ::qt_cast<QWizard*>(w) ) { + QWizard *wiz = (QWizard*)formWindow->mainContainer(); + AddWizardPageCommand *cmd = new AddWizardPageCommand( i18n( "Add Page to %1" ). + arg( wiz->name() ), formWindow, + wiz, "Page" ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void HierarchyList::removeTabPage() +{ + QObject *o = current(); + if ( !o || !o->isWidgetType() ) + return; + QWidget *w = (QWidget*)o; + if ( ::qt_cast<QTabWidget*>(w) ) { + QTabWidget *tw = (QTabWidget*)w; + if ( tw->currentPage() ) { + QDesignerTabWidget *dtw = (QDesignerTabWidget*)tw; + DeleteTabPageCommand *cmd = + new DeleteTabPageCommand( i18n( "Delete Page %1 of %2" ). + arg( dtw->pageTitle() ).arg( tw->name() ), + formWindow, tw, tw->currentPage() ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( ::qt_cast<QWizard*>(w) ) { + QWizard *wiz = (QWizard*)formWindow->mainContainer(); + if ( wiz->currentPage() ) { + QDesignerWizard *dw = (QDesignerWizard*)wiz; + DeleteWizardPageCommand *cmd = + new DeleteWizardPageCommand( i18n( "Delete Page %1 of %2" ). + arg( dw->pageTitle() ).arg( wiz->name() ), + formWindow, wiz, + wiz->indexOf( wiz->currentPage() ), TRUE ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } +} + +// ------------------------------------------------------------ + +FormDefinitionView::FormDefinitionView( QWidget *parent, FormWindow *fw ) + : HierarchyList( parent, fw, TRUE ) +{ + header()->hide(); + removeColumn( 1 ); + connect( this, SIGNAL( itemRenamed( QListViewItem *, int, const QString & ) ), + this, SLOT( renamed( QListViewItem * ) ) ); + popupOpen = FALSE; +} + +void FormDefinitionView::setup() +{ + if ( popupOpen || !formWindow ) + return; + if ( !formWindow->project()->isCpp() ) + return; + QListViewItem *i = firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::DefinitionParent ) { + QListViewItem *a = i; + i = i->nextSibling(); + delete a; + continue; + } + i = i->nextSibling(); + } + + LanguageInterface *lIface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( lIface ) { + QStringList defs = lIface->definitions(); + for ( QStringList::Iterator dit = defs.begin(); dit != defs.end(); ++dit ) { + HierarchyItem *itemDef = new HierarchyItem( HierarchyItem::DefinitionParent, this, 0, + i18n( *dit ), QString::null, QString::null ); + itemDef->setPixmap( 0, DesignerFolderPix ); + itemDef->setOpen( TRUE ); + QStringList entries = + lIface->definitionEntries( *dit, formWindow->mainWindow()->designerInterface() ); + HierarchyItem *item = 0; + for ( QStringList::Iterator eit = entries.begin(); eit != entries.end(); ++eit ) { + item = new HierarchyItem( HierarchyItem::Definition, + itemDef, item, *eit, QString::null, QString::null ); + item->setRenameEnabled( 0, TRUE ); + } + } + lIface->release(); + } + setupVariables(); + refresh(); +} + +void FormDefinitionView::setupVariables() +{ + bool pubOpen, protOpen, privOpen; + pubOpen = protOpen = privOpen = TRUE; + QListViewItem *i = firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::VarParent ) { + QListViewItem *a = i; + i = i->firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::VarPublic ) + pubOpen = i->isOpen(); + else if ( i->rtti() == HierarchyItem::VarProtected ) + protOpen = i->isOpen(); + else if ( i->rtti() == HierarchyItem::VarPrivate ) + privOpen = i->isOpen(); + i = i->nextSibling(); + } + delete a; + break; + } + i = i->nextSibling(); + } + + HierarchyItem *itemVar = new HierarchyItem( HierarchyItem::VarParent, this, 0, i18n( "Class Variables" ), + QString::null, QString::null ); + itemVar->setPixmap( 0, DesignerFolderPix ); + itemVar->setOpen( TRUE ); + + itemVarPriv = new HierarchyItem( HierarchyItem::VarPrivate, itemVar, 0, i18n( "private" ), + QString::null, QString::null ); + itemVarProt = new HierarchyItem( HierarchyItem::VarProtected, itemVar, 0, i18n( "protected" ), + QString::null, QString::null ); + itemVarPubl = new HierarchyItem( HierarchyItem::VarPublic, itemVar, 0, i18n( "public" ), + QString::null, QString::null ); + + QValueList<MetaDataBase::Variable> varList = MetaDataBase::variables( formWindow ); + QValueList<MetaDataBase::Variable>::Iterator it = --( varList.end() ); + if ( !varList.isEmpty() && itemVar ) { + for (;;) { + QListViewItem *item = 0; + if ( (*it).varAccess == "public" ) + item = new HierarchyItem( HierarchyItem::Variable, itemVarPubl, 0, (*it).varName, + QString::null, QString::null ); + else if ( (*it).varAccess == "private" ) + item = new HierarchyItem( HierarchyItem::Variable, itemVarPriv, 0, (*it).varName, + QString::null, QString::null ); + else // default is protected + item = new HierarchyItem( HierarchyItem::Variable, itemVarProt, 0, (*it).varName, + QString::null, QString::null ); + item->setPixmap( 0, DesignerEditSlotsPix ); + if ( it == varList.begin() ) + break; + --it; + } + } + itemVar->setOpen( TRUE ); + itemVarPriv->setOpen( privOpen ); + itemVarProt->setOpen( protOpen ); + itemVarPubl->setOpen( pubOpen ); +} + +void FormDefinitionView::refresh() +{ + if ( popupOpen || !formWindow || !formWindow->project()->isCpp() ) + return; + + bool fuPub, fuProt, fuPriv, slPub, slProt, slPriv; + fuPub = fuProt = fuPriv = slPub = slProt = slPriv = TRUE; + QListViewItem *i = firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::SlotParent || + i->rtti() == HierarchyItem::FunctParent ) { + QListViewItem *a = i; + i = i->firstChild(); + while ( i ) { + switch( i->rtti() ) { + case HierarchyItem::FunctPublic: + fuPub = i->isOpen(); + case HierarchyItem::FunctProtected: + fuProt = i->isOpen(); + break; + case HierarchyItem::FunctPrivate: + fuPriv = i->isOpen(); + break; + case HierarchyItem::SlotPublic: + slPub = i->isOpen(); + if ( slPub ) + break; + case HierarchyItem::SlotProtected: + slProt = i->isOpen(); + break; + case HierarchyItem::SlotPrivate: + slPriv = i->isOpen(); + } + i = i->nextSibling(); + } + i = a->nextSibling(); + delete a; + continue; + } + i = i->nextSibling(); + } + + + itemFunct = new HierarchyItem( HierarchyItem::FunctParent, + this, 0, i18n( "Functions" ), QString::null, QString::null ); + itemFunct->moveItem( i ); + itemFunct->setPixmap( 0, DesignerFolderPix ); + itemFunctPriv = new HierarchyItem( HierarchyItem::FunctPrivate, itemFunct, 0, + i18n( "private" ), QString::null, QString::null ); + itemFunctProt = new HierarchyItem( HierarchyItem::FunctProtected, itemFunct, 0, + i18n( "protected" ), QString::null, QString::null ); + itemFunctPubl = new HierarchyItem( HierarchyItem::FunctPublic, itemFunct, 0, + i18n( "public" ), QString::null, QString::null ); + + itemSlots = new HierarchyItem( HierarchyItem::SlotParent, + this, 0, i18n( "Slots" ), QString::null, QString::null ); + itemSlots->setPixmap( 0, DesignerFolderPix ); + itemPrivate = new HierarchyItem( HierarchyItem::SlotPrivate, itemSlots, 0, i18n( "private" ), + QString::null, QString::null ); + itemProtected = new HierarchyItem( HierarchyItem::SlotProtected, itemSlots, 0, i18n( "protected" ), + QString::null, QString::null ); + itemPublic = new HierarchyItem( HierarchyItem::SlotPublic, itemSlots, 0, i18n( "public" ), + QString::null, QString::null ); + + QValueList<MetaDataBase::Function> functionList = MetaDataBase::functionList( formWindow ); + QValueList<MetaDataBase::Function>::Iterator it = --( functionList.end() ); + if ( !functionList.isEmpty() && itemFunct ) { + for (;;) { + QListViewItem *item = 0; + if ( (*it).type == "slot" ) { + if ( (*it).access == "protected" ) + item = new HierarchyItem( HierarchyItem::Slot, itemProtected, 0, (*it).function, + QString::null, QString::null ); + else if ( (*it).access == "private" ) + item = new HierarchyItem( HierarchyItem::Slot, itemPrivate, 0, (*it).function, + QString::null, QString::null ); + else // default is public + item = new HierarchyItem( HierarchyItem::Slot, itemPublic, 0, (*it).function, + QString::null, QString::null ); + } else { + if ( (*it).access == "protected" ) + item = new HierarchyItem( HierarchyItem::Function, itemFunctProt, 0, (*it).function, + QString::null, QString::null ); + else if ( (*it).access == "private" ) + item = new HierarchyItem( HierarchyItem::Function, itemFunctPriv, 0, (*it).function, + QString::null, QString::null ); + else // default is public + item = new HierarchyItem( HierarchyItem::Function, itemFunctPubl, 0, (*it).function, + QString::null, QString::null ); + } + item->setPixmap( 0, DesignerEditSlotsPix ); + if ( it == functionList.begin() ) + break; + --it; + } + } + + itemFunct->setOpen( TRUE ); + itemFunctPubl->setOpen( fuPub ); + itemFunctProt->setOpen( fuProt ); + itemFunctPriv->setOpen( fuPriv ); + + itemSlots->setOpen( TRUE ); + itemPublic->setOpen( slPub ); + itemProtected->setOpen( slProt ); + itemPrivate->setOpen( slPriv ); +} + + +void FormDefinitionView::setCurrent( QWidget * ) +{ +} + +void FormDefinitionView::objectClicked( QListViewItem *i ) +{ + if ( !i ) + return; + if ( (i->rtti() == HierarchyItem::Slot) || (i->rtti() == HierarchyItem::Function) ) + { + formWindow->clearSelection(false); + formWindow->mainWindow()->part()->emitEditFunction(formWindow->fileName(), i->text( 0 )); + } +// formWindow->mainWindow()->editFunction( i->text( 0 ) ); +} + +static HierarchyItem::Type getChildType( int type ) +{ + switch ( (HierarchyItem::Type)type ) { + case HierarchyItem::Widget: + qWarning( "getChildType: Inserting childs dynamically to Widget or SlotParent is not allowed!" ); + break; + case HierarchyItem::SlotParent: + case HierarchyItem::SlotPublic: + case HierarchyItem::SlotProtected: + case HierarchyItem::SlotPrivate: + case HierarchyItem::Slot: + return HierarchyItem::Slot; + case HierarchyItem::DefinitionParent: + case HierarchyItem::Definition: + return HierarchyItem::Definition; + case HierarchyItem::Event: + case HierarchyItem::EventFunction: + return HierarchyItem::Event; + case HierarchyItem::FunctParent: + case HierarchyItem::FunctPublic: + case HierarchyItem::FunctProtected: + case HierarchyItem::FunctPrivate: + case HierarchyItem::Function: + return HierarchyItem::Function; + case HierarchyItem::VarParent: + case HierarchyItem::VarPublic: + case HierarchyItem::VarProtected: + case HierarchyItem::VarPrivate: + case HierarchyItem::Variable: + return HierarchyItem::Variable; + } + return (HierarchyItem::Type)type; +} + +void HierarchyList::insertEntry( QListViewItem *i, const QPixmap &pix, const QString &s ) +{ + QListViewItem *after = i->firstChild(); + while ( after && after->nextSibling() ) + after = after->nextSibling(); + HierarchyItem *item = new HierarchyItem( getChildType( i->rtti() ), i, after, s, + QString::null, QString::null ); + if ( !pix.isNull() ) + item->setPixmap( 0, pix ); + item->setRenameEnabled( 0, TRUE ); + setCurrentItem( item ); + ensureItemVisible( item ); + qApp->processEvents(); + newItem = item; + item->startRename( 0 ); +} + +void FormDefinitionView::contentsMouseDoubleClickEvent( QMouseEvent *e ) +{ + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if ( !i ) + return; + + if ( i->rtti() == HierarchyItem::SlotParent || i->rtti() == HierarchyItem::FunctParent || + i->rtti() == HierarchyItem::VarParent ) + return; + + HierarchyItem::Type t = getChildType( i->rtti() ); + if ( (int)t == i->rtti() ) + i = i->parent(); + + if ( formWindow->project()->isCpp() ) + switch( i->rtti() ) { + case HierarchyItem::FunctPublic: + execFunctionDialog( "public", "function", TRUE ); + break; + case HierarchyItem::FunctProtected: + execFunctionDialog( "protected", "function", TRUE ); + break; + case HierarchyItem::FunctPrivate: + execFunctionDialog( "private", "function", TRUE ); + break; + case HierarchyItem::SlotPublic: + execFunctionDialog( "public", "slot", TRUE ); + break; + case HierarchyItem::SlotProtected: + execFunctionDialog( "protected", "slot", TRUE ); + break; + case HierarchyItem::SlotPrivate: + execFunctionDialog( "private", "slot", TRUE ); + break; + case HierarchyItem::VarPublic: + case HierarchyItem::VarProtected: + case HierarchyItem::VarPrivate: { + VariableDialog varDia( formWindow, this ); + QListViewItem *i = selectedItem(); + if ( i ) + varDia.setCurrentItem( i->text( 0 ) ); + varDia.exec(); + break; + } + default: + insertEntry( i ); + } else + insertEntry( i ); +} + +void FormDefinitionView::execFunctionDialog( const QString &access, const QString &type, bool addFunc ) +{ + FormFile *formFile = formWindow->formFile(); + if ( !formFile || !formFile->isUihFileUpToDate() ) + return; + + // refresh the functions list in the metadatabase + SourceEditor *editor = formFile->editor(); + if ( editor ) + editor->refresh( TRUE ); + + EditFunctions dlg( this, formWindow ); + if ( addFunc ) + dlg.functionAdd( access, type ); + dlg.exec(); +} + +void FormDefinitionView::showRMBMenu( QListViewItem *i, const QPoint &pos ) +{ + if ( !i ) + return; + + const int EDIT = 1; + const int NEW = 2; + const int DEL = 3; + const int PROPS = 4; + const int GOIMPL = 5; + + QPopupMenu menu; + bool insertDelete = FALSE; + + if ( i->rtti() == HierarchyItem::FunctParent || i->rtti() == HierarchyItem::SlotParent || + i->rtti() == HierarchyItem::VarParent ) { + menu.insertItem( SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()), i18n( "Edit..." ), EDIT ); + } else + menu.insertItem( SmallIcon( "designer_filenew.png" , KDevDesignerPartFactory::instance()), i18n( "New..." ), NEW ); + if ( i->rtti() == HierarchyItem::DefinitionParent || i->rtti() == HierarchyItem::Variable || + i->rtti() == HierarchyItem::Definition ) { + menu.insertItem( SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()), i18n( "Edit..." ), EDIT ); + } + if ( i->rtti() == HierarchyItem::Function || i->rtti() == HierarchyItem::Slot ) { + if ( formWindow->project()->isCpp() ) + menu.insertItem( SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()), i18n( "Properties" ), PROPS ); + if ( MetaDataBase::hasEditor( formWindow->project()->language() ) ) + menu.insertItem( i18n( "Goto Implementation" ), GOIMPL ); + insertDelete = TRUE; + } + if ( insertDelete || i->rtti() == HierarchyItem::Variable || + i->rtti() == HierarchyItem::Function || i->rtti() == HierarchyItem::Slot || + i->rtti() == HierarchyItem::Definition ) { + menu.insertSeparator(); + menu.insertItem( SmallIcon( "designer_editcut.png" , KDevDesignerPartFactory::instance()), i18n( "Delete" ), DEL ); + } + popupOpen = TRUE; + int res = menu.exec( pos ); + popupOpen = FALSE; + if ( res == -1 ) + return; + + if ( res == EDIT ) { + switch( i->rtti() ) { + case HierarchyItem::FunctParent: + execFunctionDialog( "public", "function", FALSE ); + break; + case HierarchyItem::SlotParent: + execFunctionDialog( "public", "slot", FALSE ); + break; + case HierarchyItem::VarParent: + case HierarchyItem::VarPublic: + case HierarchyItem::VarProtected: + case HierarchyItem::VarPrivate: + case HierarchyItem::Variable: { + VariableDialog varDia( formWindow, this ); + QListViewItem *i = selectedItem(); + if ( i ) + varDia.setCurrentItem( i->text( 0 ) ); + if ( varDia.exec() == QDialog::Accepted ) + formWindow->commandHistory()->setModified( TRUE ); + break; + } + case HierarchyItem::Definition: + case HierarchyItem::DefinitionParent: + LanguageInterface *lIface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( !lIface ) + return; + if ( i->rtti() == HierarchyItem::Definition ) + i = i->parent(); + ListEditor dia( this, 0, TRUE ); + dia.setCaption( i18n( "Edit %1" ).arg( i->text( 0 ) ) ); + QStringList entries = lIface->definitionEntries( i->text( 0 ), MainWindow::self->designerInterface() ); + dia.setList( entries ); + dia.exec(); + Command *cmd = new EditDefinitionsCommand( i18n( "Edit %1" ).arg( i->text( 0 )), formWindow, + lIface, i->text( 0 ), dia.items() ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( res == NEW ) { + HierarchyItem::Type t = getChildType( i->rtti() ); + if ( (int)t == i->rtti() ) + i = i->parent(); + switch( i->rtti() ) { + case HierarchyItem::SlotPublic: + execFunctionDialog( "public", "slot", TRUE ); + break; + case HierarchyItem::SlotProtected: + execFunctionDialog( "protected", "slot", TRUE ); + break; + case HierarchyItem::SlotPrivate: + execFunctionDialog( "private" , "slot", TRUE ); + break; + case HierarchyItem::FunctPublic: + execFunctionDialog( "public", "function", TRUE ); + break; + case HierarchyItem::FunctProtected: + execFunctionDialog( "protected", "function", TRUE ); + break; + case HierarchyItem::FunctPrivate: + execFunctionDialog( "private" , "function", TRUE ); + break; + default: + insertEntry( i ); + } + } else if ( res == DEL ) { + if ( i->rtti() == HierarchyItem::Slot || i->rtti() == HierarchyItem::Function ) { + + QCString funct( MetaDataBase::normalizeFunction( i->text( 0 ) ).latin1() ); + Command *cmd = new RemoveFunctionCommand( i18n( "Remove Function" ), formWindow, funct, + QString::null, QString::null, QString::null, + QString::null, formWindow->project()->language() ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + } else if ( i->rtti() == HierarchyItem::Variable ) { + Command *cmd = new RemoveVariableCommand( i18n( "Remove Variable" ), formWindow, + i->text( 0 ) ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else { + QListViewItem *p = i->parent(); + delete i; + save( p, 0 ); + } + } else if ( res == PROPS ) { + if ( i->rtti() == HierarchyItem::Slot || + i->rtti() == HierarchyItem::Function ) { + EditFunctions dlg( this, formWindow ); + dlg.setCurrentFunction( MetaDataBase::normalizeFunction( i->text( 0 ) ) ); + dlg.exec(); + } + } else if ( res == GOIMPL ) { + if ( i->rtti() == HierarchyItem::Slot || + i->rtti() == HierarchyItem::Function ) { + formWindow->clearSelection(false); + formWindow->mainWindow()->part()->emitEditFunction(formWindow->fileName(), i->text( 0 )); +// formWindow->mainWindow()->editFunction( i->text( 0 ) ); + } + } +} + +void FormDefinitionView::renamed( QListViewItem *i ) +{ + if ( newItem == i ) + newItem = 0; + if ( !i->parent() ) + return; + save( i->parent(), i ); +} + + +void FormDefinitionView::save( QListViewItem *p, QListViewItem *i ) +{ + if ( i && i->text( 0 ).isEmpty() ) { + delete i; + return; + } + + if ( i && i->rtti() == HierarchyItem::Variable ) { + i->setRenameEnabled( 0, FALSE ); + QString varName = i->text( 0 ); + varName = varName.simplifyWhiteSpace(); + if ( varName[(int)varName.length() - 1] != ';' ) + varName += ";"; + if ( MetaDataBase::hasVariable( formWindow, varName ) ) { + QMessageBox::information( this, i18n( "Edit Variables" ), + i18n( "This variable has already been declared." ) ); + } else { + if ( p->rtti() == HierarchyItem::VarPublic ) + addVariable( varName, "public" ); + else if ( p->rtti() == HierarchyItem::VarProtected ) + addVariable( varName, "protected" ); + else if ( p->rtti() == HierarchyItem::VarPrivate ) + addVariable( varName, "private" ); + } + } else { + LanguageInterface *lIface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( !lIface ) + return; + QStringList lst; + i = p->firstChild(); + while ( i ) { + lst << i->text( 0 ); + i = i->nextSibling(); + } + Command *cmd = new EditDefinitionsCommand( i18n( "Edit %1" ).arg( p->text( 0 ) ), formWindow, + lIface, p->text( 0 ), lst ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void FormDefinitionView::addVariable( const QString &varName, const QString &access ) +{ + Command *cmd = new AddVariableCommand( i18n( "Add Variable" ), formWindow, + varName, access ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +// ------------------------------------------------------------ + +HierarchyView::HierarchyView( QWidget *parent ) + : QTabWidget( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_Tool |WStyle_MinMax | WStyle_SysMenu ) +{ + formwindow = 0; + editor = 0; + listview = new HierarchyList( this, formWindow() ); + fView = new FormDefinitionView( this, formWindow() ); + if ( !MainWindow::self->singleProjectMode() ) { + addTab( listview, i18n( "Objects" ) ); + setTabToolTip( listview, i18n( "List of all widgets and objects of the current form in hierarchical order" ) ); + addTab( fView, i18n( "Members" ) ); + setTabToolTip( fView, i18n( "List of all members of the current form" ) ); + } else { + listview->hide(); + fView->hide(); + } + + if ( !classBrowserInterfaceManager ) { + classBrowserInterfaceManager = + new QPluginManager<ClassBrowserInterface>( IID_ClassBrowser, QApplication::libraryPaths(), + MainWindow::self->pluginDirectory() ); + } + + classBrowsers = new QMap<QString, ClassBrowser>(); + QStringList langs = MetaDataBase::languages(); + for ( QStringList::Iterator it = langs.begin(); it != langs.end(); ++it ) { + QInterfacePtr<ClassBrowserInterface> ciface = 0; + classBrowserInterfaceManager->queryInterface( *it, &ciface ); + if ( ciface ) { + ClassBrowser cb( ciface->createClassBrowser( this ), ciface ); + addTab( cb.lv, i18n( "Class Declarations" ) ); + setTabToolTip( cb.lv, i18n( "List of all classes and its declarations of the current source file" ) ); + ciface->onClick( this, SLOT( jumpTo( const QString &, const QString &, int ) ) ); + classBrowsers->insert( *it, cb ); + setTabEnabled( cb.lv, FALSE ); + } + } +} + +HierarchyView::~HierarchyView() +{ +} + +void HierarchyView::clear() +{ + listview->clear(); + fView->clear(); + for ( QMap<QString, ClassBrowser>::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + (*it).iface->clear(); + } +} + +void HierarchyView::setFormWindow( FormWindow *fw, QObject *o ) +{ + bool fake = fw && qstrcmp( fw->name(), "qt_fakewindow" ) == 0; + if ( fw == 0 || o == 0 ) { + listview->clear(); + fView->clear(); + listview->setFormWindow( fw ); + fView->setFormWindow( fw ); + formwindow = 0; + editor = 0; + } + + setTabEnabled( listview, TRUE ); + setTabEnabled( fView, fw && fw->project()->isCpp() ); + + if ( fw == formwindow ) { + if ( fw ) { + if ( !fake ) + listview->setCurrent( (QWidget*)o ); + else + listview->clear(); + if ( MainWindow::self->qWorkspace()->activeWindow() == fw ) + showPage( listview ); + else if ( fw->project()->isCpp() ) + showPage( fView ); + else + showClasses( fw->formFile()->editor() ); + } + } + + formwindow = fw; + if ( !fake ) { + listview->setFormWindow( fw ); + } else { + listview->setFormWindow( 0 ); + listview->clear(); + } + + fView->setFormWindow( fw ); + if ( !fake ) { + listview->setup(); + listview->setCurrent( (QWidget*)o ); + } + fView->setup(); + + for ( QMap<QString, ClassBrowser>::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + (*it).iface->clear(); + setTabEnabled( (*it).lv, fw && !fw->project()->isCpp() ); + } + + if ( MainWindow::self->qWorkspace()->activeWindow() == fw ) + showPage( listview ); + else if ( fw && fw->project()->isCpp() ) + showPage( fView ); + else if ( fw ) + showClasses( fw->formFile()->editor() ); + + editor = 0; +} + +void HierarchyView::showClasses( SourceEditor *se ) +{ + if ( !se->object() ) + return; + + lastSourceEditor = se; + QTimer::singleShot( 100, this, SLOT( showClassesTimeout() ) ); +} + +void HierarchyView::showClassesTimeout() +{ + if ( !lastSourceEditor ) + return; + SourceEditor *se = (SourceEditor*)lastSourceEditor; + if ( !se->object() ) + return; + if ( se->formWindow() && se->formWindow()->project()->isCpp() ) { + setFormWindow( se->formWindow(), se->formWindow()->currentWidget() ); + MainWindow::self->propertyeditor()->setWidget( se->formWindow()->currentWidget(), + se->formWindow() ); + return; + } + + setTabEnabled( listview, !!se->formWindow() && !se->formWindow()->isFake() ); + setTabEnabled( fView, FALSE ); + + formwindow = 0; + listview->setFormWindow( 0 ); + fView->setFormWindow( 0 ); + listview->clear(); + fView->clear(); + if ( !se->formWindow() ) + MainWindow::self->propertyeditor()->setWidget( 0, 0 ); + editor = se; + + for ( QMap<QString, ClassBrowser>::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + if ( it.key() == se->project()->language() ) { + (*it).iface->update( se->text() ); + setTabEnabled( (*it).lv, TRUE ); + showPage( (*it).lv ); + } else { + setTabEnabled( (*it).lv, FALSE ); + (*it).iface->clear(); + } + } +} + +void HierarchyView::updateClassBrowsers() +{ + if ( !editor ) + return; + for ( QMap<QString, ClassBrowser>::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + if ( it.key() == editor->project()->language() ) + (*it).iface->update( editor->text() ); + else + (*it).iface->clear(); + } +} + +FormWindow *HierarchyView::formWindow() const +{ + return formwindow; +} + +void HierarchyView::closeEvent( QCloseEvent *e ) +{ + emit hidden(); + e->accept(); +} + +void HierarchyView::widgetInserted( QWidget * ) +{ + listview->setup(); +} + +void HierarchyView::widgetRemoved( QWidget * ) +{ + listview->setup(); +} + +void HierarchyView::widgetsInserted( const QWidgetList & ) +{ + listview->setup(); +} + +void HierarchyView::widgetsRemoved( const QWidgetList & ) +{ + listview->setup(); +} + +void HierarchyView::namePropertyChanged( QWidget *w, const QVariant & ) +{ + QWidget *w2 = w; + if ( ::qt_cast<QMainWindow*>(w) ) + w2 = ( (QMainWindow*)w )->centralWidget(); + listview->changeNameOf( w2, w->name() ); +} + + +void HierarchyView::databasePropertyChanged( QWidget *w, const QStringList& info ) +{ +#ifndef QT_NO_SQL + QString i = info.join( "." ); + listview->changeDatabaseOf( w, i ); +#endif +} + + +void HierarchyView::tabsChanged( QTabWidget * ) +{ + listview->setup(); +} + +void HierarchyView::pagesChanged( QWizard * ) +{ + listview->setup(); +} + +void HierarchyView::rebuild() +{ + listview->setup(); +} + +void HierarchyView::closed( FormWindow *fw ) +{ + if ( fw == formwindow ) { + listview->clear(); + fView->clear(); + } +} + +void HierarchyView::updateFormDefinitionView() +{ + fView->setup(); +} + +void HierarchyView::jumpTo( const QString &func, const QString &clss, int type ) +{ + if ( !editor ) + return; + if ( type == ClassBrowserInterface::Class ) + editor->setClass( func ); + else + editor->setFunction( func, clss ); +} + +HierarchyView::ClassBrowser::ClassBrowser( QListView *l, ClassBrowserInterface *i ) + : lv( l ), iface( i ) +{ +} + +HierarchyView::ClassBrowser::~ClassBrowser() +{ +} diff --git a/kdevdesigner/designer/hierarchyview.h b/kdevdesigner/designer/hierarchyview.h new file mode 100644 index 00000000..ffd269b7 --- /dev/null +++ b/kdevdesigner/designer/hierarchyview.h @@ -0,0 +1,249 @@ +/********************************************************************** +** 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 HIRARCHYVIEW_H +#define HIRARCHYVIEW_H + +#include <qvariant.h> +#include <qlistview.h> +#include <qtabwidget.h> +#include <qguardedptr.h> +#include <private/qcom_p.h> +#include "../interfaces/classbrowserinterface.h" + +class FormWindow; +class QCloseEvent; +class QPopupMenu; +class QKeyEvent; +class QMouseEvent; +class QWizard; +class SourceEditor; + +class HierarchyItem : public QListViewItem +{ +public: + enum Type { + Widget, + SlotParent, + SlotPublic, + SlotProtected, + SlotPrivate, + Slot, + DefinitionParent, + Definition, + Event, + EventFunction, + FunctParent, + FunctPublic, + FunctProtected, + FunctPrivate, + Function, + VarParent, + VarPublic, + VarProtected, + VarPrivate, + Variable + }; + + HierarchyItem( Type type, QListViewItem *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ); + HierarchyItem( Type type, QListView *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ); + void updateBackColor(); + + void setObject( QObject *o ); + QObject *object() const; + + void setText( int col, const QString &txt ) { if ( !txt.isEmpty() ) QListViewItem::setText( col, txt ); } + + int rtti() const { return (int)typ; } + +private: + void okRename( int col ); + void cancelRename( int col ); + +private: + QColor backgroundColor(); + QColor backColor; + QObject *obj; + Type typ; + +}; + +class HierarchyList : public QListView +{ + Q_OBJECT + +public: + HierarchyList( QWidget *parent, FormWindow *fw, bool doConnects = TRUE ); + + virtual void setup(); + virtual void setCurrent( QObject *o ); + void setOpen( QListViewItem *i, bool b ); + void changeNameOf( QObject *o, const QString &name ); + void changeDatabaseOf( QObject *o, const QString &info ); + void setFormWindow( FormWindow *fw ) { formWindow = fw; } + void drawContentsOffset( QPainter *p, int ox, int oy, + int cx, int cy, int cw, int ch ) { + setUpdatesEnabled( FALSE ); + triggerUpdate(); + setUpdatesEnabled( TRUE ); + QListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch ); + } + + void insertEntry( QListViewItem *i, const QPixmap &pix = QPixmap(), const QString &s = QString::null ); + +protected: + void keyPressEvent( QKeyEvent *e ); + void keyReleaseEvent( QKeyEvent *e ); + void viewportMousePressEvent( QMouseEvent *e ); + void viewportMouseReleaseEvent( QMouseEvent *e ); + +public slots: + void addTabPage(); + void removeTabPage(); + +private: + void insertObject( QObject *o, QListViewItem *parent ); + QObject *findObject( QListViewItem *i ); + QListViewItem *findItem( QObject *o ); + QObject *current() const; + QObject *handleObjectClick( QListViewItem *i ); + +private slots: + virtual void objectClicked( QListViewItem *i ); + virtual void objectDoubleClicked( QListViewItem *i ); + virtual void showRMBMenu( QListViewItem *, const QPoint & ); + +protected: + FormWindow *formWindow; + QPopupMenu *normalMenu, *tabWidgetMenu; + bool deselect; + + QPixmap DesignerFormPix; + QPixmap DesignerLayoutPix; + QPixmap DesignerFolderPix; + QPixmap DesignerEditSlotsPix; + +}; + +class FormDefinitionView : public HierarchyList +{ + Q_OBJECT + +public: + FormDefinitionView( QWidget *parent, FormWindow *fw ); + + void setup(); + void setupVariables(); + void refresh(); + void setCurrent( QWidget *w ); + +protected: + void contentsMouseDoubleClickEvent( QMouseEvent *e ); + +private: + void save( QListViewItem *p, QListViewItem *i ); + void execFunctionDialog( const QString &access, const QString &type, bool addFunc ); + void addVariable( const QString &varName, const QString &access ); + +private slots: + void objectClicked( QListViewItem *i ); + void showRMBMenu( QListViewItem *, const QPoint & ); + void renamed( QListViewItem *i ); + +private: + bool popupOpen; + HierarchyItem *itemSlots, *itemPrivate, *itemProtected, *itemPublic; + HierarchyItem *itemFunct, *itemFunctPriv, *itemFunctProt, *itemFunctPubl; + HierarchyItem *itemVar, *itemVarPriv, *itemVarProt, *itemVarPubl; +}; + + +class HierarchyView : public QTabWidget +{ + Q_OBJECT + +public: + HierarchyView( QWidget *parent ); + ~HierarchyView(); + + void setFormWindow( FormWindow *fw, QObject *o ); + FormWindow *formWindow() const; + SourceEditor *sourceEditor() const { return editor; } + void clear(); + + void showClasses( SourceEditor *se ); + void updateClassBrowsers(); + + void widgetInserted( QWidget *w ); + void widgetRemoved( QWidget *w ); + void widgetsInserted( const QWidgetList &l ); + void widgetsRemoved( const QWidgetList &l ); + void namePropertyChanged( QWidget *w, const QVariant &old ); + void databasePropertyChanged( QWidget *w, const QStringList& info ); + void tabsChanged( QTabWidget *w ); + void pagesChanged( QWizard *w ); + void rebuild(); + void closed( FormWindow *fw ); + void updateFormDefinitionView(); + + FormDefinitionView *formDefinitionView() const { return fView; } + HierarchyList *hierarchyList() const { return listview; } + +protected slots: + void jumpTo( const QString &func, const QString &clss,int type ); + void showClassesTimeout(); + +protected: + void closeEvent( QCloseEvent *e ); + +signals: + void hidden(); + +private: + struct ClassBrowser + { + ClassBrowser( QListView * = 0, ClassBrowserInterface * = 0 ); + ~ClassBrowser(); + QListView *lv; + QInterfacePtr<ClassBrowserInterface> iface; + + Q_DUMMY_COMPARISON_OPERATOR( ClassBrowser ) + }; + FormWindow *formwindow; + HierarchyList *listview; + FormDefinitionView *fView; + SourceEditor *editor; + QMap<QString, ClassBrowser> *classBrowsers; + QGuardedPtr<SourceEditor> lastSourceEditor; + +}; + + +#endif diff --git a/kdevdesigner/designer/iconvieweditor.ui b/kdevdesigner/designer/iconvieweditor.ui new file mode 100644 index 00000000..e06367f1 --- /dev/null +++ b/kdevdesigner/designer/iconvieweditor.ui @@ -0,0 +1,461 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>IconViewEditorBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>IconViewEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>567</width> + <height>321</height> + </rect> + </property> + <property name="caption"> + <string>Edit Iconview</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Edit Iconview</b><p>Add, edit or delete items in the icon view.</p><p>Click the <b>New Item</b>-button to create a new item, then enter text and choose a pixmap.</p><p>Select an item from the view and click the <b>Delete Item</b>-button to remove the item from the iconview.</p></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QIconView"> + <property name="name"> + <cstring>preview</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>All items in the iconview.</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>itemNew</cstring> + </property> + <property name="text"> + <string>&New Item</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add an item</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Create a new item for the iconview.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>itemDelete</cstring> + </property> + <property name="text"> + <string>&Delete Item</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete item</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Delete the selected item.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Vertical Spacing1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>&Item Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>Label1</cstring> + </property> + <property name="text"> + <string>&Text:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemText</cstring> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>itemText</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Change text</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Change the text for the selected item.</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label2</cstring> + </property> + <property name="text"> + <string>&Pixmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemChoosePixmap</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>itemPixmap</cstring> + </property> + <property name="text"> + <string>Label4</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>itemDeletePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Delete the selected item's pixmap.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>itemChoosePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Select a pixmap file for the current item.</string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Apply all changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>itemNew</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>insertNewItem()</slot> + </connection> + <connection> + <sender>itemDelete</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>deleteCurrentItem()</slot> + </connection> + <connection> + <sender>itemText</sender> + <signal>textChanged( const QString & )</signal> + <receiver>IconViewEditorBase</receiver> + <slot>currentTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>buttonApply</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>applyClicked()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>cancelClicked()</slot> + </connection> + <connection> + <sender>itemChoosePixmap</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>choosePixmap()</slot> + </connection> + <connection> + <sender>preview</sender> + <signal>selectionChanged(QIconViewItem*)</signal> + <receiver>IconViewEditorBase</receiver> + <slot>currentItemChanged(QIconViewItem*)</slot> + </connection> + <connection> + <sender>preview</sender> + <signal>currentChanged(QIconViewItem*)</signal> + <receiver>IconViewEditorBase</receiver> + <slot>currentItemChanged(QIconViewItem*)</slot> + </connection> + <connection> + <sender>itemDeletePixmap</sender> + <signal>clicked()</signal> + <receiver>IconViewEditorBase</receiver> + <slot>deletePixmap()</slot> + </connection> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>preview</tabstop> + <tabstop>itemNew</tabstop> + <tabstop>itemDelete</tabstop> + <tabstop>itemText</tabstop> + <tabstop>itemDeletePixmap</tabstop> + <tabstop>itemChoosePixmap</tabstop> + <tabstop>buttonHelp</tabstop> + <tabstop>buttonApply</tabstop> +</tabstops> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">applyClicked()</slot> + <slot access="protected">cancelClicked()</slot> + <slot access="protected">choosePixmap()</slot> + <slot access="protected">currentItemChanged( QIconViewItem * )</slot> + <slot access="protected">currentTextChanged( const QString & )</slot> + <slot access="protected">deleteCurrentItem()</slot> + <slot access="protected">insertNewItem()</slot> + <slot access="protected">deletePixmap()</slot> + <slot access="protected">okClicked()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/iconvieweditorimpl.cpp b/kdevdesigner/designer/iconvieweditorimpl.cpp new file mode 100644 index 00000000..10e2fb7d --- /dev/null +++ b/kdevdesigner/designer/iconvieweditorimpl.cpp @@ -0,0 +1,165 @@ +/********************************************************************** +** 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 "iconvieweditorimpl.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "pixmapchooser.h" + +#include <qlineedit.h> +#include <qlabel.h> +#include <qiconview.h> +#include <qpushbutton.h> +#include <qcheckbox.h> + +#include <klocale.h> + +IconViewEditor::IconViewEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ) + : IconViewEditorBase( parent, 0, TRUE ), formwindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + iconview = (QIconView*)editWidget; + + itemText->setText( "" ); + itemText->setEnabled( FALSE ); + itemPixmap->setText( "" ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + + QIconViewItem *i = 0; + for ( i = iconview->firstItem(); i; i = i->nextItem() ) { + (void)new QIconViewItem( preview, i->text(), *i->pixmap() ); + } + + if ( preview->firstItem() ) + preview->setCurrentItem( preview->firstItem() ); +} + +void IconViewEditor::insertNewItem() +{ + QIconViewItem *i = new QIconViewItem( preview, i18n( "New Item" ) ); + preview->setCurrentItem( i ); + preview->setSelected( i, TRUE ); + itemText->setFocus(); + itemText->selectAll(); +} + +void IconViewEditor::deleteCurrentItem() +{ + delete preview->currentItem(); + if ( preview->currentItem() ) + preview->setSelected( preview->currentItem(), TRUE ); +} + +void IconViewEditor::currentItemChanged( QIconViewItem *i ) +{ + itemText->blockSignals( TRUE ); + itemText->setText( "" ); + itemPixmap->setText( "" ); + itemText->blockSignals( FALSE ); + + if ( !i ) { + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + return; + } + + itemText->blockSignals( TRUE ); + itemText->setEnabled( TRUE ); + itemChoosePixmap->setEnabled( TRUE ); + itemDeletePixmap->setEnabled( i->pixmap() && !i->pixmap()->isNull() ); + + itemText->setText( i->text() ); + if ( i->pixmap() ) + itemPixmap->setPixmap( *i->pixmap() ); + itemText->blockSignals( FALSE ); +} + +void IconViewEditor::currentTextChanged( const QString &txt ) +{ + if ( !preview->currentItem() ) + return; + + preview->currentItem()->setText( txt ); +} + +void IconViewEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void IconViewEditor::cancelClicked() +{ + reject(); +} + +void IconViewEditor::applyClicked() +{ + QIconViewItem *i = 0; + QValueList<PopulateIconViewCommand::Item> items; + for ( i = preview->firstItem(); i; i = i->nextItem() ) { + PopulateIconViewCommand::Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + items.append( item ); + } + + PopulateIconViewCommand *cmd = new PopulateIconViewCommand( i18n( "Edit the Items of '%1'" ).arg( iconview->name() ), + formwindow, iconview, items ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); +} + +void IconViewEditor::choosePixmap() +{ + if ( !preview->currentItem() ) + return; + + QPixmap pix; + if ( preview->currentItem()->pixmap() ) + pix = qChoosePixmap( this, formwindow, *preview->currentItem()->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + preview->currentItem()->setPixmap( pix ); + itemPixmap->setPixmap( pix ); + itemDeletePixmap->setEnabled( TRUE ); +} + +void IconViewEditor::deletePixmap() +{ + if ( !preview->currentItem() ) + return; + + preview->currentItem()->setPixmap( QPixmap() ); + itemPixmap->setText( "" ); + itemDeletePixmap->setEnabled( FALSE ); +} diff --git a/kdevdesigner/designer/iconvieweditorimpl.h b/kdevdesigner/designer/iconvieweditorimpl.h new file mode 100644 index 00000000..49e17570 --- /dev/null +++ b/kdevdesigner/designer/iconvieweditorimpl.h @@ -0,0 +1,58 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef ICONVIEWEDITORIMPL_H +#define ICONVIEWEDITORIMPL_H + +#include "iconvieweditor.h" + +class FormWindow; + +class IconViewEditor : public IconViewEditorBase +{ + Q_OBJECT + +public: + IconViewEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ); + +protected slots: + void insertNewItem(); + void deleteCurrentItem(); + void currentItemChanged( QIconViewItem * ); + void currentTextChanged( const QString & ); + void okClicked(); + void cancelClicked(); + void applyClicked(); + void choosePixmap(); + void deletePixmap(); + +private: + QIconView *iconview; + FormWindow *formwindow; + +}; + +#endif diff --git a/kdevdesigner/designer/kdevdesigner_part.cpp b/kdevdesigner/designer/kdevdesigner_part.cpp new file mode 100644 index 00000000..a806dffc --- /dev/null +++ b/kdevdesigner/designer/kdevdesigner_part.cpp @@ -0,0 +1,565 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "kdevdesigner_part.h" + +#include <kinstance.h> +#include <kaction.h> +#include <kactionclasses.h> +#include <kstdaction.h> +#include <kfiledialog.h> +#include <kdebug.h> +#include <klocale.h> +#include <kiconloader.h> + +#include <qfile.h> +#include <qtextstream.h> +#include <qtoolbar.h> +#include <qmenubar.h> +#include <qptrlist.h> +#include <qstatusbar.h> + +#include "mainwindow.h" +#include "designeraction.h" +#include "formwindow.h" + +KDevDesignerPart::KDevDesignerPart( QWidget *parentWidget, const char *// widgetName + , + QObject *parent, const char *name, const QStringList &args ) + : KInterfaceDesigner::Designer(parent, name) +{ + setInstance( KDevDesignerPartFactory::instance() ); + + m_widget = new MainWindow( this, true ); + m_widget->reparent(parentWidget, QPoint(0,0)); + setupDesignerWindow(); + + setWidget(m_widget); + + setupActions(); + if (args.contains("in shell")) + setXMLFile("kdevdesigner_part_sh.rc"); + else + setXMLFile("kdevdesigner_part.rc"); + + setReadWrite(true); + setModified(false); + + connect(m_widget, SIGNAL(formModified(bool )), this, SLOT(formModified(bool))); +} + +void KDevDesignerPart::setupDesignerWindow() +{ + m_widget->menuBar()->hide(); + m_widget->layoutToolBar->hide(); + m_widget->projectToolBar->hide(); + m_widget->toolsToolBar->hide(); + m_widget->statusBar()->hide(); +} + +static QIconSet createPartIconSet( const QString &name ) +{ + QIconSet ic( BarIcon( "" + name, KDevDesignerPartFactory::instance() ) ); + QString prefix = "designer_"; + int right = name.length() - prefix.length(); + ic.setPixmap( BarIcon( prefix + "d_" + name.right( right ), KDevDesignerPartFactory::instance() ), + QIconSet::Small, QIconSet::Disabled ); + return ic; +} + +void KDevDesignerPart::setupActions( ) +{ + KAction *action; + action = KStdAction::openNew(this, SLOT(fileNew()), actionCollection()); + action = KStdAction::open(this, SLOT(fileOpen()), actionCollection()); + action = KStdAction::close(this, SLOT(fileClose()), actionCollection()); + stateSync(action, m_widget->actionFileClose); + action = KStdAction::save(this, SLOT(save()), actionCollection()); + stateSync(action, m_widget->actionFileSave); + action = KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection()); + stateSync(action, m_widget->actionFileSaveAs); + action = new KAction(i18n("Save Al&l"), 0, this, SLOT(fileSaveAs()), actionCollection(), "file_saveall"); + stateSync(action, m_widget->actionFileSaveAll); + new KAction(i18n("Create &Template..."), 0, this, SLOT(fileCreateTemplate()), actionCollection(), "file_createtemplate"); + + action = KStdAction::undo(this, SLOT(editUndo()), actionCollection()); + stateSync(action, m_widget->actionEditUndo); + action = KStdAction::redo(this, SLOT(editRedo()), actionCollection()); + stateSync(action, m_widget->actionEditRedo); + action = KStdAction::cut(this, SLOT(editCut()), actionCollection()); + stateSync(action, m_widget->actionEditCut); + action = KStdAction::copy(this, SLOT(editCopy()), actionCollection()); + stateSync(action, m_widget->actionEditCopy); + action = KStdAction::paste(this, SLOT(editPaste()), actionCollection()); + stateSync(action, m_widget->actionEditPaste); + action = new KAction(i18n("&Delete"), Key_Delete, this, SLOT(editDelete()), actionCollection(), "edit_delete"); + stateSync(action, m_widget->actionEditDelete); + action = KStdAction::selectAll(this, SLOT(editSelectAll()), actionCollection()); + stateSync(action, m_widget->actionEditSelectAll); + action = new KAction(i18n("Chec&k Accelerators"), ALT + Key_R, this, SLOT(editAccels()), actionCollection(), "edit_accels"); + stateSync(action, m_widget->actionEditAccels); + action = new KAction(i18n("S&lots..."), createPartIconSet("designer_editslots.png"), 0, this, SLOT(editFunctions()), actionCollection(), "edit_functions"); + stateSync(action, m_widget->actionEditFunctions); + action = new KAction(i18n("Co&nnections..."), createPartIconSet("designer_connecttool.png"), 0, this, SLOT(editConnections()), actionCollection(), "edit_connections"); + stateSync(action, m_widget->actionEditConnections); + action = new KAction(i18n("&Form Settings..."), 0, this, SLOT(editFormSettings()), actionCollection(), "edit_formsettings"); + stateSync(action, m_widget->actionEditFormSettings); + + action = new KAction(i18n("&Add File..."), 0, this, SLOT(projectAddFile()), actionCollection(), "project_addfile"); + stateSync(action, m_widget->actionProjectAddFile); + action = new KAction(i18n("&Image Collection..."), 0, this, SLOT(projectImageCollection()), actionCollection(), "project_imagecollection"); + stateSync(action, m_widget->actionEditPixmapCollection); + action = new KAction(i18n("&Database Connections..."), 0, this, SLOT(projectDatabaseCollections()), actionCollection(), "project_databasecollections"); + stateSync(action, m_widget->actionEditDatabaseConnections); + action = new KAction(i18n("&Designer Project Settings..."), 0, this, SLOT(projectSettings()), actionCollection(), "project_settings"); + stateSync(action, m_widget->actionEditProjectSettings); + + KRadioAction *toggle; + toggle = new KRadioAction(i18n("&Pointer"), createPartIconSet("designer_pointer.png"), Key_F2, actionCollection(), "tools_pointer"); + setupToolsAction(toggle, m_widget->actionPointerTool); + pointerAction = toggle; + toggle = new KRadioAction(i18n("&Connect Signal/Slots"), createPartIconSet("designer_connecttool.png"), Key_F3, actionCollection(), "tools_connect"); + setupToolsAction(toggle, m_widget->actionConnectTool); + toggle = new KRadioAction(i18n("Tab &Order"), createPartIconSet("designer_ordertool.png"), Key_F4, actionCollection(), "tools_taborder"); + setupToolsAction(toggle, m_widget->actionOrderTool); + toggle = new KRadioAction(i18n("Set &Buddy"), createPartIconSet("designer_setbuddy.png"), Key_F12, actionCollection(), "tools_setbuddy"); + setupToolsAction(toggle, m_widget->actionBuddyTool); + new KAction(i18n("Configure Toolbox..."), 0, this, SLOT(toolsConfigureToolbox()), actionCollection(), "tools_toolbox"); + new KAction(i18n("Edit &Custom Widgets..."), 0, this, SLOT(toolsEditCustomWidgets()), actionCollection(), "tools_editcustomwidgets"); + + action = new KAction(i18n("Adjust &Size"), createPartIconSet("designer_adjustsize.png"), CTRL + Key_J, this, SLOT(layoutAdjustSize()), actionCollection(), "layout_adjustsize"); + stateSync(action, m_widget->actionEditAdjustSize); + action = new KAction(i18n("Lay Out &Horizontally"), createPartIconSet("designer_edithlayout.png"), CTRL + Key_H, this, SLOT(layoutHLayout()), actionCollection(), "layout_h"); + stateSync(action, m_widget->actionEditHLayout); + action = new KAction(i18n("Lay Out &Vertically"), createPartIconSet("designer_editvlayout.png"), CTRL + Key_V, this, SLOT(layoutVLayout()), actionCollection(), "layout_v"); + stateSync(action, m_widget->actionEditVLayout); + action = new KAction(i18n("Lay Out in &Grid"), createPartIconSet("designer_editgrid.png"), CTRL + Key_G, this, SLOT(layoutGridLayout()), actionCollection(), "layout_grid"); + stateSync(action, m_widget->actionEditGridLayout); + action = new KAction(i18n("Lay Out Horizontally (in S&plitter)"), createPartIconSet("designer_editvlayoutsplit.png"), 0, this, SLOT(layoutSplitHLayout()), actionCollection(), "layout_splith"); + stateSync(action, m_widget->actionEditSplitHorizontal); + action = new KAction(i18n("Lay Out Vertically (in Sp&litter)"), createPartIconSet("designer_edithlayoutsplit.png"), 0, this, SLOT(layoutSplitVLayout()), actionCollection(), "layout_splitv"); + stateSync(action, m_widget->actionEditSplitVertical); + action = new KAction(i18n("&Break Layout"), createPartIconSet("designer_editbreaklayout.png"), CTRL + Key_B, this, SLOT(layoutBreak()), actionCollection(), "layout_break"); + stateSync(action, m_widget->actionEditBreakLayout); + toggle = new KRadioAction(i18n("Add Spacer"), createPartIconSet("designer_spacer.png"), 0, actionCollection(), "layout_spacer"); + setupToolsAction(toggle, m_widget->actionInsertSpacer); + + action = new KAction(i18n("Preview &Form"), CTRL + Key_T, this, SLOT(windowPreview()), actionCollection(), "window_preview"); + stateSync(action, m_widget->actionPreview); + action = new KAction(i18n("Ne&xt Form"), CTRL + Key_F6, this, SLOT(windowNext()), actionCollection(), "window_next"); + stateSync(action, m_widget->actionWindowNext); + action = new KAction(i18n("Pre&vious Form"), CTRL + SHIFT + Key_F6, this, SLOT(windowPrev()), actionCollection(), "window_prev"); + stateSync(action, m_widget->actionWindowPrevious); + + action = KStdAction::preferences(this, SLOT(editPreferences()), actionCollection()); + action->setText(i18n("Configure &KDevDesigner...")); + stateSync(action, m_widget->actionEditPreferences); +} + +KDevDesignerPart::~KDevDesignerPart() +{ +} + +void KDevDesignerPart::setReadWrite(bool rw) +{ + ReadWritePart::setReadWrite(rw); +} + +void KDevDesignerPart::setModified(bool modified) +{ +/* KAction *save = actionCollection()->action(KStdAction::stdName(KStdAction::Save)); + if (!save) + return; + if (modified) + save->setEnabled(true); + else + save->setEnabled(false);*/ + + ReadWritePart::setModified(modified); +} + +bool KDevDesignerPart::openFile() +{ + m_widget->fileOpen("", "", m_file); + return true; +} + +bool KDevDesignerPart::saveFile() +{ + if (isReadWrite() == false) + return false; + m_widget->actionFileSaveAll->activate(); + return true; +} + +void KDevDesignerPart::stateSync( KAction * kaction, QAction * qaction ) +{ + if (!qaction) + return; + kaction->setEnabled(qaction->isEnabled()); + DesignerAction *ac = dynamic_cast<DesignerAction*>(qaction); + if (!ac) + return; + connect(ac, SIGNAL(actionEnabled(bool )), kaction, SLOT(setEnabled(bool ))); +} + +void KDevDesignerPart::setupToolsAction( KRadioAction * toggle, QAction * action ) +{ + if (!action) + return; + + toggle->setGroup("tools"); + toggle->setExclusiveGroup("tools"); + connect(action, SIGNAL(toggled(bool )), this, SLOT(setToggleActionChecked(bool ))); + connect(toggle, SIGNAL(toggled(bool)), this, SLOT(setToggleActionOn(bool))); + toggle->setChecked(action->isOn()); + m_actionMap[action] = toggle; + m_actionMap2[toggle] = action; +} + + +// It's usually safe to leave the factory code alone.. with the +// notable exception of the KAboutData data +#include <kaboutdata.h> +#include <klocale.h> + +KInstance* KDevDesignerPartFactory::s_instance = 0L; +KAboutData* KDevDesignerPartFactory::s_about = 0L; + +KDevDesignerPartFactory::KDevDesignerPartFactory() + : KParts::Factory() +{ +} + +KDevDesignerPartFactory::~KDevDesignerPartFactory() +{ + delete s_instance; + delete s_about; + + s_instance = 0L; +} + +KParts::Part* KDevDesignerPartFactory::createPartObject( QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, + const char *classname, const QStringList &args ) +{ + // Create an instance of our Part + KDevDesignerPart* obj = new KDevDesignerPart( parentWidget, widgetName, parent, name, args ); + + // See if we are to be read-write or not + if (QCString(classname) == "KParts::ReadOnlyPart") + obj->setReadWrite(false); + + return obj; +} + +KInstance* KDevDesignerPartFactory::instance() +{ + if( !s_instance ) + { + s_about = new KAboutData("kdevdesignerpart", I18N_NOOP("KDevDesignerPart"), "0.1"); + s_about->addAuthor("Alexander Dymo", 0, "cloudtemple@mksat.net"); + s_about->addAuthor("Trolltech AS", 0, "info@trolltech.com"); + s_instance = new KInstance(s_about); + } + return s_instance; +} + +extern "C" +{ + void* init_libkdevdesignerpart() + { + return new KDevDesignerPartFactory; + } +} + +//actions + +void KDevDesignerPart::fileNew( ) +{ + if (!m_widget->actionNewFile) + { + qWarning("wrong m_widget->actionNewFile"); + return; + } + m_widget->actionNewFile->activate(); +} + +void KDevDesignerPart::fileOpen() +{ + m_widget->fileOpen(); +} + +void KDevDesignerPart::fileSaveAs() +{ + m_widget->actionFileSaveAs->activate(); +} + +void KDevDesignerPart::fileClose( ) +{ + m_widget->actionFileClose->activate(); +} + +void KDevDesignerPart::fileCreateTemplate( ) +{ + m_widget->fileCreateTemplate(); +} + +void KDevDesignerPart::editUndo( ) +{ + m_widget->actionEditUndo->activate(); +} + +void KDevDesignerPart::editRedo( ) +{ + m_widget->actionEditRedo->activate(); +} + +void KDevDesignerPart::editCut( ) +{ + m_widget->actionEditCut->activate(); +} + +void KDevDesignerPart::editPaste( ) +{ + m_widget->actionEditPaste->activate(); +} + +void KDevDesignerPart::editCopy( ) +{ + m_widget->actionEditCopy->activate(); +} + +void KDevDesignerPart::editDelete( ) +{ + m_widget->actionEditDelete->activate(); +} + +void KDevDesignerPart::editSelectAll( ) +{ + m_widget->actionEditSelectAll->activate(); +} + +void KDevDesignerPart::editAccels( ) +{ + m_widget->actionEditAccels->activate(); +} + +void KDevDesignerPart::editFunctions( ) +{ + m_widget->actionEditFunctions->activate(); +} + +void KDevDesignerPart::editConnections( ) +{ + m_widget->actionEditConnections->activate(); +} + +void KDevDesignerPart::editFormSettings( ) +{ + m_widget->actionEditFormSettings->activate(); +} + +void KDevDesignerPart::editPreferences( ) +{ + m_widget->actionEditPreferences->activate(); +} + +void KDevDesignerPart::projectAddFile( ) +{ + m_widget->actionProjectAddFile->activate(); +} + +void KDevDesignerPart::projectImageCollection( ) +{ + m_widget->actionEditPixmapCollection->activate(); +} + +void KDevDesignerPart::projectDatabaseCollections( ) +{ + m_widget->actionEditDatabaseConnections->activate(); +} + +void KDevDesignerPart::projectSettings( ) +{ + m_widget->actionEditProjectSettings->activate(); +} + +void KDevDesignerPart::toolsConfigureToolbox( ) +{ + m_widget->toolsConfigure(); +} + +void KDevDesignerPart::layoutAdjustSize( ) +{ + m_widget->actionEditAdjustSize->activate(); +} + +void KDevDesignerPart::layoutHLayout( ) +{ + m_widget->actionEditHLayout->activate(); +} + +void KDevDesignerPart::layoutVLayout( ) +{ + m_widget->actionEditVLayout->activate(); +} + +void KDevDesignerPart::layoutGridLayout( ) +{ + m_widget->actionEditGridLayout->activate(); +} + +void KDevDesignerPart::layoutSplitHLayout( ) +{ + m_widget->actionEditSplitHorizontal->activate(); +} + +void KDevDesignerPart::layoutSplitVLayout( ) +{ + m_widget->actionEditSplitVertical->activate(); +} + +void KDevDesignerPart::layoutBreak( ) +{ + m_widget->actionEditBreakLayout->activate(); +} + +void KDevDesignerPart::windowPreview( ) +{ + m_widget->actionPreview->activate(); +} + +void KDevDesignerPart::windowNext( ) +{ + m_widget->actionWindowNext->activate(); +} + +void KDevDesignerPart::windowPrev( ) +{ + m_widget->actionWindowPrevious->activate(); +} + +void KDevDesignerPart::statusMessage( const QString & msg ) +{ + emit setStatusBarText(msg); +} + +void KDevDesignerPart::setToggleActionChecked( bool b) +{ + if (!sender()) + return; + const QAction *action = dynamic_cast<const QAction*>(sender()); + if (!action) + return; + if (b) + { + if (action == m_widget->actionPointerTool) + pointerAction->setChecked(true); + return; + } + KRadioAction *kaction = m_actionMap[action]; + if (!kaction) + return; +// kdDebug() << "untoggle action: " << kaction->text() << endl; + kaction->blockSignals(true); + kaction->setChecked(b); + kaction->blockSignals(false); +} + +void KDevDesignerPart::setToggleActionOn( bool b ) +{ + if (!sender()) + return; + const KRadioAction *action = dynamic_cast<const KRadioAction *>(sender()); + if (!action) + return; +// kdDebug() << (b?QString("toggle"):QString("untoggle")) << " action: " << action->text() << endl; + QAction *qaction = m_actionMap2[action]; + if (!qaction) + return; + disconnect(qaction, SIGNAL(toggled(bool )), this, SLOT(setToggleActionChecked(bool ))); + qaction->setOn(b); + connect(qaction, SIGNAL(toggled(bool )), this, SLOT(setToggleActionChecked(bool ))); +} + +void KDevDesignerPart::openProject( const QString & // projectFile + ) +{ + //TODO: implement + return; +} + +KInterfaceDesigner::DesignerType KDevDesignerPart::designerType( ) +{ + return KInterfaceDesigner::QtDesigner; +} + +void KDevDesignerPart::emitAddedFunction( const QString & form, KInterfaceDesigner::Function func ) +{ + kdDebug() << "KDevDesignerPart::emitAddedFunction: form " << form << ", function: " << func.function << endl; + emit addedFunction(designerType(), form, func); +} + +void KDevDesignerPart::emitRemovedFunction( const QString & form, KInterfaceDesigner::Function func ) +{ + kdDebug() << "KDevDesignerPart::emitRemovedFunction: form " << form << ", function: " << func.function << endl; + emit removedFunction(designerType(), form, func); +} + +void KDevDesignerPart::emitEditedFunction( const QString & form, KInterfaceDesigner::Function oldFunc, KInterfaceDesigner::Function func ) +{ + kdDebug() << "KDevDesignerPart::emitEditedFunction: form " << form + << ", old function: " << oldFunc.function + << ", function: " << func.function << endl; + +// m_widget->formWindow()->clearSelection(false); + emit editedFunction(designerType(), form, oldFunc, func); +} + +void KDevDesignerPart::emitEditFunction(const QString &formName, const QString &functionName) +{ + kdDebug() << "KDevDesignerPart::emitEditedFunction: form " << formName + << ", function: " << functionName << endl; + emit editFunction(designerType(), formName, functionName); +} + +void KDevDesignerPart::formModified(bool b) +{ + kdDebug() << "KDevDesignerPart::formModified " << b << endl; + setModified(b); +} + +void KDevDesignerPart::emitEditSource(const QString &formName) +{ + emit editSource(designerType(), formName); +} + +void KDevDesignerPart::emitNewStatus(const QString &formName, int status) +{ + emit newStatus(formName, status); +} + +void KDevDesignerPart::toolsEditCustomWidgets( ) +{ + m_widget->toolsCustomWidget(); +} + +#include "kdevdesigner_part.moc" diff --git a/kdevdesigner/designer/kdevdesigner_part.desktop b/kdevdesigner/designer/kdevdesigner_part.desktop new file mode 100644 index 00000000..2451bd55 --- /dev/null +++ b/kdevdesigner/designer/kdevdesigner_part.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Name=KDevDesignerPart +Name[da]=KDevelop Designer-part +Name[el]=ΤμήμαKDevDesigner +Name[nds]=Kdevelop-Makerkomponent +Name[ne]=केडीई विकास डिजाइनर भाग +Name[sv]=KDevelop designerdel +Name[ta]=கேமேம்பாட்டு வடிவமைப்பாளர் பகுதி +Name[tg]=KDevҚисми дизайнгар +Name[zh_TW]=KDevelop 設計元件 +MimeType=application/x-designer +ServiceTypes=KParts/ReadOnlyPart,KParts/ReadWritePart +X-KDE-Library=libkdevdesignerpart +Type=Service +InitialPreference=10 + diff --git a/kdevdesigner/designer/kdevdesigner_part.h b/kdevdesigner/designer/kdevdesigner_part.h new file mode 100644 index 00000000..70712210 --- /dev/null +++ b/kdevdesigner/designer/kdevdesigner_part.h @@ -0,0 +1,146 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _KDEVDESIGNERPART_H_ +#define _KDEVDESIGNERPART_H_ + +#include <qmap.h> + +#include <kparts/part.h> +#include <kparts/factory.h> + +#include "designer.h" + +class QWidget; +class QPainter; +class KURL; +class MainWindow; +class KAction; +class QAction; +class KRadioAction; + +class KDevDesignerPart : public KInterfaceDesigner::Designer +{ + Q_OBJECT +public: + KDevDesignerPart(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, const QStringList &args); + virtual ~KDevDesignerPart(); + + virtual void setReadWrite(bool rw); + virtual void setModified(bool modified); + + void statusMessage(const QString &msg); + + //KInterfaceDesigner::Designer methods + virtual void openProject(const QString &projectFile); + virtual KInterfaceDesigner::DesignerType designerType(); + + void emitAddedFunction(const QString &form, KInterfaceDesigner::Function func); + void emitEditedFunction(const QString &form, KInterfaceDesigner::Function oldFunc, KInterfaceDesigner::Function func); + void emitRemovedFunction(const QString &form, KInterfaceDesigner::Function func); + + void emitEditFunction(const QString &formName, const QString &functionName); + void emitEditSource(const QString &formName); + + void emitNewStatus(const QString &formName, int status); + +protected: + virtual bool openFile(); + virtual bool saveFile(); + + void setupDesignerWindow(); + void setupActions(); + + void stateSync(KAction *kaction, QAction *qaction); + void setupToolsAction(KRadioAction *toggle, QAction *action); + +protected slots: + void setToggleActionChecked(bool b); + void setToggleActionOn(bool b); + + void fileNew(); + void fileOpen(); + void fileClose(); + void fileSaveAs(); + void fileCreateTemplate(); + + void editUndo(); + void editRedo(); + void editCut(); + void editCopy(); + void editPaste(); + void editDelete(); + void editSelectAll(); + void editAccels(); + void editFunctions(); + void editConnections(); + void editFormSettings(); + void editPreferences(); + + void projectAddFile(); + void projectImageCollection(); + void projectDatabaseCollections(); + void projectSettings(); + + void toolsConfigureToolbox(); + void toolsEditCustomWidgets(); + + void layoutAdjustSize(); + void layoutHLayout(); + void layoutVLayout(); + void layoutGridLayout(); + void layoutSplitHLayout(); + void layoutSplitVLayout(); + void layoutBreak(); + + void windowPreview(); + void windowNext(); + void windowPrev(); + + void formModified(bool b); +private: + MainWindow *m_widget; + + QMap<const QAction*, KRadioAction*> m_actionMap; + QMap<const KRadioAction*, QAction*> m_actionMap2; + KRadioAction* pointerAction; +}; + +class KInstance; +class KAboutData; + +class KDevDesignerPartFactory : public KParts::Factory +{ + Q_OBJECT +public: + KDevDesignerPartFactory(); + virtual ~KDevDesignerPartFactory(); + virtual KParts::Part* createPartObject( QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, + const char *classname, const QStringList &args ); + static KInstance* instance(); + +private: + static KInstance* s_instance; + static KAboutData* s_about; +}; + +#endif // _KDEVDESIGNERPART_H_ diff --git a/kdevdesigner/designer/kdevdesigner_part.rc b/kdevdesigner/designer/kdevdesigner_part.rc new file mode 100644 index 00000000..71adcdc9 --- /dev/null +++ b/kdevdesigner/designer/kdevdesigner_part.rc @@ -0,0 +1,121 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kdevdesigner_part" version="6"> +<MenuBar> + <Menu name="file" noMerge="1"><text>&File</text> + <Action name="file_createtemplate" group="new_merge"/> + <Action name="file_save" group="save_merge"/> + <Action name="file_save_as" group="save_merge"/> + </Menu> + + <Menu name="edit" noMerge="1"><text>&Edit</text> + <Action name="edit_undo" group="edit_undo_merge"/> + <Action name="edit_redo" group="edit_undo_merge"/> + <Separator group="edit_undo_merge"/> + <Action name="edit_cut" group="edit_paste_merge"/> + <Action name="edit_copy" group="edit_paste_merge"/> + <Action name="edit_paste" group="edit_paste_merge"/> + <Separator group="edit_paste_merge"/> + <Action name="edit_delete" group="edit_select_merge"/> + <Action name="edit_select_all" group="edit_select_merge"/> + <Separator group="edit_select_merge"/> + <Action name="edit_accels" group="edit_select_merge"/> + <Separator group="edit_select_merge"/> + <Action name="edit_functions" group="edit_select_merge"/> + <Action name="edit_connections" group="edit_select_merge"/> + <Action name="edit_formsettings" group="edit_select_merge"/> + <Separator group="edit_select_merge"/> + </Menu> + + <Menu name="project" noMerge="1"><text>&Project</text> + <Action name="project_imagecollection" group="designer_project"/> + <Action name="project_databasecollections" group="designer_project"/> + <Separator group="designer_project"/> + <Action name="project_settings" group="designer_project"/> + <Separator group="designer_project"/> + </Menu> + + <Menu name="tools" noMerge="1"><text>&Tools</text> + <Action name="tools_pointer" group="tools_operations"/> + <Action name="tools_connect" group="tools_operations"/> + <Action name="tools_taborder" group="tools_operations"/> + <Action name="tools_setbuddy" group="tools_operations"/> + <Action name="tools_toolbox" group="tools_operations"/> + <Action name="tools_editcustomwidgets" group="tools_operations"/> + <Separator group="tools_operations"/> + </Menu> + + <Menu name="layout" noMerge="1"><text>&Layout</text> + <Action name="layout_adjustsize"/> + <Separator/> + <Action name="layout_h"/> + <Action name="layout_v"/> + <Action name="layout_grid"/> + <Action name="layout_splith"/> + <Action name="layout_splitv"/> + <Action name="layout_break"/> + <Separator/> + <Action name="layout_spacer"/> + </Menu> + + <Menu name="settings" noMerge="1"><text>&Settings</text> + <Action name="options_configure" group="configure_merge"/> + </Menu> + + <Menu name="window" noMerge="1"><text>&Window</text> + <Action name="window_preview" group="window_operations"/> + <Separator group="window_operations"/> + <Action name="window_next" group="window_operations"/> + <Action name="window_prev" group="window_operations"/> + </Menu> + +</MenuBar> + +<!--<ToolBar name="fileToolBar" noMerge="1"><text>File Toolbar</text> + <Action name="file_new"/> + <Action name="file_open"/> + <Action name="file_save"/> +</ToolBar> + +<ToolBar name="editToolBar" noMerge="1"><text>Edit Toolbar</text> + <Action name="edit_undo"/> + <Action name="edit_redo"/> + <Separator/> + <Action name="edit_cut"/> + <Action name="edit_copy"/> + <Action name="edit_paste"/> +</ToolBar> --> + +<ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text> + <Action name="file_open" group="file_operations"/> + <Action name="file_save" group="file_operations"/> + <Separator group="file_operations"/> + <Action name="edit_undo" group="edit_operations"/> + <Action name="edit_redo" group="edit_operations"/> + <Separator group="edit_operations"/> + <Action name="edit_cut" group="edit_operations"/> + <Action name="edit_copy" group="edit_operations"/> + <Action name="edit_paste" group="edit_operations"/> +</ToolBar> + + +<ToolBar name="layoutToolBar" noMerge="1"><text>Layout Toolbar</text> + <Action name="layout_adjustsize"/> + <Separator/> + <Action name="layout_h"/> + <Action name="layout_v"/> + <Action name="layout_grid"/> + <Action name="layout_splith"/> + <Action name="layout_splitv"/> + <Action name="layout_break"/> + <Separator/> + <Action name="layout_spacer"/> +</ToolBar> + +<ToolBar name="toolsToolBar" noMerge="1"><text>Tools Toolbar</text> + <Action name="tools_pointer"/> + <Action name="tools_connect"/> + <Action name="tools_taborder"/> + <Action name="tools_setbuddy"/> +</ToolBar> + +</kpartgui> diff --git a/kdevdesigner/designer/kdevdesigner_part_sh.rc b/kdevdesigner/designer/kdevdesigner_part_sh.rc new file mode 100644 index 00000000..eb6b503b --- /dev/null +++ b/kdevdesigner/designer/kdevdesigner_part_sh.rc @@ -0,0 +1,116 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kdevdesigner_part" version="4"> +<MenuBar> + <Menu name="file" noMerge="1"><text>&File</text> + <Action name="file_new" group="new_merge"/> + <Action name="file_open" group="open_merge"/> + <Separator/> + <Action name="file_close" group="close_merge"/> + <Separator/> + <Action name="file_save" group="save_merge"/> + <Action name="file_save_as" group="save_merge"/> + <Action name="file_saveall" group="save_merge"/> + <Separator/> + <Action name="file_createtemplate"/> + <Separator/> + </Menu> + + <Menu name="edit" noMerge="1"><text>&Edit</text> + <Action name="edit_undo" group="edit_undo_merge"/> + <Action name="edit_redo" group="edit_undo_merge"/> + <Separator group="edit_undo_merge"/> + <Action name="edit_cut" group="edit_paste_merge"/> + <Action name="edit_copy" group="edit_paste_merge"/> + <Action name="edit_paste" group="edit_paste_merge"/> + <Separator group="edit_paste_merge"/> + <Action name="edit_delete" group="edit_select_merge"/> + <Action name="edit_select_all" group="edit_select_merge"/> + <Separator group="edit_select_merge"/> + <Action name="edit_accels"/> + <Separator/> + <Action name="edit_functions"/> + <Action name="edit_connections"/> + <Action name="edit_formsettings"/> + </Menu> + + <Menu name="project" noMerge="1"><text>&Project</text> + <Action name="project_addfile"/> + <Action name="project_imagecollection"/> + <Action name="project_databasecollections"/> + <Separator/> + <Action name="project_settings"/> + </Menu> + + <Menu name="tools" noMerge="1"><text>&Tools</text> + <Action name="tools_pointer" group="tools_operations"/> + <Action name="tools_connect" group="tools_operations"/> + <Action name="tools_taborder" group="tools_operations"/> + <Action name="tools_setbuddy" group="tools_operations"/> + <Action name="tools_toolbox" group="tools_operations"/> + <Action name="tools_editcustomwidgets" group="tools_operations"/> +<!-- <Separator/> + <Action name="tools_toolbox"/>--> + </Menu> + + <Menu name="layout" noMerge="1"><text>&Layout</text> + <Action name="layout_adjustsize"/> + <Separator/> + <Action name="layout_h"/> + <Action name="layout_v"/> + <Action name="layout_grid"/> + <Action name="layout_splith"/> + <Action name="layout_splitv"/> + <Action name="layout_break"/> + <Separator/> + <Action name="layout_spacer"/> + </Menu> + + <Menu name="settings" noMerge="1"><text>&Settings</text> + <Action name="options_configure"/> + </Menu> + + <Menu name="window" noMerge="1"><text>&Window</text> + <Action name="window_preview" group="window_operations"/> + <Separator/> + <Action name="window_next" group="window_operations"/> + <Action name="window_prev" group="window_operations"/> + </Menu> + +</MenuBar> + +<ToolBar name="fileToolBar" noMerge="1"><text>File Toolbar</text> + <Action name="file_new"/> + <Action name="file_open"/> + <Action name="file_save"/> +</ToolBar> + +<ToolBar name="editToolBar" noMerge="1"><text>Edit Toolbar</text> + <Action name="edit_undo"/> + <Action name="edit_redo"/> + <Separator/> + <Action name="edit_cut"/> + <Action name="edit_copy"/> + <Action name="edit_paste"/> +</ToolBar> + +<ToolBar name="layoutToolBar" noMerge="1"><text>Layout Toolbar</text> + <Action name="layout_adjustsize"/> + <Separator/> + <Action name="layout_h"/> + <Action name="layout_v"/> + <Action name="layout_grid"/> + <Action name="layout_splith"/> + <Action name="layout_splitv"/> + <Action name="layout_break"/> + <Separator/> + <Action name="layout_spacer"/> +</ToolBar> + +<ToolBar name="toolsToolBar" noMerge="1"><text>Tools Toolbar</text> + <Action name="tools_pointer"/> + <Action name="tools_connect"/> + <Action name="tools_taborder"/> + <Action name="tools_setbuddy"/> +</ToolBar> + +</kpartgui> diff --git a/kdevdesigner/designer/layout.cpp b/kdevdesigner/designer/layout.cpp new file mode 100644 index 00000000..2926b4f6 --- /dev/null +++ b/kdevdesigner/designer/layout.cpp @@ -0,0 +1,1017 @@ +/********************************************************************** +** 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 "formwindow.h" +#include "layout.h" +#include <widgetdatabase.h> +#include "widgetfactory.h" + +#include <qlayout.h> +#include <qevent.h> +#include <qpainter.h> +#include <qpen.h> +#include <qbitmap.h> +#include <qsplitter.h> +#include <qvaluevector.h> +#include <qmainwindow.h> + +bool operator<( const QGuardedPtr<QWidget> &p1, const QGuardedPtr<QWidget> &p2 ) +{ + return p1.operator->() < p2.operator->(); +} + +/*! + \class Layout layout.h + \brief Baseclass for layouting widgets in the Designer + + Classes derived from this abstract base class are used for layouting + operations in the Designer. + +*/ + +/*! \a p specifies the parent of the layoutBase \a lb. The parent + might be changed in setup(). If the layoutBase is a + container, the parent and the layoutBase are the same. Also they + always have to be a widget known to the designer (e.g. in the case + of the tabwidget parent and layoutBase are the tabwidget and not the + page which actually gets laid out. For actual usage the correct + widget is found later by Layout.) + */ + +Layout::Layout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup, bool splitter ) + : widgets( wl ), parent( p ), formWindow( fw ), isBreak( !doSetup ), useSplitter( splitter ) +{ + widgets.setAutoDelete( FALSE ); + layoutBase = lb; + if ( !doSetup && layoutBase ) + oldGeometry = layoutBase->geometry(); +} + +/*! The widget list we got in the constructor might contain too much + widgets (like widgets with different parents, already laid out + widgets, etc.). Here we set up the list and so the only the "best" + widgets get laid out. +*/ + +void Layout::setup() +{ + startPoint = QPoint( 32767, 32767 ); + QValueList<QWidgetList> lists; + QWidget *lastParent = 0; + QWidgetList *lastList = 0; + QWidget *w = 0; + + // Go through all widgets of the list we got. As we can only + // layout widgets which have the same parent, we first do some + // sorting which means create a list for each parent containing + // its child here. After that we keep working on the list of + // childs which has the most entries. + // Widgets which are already laid out are thrown away here too + for ( w = widgets.first(); w; w = widgets.next() ) { + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + continue; + if ( lastParent != w->parentWidget() ) { + lastList = 0; + lastParent = w->parentWidget(); + QValueList<QWidgetList>::Iterator it = lists.begin(); + for ( ; it != lists.end(); ++it ) { + if ( ( *it ).first()->parentWidget() == w->parentWidget() ) + lastList = &( *it ); + } + if ( !lastList ) { + QWidgetList l; + l.setAutoDelete( FALSE ); + lists.append( l ); + lastList = &lists.last(); + } + } + lastList->append( w ); + } + + // So, now find the list with the most entries + lastList = 0; + QValueList<QWidgetList>::Iterator it = lists.begin(); + for ( ; it != lists.end(); ++it ) { + if ( !lastList || ( *it ).count() > lastList->count() ) + lastList = &( *it ); + } + + // If we found no list (because no widget did fit at all) or the + // best list has only one entry and we do not layout a container, + // we leave here. + if ( !lastList || ( lastList->count() < 2 && + ( !layoutBase || + ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( layoutBase ) ) ) && + layoutBase != formWindow->mainContainer() ) ) + ) ) { + widgets.clear(); + startPoint = QPoint( 0, 0 ); + return; + } + + // Now we have a new and clean widget list, which makes sense + // to layout + widgets = *lastList; + // Also use the only correct parent later, so store it + parent = WidgetFactory::widgetOfContainer( widgets.first()->parentWidget() ); + // Now calculate the position where the layout-meta-widget should + // be placed and connect to widgetDestroyed() signals of the + // widgets to get informed if one gets deleted to be able to + // handle that and do not crash in this case + for ( w = widgets.first(); w; w = widgets.next() ) { + connect( w, SIGNAL( destroyed() ), + this, SLOT( widgetDestroyed() ) ); + startPoint = QPoint( QMIN( startPoint.x(), w->x() ), + QMIN( startPoint.y(), w->y() ) ); + geometries.insert( w, QRect( w->pos(), w->size() ) ); + // Change the Z-order, as saving/loading uses the Z-order for + // writing/creating widgets and this has to be the same as in + // the layout. Else saving + loading will give different results + w->raise(); + } +} + +void Layout::widgetDestroyed() +{ + if ( sender() && sender()->isWidgetType() ) + widgets.removeRef( (QWidget*)sender() ); +} + +bool Layout::prepareLayout( bool &needMove, bool &needReparent ) +{ + if ( !widgets.count() ) + return FALSE; + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) + w->raise(); + needMove = !layoutBase; + needReparent = needMove || ::qt_cast<QLayoutWidget*>(layoutBase) || ::qt_cast<QSplitter*>(layoutBase); + if ( !layoutBase ) { + if ( !useSplitter ) + layoutBase = WidgetFactory::create( WidgetDatabase::idFromClassName( "QLayoutWidget" ), + WidgetFactory::containerOfWidget( parent ) ); + else + layoutBase = WidgetFactory::create( WidgetDatabase::idFromClassName( "QSplitter" ), + WidgetFactory::containerOfWidget( parent ) ); + } else { + WidgetFactory::deleteLayout( layoutBase ); + } + + return TRUE; +} + +void Layout::finishLayout( bool needMove, QLayout *layout ) +{ + if ( needMove ) + layoutBase->move( startPoint ); + QRect g( QRect( layoutBase->pos(), layoutBase->size() ) ); + if ( WidgetFactory::layoutType( layoutBase->parentWidget() ) == WidgetFactory::NoLayout && !isBreak ) + layoutBase->adjustSize(); + else if ( isBreak ) + layoutBase->setGeometry( oldGeometry ); + oldGeometry = g; + layoutBase->show(); + layout->activate(); + formWindow->insertWidget( layoutBase ); + formWindow->selectWidget( layoutBase ); + QString n = layoutBase->name(); + if ( n.find( "qt_dead_widget_" ) != -1 ) { + n.remove( 0, QString( "qt_dead_widget_" ).length() ); + layoutBase->setName( n ); + } +} + +void Layout::undoLayout() +{ + if ( !widgets.count() ) + return; + QMap<QGuardedPtr<QWidget>, QRect>::Iterator it = geometries.begin(); + for ( ; it != geometries.end(); ++it ) { + if ( !it.key() ) + continue; + it.key()->reparent( WidgetFactory::containerOfWidget( parent ), 0, ( *it ).topLeft(), it.key()->isVisibleTo( formWindow ) ); + it.key()->resize( ( *it ).size() ); + } + formWindow->selectWidget( layoutBase, FALSE ); + WidgetFactory::deleteLayout( layoutBase ); + if ( parent != layoutBase && !::qt_cast<QMainWindow*>(layoutBase) ) { + layoutBase->hide(); + QString n = layoutBase->name(); + n.prepend( "qt_dead_widget_" ); + layoutBase->setName( n ); + } else { + layoutBase->setGeometry( oldGeometry ); + } + if ( widgets.first() ) + formWindow->selectWidget( widgets.first() ); + else + formWindow->selectWidget( formWindow ); +} + +void Layout::breakLayout() +{ + QMap<QWidget*, QRect> rects; + if ( !widgets.isEmpty() ) { + QWidget *w; + for ( w = widgets.first(); w; w = widgets.next() ) + rects.insert( w, w->geometry() ); + } + WidgetFactory::deleteLayout( layoutBase ); + bool needReparent = qstrcmp( layoutBase->className(), "QLayoutWidget" ) == 0 || + qstrcmp( layoutBase->className(), "QSplitter" ) == 0 || + ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( layoutBase ) ) ) && + layoutBase != formWindow->mainContainer() ); + bool needResize = qstrcmp( layoutBase->className(), "QSplitter" ) == 0; + bool add = geometries.isEmpty(); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( needReparent ) + w->reparent( layoutBase->parentWidget(), 0, + layoutBase->pos() + w->pos(), TRUE ); + if ( needResize ) { + QMap<QWidget*, QRect>::Iterator it = rects.find( w ); + if ( it != rects.end() ) + w->setGeometry( QRect( layoutBase->pos() + (*it).topLeft(), (*it).size() ) ); + } + if ( add ) + geometries.insert( w, QRect( w->pos(), w->size() ) ); + } + if ( needReparent ) { + layoutBase->hide(); + parent = layoutBase->parentWidget(); + QString n = layoutBase->name(); + n.prepend( "qt_dead_widget_" ); + layoutBase->setName( n ); + } else { + parent = layoutBase; + } + if ( widgets.first() && widgets.first()->isVisibleTo( formWindow ) ) + formWindow->selectWidget( widgets.first() ); + else + formWindow->selectWidget( formWindow ); +} + +class HorizontalLayoutList : public QWidgetList +{ +public: + HorizontalLayoutList( const QWidgetList &l ) + : QWidgetList( l ) {} + + int compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 ) { + QWidget *w1 = (QWidget*)item1; + QWidget *w2 = (QWidget*)item2; + if ( w1->x() == w2->x() ) + return 0; + if ( w1->x() > w2->x() ) + return 1; + return -1; + } + +}; + +HorizontalLayout::HorizontalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup, bool splitter ) + : Layout( wl, p, fw, lb, doSetup, splitter ) +{ + if ( doSetup ) + setup(); +} + +void HorizontalLayout::setup() +{ + HorizontalLayoutList l( widgets ); + l.sort(); + widgets = l; + Layout::setup(); +} + +void HorizontalLayout::doLayout() +{ + bool needMove, needReparent; + if ( !prepareLayout( needMove, needReparent ) ) + return; + + QHBoxLayout *layout = (QHBoxLayout*)WidgetFactory::createLayout( layoutBase, 0, WidgetFactory::HBox ); + + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( needReparent && w->parent() != layoutBase ) + w->reparent( layoutBase, 0, QPoint( 0, 0 ), FALSE ); + if ( !useSplitter ) { + if ( qstrcmp( w->className(), "Spacer" ) == 0 ) + layout->addWidget( w, 0, ( (Spacer*)w )->alignment() ); + else + layout->addWidget( w ); + if ( ::qt_cast<QLayoutWidget*>(w) ) + ( (QLayoutWidget*)w )->updateSizePolicy(); + } + w->show(); + } + + if ( ::qt_cast<QSplitter*>(layoutBase) ) + ( (QSplitter*)layoutBase )->setOrientation( Qt::Horizontal ); + + finishLayout( needMove, layout ); +} + + + + +class VerticalLayoutList : public QWidgetList +{ +public: + VerticalLayoutList( const QWidgetList &l ) + : QWidgetList( l ) {} + + int compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 ) { + QWidget *w1 = (QWidget*)item1; + QWidget *w2 = (QWidget*)item2; + if ( w1->y() == w2->y() ) + return 0; + if ( w1->y() > w2->y() ) + return 1; + return -1; + } + +}; + +VerticalLayout::VerticalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup, bool splitter ) + : Layout( wl, p, fw, lb, doSetup, splitter ) +{ + if ( doSetup ) + setup(); +} + +void VerticalLayout::setup() +{ + VerticalLayoutList l( widgets ); + l.sort(); + widgets = l; + Layout::setup(); +} + +void VerticalLayout::doLayout() +{ + bool needMove, needReparent; + if ( !prepareLayout( needMove, needReparent ) ) + return; + + QVBoxLayout *layout = (QVBoxLayout*)WidgetFactory::createLayout( layoutBase, 0, WidgetFactory::VBox ); + + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( needReparent && w->parent() != layoutBase ) + w->reparent( layoutBase, 0, QPoint( 0, 0 ), FALSE ); + if ( !useSplitter ) { + if ( qstrcmp( w->className(), "Spacer" ) == 0 ) + layout->addWidget( w, 0, ( (Spacer*)w )->alignment() ); + else + layout->addWidget( w ); + if ( ::qt_cast<QLayoutWidget*>(w) ) + ( (QLayoutWidget*)w )->updateSizePolicy(); + } + w->show(); + } + + if ( ::qt_cast<QSplitter*>(layoutBase) ) + ( (QSplitter*)layoutBase )->setOrientation( Qt::Vertical ); + + finishLayout( needMove, layout ); +} + + + + + +class Grid +{ +public: + Grid( int rows, int cols ); + ~Grid(); + + QWidget* cell( int row, int col ) const { return cells[ row * ncols + col]; } + void setCell( int row, int col, QWidget* w ) { cells[ row*ncols + col] = w; } + void setCells( QRect c, QWidget* w ) { + for ( int rows = c.bottom()-c.top(); rows >= 0; rows--) + for ( int cols = c.right()-c.left(); cols >= 0; cols--) { + setCell(c.top()+rows, c.left()+cols, w); + } + } + int numRows() const { return nrows; } + int numCols() const { return ncols; } + + void simplify(); + bool locateWidget( QWidget* w, int& row, int& col, int& rowspan, int& colspan ); + +private: + void merge(); + int countRow( int r, int c ) const; + int countCol( int r, int c ) const; + void setRow( int r, int c, QWidget* w, int count ); + void setCol( int r, int c, QWidget* w, int count ); + bool isWidgetStartCol( int c ) const; + bool isWidgetEndCol( int c ) const; + bool isWidgetStartRow( int r ) const; + bool isWidgetEndRow( int r ) const; + bool isWidgetTopLeft( int r, int c ) const; + void extendLeft(); + void extendRight(); + void extendUp(); + void extendDown(); + QWidget** cells; + bool* cols; + bool* rows; + int nrows, ncols; + +}; + +Grid::Grid( int r, int c ) + : nrows( r ), ncols( c ) +{ + cells = new QWidget*[ r * c ]; + memset( cells, 0, sizeof( cells ) * r * c ); + rows = new bool[ r ]; + cols = new bool[ c ]; + +} + +Grid::~Grid() +{ + delete [] cells; + delete [] cols; + delete [] rows; +} + +int Grid::countRow( int r, int c ) const +{ + QWidget* w = cell( r, c ); + int i = c + 1; + while ( i < ncols && cell( r, i ) == w ) + i++; + return i - c; +} + +int Grid::countCol( int r, int c ) const +{ + QWidget* w = cell( r, c ); + int i = r + 1; + while ( i < nrows && cell( i, c ) == w ) + i++; + return i - r; +} + +void Grid::setCol( int r, int c, QWidget* w, int count ) +{ + for (int i = 0; i < count; i++ ) + setCell( r + i, c, w ); +} + +void Grid::setRow( int r, int c, QWidget* w, int count ) +{ + for (int i = 0; i < count; i++ ) + setCell( r, c + i, w ); +} + +bool Grid::isWidgetStartCol( int c ) const +{ + int r; + for ( r = 0; r < nrows; r++ ) { + if ( cell( r, c ) && ( (c==0) || (cell( r, c) != cell( r, c-1) )) ) { + return TRUE; + } + } + return FALSE; +} + +bool Grid::isWidgetEndCol( int c ) const +{ + int r; + for ( r = 0; r < nrows; r++ ) { + if ( cell( r, c ) && ((c == ncols-1) || (cell( r, c) != cell( r, c+1) )) ) + return TRUE; + } + return FALSE; +} + +bool Grid::isWidgetStartRow( int r ) const +{ + int c; + for ( c = 0; c < ncols; c++ ) { + if ( cell( r, c ) && ( (r==0) || (cell( r, c) != cell( r-1, c) )) ) + return TRUE; + } + return FALSE; +} + +bool Grid::isWidgetEndRow( int r ) const +{ + int c; + for ( c = 0; c < ncols; c++ ) { + if ( cell( r, c ) && ((r == nrows-1) || (cell( r, c) != cell( r+1, c) )) ) + return TRUE; + } + return FALSE; +} + + +bool Grid::isWidgetTopLeft( int r, int c ) const +{ + QWidget* w = cell( r, c ); + if ( !w ) + return FALSE; + return ( !r || cell( r-1, c) != w ) && (!c || cell( r, c-1) != w); +} + +void Grid::extendLeft() +{ + int r,c,i; + for ( c = 1; c < ncols; c++ ) { + for ( r = 0; r < nrows; r++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cc = countCol( r, c); + int stretch = 0; + for ( i = c-1; i >= 0; i-- ) { + if ( cell( r, i ) ) + break; + if ( countCol( r, i ) < cc ) + break; + if ( isWidgetEndCol( i ) ) + break; + if ( isWidgetStartCol( i ) ) { + stretch = c - i; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setCol( r, c-i-1, w, cc ); + } + } + } +} + + +void Grid::extendRight() +{ + int r,c,i; + for ( c = ncols - 2; c >= 0; c-- ) { + for ( r = 0; r < nrows; r++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cc = countCol( r, c); + int stretch = 0; + for ( i = c+1; i < ncols; i++ ) { + if ( cell( r, i ) ) + break; + if ( countCol( r, i ) < cc ) + break; + if ( isWidgetStartCol( i ) ) + break; + if ( isWidgetEndCol( i ) ) { + stretch = i - c; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setCol( r, c+i+1, w, cc ); + } + } + } + +} + +void Grid::extendUp() +{ + int r,c,i; + for ( r = 1; r < nrows; r++ ) { + for ( c = 0; c < ncols; c++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cr = countRow( r, c); + int stretch = 0; + for ( i = r-1; i >= 0; i-- ) { + if ( cell( i, c ) ) + break; + if ( countRow( i, c ) < cr ) + break; + if ( isWidgetEndRow( i ) ) + break; + if ( isWidgetStartRow( i ) ) { + stretch = r - i; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setRow( r-i-1, c, w, cr ); + } + } + } +} + +void Grid::extendDown() +{ + int r,c,i; + for ( r = nrows - 2; r >= 0; r-- ) { + for ( c = 0; c < ncols; c++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cr = countRow( r, c); + int stretch = 0; + for ( i = r+1; i < nrows; i++ ) { + if ( cell( i, c ) ) + break; + if ( countRow( i, c ) < cr ) + break; + if ( isWidgetStartRow( i ) ) + break; + if ( isWidgetEndRow( i ) ) { + stretch = i - r; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setRow( r+i+1, c, w, cr ); + } + } + } + +} + +void Grid::simplify() +{ + extendLeft(); + extendRight(); + extendUp(); + extendDown(); + merge(); +} + + +void Grid::merge() +{ + int r,c; + for ( c = 0; c < ncols; c++ ) + cols[c] = FALSE; + + for ( r = 0; r < nrows; r++ ) + rows[r] = FALSE; + + for ( c = 0; c < ncols; c++ ) { + for ( r = 0; r < nrows; r++ ) { + if ( isWidgetTopLeft( r, c ) ) { + rows[r] = TRUE; + cols[c] = TRUE; + } + } + } +} + +bool Grid::locateWidget( QWidget* w, int& row, int& col, int& rowspan, int & colspan ) +{ + int r,c, r2, c2; + for ( c = 0; c < ncols; c++ ) { + for ( r = 0; r < nrows; r++ ) { + if ( cell( r, c ) == w ) { + row = 0; + for ( r2 = 1; r2 <= r; r2++ ) { + if ( rows[ r2-1 ] ) + row++; + } + col = 0; + for ( c2 = 1; c2 <= c; c2++ ) { + if ( cols[ c2-1 ] ) + col++; + } + rowspan = 0; + for ( r2 = r ; r2 < nrows && cell( r2, c) == w; r2++ ) { + if ( rows[ r2 ] ) + rowspan++; + } + colspan = 0; + for ( c2 = c; c2 < ncols && cell( r, c2) == w; c2++ ) { + if ( cols[ c2] ) + colspan++; + } + return TRUE; + } + } + } + return FALSE; +} + + + + +GridLayout::GridLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, const QSize &res, bool doSetup ) + : Layout( wl, p, fw, lb, doSetup ), resolution( res ) +{ + grid = 0; + if ( doSetup ) + setup(); +} + +GridLayout::~GridLayout() +{ + delete grid; +} + +void GridLayout::doLayout() +{ + bool needMove, needReparent; + if ( !prepareLayout( needMove, needReparent ) ) + return; + + QDesignerGridLayout *layout = (QDesignerGridLayout*)WidgetFactory::createLayout( layoutBase, 0, WidgetFactory::Grid ); + + if ( !grid ) + buildGrid(); + + QWidget* w; + int r, c, rs, cs; + for ( w = widgets.first(); w; w = widgets.next() ) { + if ( grid->locateWidget( w, r, c, rs, cs) ) { + if ( needReparent && w->parent() != layoutBase ) + w->reparent( layoutBase, 0, QPoint( 0, 0 ), FALSE ); + if ( rs * cs == 1 ) { + layout->addWidget( w, r, c, ::qt_cast<Spacer*>(w) ? ( (Spacer*)w )->alignment() : 0 ); + } else { + layout->addMultiCellWidget( w, r, r+rs-1, c, c+cs-1, ::qt_cast<Spacer*>(w) ? ( (Spacer*)w )->alignment() : 0 ); + } + if ( ::qt_cast<QLayoutWidget*>(w) ) + ( (QLayoutWidget*)w )->updateSizePolicy(); + w->show(); + } else { + qWarning("ooops, widget '%s' does not fit in layout", w->name() ); + } + } + finishLayout( needMove, layout ); +} + +void GridLayout::setup() +{ + Layout::setup(); + buildGrid(); +} + +void GridLayout::buildGrid() +{ + if ( !widgets.count() ) + return; + + // Pixel to cell conversion: + // By keeping a list of start'n'stop values (x & y) for each widget, + // it is possible to create a very small grid of cells to represent + // the widget layout. + // ----------------------------------------------------------------- + + // We need a list of both start and stop values for x- & y-axis + QValueVector<int> x( widgets.count()*2 ); + QValueVector<int> y( widgets.count()*2 ); + + // Using push_back would look nicer, but operator[] is much faster + int index = 0; + QWidget* w = 0; + for ( w = widgets.first(); w; w = widgets.next() ) { + QRect widgetPos = w->geometry(); + x[index] = widgetPos.left(); + x[index+1] = widgetPos.right(); + y[index] = widgetPos.top(); + y[index+1] = widgetPos.bottom(); + index += 2; + } + + qHeapSort(x); + qHeapSort(y); + + // Remove duplicate x enteries (Remove next, if equal to current) + if ( !x.empty() ) { + for (QValueVector<int>::iterator current = x.begin() ; + (current != x.end()) && ((current+1) != x.end()) ; ) + if ( (*current == *(current+1)) ) + x.erase(current+1); + else + current++; + } + + // Remove duplicate y enteries (Remove next, if equal to current) + if ( !y.empty() ) { + for (QValueVector<int>::iterator current = y.begin() ; + (current != y.end()) && ((current+1) != y.end()) ; ) + if ( (*current == *(current+1)) ) + y.erase(current+1); + else + current++; + } + + // Create the smallest grid possible to represent the current layout + // Since no widget will be placed in the last row and column, we'll + // skip them to increase speed even further + delete grid; + grid = new Grid( y.size()-1, x.size()-1 ); + + // Mark the cells in the grid that contains a widget + for ( w = widgets.first(); w; w = widgets.next() ) { + QRect c(0,0,0,0), widgetPos = w->geometry(); + // From left til right (not including) + for (uint cw=0; cw<x.size(); cw++) { + if ( x[cw] == widgetPos.left() ) + c.setLeft(cw); + if ( x[cw] < widgetPos.right()) + c.setRight(cw); + } + // From top til bottom (not including) + for (uint ch=0; ch<y.size(); ch++) { + if ( y[ch] == widgetPos.top() ) + c.setTop(ch); + if ( y[ch] < widgetPos.bottom() ) + c.setBottom(ch); + } + grid->setCells(c, w); // Mark cellblock + } + grid->simplify(); +} + + + + + + + +Spacer::Spacer( QWidget *parent, const char *name ) + : QWidget( parent, name, WMouseNoMask ), + orient( Vertical ), interactive(TRUE), sh( QSize(20,20) ) +{ + setSizeType( Expanding ); + setAutoMask( TRUE ); +} + +void Spacer::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.setPen( Qt::blue ); + + if ( orient == Horizontal ) { + const int dist = 3; + const int amplitude = QMIN( 3, height() / 3 ); + const int base = height() / 2; + int i = 0; + p.setPen( white ); + for ( i = 0; i < width() / 3 +2; ++i ) + p.drawLine( i * dist, base - amplitude, i * dist + dist / 2, base + amplitude ); + p.setPen( blue ); + for ( i = 0; i < width() / 3 +2; ++i ) + p.drawLine( i * dist + dist / 2, base + amplitude, i * dist + dist, base - amplitude ); + p.drawLine( 0, 0, 0, height() ); + p.drawLine( width() - 1, 0, width() - 1, height()); + } else { + const int dist = 3; + const int amplitude = QMIN( 3, width() / 3 ); + const int base = width() / 2; + int i = 0; + p.setPen( white ); + for ( i = 0; i < height() / 3 +2; ++i ) + p.drawLine( base - amplitude, i * dist, base + amplitude,i * dist + dist / 2 ); + p.setPen( blue ); + for ( i = 0; i < height() / 3 +2; ++i ) + p.drawLine( base + amplitude, i * dist + dist / 2, base - amplitude, i * dist + dist ); + p.drawLine( 0, 0, width(), 0 ); + p.drawLine( 0, height() - 1, width(), height() - 1 ); + } +} + +void Spacer::resizeEvent( QResizeEvent* e) +{ + QWidget::resizeEvent( e ); + if ( !parentWidget() || WidgetFactory::layoutType( parentWidget() ) == WidgetFactory::NoLayout ) + sh = size(); +} + +void Spacer::updateMask() +{ + QRegion r( rect() ); + if ( orient == Horizontal ) { + const int amplitude = QMIN( 3, height() / 3 ); + const int base = height() / 2; + r = r.subtract( QRect(1, 0, width() - 2, base - amplitude ) ); + r = r.subtract( QRect(1, base + amplitude, width() - 2, height() - base - amplitude ) ); + } else { + const int amplitude = QMIN( 3, width() / 3 ); + const int base = width() / 2; + r = r.subtract( QRect(0, 1, base - amplitude, height() - 2 ) ); + r = r.subtract( QRect( base + amplitude, 1, width() - base - amplitude, height() - 2 ) ); + } + setMask( r ); +} + +void Spacer::setSizeType( SizeType t ) +{ + QSizePolicy sizeP; + if ( orient == Vertical ) + sizeP = QSizePolicy( QSizePolicy::Minimum, (QSizePolicy::SizeType)t ); + else + sizeP = QSizePolicy( (QSizePolicy::SizeType)t, QSizePolicy::Minimum ); + setSizePolicy( sizeP ); +} + + +Spacer::SizeType Spacer::sizeType() const +{ + if ( orient == Vertical ) + return (SizeType)sizePolicy().verData(); + return (SizeType)sizePolicy().horData(); +} + +int Spacer::alignment() const +{ + if ( orient == Vertical ) + return AlignHCenter; + return AlignVCenter; +} + +QSize Spacer::minimumSize() const +{ + QSize s = QSize( 20,20 ); + if ( sizeType() == Expanding ) + if ( orient == Vertical ) + s.rheight() = 0; + else + s.rwidth() = 0; + return s; +} + +QSize Spacer::sizeHint() const +{ + return sh; +} + + +void Spacer::setSizeHint( const QSize &s ) +{ + sh = s; + if ( !parentWidget() || WidgetFactory::layoutType( parentWidget() ) == WidgetFactory::NoLayout ) + resize( sizeHint() ); + updateGeometry(); +} + +Qt::Orientation Spacer::orientation() const +{ + return orient; +} + +void Spacer::setOrientation( Qt::Orientation o ) +{ + if ( orient == o ) + return; + + SizeType st = sizeType(); + orient = o; + setSizeType( st ); + if ( interactive ) { + sh = QSize( sh.height(), sh.width() ); + if (!parentWidget() || WidgetFactory::layoutType( parentWidget() ) == WidgetFactory::NoLayout ) + resize( height(), width() ); + } + updateMask(); + update(); + updateGeometry(); +} + + +void QDesignerGridLayout::addWidget( QWidget *w, int row, int col, int align_ ) +{ + items.insert( w, Item(row, col, 1, 1) ); + QGridLayout::addWidget( w, row, col, align_ ); +} + +void QDesignerGridLayout::addMultiCellWidget( QWidget *w, int fromRow, int toRow, + int fromCol, int toCol, int align_ ) +{ + items.insert( w, Item(fromRow, fromCol, toRow - fromRow + 1, toCol - fromCol +1) ); + QGridLayout::addMultiCellWidget( w, fromRow, toRow, fromCol, toCol, align_ ); +} diff --git a/kdevdesigner/designer/layout.h b/kdevdesigner/designer/layout.h new file mode 100644 index 00000000..2ead5d0d --- /dev/null +++ b/kdevdesigner/designer/layout.h @@ -0,0 +1,188 @@ +/********************************************************************** +** 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 LAYOUT_H +#define LAYOUT_H + +#include <qwidget.h> +#include <qmap.h> +#include <qguardedptr.h> +#include <qobject.h> +#include <qlayout.h> +#include <qmap.h> +#include <qwidgetlist.h> + +class FormWindow; +class QPaintEvent; + +class Layout : public QObject +{ + Q_OBJECT + +public: + Layout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup = TRUE, bool splitter = FALSE ); + virtual ~Layout() {} + + virtual void doLayout() = 0; + virtual void undoLayout(); + virtual void breakLayout(); + virtual bool prepareLayout( bool &needMove, bool &needReparent ); + virtual void finishLayout( bool needMove, QLayout *layout ); + +protected: + QWidgetList widgets; + QWidget *parent; + QPoint startPoint; + QMap<QGuardedPtr<QWidget>, QRect> geometries; + QWidget *layoutBase; + FormWindow *formWindow; + QRect oldGeometry; + bool isBreak; + bool useSplitter; + +protected: + virtual void setup(); + +protected slots: + void widgetDestroyed(); + +}; + +class HorizontalLayout : public Layout +{ +public: + HorizontalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup = TRUE, bool splitter = FALSE ); + + void doLayout(); + +protected: + void setup(); + +}; + +class VerticalLayout : public Layout +{ +public: + VerticalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup = TRUE, bool splitter = FALSE ); + + void doLayout(); + +protected: + void setup(); + +}; + +class Grid; + +class GridLayout : public Layout +{ +public: + GridLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, const QSize &res, bool doSetup = TRUE ); + ~GridLayout(); + + void doLayout(); + +protected: + void setup(); + +protected: + void buildGrid(); + QSize resolution; + Grid* grid; + +}; + +class Spacer : public QWidget +{ + Q_OBJECT + + Q_OVERRIDE( QCString name ) + Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation ) + Q_ENUMS( SizeType ) + Q_PROPERTY( SizeType sizeType READ sizeType WRITE setSizeType ) + Q_PROPERTY( QSize sizeHint READ sizeHint WRITE setSizeHint DESIGNABLE true STORED true ) + Q_OVERRIDE( QRect geometry DESIGNABLE false ) + +private: + enum { HSize = 6, HMask = 0x3f, VMask = HMask << HSize, + MayGrow = 1, ExpMask = 2, MayShrink = 4 }; + +public: + enum SizeType { Fixed = 0, + Minimum = MayGrow, + Maximum = MayShrink, + Preferred = MayGrow|MayShrink , + MinimumExpanding = Minimum|ExpMask, + Expanding = MinimumExpanding|MayShrink }; + + Spacer( QWidget *parent, const char *name ); + + QSize minimumSize() const; + QSize sizeHint() const; + void setSizeType( SizeType t ); + SizeType sizeType() const; + int alignment() const; + Orientation orientation() const; + void setOrientation( Orientation o ); + void setInteraciveMode( bool b ) { interactive = b; }; + void setSizeHint( const QSize &s ); + +protected: + void paintEvent( QPaintEvent *e ); + void resizeEvent( QResizeEvent* e ); + void updateMask(); + Qt::Orientation orient; + bool interactive; + QSize sh; +}; + +class QDesignerGridLayout : public QGridLayout +{ + Q_OBJECT +public: + QDesignerGridLayout( QWidget *parent ) : QGridLayout( parent ){}; + QDesignerGridLayout( QLayout *parentLayout ) : QGridLayout( parentLayout ){}; + + void addWidget( QWidget *, int row, int col, int align = 0 ); + void addMultiCellWidget( QWidget *, int fromRow, int toRow, + int fromCol, int toCol, int align = 0 ); + + struct Item + { + Item(): row(0), column(0),rowspan(1),colspan(1){} + Item( int r, int c, int rs, int cs): row(r), column(c), rowspan(rs), colspan(cs){} + int row; + int column; + int rowspan; + int colspan; + Q_DUMMY_COMPARISON_OPERATOR( Item ) + }; + + QMap<QWidget*, Item> items; +}; + + +#endif diff --git a/kdevdesigner/designer/listboxdnd.cpp b/kdevdesigner/designer/listboxdnd.cpp new file mode 100644 index 00000000..a83ace44 --- /dev/null +++ b/kdevdesigner/designer/listboxdnd.cpp @@ -0,0 +1,305 @@ +/********************************************************************** +** Copyright (C) 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 "listboxdnd.h" +#include <qwidget.h> +#include <qheader.h> +#include <qpainter.h> +#include <qdragobject.h> +#include <qvaluelist.h> + +// The Dragobject Declaration --------------------------------------- +class ListBoxItemDrag : public QStoredDrag +{ +public: + ListBoxItemDrag( ListBoxItemList & items, bool sendPtr = FALSE, QListBox * parent = 0, const char * name = 0 ); + ~ListBoxItemDrag() {}; + static bool canDecode( QDragMoveEvent * event ); + static bool decode( QDropEvent * event, QListBox * parent, QListBoxItem * insertPoint ); + enum ItemType { ListBoxText = 1, ListBoxPixmap = 2 }; +}; +// ------------------------------------------------------------------ + +ListBoxDnd::ListBoxDnd( QListBox * eventSource, const char * name ) + : ListDnd( eventSource, name ) { } + +void ListBoxDnd::confirmDrop( QListBoxItem * ) +{ + dropConfirmed = TRUE; +} + +bool ListBoxDnd::dropEvent( QDropEvent * event ) +{ + if ( dragInside ) { + + if ( dMode & NullDrop ) { // combined with Move, a NullDrop will delete an item + event->accept(); + emit dropped( 0 ); // a NullDrop + return TRUE; + } + + QPoint pos = event->pos(); + QListBoxItem * after = itemAt( pos ); + + if ( ListBoxItemDrag::decode( event, (QListBox *) src, after ) ) { + event->accept(); + QListBox * src = (QListBox *) this->src; + QListBoxItem * item = ( after ? after->next() : src->firstItem() ); + src->setCurrentItem( item ); + emit dropped( item ); // ###FIX: Supports only one item! + } + } + + line->hide(); + dragInside = FALSE; + + return TRUE; +} + +bool ListBoxDnd::mouseMoveEvent( QMouseEvent * event ) +{ + if ( event->state() & LeftButton ) { + if ( ( event->pos() - mousePressPos ).manhattanLength() > 3 ) { + + ListBoxItemList list; + buildList( list ); + ListBoxItemDrag * dragobject = new ListBoxItemDrag( list, (dMode & Internal), (QListBox *) src ); + + // Emit signal for all dragged items + QListBoxItem * i = list.first(); + while ( i ) { + emit dragged( i ); + i = list.next(); + } + + if ( dMode & Move ) { + removeList( list ); // "hide" items + } + + dragobject->dragCopy(); + + if ( dMode & Move ) { + if ( dropConfirmed ) { + // ###FIX: memleak ? in internal mode, only pointers are transfered... + //list.setAutoDelete( TRUE ); + list.clear(); + dropConfirmed = FALSE; + } + insertList( list ); // "show" items + } + } + } + return FALSE; +} + +int ListBoxDnd::buildList( ListBoxItemList & list ) +{ + QListBoxItem * i = ((QListBox *)src)->firstItem(); + while ( i ) { + if ( i->isSelected() ) { + ((QListBox *)src)->setSelected( i, FALSE ); + list.append( i ); + } + i = i->next(); + } + return list.count(); +} + +void ListBoxDnd::insertList( ListBoxItemList & list ) +{ + QListBoxItem * i = list.first(); + while ( i ) { + ((QListBox *)src)->insertItem( i, i->prev() ); + i = list.next(); + } +} + +void ListBoxDnd::removeList( ListBoxItemList & list ) +{ + QListBoxItem * i = list.first(); + while ( i ) { + ((QListBox *)src)->takeItem( i ); // remove item from QListBox + i = list.next(); + } +} + +void ListBoxDnd::updateLine( const QPoint & dragPos ) +{ + QListBox * src = (QListBox *) this->src; + QListBoxItem *item = itemAt( dragPos ); + + int ypos = item ? + ( src->itemRect( item ).bottom() - ( line->height() / 2 ) ) : + ( src->itemRect( ((QListBox *)src)->firstItem() ).top() ); + + line->resize( src->viewport()->width(), line->height() ); + line->move( 0, ypos ); +} + +QListBoxItem * ListBoxDnd::itemAt( QPoint pos ) +{ + QListBox * src = (QListBox *) this->src; + QListBoxItem * result = src->itemAt( pos ); + QListBoxItem * last = src->item( src->count() - 1 ); + int i = src->index( result ); + + if ( result && ( pos.y() < (src->itemRect(result).top() + src->itemHeight(i)/2) ) ) + result = result->prev(); + else if ( !result && pos.y() > src->itemRect( last ).bottom() ) + result = last; + + return result; +} + +bool ListBoxDnd::canDecode( QDragEnterEvent * event ) +{ + return ListBoxItemDrag::canDecode( event ); +} + + +// ------------------------------------------------------------------ +// The Dragobject Implementation ------------------------------------ +// ------------------------------------------------------------------ + +ListBoxItemDrag::ListBoxItemDrag( ListBoxItemList & items, bool sendPtr, QListBox * parent, const char * name ) + : QStoredDrag( "qt/listboxitem", parent, name ) +{ + // ### FIX! + QByteArray data( sizeof( Q_INT32 ) + sizeof( QListBoxItem ) * items.count() ); + QDataStream stream( data, IO_WriteOnly ); + + stream << items.count(); + stream << (Q_UINT8) sendPtr; // just transfer item pointer; omit data + + QListBoxItem * i = items.first(); + + if ( sendPtr ) { + + while ( i ) { + + stream << (Q_ULONG) i; //###FIX: demands sizeof(ulong) >= sizeof(void*) + i = items.next(); + + } + + } else { + + while ( i ) { + + Q_UINT8 b = 0; + + b = (Q_UINT8) ( i->text() != QString::null ); // does item have text ? + stream << b; + if ( b ) { + stream << i->text(); + } + + b = (Q_UINT8) ( !!i->pixmap() ); // does item have a pixmap ? + stream << b; + if ( b ) { + stream << ( *i->pixmap() ); + } + + stream << (Q_UINT8) i->isSelectable(); + + i = items.next(); + } + + } + + setEncodedData( data ); +} + +bool ListBoxItemDrag::canDecode( QDragMoveEvent * event ) +{ + return event->provides( "qt/listboxitem" ); +} + +bool ListBoxItemDrag::decode( QDropEvent * event, QListBox * parent, QListBoxItem * after ) +{ + QByteArray data = event->encodedData( "qt/listboxitem" ); + + if ( data.size() ) { + event->accept(); + QDataStream stream( data, IO_ReadOnly ); + + int count = 0; + stream >> count; + + Q_UINT8 recievePtr = 0; // data contains just item pointers; no data + stream >> recievePtr; + + QListBoxItem * item = 0; + + if ( recievePtr ) { + + for( int i = 0; i < count; i++ ) { + + Q_ULONG p = 0; //###FIX: demands sizeof(ulong) >= sizeof(void*) + stream >> p; + item = (QListBoxItem *) p; + + parent->insertItem( item, after ); + + } + + } else { + + for ( int i = 0; i < count; i++ ) { + + Q_UINT8 hasText = 0; + QString text; + stream >> hasText; + if ( hasText ) { + stream >> text; + } + + Q_UINT8 hasPixmap = 0; + QPixmap pixmap; + stream >> hasPixmap; + if ( hasPixmap ) { + stream >> pixmap; + } + + Q_UINT8 isSelectable = 0; + stream >> isSelectable; + + if ( hasPixmap ) { + item = new QListBoxPixmap( parent, pixmap, text, after ); + } else { + item = new QListBoxText( parent, text, after ); + } + + item->setSelectable( isSelectable ); + + } + + } + + return TRUE; + } + return FALSE; +} diff --git a/kdevdesigner/designer/listboxdnd.h b/kdevdesigner/designer/listboxdnd.h new file mode 100644 index 00000000..c0f91845 --- /dev/null +++ b/kdevdesigner/designer/listboxdnd.h @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 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. +** +**********************************************************************/ + +#ifndef LISTBOXDND_H +#define LISTBOXDND_H + +#include <qptrlist.h> +#include <qlistbox.h> +#include "listdnd.h" + +typedef QPtrList<QListBoxItem> ListBoxItemList; + +class ListBoxDnd : public ListDnd +{ + Q_OBJECT +public: + // dragModes are enumerated in ListDnd + ListBoxDnd( QListBox * eventSource, const char * name = 0 ); + +signals: + void dropped( QListBoxItem * ); + void dragged( QListBoxItem * ); + +public slots: + void confirmDrop( QListBoxItem * ); + +protected: + virtual bool dropEvent( QDropEvent * event ); + virtual bool mouseMoveEvent( QMouseEvent * event ); + virtual void updateLine( const QPoint & pos ); + virtual bool canDecode( QDragEnterEvent * event ); + +private: + QListBoxItem * itemAt( QPoint pos ); + int buildList( ListBoxItemList & list ); + void insertList( ListBoxItemList & list ); + void removeList( ListBoxItemList & list ); +}; + +#endif //LISTBOXDND_H diff --git a/kdevdesigner/designer/listboxeditor.ui b/kdevdesigner/designer/listboxeditor.ui new file mode 100644 index 00000000..ce3d4b79 --- /dev/null +++ b/kdevdesigner/designer/listboxeditor.ui @@ -0,0 +1,457 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ListBoxEditorBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ListBoxEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>482</width> + <height>229</height> + </rect> + </property> + <property name="caption"> + <string>Edit Listbox</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Edit Listbox</b><p>Add, edit or delete items in the listbox.</p><p>Click the <b>New Item</b>-button to create a new listbox entry, then enter text and choose a pixmap.</p><p>Select an item from the list and click the <b>Delete Item</b>-button to remove the item from the list.</p></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="5" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Apply all changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QListBox" row="0" column="0" rowspan="5" colspan="1"> + <property name="name"> + <cstring>preview</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Item</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The list of items.</string> + </property> + </widget> + <widget class="QGroupBox" row="0" column="2" rowspan="5" colspan="1"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="title"> + <string>&Item Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label2</cstring> + </property> + <property name="text"> + <string>&Pixmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemChoosePixmap</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>itemPixmap</cstring> + </property> + <property name="text"> + <string>Label4</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>itemDeletePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Delete the selected item's pixmap.</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>itemChoosePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose a pixmap file for the selected item.</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>Label1</cstring> + </property> + <property name="text"> + <string>&Text:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemText</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>itemText</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Change text</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Change the selected item's text.</string> + </property> + </widget> + </grid> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>itemNew</cstring> + </property> + <property name="text"> + <string>&New Item</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add an item</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Add a new item.</b><p>New items are appended to the list.</p></string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>itemDelete</cstring> + </property> + <property name="text"> + <string>&Delete Item</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Item</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Delete the selected item</string> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>Vertical Spacing1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="3" column="1"> + <property name="name"> + <cstring>itemUp</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move up</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Moves the selected item up.</string> + </property> + </widget> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>itemDown</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move down</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Move the selected item down.</string> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>itemNew</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>insertNewItem()</slot> + </connection> + <connection> + <sender>itemDelete</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>deleteCurrentItem()</slot> + </connection> + <connection> + <sender>itemText</sender> + <signal>textChanged( const QString & )</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>currentTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>buttonApply</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>applyClicked()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>cancelClicked()</slot> + </connection> + <connection> + <sender>itemChoosePixmap</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>choosePixmap()</slot> + </connection> + <connection> + <sender>itemDeletePixmap</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>deletePixmap()</slot> + </connection> + <connection> + <sender>itemUp</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>moveItemUp()</slot> + </connection> + <connection> + <sender>itemDown</sender> + <signal>clicked()</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>moveItemDown()</slot> + </connection> + <connection> + <sender>preview</sender> + <signal>selectionChanged(QListBoxItem*)</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>currentItemChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>preview</sender> + <signal>currentChanged( QListBoxItem * )</signal> + <receiver>ListBoxEditorBase</receiver> + <slot>currentItemChanged(QListBoxItem*)</slot> + </connection> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>preview</tabstop> + <tabstop>itemNew</tabstop> + <tabstop>itemDelete</tabstop> + <tabstop>itemUp</tabstop> + <tabstop>itemDown</tabstop> + <tabstop>itemText</tabstop> + <tabstop>itemDeletePixmap</tabstop> + <tabstop>itemChoosePixmap</tabstop> + <tabstop>helpButton</tabstop> + <tabstop>buttonApply</tabstop> +</tabstops> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">insertNewItem()</slot> + <slot access="protected">deleteCurrentItem()</slot> + <slot access="protected">currentItemChanged( QListBoxItem * )</slot> + <slot access="protected">currentTextChanged( const QString & )</slot> + <slot access="protected">okClicked()</slot> + <slot access="protected">cancelClicked()</slot> + <slot access="protected">applyClicked()</slot> + <slot access="protected">choosePixmap()</slot> + <slot access="protected">deletePixmap()</slot> + <slot access="protected">moveItemUp()</slot> + <slot access="protected">moveItemDown()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/listboxeditorimpl.cpp b/kdevdesigner/designer/listboxeditorimpl.cpp new file mode 100644 index 00000000..d19f22b2 --- /dev/null +++ b/kdevdesigner/designer/listboxeditorimpl.cpp @@ -0,0 +1,245 @@ +/********************************************************************** +** 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 "listboxeditorimpl.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "pixmapchooser.h" +#include "command.h" +#include "listboxdnd.h" +#include "listboxrename.h" + +#include <klineedit.h> +#include <qlabel.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qcheckbox.h> + +#include <klocale.h> + +ListBoxEditor::ListBoxEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ) + : ListBoxEditorBase( parent, 0, TRUE ), formwindow( fw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + listbox = (QListBox*)editWidget; + + itemText->setText( "" ); + itemText->setEnabled( FALSE ); + itemPixmap->setText( "" ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + + QListBoxItem *i = 0; + for ( i = listbox->firstItem(); i; i = i->next() ) { + if ( i->pixmap() ) + (void)new QListBoxPixmap( preview, *i->pixmap(), i->text() ); + else + (void)new QListBoxText( preview, i->text() ); + } + + if ( preview->firstItem() ) + preview->setCurrentItem( preview->firstItem() ); + + ListBoxDnd *editorDnd = new ListBoxDnd( preview ); + editorDnd->setDragMode( ListBoxDnd::Internal | ListBoxDnd::Move ); + QObject::connect( editorDnd, SIGNAL( dropped( QListBoxItem * ) ), + editorDnd, SLOT( confirmDrop( QListBoxItem * ) ) ); + + ListBoxRename *editorRename = new ListBoxRename( preview ); + + QObjectList *l = parent->queryList( "QLineEdit", "itemText" ); + QObjectListIt it( *l ); + QObject *obj; + while ( (obj = it.current()) != 0 ) { + ++it; + QObject::connect( editorRename, + SIGNAL( itemTextChanged( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; + +} + +void ListBoxEditor::insertNewItem() +{ + QListBoxItem *i = new QListBoxText( preview, i18n("New Item") ); + preview->setCurrentItem( i ); + preview->setSelected( i, TRUE ); + itemText->setFocus(); + itemText->selectAll(); +} + +void ListBoxEditor::deleteCurrentItem() +{ + delete preview->item( preview->currentItem() ); + if ( preview->currentItem() != -1 ) + preview->setSelected( preview->currentItem(), TRUE ); +} + +void ListBoxEditor::currentItemChanged( QListBoxItem *i ) +{ + itemText->blockSignals( TRUE ); + itemText->setText( "" ); + itemPixmap->setText( "" ); + itemText->blockSignals( FALSE ); + + if ( !i ) { + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + return; + } + + itemText->blockSignals( TRUE ); + itemText->setEnabled( TRUE ); + itemChoosePixmap->setEnabled( TRUE ); + itemDeletePixmap->setEnabled( i->pixmap() && !i->pixmap()->isNull() ); + + itemText->setText( i->text() ); + if ( i->pixmap() ) + itemPixmap->setPixmap( *i->pixmap() ); + itemText->blockSignals( FALSE ); +} + +void ListBoxEditor::currentTextChanged( const QString &txt ) +{ + if ( preview->currentItem() == -1 ) + return; + + preview->blockSignals( TRUE ); + if ( preview->item( preview->currentItem() )->pixmap() ) + preview->changeItem( *preview->item( preview->currentItem() )->pixmap(), txt, preview->currentItem() ); + else + preview->changeItem( txt, preview->currentItem() ); + preview->blockSignals( FALSE ); +} + +void ListBoxEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void ListBoxEditor::cancelClicked() +{ + reject(); +} + +void ListBoxEditor::applyClicked() +{ + QListBoxItem *i = 0; + QValueList<PopulateListBoxCommand::Item> items; + for ( i = preview->firstItem(); i; i = i->next() ) { + PopulateListBoxCommand::Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + items.append( item ); + } + + PopulateListBoxCommand *cmd = new PopulateListBoxCommand( i18n( "Edit the Items of '%1'" ).arg( listbox->name() ), + formwindow, listbox, items ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); +} + +void ListBoxEditor::choosePixmap() +{ + if ( preview->currentItem() == -1 ) + return; + + QPixmap pix; + if ( preview->item( preview->currentItem() )->pixmap() ) + pix = qChoosePixmap( this, formwindow, *preview->item( preview->currentItem() )->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + QString txt = preview->item( preview->currentItem() )->text(); + preview->changeItem( pix, txt, preview->currentItem() ); + itemDeletePixmap->setEnabled( TRUE ); +} + +void ListBoxEditor::moveItemUp() +{ + if ( preview->currentItem() < 1 ) + return; + + QListBoxItem *i = preview->item( preview->currentItem() ); + bool hasPix = (i->pixmap() != 0); + QPixmap pix; + if ( hasPix ) + pix = *i->pixmap(); + QString txt = i->text(); + + QListBoxItem *p = i->prev(); + if ( p->pixmap() ) + preview->changeItem( *p->pixmap(), p->text(), preview->currentItem() ); + else + preview->changeItem( p->text(), preview->currentItem() ); + + if ( hasPix ) + preview->changeItem( pix, txt, preview->currentItem() - 1 ); + else + preview->changeItem( txt, preview->currentItem() - 1 ); +} + +void ListBoxEditor::moveItemDown() +{ + if ( preview->currentItem() == -1 || preview->currentItem() > (int)preview->count() - 2 ) + return; + + QListBoxItem *i = preview->item( preview->currentItem() ); + bool hasPix = (i->pixmap() != 0); + QPixmap pix; + if ( hasPix ) + pix = *i->pixmap(); + QString txt = i->text(); + + QListBoxItem *n = i->next(); + if ( n->pixmap() ) + preview->changeItem( *n->pixmap(), n->text(), preview->currentItem() ); + else + preview->changeItem( n->text(), preview->currentItem() ); + + if ( hasPix ) + preview->changeItem( pix, txt, preview->currentItem() + 1 ); + else + preview->changeItem( txt, preview->currentItem() + 1 ); +} + +void ListBoxEditor::deletePixmap() +{ + if ( preview->currentItem() == -1 ) + return; + + QListBoxItem *i = preview->item( preview->currentItem() ); + preview->changeItem( i->text(), preview->currentItem() ); + itemDeletePixmap->setEnabled( FALSE ); +} diff --git a/kdevdesigner/designer/listboxeditorimpl.h b/kdevdesigner/designer/listboxeditorimpl.h new file mode 100644 index 00000000..3719bc59 --- /dev/null +++ b/kdevdesigner/designer/listboxeditorimpl.h @@ -0,0 +1,61 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef LISTBOXEDITORIMPL_H +#define LISTBOXEDITORIMPL_H + +class QListBox; +class FormWindow; + +#include "listboxeditor.h" + +class ListBoxEditor : public ListBoxEditorBase +{ + Q_OBJECT + +public: + ListBoxEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ); + +protected slots: + void insertNewItem(); + void deleteCurrentItem(); + void currentItemChanged( QListBoxItem * ); + void currentTextChanged( const QString & ); + void okClicked(); + void cancelClicked(); + void applyClicked(); + void choosePixmap(); + void moveItemUp(); + void moveItemDown(); + void deletePixmap(); + +private: + QListBox *listbox; + FormWindow *formwindow; + +}; + +#endif diff --git a/kdevdesigner/designer/listboxrename.cpp b/kdevdesigner/designer/listboxrename.cpp new file mode 100644 index 00000000..464ef412 --- /dev/null +++ b/kdevdesigner/designer/listboxrename.cpp @@ -0,0 +1,157 @@ +/********************************************************************** +** Copyright (C) 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 <qheader.h> +#include <qlineedit.h> +#include <qtimer.h> +#include "listboxrename.h" + +class EditableListBoxItem : public QListBoxItem +{ +public: + void setText( const QString & text ) + { + QListBoxItem::setText( text ); + } +}; + +ListBoxRename::ListBoxRename( QListBox * eventSource, const char * name ) + : QObject( eventSource, name ), + clickedItem( 0 ), activity( FALSE ) +{ + src = eventSource; + src->installEventFilter( this ); + ed = new QLineEdit( src->viewport() ); + ed->hide(); + ed->setFrame( FALSE ); + + QObject::connect( ed, SIGNAL( returnPressed() ), + this, SLOT( renameClickedItem() ) ); +} + +bool ListBoxRename::eventFilter( QObject *, QEvent * event ) +{ + switch ( event->type() ) { + + case QEvent::MouseButtonPress: + { + QPoint pos = ((QMouseEvent *) event)->pos(); + + if ( clickedItem && + clickedItem->isSelected() && + (clickedItem == src->itemAt( pos )) ) { + QTimer::singleShot( 500, this, SLOT( showLineEdit() ) ); + activity = FALSE; // no drags or clicks for 500 ms before we start the renaming + } else { // new item clicked + activity = TRUE; + clickedItem = src->itemAt( pos ); + ed->hide(); + } + } + break; + + case QEvent::MouseMove: + + if ( ((QMouseEvent *) event)->state() & Qt::LeftButton ) { + activity = TRUE; // drag + } + break; + + case QEvent::KeyPress: + + switch ( ((QKeyEvent *) event)->key() ) { + + case Qt::Key_F2: + + activity = FALSE; + clickedItem = src->item( src->currentItem() ); + showLineEdit(); + break; + + case Qt::Key_Escape: + if ( !ed->isHidden() ) { + hideLineEdit(); // abort rename + return TRUE; + } + break; + + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + + if ( !ed->isHidden() ) + return TRUE; // Filter out the keystrokes + break; + + } + break; + + case QEvent::Resize: + + if ( clickedItem && ed && !ed->isHidden() ) { + QRect rect = src->itemRect( clickedItem ); + ed->resize( rect.right() - rect.left() - 1, + rect.bottom() - rect.top() - 1 ); + } + break; + + default: + break; + } + + return FALSE; +} + +void ListBoxRename::showLineEdit() +{ + if ( !clickedItem || activity ) + return; + QRect rect = src->itemRect( clickedItem ); + ed->resize( rect.right() - rect.left() - 1, + rect.bottom() - rect.top() - 1 ); + ed->move( rect.left() + 1, rect.top() + 1 ); + ed->setText( clickedItem->text() ); + ed->selectAll(); + ed->show(); + ed->setFocus(); +} + +void ListBoxRename::hideLineEdit() +{ + ed->hide(); + clickedItem = 0; + src->setFocus(); +} + +void ListBoxRename::renameClickedItem() +{ + if ( clickedItem && ed ) { + ( (EditableListBoxItem *) clickedItem )->setText( ed->text() ); + emit itemTextChanged( ed->text() ); + } + hideLineEdit(); +} diff --git a/kdevdesigner/designer/listboxrename.h b/kdevdesigner/designer/listboxrename.h new file mode 100644 index 00000000..cdb6d67b --- /dev/null +++ b/kdevdesigner/designer/listboxrename.h @@ -0,0 +1,57 @@ +/********************************************************************** +** Copyright (C) 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. +** +**********************************************************************/ + +#ifndef LISTBOXRENAME_H +#define LISTBOXRENAME_H + +#include <qobject.h> +#include <qlistbox.h> + +class QLineEdit; + +class ListBoxRename : public QObject +{ + Q_OBJECT +public: + ListBoxRename( QListBox * eventSource, const char * name = 0 ); + bool eventFilter( QObject *, QEvent * event ); + +signals: + void itemTextChanged( const QString & ); + +public slots: + void showLineEdit(); + void hideLineEdit(); + void renameClickedItem(); + +private: + QListBoxItem * clickedItem; + QListBox * src; + QLineEdit * ed; + bool activity; +}; + +#endif //LISTBOXRENAME_H diff --git a/kdevdesigner/designer/listdnd.cpp b/kdevdesigner/designer/listdnd.cpp new file mode 100644 index 00000000..34562e6f --- /dev/null +++ b/kdevdesigner/designer/listdnd.cpp @@ -0,0 +1,142 @@ +/********************************************************************** +** Copyright (C) 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 "listdnd.h" +#include <qwidget.h> +#include <qpainter.h> + +ListDnd::ListDnd( QScrollView * eventSource, const char * name ) + : QObject( eventSource, name ), + dragInside( FALSE ), dragDelete( TRUE ), dropConfirmed( FALSE ), dMode( Both ) +{ + src = eventSource; + src->setAcceptDrops( TRUE ); + src->installEventFilter( this ); + src->viewport()->installEventFilter( this ); + + line = new QWidget( src->viewport(), 0, Qt::WStyle_NoBorder | WStyle_StaysOnTop ); + line->setBackgroundColor( Qt::black ); + line->resize( src->viewport()->width(), 2 ); + line->hide(); +} + +void ListDnd::setDragMode( int mode ) +{ + dMode = mode; +} + +int ListDnd::dragMode() const +{ + return dMode; +} + +bool ListDnd::eventFilter( QObject *, QEvent * event ) +{ + switch ( event->type() ) { + case QEvent::DragEnter: + return dragEnterEvent( (QDragEnterEvent *) event ); + case QEvent::DragLeave: + return dragLeaveEvent( (QDragLeaveEvent *) event ); + case QEvent::DragMove: + return dragMoveEvent( (QDragMoveEvent *) event ); + case QEvent::Drop: + return dropEvent( (QDropEvent *) event ); + case QEvent::MouseButtonPress: + return mousePressEvent( (QMouseEvent *) event ); + case QEvent::MouseMove: + return mouseMoveEvent( (QMouseEvent *) event ); + default: + break; + } + return FALSE; +} + + +bool ListDnd::dragEnterEvent( QDragEnterEvent * event ) +{ + if ( dMode == None ) { + return TRUE; + } + + bool ok = ( ( ( dMode & Both ) == Both ) || + ( ( dMode & Internal ) && ( event->source() == src ) ) || + ( ( dMode & External ) && ( event->source() != src ) ) ); + + if ( ok && canDecode( event ) ) { + event->accept(); + dragInside = TRUE; + if ( !( dMode & NullDrop ) ) { + updateLine( event->pos() ); + line->show(); + } + } + return TRUE; +} + +bool ListDnd::dragLeaveEvent( QDragLeaveEvent * ) +{ + dragInside = FALSE; + line->hide(); + return TRUE; +} + +bool ListDnd::dragMoveEvent( QDragMoveEvent * event ) +{ + if ( dragInside && dMode && !( dMode & NullDrop ) ) { + updateLine( event->pos() ); + } + return TRUE; +} + +bool ListDnd::dropEvent( QDropEvent * ) +{ + // do nothing + return FALSE; +} + +bool ListDnd::mousePressEvent( QMouseEvent * event ) +{ + if ( event->button() == LeftButton ) + mousePressPos = event->pos(); + return FALSE; +} + +bool ListDnd::mouseMoveEvent( QMouseEvent * ) +{ + // do nothing + return FALSE; +} + +void ListDnd::updateLine( const QPoint & ) +{ + // do nothing +} + +bool ListDnd::canDecode( QDragEnterEvent * ) +{ + // do nothing + return FALSE; +} diff --git a/kdevdesigner/designer/listdnd.h b/kdevdesigner/designer/listdnd.h new file mode 100644 index 00000000..9e3e6351 --- /dev/null +++ b/kdevdesigner/designer/listdnd.h @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 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. +** +**********************************************************************/ + +#ifndef LISTDND_H +#define LISTDND_H + +#include <qobject.h> +#include <qscrollview.h> + +class ListDnd : public QObject +{ + Q_OBJECT +public: + enum DragMode { None = 0, External = 1, Internal = 2, Both = 3, Move = 4, NullDrop = 8 }; + ListDnd( QScrollView * eventSource, const char * name = 0 ); + void setDragMode( int mode ); + int dragMode() const; + bool eventFilter( QObject *, QEvent * event ); + +protected: + virtual bool dragEnterEvent( QDragEnterEvent * event ); + virtual bool dragLeaveEvent( QDragLeaveEvent * ); + virtual bool dragMoveEvent( QDragMoveEvent * event ); + virtual bool dropEvent( QDropEvent * event ); + virtual bool mousePressEvent( QMouseEvent * event ); + virtual bool mouseMoveEvent( QMouseEvent * event ); + virtual void updateLine( const QPoint & dragPos ); + virtual bool canDecode( QDragEnterEvent * event ); + + QScrollView * src; + QWidget * line; + QPoint mousePressPos; + QPoint dragPos; + bool dragInside; + bool dragDelete; + bool dropConfirmed; + int dMode; +}; + +#endif // LISTDND_H diff --git a/kdevdesigner/designer/listeditor.ui b/kdevdesigner/designer/listeditor.ui new file mode 100644 index 00000000..6118ba2b --- /dev/null +++ b/kdevdesigner/designer/listeditor.ui @@ -0,0 +1,179 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ListEditor</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ListEditor</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>331</width> + <height>301</height> + </rect> + </property> + <property name="caption"> + <string>Edit</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0" rowspan="5" colspan="1"> + <column> + <property name="text"> + <string>Column 1</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listview</cstring> + </property> + <property name="selectionMode"> + <enum>Extended</enum> + </property> + <property name="resizeMode"> + <enum>AllColumns</enum> + </property> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <widget class="QPushButton" row="2" column="1"> + <property name="name"> + <cstring>PushButton3</cstring> + </property> + <property name="text"> + <string>Re&name</string> + </property> + </widget> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>PushButton4</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>ListEditor</receiver> + <slot>addItem()</slot> + </connection> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>ListEditor</receiver> + <slot>removeItems()</slot> + </connection> + <connection> + <sender>PushButton4</sender> + <signal>clicked()</signal> + <receiver>ListEditor</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>listview</sender> + <signal>itemRenamed(QListViewItem*,int)</signal> + <receiver>ListEditor</receiver> + <slot>renamed(QListViewItem*)</slot> + </connection> + <connection> + <sender>PushButton3</sender> + <signal>clicked()</signal> + <receiver>ListEditor</receiver> + <slot>renameItem()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">listeditor.ui.h</include> +</includes> +<forwards> + <forward>class QStringList;</forward> +</forwards> +<slots> + <slot>init()</slot> + <slot>setList( const QStringList & l )</slot> + <slot>addItem()</slot> + <slot>renamed( QListViewItem * i )</slot> + <slot>removeItems()</slot> + <slot returnType="QStringList">items()</slot> + <slot>renameItem()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/listeditor.ui.h b/kdevdesigner/designer/listeditor.ui.h new file mode 100644 index 00000000..bba06104 --- /dev/null +++ b/kdevdesigner/designer/listeditor.ui.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include <qheader.h> +#include <qapplication.h> + +void ListEditor::init() +{ + listview->header()->hide(); + listview->setSorting( -1 ); + listview->setDefaultRenameAction( QListView::Accept ); +} + +void ListEditor::setList( const QStringList &l ) +{ + QListViewItem *i = 0; + for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + i = new QListViewItem( listview, i ); + i->setText( 0, *it ); + i->setRenameEnabled( 0, TRUE ); + } +} + +void ListEditor::addItem() +{ + QListViewItem *i = new QListViewItem( listview, listview->lastItem() ); + i->setRenameEnabled( 0, TRUE ); + qApp->processEvents(); + i->startRename( 0 ); +} + +void ListEditor::renamed( QListViewItem *i ) +{ + if ( i && i->text( 0 ).isEmpty() ) + i->startRename( 0 ); +} + +void ListEditor::removeItems() +{ + QListViewItemIterator it( listview ); + QListViewItem *i = 0; + while ( ( i = it.current() ) ) { + ++it; + if ( i->isSelected() ) + delete i; + } +} + +QStringList ListEditor::items() +{ + QStringList l; + QListViewItemIterator it( listview ); + QListViewItem *i = 0; + while ( ( i = it.current() ) ) { + ++it; + if ( !i->text( 0 ).isEmpty() ) + l << i->text( 0 ); + } + return l; +} + +void ListEditor::renameItem() +{ + QListViewItem *i = listview->currentItem(); + if ( i ) + i->startRename( 0 ); +} diff --git a/kdevdesigner/designer/listviewdnd.cpp b/kdevdesigner/designer/listviewdnd.cpp new file mode 100644 index 00000000..b4098237 --- /dev/null +++ b/kdevdesigner/designer/listviewdnd.cpp @@ -0,0 +1,432 @@ +/********************************************************************** +** Copyright (C) 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 "listviewdnd.h" +#include <qwidget.h> +#include <qheader.h> +#include <qpainter.h> +#include <qdragobject.h> +#include <qvaluelist.h> + +// The Dragobject Declaration --------------------------------------- +class ListViewItemDrag : public QStoredDrag +{ +public: + enum DropRelation { Sibling, Child }; + ListViewItemDrag( ListViewItemList & items, QWidget * parent = 0, const char * name = 0 ); + ~ListViewItemDrag() {}; + static bool canDecode( QDragMoveEvent * event ); + static bool decode( QDropEvent * event, QListView * parent, QListViewItem * insertPoint, DropRelation dr ); +}; +// ------------------------------------------------------------------ + +ListViewDnd::ListViewDnd( QListView * eventSource, const char * name ) + : ListDnd( eventSource, name ) { } + +void ListViewDnd::confirmDrop( QListViewItem * ) +{ + dropConfirmed = TRUE; +} + +bool ListViewDnd::dropEvent( QDropEvent * event ) +{ + if ( dragInside ) { + + if ( dMode & NullDrop ) { // combined with Move, a NullDrop will delete an item + event->accept(); + emit dropped( 0 ); // a NullDrop + return TRUE; + } + + QPoint pos = event->pos(); + + ListViewItemDrag::DropRelation dr = ListViewItemDrag::Sibling; + QListViewItem *item = itemAt( pos ); + int dpos = dropDepth( item, pos ); + + if ( item ) { + if ( dpos > item->depth() && !(dMode & Flat) ) { + // Child node + dr = ListViewItemDrag::Child; + } else if ( dpos < item->depth() ) { + // Parent(s) Sibling + while ( item && (item->depth() > dpos) ) + item = item->parent(); + } + } + + if ( ListViewItemDrag::decode( event, (QListView *) src, item, dr ) ) { + event->accept(); + emit dropped( 0 ); // Use ID instead of item? + } + } + + line->hide(); + dragInside = FALSE; + + return TRUE; +} + +bool ListViewDnd::mouseMoveEvent( QMouseEvent * event ) +{ + if ( event->state() & LeftButton ) { + if ( ( event->pos() - mousePressPos ).manhattanLength() > 3 ) { + ListViewItemList list; + + if ( dMode & Flat ) + buildFlatList( list ); + else + buildTreeList( list ); + + ListViewItemDrag * dragobject = new ListViewItemDrag( list, (QListView *) src ); + + if ( dMode & Move ) { + disabledItems = list; + setVisibleItems( FALSE ); + } + + dragobject->dragCopy(); + + if ( dMode & Move ) { + // Did the target accept the drop? + if ( dropConfirmed ) { + // Shouldn't autoDelete handle this? + for( list.first(); list.current(); list.next() ) + delete list.current(); + dropConfirmed = FALSE; + } else { + // Reenable disabled items since + // drag'n'drop was aborted + setVisibleItems( TRUE ); + } + disabledItems.clear(); + } + } + } + return FALSE; +} + +int ListViewDnd::buildFlatList( ListViewItemList & list ) +{ + bool addKids = FALSE; + QListViewItem *nextSibling = 0; + QListViewItem *nextParent = 0; + QListViewItemIterator it = ((QListView *)src)->firstChild(); + for ( ; *it; it++ ) { + // Hit the nextSibling, turn of child processing + if ( (*it) == nextSibling ) + addKids = FALSE; + + if ( (*it)->isSelected() ) { + if ( (*it)->childCount() == 0 ) { + // Selected, no children + list.append( *it ); + } else if ( !addKids ) { + // Children processing not set, so set it + // Also find the item were we shall quit + // processing children...if any such item + addKids = TRUE; + nextSibling = (*it)->nextSibling(); + nextParent = (*it)->parent(); + while ( nextParent && !nextSibling ) { + nextSibling = nextParent->nextSibling(); + nextParent = nextParent->parent(); + } + } + } else if ( ((*it)->childCount() == 0) && addKids ) { + // Leaf node, and we _do_ process children + list.append( *it ); + } + } + return list.count(); +} + +int ListViewDnd::buildTreeList( ListViewItemList & list ) +{ + QListViewItemIterator it = ((QListView *)src)->firstChild(); + for ( ; *it; it++ ) { + if ( (*it)->isSelected() ) + list.append( *it ); + } + return list.count(); +} + +void ListViewDnd::setVisibleItems( bool b ) +{ + if ( disabledItems.isEmpty() ) + return; + + disabledItems.first(); + do { + disabledItems.current()->setVisible( b ); + } while ( disabledItems.next() ); +} + +void ListViewDnd::updateLine( const QPoint & dragPos ) +{ + QListViewItem * item = itemAt(dragPos); + QListView * src = (QListView *) this->src; + + int ypos = item ? + ( src->itemRect( item ).bottom() - ( line->height() / 2 ) ) : + ( src->itemRect( src->firstChild() ).top() ); + + int xpos = dropDepth( item, dragPos ) * src->treeStepSize(); + line->resize( src->viewport()->width() - xpos, line->height() ); + line->move( xpos, ypos ); +} + +QListViewItem * ListViewDnd::itemAt( QPoint pos ) +{ + QListView * src = (QListView *) this->src; + int headerHeight = (int)(src->header()->height()); + pos.ry() -= headerHeight; + QListViewItem * result = src->itemAt( pos ); + + if ( result && ( pos.ry() < (src->itemPos(result) + result->height()/2) ) ) + result = result->itemAbove(); + + // Wind back if has parent, and we're in flat mode + while ( result && result->parent() && (dMode & Flat) ) + result = result->parent(); + + // Wind back if has parent, and we're in flat mode + while ( result && !result->isVisible() && result->parent() ) + result = result->parent(); + + if ( !result && src->firstChild() && (pos.y() > src->itemRect(src->firstChild()).bottom()) ) { + result = src->lastItem(); + if ( !result->isVisible() ) + // Handle special case where last item is actually hidden + result = result->itemAbove(); + } + + return result; +} + +int ListViewDnd::dropDepth( QListViewItem * item, QPoint pos ) +{ + if ( !item || (dMode & Flat) ) + return 0; + + int result = 0; + int itemDepth = item->depth(); + int indentSize = ((QListView *)src)->treeStepSize(); + int itemLeft = indentSize * itemDepth; + int childMargin = indentSize*2; + if ( pos.x() > itemLeft + childMargin ) { + result = itemDepth + 1; + } else if ( pos.x() < itemLeft ) { + result = pos.x() / indentSize; + } else { + result = itemDepth; + } + return result; +} + +bool ListViewDnd::canDecode( QDragEnterEvent * event ) +{ + return ListViewItemDrag::canDecode( event ); +} + +// ------------------------------------------------------------------ +// The Dragobject Implementation ------------------------------------ +// ------------------------------------------------------------------ + +QDataStream & operator<< ( QDataStream & stream, const QListViewItem & item ); +QDataStream & operator>> ( QDataStream & stream, QListViewItem & item ); + +ListViewItemDrag::ListViewItemDrag( ListViewItemList & items, QWidget * parent, const char * name ) + : QStoredDrag( "qt/listviewitem", parent, name ) +{ + // ### FIX! + QByteArray data( sizeof( Q_INT32 ) + sizeof( QListViewItem ) * items.count() ); + QDataStream stream( data, IO_WriteOnly ); + + stream << items.count(); + + QListViewItem *i = items.first(); + while ( i ) { + stream << *i; + i = items.next(); + } + + setEncodedData( data ); +} + +bool ListViewItemDrag::canDecode( QDragMoveEvent * event ) +{ + return event->provides( "qt/listviewitem" ); +} + +bool ListViewItemDrag::decode( QDropEvent * event, QListView * parent, QListViewItem * insertPoint, DropRelation dr ) +{ + QByteArray data = event->encodedData( "qt/listviewitem" ); + QListViewItem* itemParent = insertPoint ? insertPoint->parent() : 0; + + // Change from sibling (default) to child creation + if ( insertPoint && dr == Child ) { + itemParent = insertPoint; + insertPoint = 0; + } + + if ( data.size() ) { + event->accept(); + QDataStream stream( data, IO_ReadOnly ); + + int count = 0; + stream >> count; + + for( int i = 0; i < count; i++ ) { + if ( itemParent ) { + insertPoint = new QListViewItem( itemParent, insertPoint ); + itemParent->setOpen( TRUE ); + } else { // No parent for insertPoint, use QListView + insertPoint = new QListViewItem( parent, insertPoint ); + } + stream >> *insertPoint; + } + return TRUE; + } + return FALSE; +} + + +QDataStream & operator<< ( QDataStream & stream, const QListViewItem & item ) +{ + int columns = item.listView()->columns(); + stream << columns; + + Q_UINT8 b = 0; + + int i; + for ( i = 0; i < columns; i++ ) { + b = (Q_UINT8) ( item.text( i ) != QString::null ); // does column i have a string ? + stream << b; + if ( b ) { + stream << item.text( i ); + } + } + + for ( i = 0; i < columns; i++ ) { + b = (Q_UINT8) ( !!item.pixmap( i ) ); // does column i have a pixmap ? + stream << b; + if ( b ) { + stream << ( *item.pixmap( i ) ); + } + } + + stream << (Q_UINT8) item.isOpen(); + stream << (Q_UINT8) item.isSelectable(); + stream << (Q_UINT8) item.isExpandable(); + stream << (Q_UINT8) item.dragEnabled(); + stream << (Q_UINT8) item.dropEnabled(); + stream << (Q_UINT8) item.isVisible(); + + for ( i = 0; i < columns; i++ ) { + stream << (Q_UINT8) item.renameEnabled( i ); + } + + stream << (Q_UINT8) item.multiLinesEnabled(); + stream << item.childCount(); + + if ( item.childCount() > 0 ) { + QListViewItem * child = item.firstChild(); + while ( child ) { + stream << ( *child ); // recursive call + child = child->nextSibling(); + } + } + + return stream; +} + +QDataStream & operator>> ( QDataStream & stream, QListViewItem & item ) +{ + Q_INT32 columns; + stream >> columns; + + Q_UINT8 b = 0; + + QString text; + int i; + for ( i = 0; i < columns; i++ ) { + stream >> b; + if ( b ) { // column i has string ? + stream >> text; + item.setText( i, text ); + } + } + + QPixmap pixmap; + for ( i = 0; i < columns; i++ ) { + stream >> b; // column i has pixmap ? + if ( b ) { + stream >> pixmap; + item.setPixmap( i, pixmap ); + } + } + + stream >> b; + item.setOpen( b ); + + stream >> b; + item.setSelectable( b ); + + stream >> b; + item.setExpandable( b ); + + stream >> b; + item.setDragEnabled( b ); + + stream >> b; + item.setDropEnabled( b ); + + stream >> b; + item.setVisible( b ); + + for ( i = 0; i < columns; i++ ) { + stream >> b; + item.setRenameEnabled( i, b ); + } + + stream >> b; + item.setMultiLinesEnabled( b ); + + int childCount; + stream >> childCount; + + QListViewItem *child = 0; + QListViewItem *prevchild = 0; + for ( i = 0; i < childCount; i++ ) { + child = new QListViewItem( &item, prevchild ); + stream >> ( *child ); + item.insertItem( child ); + prevchild = child; + } + + return stream; +} diff --git a/kdevdesigner/designer/listviewdnd.h b/kdevdesigner/designer/listviewdnd.h new file mode 100644 index 00000000..52b18091 --- /dev/null +++ b/kdevdesigner/designer/listviewdnd.h @@ -0,0 +1,66 @@ +/********************************************************************** +** Copyright (C) 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. +** +**********************************************************************/ + +#ifndef LISTVIEWDND_H +#define LISTVIEWDND_H + +#include <qptrlist.h> +#include <qlistview.h> +#include "listdnd.h" + +class QWidget; +class QListView; +typedef QPtrList<QListViewItem> ListViewItemList; + +class ListViewDnd : public ListDnd +{ + Q_OBJECT +public: + enum DragMode { Flat = 16 }; // see ListDnd::DragMode + + ListViewDnd( QListView * eventSource, const char * name = 0 ); + +signals: + void dropped( QListViewItem * ); + +public slots: + void confirmDrop( QListViewItem * ); + +protected: + virtual bool dropEvent( QDropEvent * event ); + virtual bool mouseMoveEvent( QMouseEvent * event ); + virtual void updateLine( const QPoint & pos ); + virtual bool canDecode( QDragEnterEvent * event ); +private: + QListViewItem * itemAt( QPoint pos ); + int dropDepth( QListViewItem * item, QPoint pos ); + int buildFlatList( ListViewItemList & list ); + int buildTreeList( ListViewItemList & list ); + void setVisibleItems( bool b ); + ListViewItemList disabledItems; +}; + +#endif //LISTVIEWDND_H diff --git a/kdevdesigner/designer/listvieweditor.ui b/kdevdesigner/designer/listvieweditor.ui new file mode 100644 index 00000000..d9e87240 --- /dev/null +++ b/kdevdesigner/designer/listvieweditor.ui @@ -0,0 +1,935 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ListViewEditorBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ListViewEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>567</width> + <height>398</height> + </rect> + </property> + <property name="caption"> + <string>Edit Listview</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Edit Listview</b><p>Use the controls on the <b>Items</b>-tab to add, edit or delete items in the listview. Change the column configuration of the listview using the controls on the <b>Columns</b>-tab.</p>Click the <b>New Item</b>-button to create a new item, then enter text and add a pixmap.</p><p>Select an item from the list and click the <b>Delete Item</b>-button to remove the item from the list.</p></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget10</cstring> + </property> + <attribute name="title"> + <string>&Items</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton" row="2" column="1"> + <property name="name"> + <cstring>itemDelete</cstring> + </property> + <property name="text"> + <string>&Delete Item</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete item</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Deletes the selected item.</b><p>Any sub-items are also deleted.</p></string> + </property> + </widget> + <widget class="QGroupBox" row="0" column="2" rowspan="8" colspan="1"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Item Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>Label2</cstring> + </property> + <property name="text"> + <string>Pi&xmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemChoosePixmap</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label1</cstring> + </property> + <property name="text"> + <string>&Text:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemText</cstring> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>itemText</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Change text</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Change the text of the item.</b><p>The text will be changed in the current column of the selected item.</p></string> + </property> + </widget> + <widget class="QSpinBox" row="0" column="1"> + <property name="name"> + <cstring>itemColumn</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Change column</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select the current column.</b><p>The item's text and pixmap will be changed for the current column</p></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>Label4</cstring> + </property> + <property name="text"> + <string>Colu&mn:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemColumn</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>itemPixmap</cstring> + </property> + <property name="text"> + <string>Label4</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>itemDeletePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the selected item's pixmap.</b><p>The pixmap in the current column of the selected item will be deleted.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>itemChoosePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a pixmap file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p></string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>itemNew</cstring> + </property> + <property name="text"> + <string>&New Item</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add an item</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Adds a new item to the list.</b><p>The item will be inserted at the top of the list and can be moved using the up- and down-buttons.</p></string> + </property> + </widget> + <widget class="QListView" row="0" column="0" rowspan="8" colspan="1"> + <property name="name"> + <cstring>itemsPreview</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>The list of items.</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>itemNewSub</cstring> + </property> + <property name="text"> + <string>New &Subitem</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add a subitem</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Create a new sub-item for the selected item.</b><p>New sub-items are inserted at the top of the list of sub-items, and new levels are created automatically.</p></string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Vertical Spacing1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>itemUp</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move up</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item up.</b><p>The item will be moved within its level in the hierarchy.</p></string> + </property> + </widget> + <widget class="QPushButton" row="5" column="1"> + <property name="name"> + <cstring>itemDown</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move down</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item down.</b><p>The item will be moved within its level in the hierarchy.</p></string> + </property> + </widget> + <widget class="QPushButton" row="6" column="1"> + <property name="name"> + <cstring>itemLeft</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_left.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move left</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item one level up.</b><p>This will also change the level of the item's sub-items.</p></string> + </property> + </widget> + <widget class="QPushButton" row="7" column="1"> + <property name="name"> + <cstring>itemRight</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_right.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move right</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item one level down.</b><p>This will also change the level of the item's sub-items.</p></string> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget11</cstring> + </property> + <attribute name="title"> + <string>Co&lumns</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QGroupBox" row="0" column="2" rowspan="5" colspan="1"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="title"> + <string>Column Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label2</cstring> + </property> + <property name="text"> + <string>&Pixmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>colChoosePixmap</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>colPixmap</cstring> + </property> + <property name="text"> + <string>Label4</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>colDeletePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Delete the pixmap of the selected column.</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>colChoosePixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a pixmap file for the selected column.</b><p>The pixmap will be displayed in the header of the listview.</p></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>Label1</cstring> + </property> + <property name="text"> + <string>&Text:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>colText</cstring> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>colText</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Enter column text</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Enter the text for the selected column.</b><p>The text will be displayed in the header of the listview.</p></string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>colClickable</cstring> + </property> + <property name="text"> + <string>Clicka&ble</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If this option is checked, the selected column will react to mouse clicks on the header.</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>colResizable</cstring> + </property> + <property name="text"> + <string>Re&sizable</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The column's width will be resizable if this option is checked.</string> + </property> + </widget> + </grid> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>colDelete</cstring> + </property> + <property name="text"> + <string>&Delete Column</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete column</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Deletes the selected Column.</string> + </property> + </widget> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>colDown</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move down</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item down.</b><p>The top-most column will be the first column in the list.</p></string> + </property> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>colNew</cstring> + </property> + <property name="text"> + <string>&New Column</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add a Column</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Create a new column.</b><p>New columns are appended at the end of (right of) the list and may be moved using the up- and down-buttons.</p></string> + </property> + </widget> + <widget class="QPushButton" row="3" column="1"> + <property name="name"> + <cstring>colUp</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move up</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item up.</b><p>The top-most column will be the first column in the list.</p></string> + </property> + </widget> + <widget class="QListBox" row="0" column="0" rowspan="5" colspan="1"> + <property name="name"> + <cstring>colPreview</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>The list of columns.</string> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>Vertical Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>applyButton</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Apply all changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>itemNew</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemNewClicked()</slot> + </connection> + <connection> + <sender>itemDelete</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemDeleteClicked()</slot> + </connection> + <connection> + <sender>itemUp</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemUpClicked()</slot> + </connection> + <connection> + <sender>itemDown</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemDownClicked()</slot> + </connection> + <connection> + <sender>itemColumn</sender> + <signal>valueChanged(int)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemColChanged(int)</slot> + </connection> + <connection> + <sender>itemText</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>itemDeletePixmap</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemPixmapDeleted()</slot> + </connection> + <connection> + <sender>itemChoosePixmap</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemPixmapChoosen()</slot> + </connection> + <connection> + <sender>colNew</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>newColumnClicked()</slot> + </connection> + <connection> + <sender>colDelete</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>deleteColumnClicked()</slot> + </connection> + <connection> + <sender>colUp</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnUpClicked()</slot> + </connection> + <connection> + <sender>colDown</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnDownClicked()</slot> + </connection> + <connection> + <sender>colText</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>colDeletePixmap</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnPixmapDeleted()</slot> + </connection> + <connection> + <sender>colChoosePixmap</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnPixmapChosen()</slot> + </connection> + <connection> + <sender>colResizable</sender> + <signal>toggled(bool)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnResizable(bool)</slot> + </connection> + <connection> + <sender>colClickable</sender> + <signal>toggled(bool)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>columnClickable(bool)</slot> + </connection> + <connection> + <sender>tabWidget</sender> + <signal>selected(const QString&)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>initTabPage(const QString&)</slot> + </connection> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>applyButton</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>applyClicked()</slot> + </connection> + <connection> + <sender>colPreview</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>currentColumnChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>colPreview</sender> + <signal>selectionChanged(QListBoxItem*)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>currentColumnChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>itemsPreview</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>currentItemChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>itemsPreview</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>ListViewEditorBase</receiver> + <slot>currentItemChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>itemNewSub</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemNewSubClicked()</slot> + </connection> + <connection> + <sender>itemLeft</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemLeftClicked()</slot> + </connection> + <connection> + <sender>itemRight</sender> + <signal>clicked()</signal> + <receiver>ListViewEditorBase</receiver> + <slot>itemRightClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>okButton</tabstop> + <tabstop>cancelButton</tabstop> + <tabstop>tabWidget</tabstop> + <tabstop>itemsPreview</tabstop> + <tabstop>itemNew</tabstop> + <tabstop>itemNewSub</tabstop> + <tabstop>itemDelete</tabstop> + <tabstop>itemUp</tabstop> + <tabstop>itemDown</tabstop> + <tabstop>itemLeft</tabstop> + <tabstop>itemRight</tabstop> + <tabstop>itemColumn</tabstop> + <tabstop>itemText</tabstop> + <tabstop>itemDeletePixmap</tabstop> + <tabstop>itemChoosePixmap</tabstop> + <tabstop>helpButton</tabstop> + <tabstop>applyButton</tabstop> + <tabstop>colPreview</tabstop> + <tabstop>colNew</tabstop> + <tabstop>colDelete</tabstop> + <tabstop>colUp</tabstop> + <tabstop>colDown</tabstop> + <tabstop>colText</tabstop> + <tabstop>colDeletePixmap</tabstop> + <tabstop>colChoosePixmap</tabstop> + <tabstop>colClickable</tabstop> + <tabstop>colResizable</tabstop> +</tabstops> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">applyClicked()</slot> + <slot access="protected">columnClickable(bool)</slot> + <slot access="protected">columnDownClicked()</slot> + <slot access="protected">columnPixmapChosen()</slot> + <slot access="protected">columnPixmapDeleted()</slot> + <slot access="protected">columnResizable(bool)</slot> + <slot access="protected">columnTextChanged(const QString &)</slot> + <slot access="protected">columnUpClicked()</slot> + <slot access="protected">currentColumnChanged(QListBoxItem*)</slot> + <slot access="protected">currentItemChanged(QListViewItem*)</slot> + <slot access="protected">deleteColumnClicked()</slot> + <slot access="protected">initTabPage(const QString &)</slot> + <slot access="protected">itemColChanged(int)</slot> + <slot access="protected">itemDeleteClicked()</slot> + <slot access="protected">itemDownClicked()</slot> + <slot access="protected">itemLeftClicked()</slot> + <slot access="protected">itemNewClicked()</slot> + <slot access="protected">itemNewSubClicked()</slot> + <slot access="protected">itemPixmapChoosen()</slot> + <slot access="protected">itemPixmapDeleted()</slot> + <slot access="protected">itemTextChanged(const QString &)</slot> + <slot access="protected">itemUpClicked()</slot> + <slot access="protected">newColumnClicked()</slot> + <slot access="protected">itemRightClicked()</slot> + <slot access="protected">okClicked()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/listvieweditorimpl.cpp b/kdevdesigner/designer/listvieweditorimpl.cpp new file mode 100644 index 00000000..78055f92 --- /dev/null +++ b/kdevdesigner/designer/listvieweditorimpl.cpp @@ -0,0 +1,650 @@ +/********************************************************************** +** 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 "formwindow.h" +#include "mainwindow.h" +#include "listvieweditorimpl.h" +#include "pixmapchooser.h" +#include "command.h" +#include "listviewdnd.h" +#include "listboxdnd.h" +#include "listboxrename.h" + +#include <qlistview.h> +#include <qheader.h> +#include <qlistbox.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qtabwidget.h> +#include <qspinbox.h> +#include <qpushbutton.h> +#include <qptrstack.h> + +#include <klocale.h> + +ListViewEditor::ListViewEditor( QWidget *parent, QListView *lv, FormWindow *fw ) + : ListViewEditorBase( parent, 0, TRUE ), listview( lv ), formwindow( fw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + itemColumn->setEnabled( FALSE ); + + setupColumns(); + PopulateListViewCommand::transferItems( listview, itemsPreview ); + setupItems(); + + itemsPreview->setShowSortIndicator( listview->showSortIndicator() ); + itemsPreview->setAllColumnsShowFocus( listview->allColumnsShowFocus() ); + itemsPreview->setRootIsDecorated( listview->rootIsDecorated() ); + + if ( itemsPreview->firstChild() ) { + itemsPreview->setCurrentItem( itemsPreview->firstChild() ); + itemsPreview->setSelected( itemsPreview->firstChild(), TRUE ); + } + + // Clamp on drag and drop to QListView + ListViewDnd *itemsDnd = new ListViewDnd( itemsPreview ); + itemsDnd->setDragMode( ListViewDnd::Internal | ListViewDnd::Move ); + QObject::connect( itemsDnd, SIGNAL( dropped( QListViewItem * ) ), + itemsDnd, SLOT( confirmDrop( QListViewItem * ) ) ); + + // Enable rename for all QListViewItems + QListViewItemIterator it = ((QListView *)itemsPreview)->firstChild(); + for ( ; *it; it++ ) + (*it)->setRenameEnabled( 0, TRUE ); + + // Connect listview signal to signal-relay + QObject::connect( itemsPreview, + SIGNAL( itemRenamed( QListViewItem*, int, const QString & ) ), + this, + SLOT( emitItemRenamed(QListViewItem*, int, const QString&) ) ); + + // Connect signal-relay to QLineEdit "itemText" + QObjectList *l = parent->queryList( "QLineEdit", "itemText" ); + QObject *obj; + QObjectListIt itemsLineEditIt( *l ); + while ( (obj = itemsLineEditIt.current()) != 0 ) { + ++itemsLineEditIt; + QObject::connect( this, + SIGNAL( itemRenamed( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; + + // Clamp on drag and drop to QListBox + ListBoxDnd *columnsDnd = new ListBoxDnd( colPreview ); + columnsDnd->setDragMode( ListBoxDnd::Internal | ListBoxDnd::Move ); + QObject::connect( columnsDnd, SIGNAL( dropped( QListBoxItem * ) ), + columnsDnd, SLOT( confirmDrop( QListBoxItem * ) ) ); + + // Clamp on rename to QListBox + ListBoxRename *columnsRename = new ListBoxRename( colPreview ); + QObject::connect( columnsRename, + SIGNAL( itemTextChanged( const QString & ) ), + this, + SLOT( columnTextChanged( const QString & ) ) ); + + // Find QLineEdit "colText" and connect + l = parent->queryList( "QLineEdit", "colText" ); + QObjectListIt columnsLineEditIt( *l ); + while ( (obj = columnsLineEditIt.current()) != 0 ) { + ++columnsLineEditIt; + QObject::connect( columnsRename, + SIGNAL( itemTextChanged( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; +} + +void ListViewEditor::applyClicked() +{ + setupItems(); + PopulateListViewCommand *cmd = new PopulateListViewCommand( i18n( "Edit the Items and Columns of '%1'" ).arg( listview->name() ), + formwindow, listview, itemsPreview ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); +} + +void ListViewEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void ListViewEditor::columnClickable( bool b ) +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + c->clickable = b; +} + +void ListViewEditor::columnDownClicked() +{ + if ( colPreview->currentItem() == -1 || + colPreview->currentItem() > (int)colPreview->count() - 2 ) + return; + + colPreview->clearSelection(); + QListBoxItem *i = colPreview->item( colPreview->currentItem() ); + QListBoxItem *below = i->next(); + + colPreview->takeItem( i ); + colPreview->insertItem( i, below ); + + colPreview->setCurrentItem( i ); + colPreview->setSelected( i, TRUE ); +} + +void ListViewEditor::columnPixmapChosen() +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + + QPixmap pix; + if ( colPixmap->pixmap() ) + pix = qChoosePixmap( this, formwindow, *colPixmap->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + c->pixmap = pix; + colPreview->blockSignals( TRUE ); + if ( !c->pixmap.isNull() ) + colPreview->changeItem( c->pixmap, c->text, colPreview->index( c->item ) ); + else + colPreview->changeItem( c->text, colPreview->index( c->item ) ); + c->item = colPreview->item( colPreview->currentItem() ); + colPixmap->setPixmap( c->pixmap ); + colPreview->blockSignals( FALSE ); + colDeletePixmap->setEnabled( TRUE ); +} + +void ListViewEditor::columnPixmapDeleted() +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + + c->pixmap = QPixmap(); + colPreview->blockSignals( TRUE ); + if ( !c->pixmap.isNull() ) + colPreview->changeItem( c->pixmap, c->text, colPreview->index( c->item ) ); + else + colPreview->changeItem( c->text, colPreview->index( c->item ) ); + c->item = colPreview->item( colPreview->currentItem() ); + colPixmap->setText( "" ); + colPreview->blockSignals( FALSE ); + colDeletePixmap->setEnabled( FALSE ); +} + +void ListViewEditor::columnResizable( bool b ) +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + c->resizable = b; +} + +void ListViewEditor::columnTextChanged( const QString &txt ) +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + + c->text = txt; + colPreview->blockSignals( TRUE ); + if ( !c->pixmap.isNull() ) + colPreview->changeItem( c->pixmap, c->text, colPreview->index( c->item ) ); + else + colPreview->changeItem( c->text, colPreview->index( c->item ) ); + c->item = colPreview->item( colPreview->currentItem() ); + colPreview->blockSignals( FALSE ); +} + +void ListViewEditor::columnUpClicked() +{ + if ( colPreview->currentItem() <= 0 ) + return; + + colPreview->clearSelection(); + QListBoxItem *i = colPreview->item( colPreview->currentItem() ); + QListBoxItem *above = i->prev(); + + colPreview->takeItem( above ); + colPreview->insertItem( above, i ); + + colPreview->setCurrentItem( i ); + colPreview->setSelected( i, TRUE ); +} + +void ListViewEditor::currentColumnChanged( QListBoxItem *i ) +{ + Column *c = findColumn( i ); + if ( !i || !c ) { + colText->setEnabled( FALSE ); + colPixmap->setEnabled( FALSE ); + colDeletePixmap->setEnabled( FALSE ); + colText->blockSignals( TRUE ); + colText->setText( "" ); + colText->blockSignals( FALSE ); + colClickable->setEnabled( FALSE ); + colResizable->setEnabled( FALSE ); + return; + } + + colText->setEnabled( TRUE ); + colPixmap->setEnabled( TRUE ); + colDeletePixmap->setEnabled( i->pixmap() && !i->pixmap()->isNull() ); + colClickable->setEnabled( TRUE ); + colResizable->setEnabled( TRUE ); + + colText->blockSignals( TRUE ); + colText->setText( c->text ); + colText->blockSignals( FALSE ); + if ( !c->pixmap.isNull() ) + colPixmap->setPixmap( c->pixmap ); + else + colPixmap->setText( "" ); + colClickable->setChecked( c->clickable ); + colResizable->setChecked( c->resizable ); +} + +void ListViewEditor::newColumnClicked() +{ + Column col; + col.text = i18n( "New Column" ); + col.pixmap = QPixmap(); + col.clickable = TRUE; + col.resizable = TRUE; + if ( !col.pixmap.isNull() ) + col.item = new QListBoxPixmap( colPreview, col.pixmap, col.text ); + else + col.item = new QListBoxText( colPreview, col.text ); + columns.append( col ); + colPreview->setCurrentItem( col.item ); + colPreview->setSelected( col.item, TRUE ); +} + +void ListViewEditor::deleteColumnClicked() +{ + QListBoxItem *i = colPreview->item( colPreview->currentItem() ); + if ( !i ) + return; + + for ( QValueList<Column>::Iterator it = columns.begin(); it != columns.end(); ++it ) { + if ( ( *it ).item == i ) { + delete (*it).item; + columns.remove( it ); + break; + } + } + + if ( colPreview->currentItem() != -1 ) + colPreview->setSelected( colPreview->currentItem(), TRUE ); +} + +void ListViewEditor::currentItemChanged( QListViewItem *i ) +{ + if ( !i ) { + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + itemColumn->setEnabled( FALSE ); + return; + } + + itemText->setEnabled( TRUE ); + itemChoosePixmap->setEnabled( TRUE ); + itemDeletePixmap->setEnabled( i->pixmap( itemColumn->value() ) && + !i->pixmap( itemColumn->value() )->isNull() ); + itemColumn->setEnabled( TRUE ); + + displayItem( i, itemColumn->value() ); +} + +void ListViewEditor::displayItem( QListViewItem *i, int col ) +{ + itemText->blockSignals( TRUE ); + itemText->setText( i->text( col ) ); + itemText->blockSignals( FALSE ); + + itemPixmap->blockSignals( TRUE ); + if ( i->pixmap( col ) ) + itemPixmap->setPixmap( *i->pixmap( col ) ); + else + itemPixmap->setText( "" ); + itemPixmap->blockSignals( FALSE ); +} + +void ListViewEditor::itemColChanged( int col ) +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + displayItem( i, col ); + itemDeletePixmap->setEnabled( i->pixmap( col ) && !i->pixmap( col )->isNull() ); +} + +void ListViewEditor::itemDeleteClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + delete i; + if ( itemsPreview->firstChild() ) { + itemsPreview->setCurrentItem( itemsPreview->firstChild() ); + itemsPreview->setSelected( itemsPreview->firstChild(), TRUE ); + } +} + +void ListViewEditor::itemDownClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + it++; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + it++; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + i->moveItem( other ); +} + +void ListViewEditor::itemNewClicked() +{ + QListViewItem *item = new QListViewItem( itemsPreview ); + item->setText( 0, i18n( "Item" ) ); + item->setRenameEnabled( 0, TRUE ); + itemsPreview->setCurrentItem( item ); + itemsPreview->setSelected( item, TRUE ); + itemText->setFocus(); + itemText->selectAll(); +} + +void ListViewEditor::itemNewSubClicked() +{ + QListViewItem *parent = itemsPreview->currentItem(); + QListViewItem *item = 0; + if ( parent ) { + item = new QListViewItem( parent ); + parent->setOpen( TRUE ); + } else { + item = new QListViewItem( itemsPreview ); + } + item->setText( 0, i18n( "Subitem" ) ); + item->setRenameEnabled( 0, TRUE ); + itemsPreview->setCurrentItem( item ); + itemsPreview->setSelected( item, TRUE ); +} + +void ListViewEditor::itemPixmapChoosen() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QPixmap pix; + if ( itemPixmap->pixmap() ) + pix = qChoosePixmap( this, formwindow, *itemPixmap->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + i->setPixmap( itemColumn->value(), QPixmap( pix ) ); + itemPixmap->setPixmap( pix ); + itemDeletePixmap->setEnabled( TRUE ); +} + +void ListViewEditor::itemPixmapDeleted() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + i->setPixmap( itemColumn->value(), QPixmap() ); + itemPixmap->setText( "" ); + itemDeletePixmap->setEnabled( FALSE ); +} + +void ListViewEditor::itemTextChanged( const QString &txt ) +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + i->setText( itemColumn->value(), txt ); +} + +void ListViewEditor::itemUpClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + --it; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + --it; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + other->moveItem( i ); +} + +void ListViewEditor::itemRightClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + parent = parent ? parent->firstChild() : itemsPreview->firstChild(); + if ( !parent ) + return; + it++; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + it++; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + for ( int c = 0; c < itemsPreview->columns(); ++c ) { + QString s = i->text( c ); + i->setText( c, other->text( c ) ); + other->setText( c, s ); + QPixmap pix; + if ( i->pixmap( c ) ) + pix = *i->pixmap( c ); + if ( other->pixmap( c ) ) + i->setPixmap( c, *other->pixmap( c ) ); + else + i->setPixmap( c, QPixmap() ); + other->setPixmap( c, pix ); + } + + itemsPreview->setCurrentItem( other ); + itemsPreview->setSelected( other, TRUE ); +} + +void ListViewEditor::itemLeftClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + if ( !parent ) + return; + parent = parent->parent(); + --it; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + --it; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + for ( int c = 0; c < itemsPreview->columns(); ++c ) { + QString s = i->text( c ); + i->setText( c, other->text( c ) ); + other->setText( c, s ); + QPixmap pix; + if ( i->pixmap( c ) ) + pix = *i->pixmap( c ); + if ( other->pixmap( c ) ) + i->setPixmap( c, *other->pixmap( c ) ); + else + i->setPixmap( c, QPixmap() ); + other->setPixmap( c, pix ); + } + + itemsPreview->setCurrentItem( other ); + itemsPreview->setSelected( other, TRUE ); +} + +void ListViewEditor::setupColumns() +{ + QHeader *h = listview->header(); + for ( int i = 0; i < (int)h->count(); ++i ) { + Column col; + col.text = h->label( i ); + col.pixmap = QPixmap(); + if ( h->iconSet( i ) ) + col.pixmap = h->iconSet( i )->pixmap(); + col.clickable = h->isClickEnabled( i ); + col.resizable = h->isResizeEnabled( i ); + if ( !col.pixmap.isNull() ) + col.item = new QListBoxPixmap( colPreview, col.pixmap, col.text ); + else + col.item = new QListBoxText( colPreview, col.text ); + columns.append( col ); + } + + colText->setEnabled( FALSE ); + colPixmap->setEnabled( FALSE ); + colClickable->setEnabled( FALSE ); + colResizable->setEnabled( FALSE ); + + if ( colPreview->firstItem() ) + colPreview->setCurrentItem( colPreview->firstItem() ); + numColumns = colPreview->count(); +} + +void ListViewEditor::setupItems() +{ + itemColumn->setMinValue( 0 ); + itemColumn->setMaxValue( QMAX( numColumns - 1, 0 ) ); + int i = 0; + QHeader *header = itemsPreview->header(); + for ( QListBoxItem *item = colPreview->firstItem(); item; item = item->next() ) { + Column *col = findColumn( item ); + if ( !col ) + continue; + if ( i >= itemsPreview->columns() ) + itemsPreview->addColumn( col->text ); + header->setLabel( i, col->pixmap, col->text ); + header->setResizeEnabled( col->resizable, i ); + header->setClickEnabled( col->clickable, i ); + ++i; + } + while ( itemsPreview->columns() > i ) + itemsPreview->removeColumn( i ); + + itemColumn->setValue( QMIN( numColumns - 1, itemColumn->value() ) ); +} + +ListViewEditor::Column *ListViewEditor::findColumn( QListBoxItem *i ) +{ + if ( !i ) + return 0; + + for ( QValueList<Column>::Iterator it = columns.begin(); it != columns.end(); ++it ) { + if ( ( *it ).item == i ) + return &( *it ); + } + + return 0; +} + +void ListViewEditor::initTabPage( const QString &page ) +{ + numColumns = colPreview->count(); + if ( page == i18n( "&Items" ) ) { + setupItems(); + if ( numColumns == 0 ) { + itemNew->setEnabled( FALSE ); + itemNewSub->setEnabled( FALSE ); + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + itemColumn->setEnabled( FALSE ); + } else { + itemNew->setEnabled( TRUE ); + itemNewSub->setEnabled( TRUE ); + } + } +} + +void ListViewEditor::emitItemRenamed( QListViewItem *, int, const QString & text ) +{ + emit itemRenamed( text ); // Relay signal ( to QLineEdit ) +} diff --git a/kdevdesigner/designer/listvieweditorimpl.h b/kdevdesigner/designer/listvieweditorimpl.h new file mode 100644 index 00000000..476e47ca --- /dev/null +++ b/kdevdesigner/designer/listvieweditorimpl.h @@ -0,0 +1,102 @@ +/********************************************************************** +** 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 LISTVIEWEDITORIMPL_H +#define LISTVIEWEDITORIMPL_H + +#include "listvieweditor.h" + +#include <qmap.h> +#include <qpixmap.h> +#include <qvaluelist.h> + +class FormWindow; + +class ListViewEditor : public ListViewEditorBase +{ + Q_OBJECT + +public: + ListViewEditor( QWidget *parent, QListView *lv, FormWindow *fw ); + +signals: + void itemRenamed(const QString &); + +protected slots: + void applyClicked(); + void columnClickable(bool); + void columnDownClicked(); + void columnPixmapChosen(); + void columnPixmapDeleted(); + void columnResizable(bool); + void columnTextChanged(const QString &); + void columnUpClicked(); + void currentColumnChanged(QListBoxItem*); + void currentItemChanged(QListViewItem*); + void deleteColumnClicked(); + void itemColChanged(int); + void itemDeleteClicked(); + void itemDownClicked(); + void itemNewClicked(); + void itemNewSubClicked(); + void itemPixmapChoosen(); + void itemPixmapDeleted(); + void itemTextChanged(const QString &); + void itemUpClicked(); + void itemLeftClicked(); + void itemRightClicked(); + void newColumnClicked(); + void okClicked(); + void initTabPage(const QString &page); + void emitItemRenamed(QListViewItem*, int, const QString&); // signal relay + +private: + struct Column + { + QListBoxItem *item; + QString text; + QPixmap pixmap; + bool clickable, resizable; + Q_DUMMY_COMPARISON_OPERATOR( Column ) + }; + +private: + void setupColumns(); + void setupItems(); + Column *findColumn( QListBoxItem *i ); + void transferItems( QListView *from, QListView *to ); + void displayItem( QListViewItem *i, int col ); + +private: + QListView *listview; + QValueList<Column> columns; + int numColumns; + FormWindow *formwindow; + +}; + + +#endif diff --git a/kdevdesigner/designer/mainwindow.cpp b/kdevdesigner/designer/mainwindow.cpp new file mode 100644 index 00000000..530d9b07 --- /dev/null +++ b/kdevdesigner/designer/mainwindow.cpp @@ -0,0 +1,3784 @@ + /********************************************************************** +** 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 "designerappiface.h" +#include "designerapp.h" + +#include "mainwindow.h" +#include "defs.h" +#include "globaldefs.h" +#include "formwindow.h" +#include "widgetdatabase.h" +#include "widgetfactory.h" +#include "propertyeditor.h" +#include "metadatabase.h" +#include "resource.h" +#include "hierarchyview.h" +#include "newformimpl.h" +#include "workspace.h" +#include "about.h" +#include "multilineeditorimpl.h" +#include "wizardeditorimpl.h" +#include "outputwindow.h" +#include "actioneditorimpl.h" +#include "actiondnd.h" +#include "project.h" +#include "projectsettingsimpl.h" +#include "qwidgetfactory.h" +#include "pixmapcollection.h" +#include "qcompletionedit.h" +#include "sourcefile.h" +#include "orderindicator.h" +#include <qtoolbox.h> +#include "widgetaction.h" +#include "propertyobject.h" +#include "popupmenueditor.h" +#include "menubareditor.h" + +#include "startdialog.h" +#include "createtemplate.h" +#include "editfunctions.h" +//#include "connectionviewer.h" +#include "formsettings.h" +#include "preferences.h" +#include "pixmapcollectioneditor.h" +#ifndef QT_NO_SQL +#include "dbconnectionimpl.h" +#endif +//#include "connectioneditor.h" +#include "customwidgeteditorimpl.h" +#include "paletteeditorimpl.h" +#include "listboxeditorimpl.h" +#include "listvieweditorimpl.h" +#include "iconvieweditorimpl.h" +#include "tableeditorimpl.h" +#include "multilineeditor.h" +#include "finddialog.h" +#include "replacedialog.h" +#include "gotolinedialog.h" +#include "designeraction.h" + +#include <kiconloader.h> +#include <klocale.h> + +#include <qinputdialog.h> +#include <qtoolbar.h> +#include <qfeatures.h> +#include <qmetaobject.h> +#include <qaction.h> +#include <qpixmap.h> +#include <qworkspace.h> +#include <qfiledialog.h> +#include <qclipboard.h> +#include <qmessagebox.h> +#include <qbuffer.h> +#include <qdir.h> +#include <qstyle.h> +#include <qlabel.h> +#include <qstatusbar.h> +#include <qfile.h> +#include <qcheckbox.h> +#include <qwhatsthis.h> +#include <qwizard.h> +#include <qtimer.h> +#include <qlistbox.h> +#include <qdockwindow.h> +#include <qstylefactory.h> +#include <qvbox.h> +#include <qprocess.h> +#include <qsettings.h> +#include <qaccel.h> +#include <qtooltip.h> +#include <qsizegrip.h> +#include <qtextview.h> +#include <qassistantclient.h> +#include <stdlib.h> + +#include "kdevdesigner_part.h" + +static bool mblockNewForms = FALSE; +extern QMap<QWidget*, QString> *qwf_forms; +extern QString *qwf_language; +extern bool qwf_execute_code; +extern bool qwf_stays_on_top; +extern void set_splash_status( const QString &txt ); +extern QObject* qwf_form_object; +extern QString *qwf_plugin_dir; + +MainWindow *MainWindow::self = 0; + +QString assistantPath() +{ + QString path = QDir::cleanDirPath( QString( qInstallPathBins() ) + + QDir::separator() ); + return path; +} + + +static QString textNoAccel( const QString& text) +{ + QString t = text; + int i; + while ( (i = t.find('&') )>= 0 ) { + t.remove(i,1); + } + return t; +} + + +MainWindow::MainWindow( KDevDesignerPart *part, bool asClient, bool single, const QString &plgDir ) + : QMainWindow( 0, "designer_mainwindow"/*, WType_TopLevel | (single ? 0 : WDestructiveClose) | WGroupLeader*/ ), + grd( 10, 10 ), sGrid( TRUE ), snGrid( TRUE ), restoreConfig( TRUE ), splashScreen( TRUE ), + fileFilter( i18n( "Qt User-Interface Files (*.ui)" ) ), client( asClient ), + previewing( FALSE ), databaseAutoEdit( FALSE ), autoSaveEnabled( FALSE ), autoSaveInterval( 1800 ), m_part(part) +{ +// extern void qInitImages_designercore(); +// qInitImages_designercore(); + + self = this; + setPluginDirectory( plgDir ); + customWidgetToolBar = customWidgetToolBar2 = 0; + guiStuffVisible = TRUE; + editorsReadOnly = FALSE; + sSignalHandlers = TRUE; + init_colors(); + shStartDialog = FALSE; + + desInterface = new DesignerInterfaceImpl( this ); + desInterface->addRef(); + inDebugMode = FALSE; + savePluginPaths = FALSE; + + updateFunctionsTimer = new QTimer( this ); + connect( updateFunctionsTimer, SIGNAL( timeout() ), + this, SLOT( doFunctionsChanged() ) ); + + autoSaveTimer = new QTimer( this ); + connect( autoSaveTimer, SIGNAL( timeout() ), + this, SLOT( fileSaveAll() ) ); + + set_splash_status( "Loading Plugins..." ); + setupPluginManagers(); + +/* if ( !single ) + qApp->setMainWidget( this );*/ + QWidgetFactory::addWidgetFactory( new CustomWidgetFactory ); +#ifndef Q_WS_MACX + setIcon( BarIcon( "designer_appicon.png", KDevDesignerPartFactory::instance() ) ); +#endif + + actionGroupTools = 0; + prefDia = 0; + windowMenu = 0; + hierarchyView = 0; + actionEditor = 0; + currentProject = 0; + wspace = 0; + oWindow = 0; + singleProject = single; + + statusBar()->clear(); +#if defined(QT_NON_COMMERCIAL) + statusBar()->addWidget( new QLabel(i18n("Ready - This is the non-commercial version of Qt - " + "For commercial evaluations, use the help menu to register with Trolltech."), statusBar()), 1 ); +#else + statusBar()->addWidget( new QLabel("Ready", statusBar()), 1 ); +#endif + + + set_splash_status( "Setting up GUI..." ); + setupMDI(); + setupMenuBar(); + + setupToolbox(); + + setupFileActions(); + setupEditActions(); + setupProjectActions(); + setupSearchActions(); + layoutToolBar = new QToolBar( this, "Layout" ); + layoutToolBar->setCloseMode( QDockWindow::Undocked ); + addToolBar( layoutToolBar, i18n( "Layout" ) ); + interpreterPluginManager = 0; + setupToolActions(); + setupLayoutActions(); + setupPreviewActions(); + setupOutputWindow(); + setupActionManager(); + setupWindowActions(); + + setupWorkspace(); + setupHierarchyView(); + setupPropertyEditor(); + setupActionEditor(); + + setupHelpActions(); + + setupRMBMenus(); + + connect( this, SIGNAL( projectChanged() ), this, SLOT( emitProjectSignals() ) ); + connect( this, SIGNAL( hasActiveWindow(bool) ), this, SLOT( emitProjectSignals() ) ); + + emit hasActiveForm( FALSE ); + emit hasActiveWindow( FALSE ); + + lastPressWidget = 0; + qApp->installEventFilter( this ); + + QSize as( qApp->desktop()->size() ); + as -= QSize( 30, 30 ); + resize( QSize( 1200, 1000 ).boundedTo( as ) ); + + connect( qApp->clipboard(), SIGNAL( dataChanged() ), + this, SLOT( clipboardChanged() ) ); + clipboardChanged(); + layoutChilds = FALSE; + layoutSelected = FALSE; + breakLayout = FALSE; + backPix = TRUE; + + set_splash_status( "Loading User Settings..." ); + readConfig(); + // hack to make WidgetFactory happy (so it knows QWidget and QDialog for resetting properties) + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QWidget" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QDialog" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QLabel" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QTabWidget" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QFrame" ), this, 0, FALSE ); + delete w; + setAppropriate( (QDockWindow*)actionEditor->parentWidget(), FALSE ); + actionEditor->parentWidget()->hide(); + + assistant = new QAssistantClient( assistantPath(), this ); + + statusBar()->setSizeGripEnabled( TRUE ); + set_splash_status( "Initialization Done." ); +/* if ( shStartDialog ) + QTimer::singleShot( 0, this, SLOT( showStartDialog() ));*/ + + if ( autoSaveEnabled ) + autoSaveTimer->start( autoSaveInterval * 1000 ); + + setFocusPolicy( StrongFocus ); +} + +MainWindow::~MainWindow() +{ + QValueList<Tab>::Iterator tit; + for ( tit = preferenceTabs.begin(); tit != preferenceTabs.end(); ++tit ) { + Tab t = *tit; + delete t.w; + } + for ( tit = projectTabs.begin(); tit != projectTabs.end(); ++tit ) { + Tab t = *tit; + delete t.w; + } + + QMap< QAction*, Project* >::Iterator it = projects.begin(); + while ( it != projects.end() ) { + Project *p = *it; + ++it; + delete p; + } + projects.clear(); + + delete oWindow; + oWindow = 0; + + desInterface->release(); + desInterface = 0; + + delete actionPluginManager; + delete preferencePluginManager; + delete projectSettingsPluginManager; + delete interpreterPluginManager; + delete templateWizardPluginManager; + delete editorPluginManager; + delete sourceTemplatePluginManager; + + MetaDataBase::clearDataBase(); + if(self == this) + self = 0; +} + +void MainWindow::setupMDI() +{ + QVBox *vbox = new QVBox( this ); + setCentralWidget( vbox ); + vbox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + vbox->setMargin( 1 ); + vbox->setLineWidth( 1 ); + qworkspace = new QWorkspace( vbox ); + qworkspace->setPaletteBackgroundPixmap( UserIcon( "designer_background.png", KDevDesignerPartFactory::instance() ) ); + qworkspace->setScrollBarsEnabled( TRUE ); + connect( qworkspace, SIGNAL( windowActivated( QWidget * ) ), + this, SLOT( activeWindowChanged( QWidget * ) ) ); + lastActiveFormWindow = 0; + qworkspace->setAcceptDrops( TRUE ); +} + +void MainWindow::setupMenuBar() +{ + menubar = menuBar(); +} + +void MainWindow::setupPropertyEditor() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + propertyEditor = new PropertyEditor( dw ); + addToolBar( dw, Qt::DockRight ); + dw->setWidget( propertyEditor ); + dw->setFixedExtentWidth( 250 ); + dw->setCaption( i18n( "Property Editor/Signal Handlers" ) ); + QWhatsThis::add( propertyEditor, + i18n("<b>The Property Editor</b>" + "<p>You can change the appearance and behavior of the selected widget in the " + "property editor.</p>" + "<p>You can set properties for components and forms at design time and see the " + "immediately see the effects of the changes. " + "Each property has its own editor which (depending on the property) can be used " + "to enter " + "new values, open a special dialog, or to select values from a predefined list. " + "Click <b>F1</b> to get detailed help for the selected property.</p>" + "<p>You can resize the columns of the editor by dragging the separators in the " + "list's header.</p>" + "<p><b>Signal Handlers</b></p>" + "<p>In the Signal Handlers tab you can define connections between " + "the signals emitted by widgets and the slots in the form. " + "(These connections can also be made using the connection tool.)" ) ); + dw->show(); +} + +void MainWindow::setupOutputWindow() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + addToolBar( dw, Qt::DockBottom ); + oWindow = new OutputWindow( dw ); + dw->setWidget( oWindow ); + dw->setFixedExtentHeight( 150 ); + dw->setCaption( i18n( "Output Window" ) ); +} + +void MainWindow::setupHierarchyView() +{ + if ( hierarchyView ) + return; + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + hierarchyView = new HierarchyView( dw ); + addToolBar( dw, Qt::DockRight ); + dw->setWidget( hierarchyView ); + + dw->setCaption( i18n( "Object Explorer" ) ); + dw->setFixedExtentWidth( 250 ); + QWhatsThis::add( hierarchyView, + i18n("<b>The Object Explorer</b>" + "<p>The Object Explorer provides an overview of the relationships " + "between the widgets in a form. You can use the clipboard functions using " + "a context menu for each item in the view. It is also useful for selecting widgets " + "in forms that have complex layouts.</p>" + "<p>The columns can be resized by dragging the separator in the list's header.</p>" + "<p>The second tab shows all the form's slots, class variables, includes, etc.</p>") ); + dw->show(); +} + +void MainWindow::setupWorkspace() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + QVBox *vbox = new QVBox( dw ); + QCompletionEdit *edit = new QCompletionEdit( vbox ); + QToolTip::add( edit, i18n( "Start typing the buffer you want to switch to here (ALT+B)" ) ); + QAccel *a = new QAccel( this ); + a->connectItem( a->insertItem( ALT + Key_B ), edit, SLOT( setFocus() ) ); + wspace = new Workspace( vbox, this ); + wspace->setBufferEdit( edit ); + wspace->setCurrentProject( currentProject ); + addToolBar( dw, Qt::DockRight ); + dw->setWidget( vbox ); + + dw->setCaption( i18n( "Project Overview" ) ); + QWhatsThis::add( wspace, i18n("<b>The Project Overview Window</b>" + "<p>The Project Overview Window displays all the current " + "project, including forms and source files.</p>" + "<p>Use the search field to rapidly switch between files.</p>")); + dw->setFixedExtentHeight( 100 ); + dw->show(); +} + +void MainWindow::setupActionEditor() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::OutsideDock, this, 0 ); + addDockWindow( dw, Qt::DockTornOff ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + actionEditor = new ActionEditor( dw ); + dw->setWidget( actionEditor ); + actionEditor->show(); + dw->setCaption( i18n( "Action Editor" ) ); + QWhatsThis::add( actionEditor, i18n("<b>The Action Editor</b>" + "<p>The Action Editor is used to add actions and action groups to " + "a form, and to connect actions to slots. Actions and action " + "groups can be dragged into menus and into toolbars, and may " + "feature keyboard shortcuts and tooltips. If actions have pixmaps " + "these are displayed on toolbar buttons and besides their names in " + "menus.</p>" ) ); + dw->hide(); + setAppropriate( dw, FALSE ); +} + +void MainWindow::setupToolbox() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + addToolBar( dw, Qt::DockLeft ); + toolBox = new QToolBox( dw ); + dw->setWidget( toolBox ); + dw->setFixedExtentWidth( 160 ); + dw->setCaption( i18n( "Toolbox" ) ); + dw->show(); + setDockEnabled( dw, Qt::DockTop, FALSE ); + setDockEnabled( dw, Qt::DockBottom, FALSE ); + commonWidgetsToolBar = new QToolBar( "Common Widgets", 0, toolBox, FALSE, "Common Widgets" ); + commonWidgetsToolBar->setFrameStyle( QFrame::NoFrame ); + commonWidgetsToolBar->setOrientation( Qt::Vertical ); + commonWidgetsToolBar->setBackgroundMode(PaletteBase); + toolBox->addItem( commonWidgetsToolBar, "Common Widgets" ); +} + +void MainWindow::setupRMBMenus() +{ + rmbWidgets = new QPopupMenu( this ); + actionEditCut->addTo( rmbWidgets ); + actionEditCopy->addTo( rmbWidgets ); + actionEditPaste->addTo( rmbWidgets ); + actionEditDelete->addTo( rmbWidgets ); +#if 0 + rmbWidgets->insertSeparator(); + actionEditLower->addTo( rmbWidgets ); + actionEditRaise->addTo( rmbWidgets ); +#endif + rmbWidgets->insertSeparator(); + actionEditAdjustSize->addTo( rmbWidgets ); + actionEditHLayout->addTo( rmbWidgets ); + actionEditVLayout->addTo( rmbWidgets ); + actionEditGridLayout->addTo( rmbWidgets ); + actionEditSplitHorizontal->addTo( rmbWidgets ); + actionEditSplitVertical->addTo( rmbWidgets ); + actionEditBreakLayout->addTo( rmbWidgets ); + rmbWidgets->insertSeparator(); + if ( !singleProjectMode() ) + actionEditConnections->addTo( rmbWidgets ); + actionEditSource->addTo( rmbWidgets ); + + rmbFormWindow = new QPopupMenu( this ); + actionEditPaste->addTo( rmbFormWindow ); + actionEditSelectAll->addTo( rmbFormWindow ); + actionEditAccels->addTo( rmbFormWindow ); + rmbFormWindow->insertSeparator(); + actionEditAdjustSize->addTo( rmbFormWindow ); + actionEditHLayout->addTo( rmbFormWindow ); + actionEditVLayout->addTo( rmbFormWindow ); + actionEditGridLayout->addTo( rmbFormWindow ); + actionEditBreakLayout->addTo( rmbFormWindow ); + rmbFormWindow->insertSeparator(); + if ( !singleProjectMode() ) { + actionEditFunctions->addTo( rmbFormWindow ); + actionEditConnections->addTo( rmbFormWindow ); + } + actionEditSource->addTo( rmbFormWindow ); + rmbFormWindow->insertSeparator(); + actionEditFormSettings->addTo( rmbFormWindow ); +} + +void MainWindow::toolSelected( QAction* action ) +{ + actionCurrentTool = action; + emit currentToolChanged(); + if ( formWindow() ) + formWindow()->commandHistory()->emitUndoRedo(); +} + +int MainWindow::currentTool() const +{ + if ( !actionCurrentTool ) + return POINTER_TOOL; + return QString::fromLatin1(actionCurrentTool->name()).toInt(); +} + +void MainWindow::runProjectPrecondition() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + e->save(); + e->saveBreakPoints(); + } + fileSaveProject(); + + if ( currentTool() == ORDER_TOOL ) + resetTool(); + oWindow->clearErrorMessages(); + oWindow->clearDebug(); + oWindow->showDebugTab(); + previewing = TRUE; +} + +void MainWindow::runProjectPostcondition( QObjectList *l ) +{ + inDebugMode = TRUE; + debuggingForms = *l; + enableAll( FALSE ); + for ( SourceEditor *e2 = sourceEditors.first(); e2; e2 = sourceEditors.next() ) { + if ( e2->project() == currentProject ) + e2->editorInterface()->setMode( EditorInterface::Debugging ); + } +} + +QWidget* MainWindow::previewFormInternal( QStyle* style, QPalette* palet ) +{ + qwf_execute_code = FALSE; + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->save(); + if ( currentTool() == ORDER_TOOL ) + resetTool(); + + FormWindow *fw = formWindow(); + if ( !fw ) + return 0; + + QStringList databases; + QPtrDictIterator<QWidget> wit( *fw->widgets() ); + while ( wit.current() ) { + QStringList lst = MetaDataBase::fakeProperty( wit.current(), "database" ).toStringList(); + if ( !lst.isEmpty() ) + databases << lst [ 0 ]; + ++wit; + } + + if ( fw->project() ) { + QStringList::ConstIterator it; + for ( it = databases.begin(); it != databases.end(); ++it ) + fw->project()->openDatabase( *it, FALSE ); + } + QApplication::setOverrideCursor( WaitCursor ); + + QCString s; + QBuffer buffer( s ); + buffer.open( IO_WriteOnly ); + Resource resource( this ); + resource.setWidget( fw ); + QValueList<Resource::Image> images; + resource.save( &buffer ); + + buffer.close(); + buffer.open( IO_ReadOnly ); + + QWidget *w = QWidgetFactory::create( &buffer ); + if ( w ) { + previewedForm = w; + if ( palet ) { + if ( style ) + style->polish( *palet ); + w->setPalette( *palet ); + } + + if ( style ) + w->setStyle( style ); + + QObjectList *l = w->queryList( "QWidget" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( style ) + ( (QWidget*)o )->setStyle( style ); + } + delete l; + + w->move( fw->mapToGlobal( QPoint(0,0) ) ); + ((MainWindow*)w )->setWFlags( WDestructiveClose ); + previewing = TRUE; + w->show(); + previewing = FALSE; + QApplication::restoreOverrideCursor(); + return w; + } + QApplication::restoreOverrideCursor(); + return 0; +} + +void MainWindow::previewForm() +{ + QWidget* w = previewFormInternal(); + if ( w ) + w->show(); +} + +void MainWindow::previewForm( const QString & style ) +{ + QStyle* st = QStyleFactory::create( style ); + QWidget* w = 0; + if ( style == "Motif" ) { + QPalette p( QColor( 192, 192, 192 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "Windows" ) { + QPalette p( QColor( 212, 208, 200 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "Platinum" ) { + QPalette p( QColor( 220, 220, 220 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "CDE" ) { + QPalette p( QColor( 75, 123, 130 ) ); + p.setColor( QPalette::Active, QColorGroup::Base, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Inactive, QColorGroup::Base, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Disabled, QColorGroup::Base, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Active, QColorGroup::Highlight, Qt::white ); + p.setColor( QPalette::Active, QColorGroup::HighlightedText, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Inactive, QColorGroup::Highlight, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::HighlightedText, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Disabled, QColorGroup::Highlight, Qt::white ); + p.setColor( QPalette::Disabled, QColorGroup::HighlightedText, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Active, QColorGroup::Foreground, Qt::white ); + p.setColor( QPalette::Active, QColorGroup::Text, Qt::white ); + p.setColor( QPalette::Active, QColorGroup::ButtonText, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::Foreground, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::Text, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::ButtonText, Qt::white ); + p.setColor( QPalette::Disabled, QColorGroup::Foreground, Qt::lightGray ); + p.setColor( QPalette::Disabled, QColorGroup::Text, Qt::lightGray ); + p.setColor( QPalette::Disabled, QColorGroup::ButtonText, Qt::lightGray ); + + w = previewFormInternal( st, &p ); + } else if ( style == "SGI" ) { + QPalette p( QColor( 220, 220, 220 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "MotifPlus" ) { + QColor gtkfg(0x00, 0x00, 0x00); + QColor gtkdf(0x75, 0x75, 0x75); + QColor gtksf(0xff, 0xff, 0xff); + QColor gtkbs(0xff, 0xff, 0xff); + QColor gtkbg(0xd6, 0xd6, 0xd6); + QColor gtksl(0x00, 0x00, 0x9c); + QColorGroup active(gtkfg, // foreground + gtkbg, // button + gtkbg.light(), // light + gtkbg.dark(142), // dark + gtkbg.dark(110), // mid + gtkfg, // text + gtkfg, // bright text + gtkbs, // base + gtkbg), // background + disabled(gtkdf, // foreground + gtkbg, // button + gtkbg.light(), // light + gtkbg.dark(156), // dark + gtkbg.dark(110), // mid + gtkdf, // text + gtkdf, // bright text + gtkbs, // base + gtkbg); // background + + QPalette pal(active, disabled, active); + + pal.setColor(QPalette::Active, QColorGroup::Highlight, + gtksl); + pal.setColor(QPalette::Active, QColorGroup::HighlightedText, + gtksf); + pal.setColor(QPalette::Inactive, QColorGroup::Highlight, + gtksl); + pal.setColor(QPalette::Inactive, QColorGroup::HighlightedText, + gtksf); + pal.setColor(QPalette::Disabled, QColorGroup::Highlight, + gtksl); + pal.setColor(QPalette::Disabled, QColorGroup::HighlightedText, + gtkdf); + w = previewFormInternal( st, &pal ); + } else { + w = previewFormInternal( st ); + } + + if ( !w ) + return; + w->insertChild( st ); + w->show(); +} + +void MainWindow::helpContents() +{ + QWidget *focusWidget = qApp->focusWidget(); + bool showClassDocu = TRUE; + while ( focusWidget ) { + if ( focusWidget->isA( "PropertyList" ) ) { + showClassDocu = FALSE; + break; + } + focusWidget = focusWidget->parentWidget(); + } + + QString source = "designer-manual.html"; + if ( propertyDocumentation.isEmpty() ) { + QString indexFile = documentationPath() + "/propertyindex"; + QFile f( indexFile ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + while ( !ts.eof() ) { + QString s = ts.readLine(); + int from = s.find( "\"" ); + if ( from == -1 ) + continue; + int to = s.findRev( "\"" ); + if ( to == -1 ) + continue; + propertyDocumentation[ s.mid( from + 1, to - from - 1 ) ] = s.mid( to + 2 ) + "-prop"; + } + f.close(); + } + } + + if ( propertyEditor->widget() && !showClassDocu ) { + if ( !propertyEditor->currentProperty().isEmpty() ) { + QMetaObject* mo = propertyEditor->metaObjectOfCurrentProperty(); + QString s; + QString cp = propertyEditor->currentProperty(); + if ( cp == "layoutMargin" ) { + source = propertyDocumentation[ "QLayout/margin" ]; + } else if ( cp == "layoutSpacing" ) { + source = propertyDocumentation[ "QLayout/spacing" ]; + } else if ( cp == "toolTip" ) { + source = "qtooltip.html#details"; + } else if ( mo && qstrcmp( mo->className(), "Spacer" ) == 0 ) { + if ( cp != "name" ) + source = "qsizepolicy.html#SizeType"; + else + source = propertyDocumentation[ "QObject/name" ]; + } else { + while ( mo && !propertyDocumentation.contains( ( s = QString( mo->className() ) + "/" + cp ) ) ) + mo = mo->superClass(); + if ( mo ) + source = "p:" + propertyDocumentation[s]; + } + } + + QString classname = WidgetFactory::classNameOf( propertyEditor->widget() ); + if ( source.isEmpty() || source == "designer-manual.html" ) { + if ( classname.lower() == "spacer" ) + source = "qspaceritem.html#details"; + else if ( classname == "QLayoutWidget" ) + source = "layout.html"; + else + source = QString( WidgetFactory::classNameOf( propertyEditor->widget() ) ).lower() + ".html#details"; + } + } else if ( propertyEditor->widget() ) { + source = QString( WidgetFactory::classNameOf( propertyEditor->widget() ) ).lower() + ".html#details"; + } + + if ( !source.isEmpty() ) + assistant->showPage( documentationPath() + source ); +} + +void MainWindow::helpManual() +{ + assistant->showPage( documentationPath() + "/designer-manual.html" ); +} + +void MainWindow::helpAbout() +{ + AboutDialog dlg( this, 0, TRUE ); + if ( singleProjectMode() ) { + dlg.aboutPixmap->setText( "" ); + dlg.aboutVersion->setText( "" ); + dlg.aboutCopyright->setText( "" ); + LanguageInterface *iface = MetaDataBase::languageInterface( eProject->language() ); + dlg.aboutLicense->setText( iface->aboutText() ); + } + dlg.aboutVersion->setText(QString("Version ") + QString(QT_VERSION_STR)); + dlg.resize( dlg.width(), dlg.layout()->heightForWidth(dlg.width()) ); + dlg.exec(); +} + +void MainWindow::helpAboutQt() +{ + QMessageBox::aboutQt( this, "Qt Designer" ); +} + +#if defined(_WS_WIN_) +#include <qt_windows.h> +#include <qprocess.h> +#endif + +void MainWindow::helpRegister() +{ +#if defined(_WS_WIN_) + HKEY key; + HKEY subkey; + long res; + DWORD type; + DWORD size = 255; + QString command; + QString sub( "htmlfile\\shell" ); +#if defined(UNICODE) + if ( QApplication::winVersion() & Qt::WV_NT_based ) { + unsigned char data[256]; + res = RegOpenKeyExW( HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &key ); + res = RegOpenKeyExW( key, (TCHAR*)sub.ucs2(), 0, KEY_READ, &subkey ); + res = RegQueryValueExW( subkey, NULL, NULL, &type, data, &size ); + command = qt_winQString( data ) + "\\command"; + size = 255; + res = RegOpenKeyExW( subkey, (TCHAR*)command.ucs2(), 0, KEY_READ, &subkey ); + res = RegQueryValueExW( subkey, NULL, NULL, &type, data, &size ); + command = qt_winQString( data ); + } else +#endif + { + unsigned char data[256]; + res = RegOpenKeyExA( HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &key ); + res = RegOpenKeyExA( key, sub.local8Bit(), 0, KEY_READ, &subkey ); + res = RegQueryValueExA( subkey, NULL, NULL, &type, data, &size ); + command = QString::fromLocal8Bit( (const char*) data ) + "\\command"; + size = 255; + res = RegOpenKeyExA( subkey, command.local8Bit(), 0, KEY_READ, &subkey ); + res = RegQueryValueExA( subkey, NULL, NULL, &type, data, &size ); + command = QString::fromLocal8Bit( (const char*) data ); + } + + res = RegCloseKey( subkey ); + res = RegCloseKey( key ); + + QProcess process( command + " www.trolltech.com/products/download/eval/evaluation.html" ); + if ( !process.start() ) + QMessageBox::information( this, "Register Qt", "Launching your web browser failed.\n" + "To register Qt, point your browser to www.trolltech.com/products/download/eval/evaluation.html" ); +#endif +} + +void MainWindow::showProperties( QObject *o ) +{ + if ( !o->isWidgetType() ) { + propertyEditor->setWidget( o, lastActiveFormWindow ); + if ( lastActiveFormWindow ) + hierarchyView->setFormWindow( lastActiveFormWindow, lastActiveFormWindow->mainContainer() ); + else + hierarchyView->setFormWindow( 0, 0 ); + return; + } + QWidget *w = (QWidget*)o; + setupHierarchyView(); + FormWindow *fw = (FormWindow*)isAFormWindowChild( w ); + if ( fw ) { + if ( fw->numSelectedWidgets() > 1 ) { + QWidgetList wl = fw->selectedWidgets(); + if ( wl.first() != w ) { + wl.removeRef( w ); + wl.insert( 0, w ); + } + propertyEditor->setWidget( new PropertyObject( wl ), fw ); + } else { + propertyEditor->setWidget( w, fw ); + } + hierarchyView->setFormWindow( fw, w ); + } else { + propertyEditor->setWidget( 0, 0 ); + hierarchyView->setFormWindow( 0, 0 ); + } + + if ( currentTool() == POINTER_TOOL && fw && + ( !qworkspace->activeWindow() || !::qt_cast<SourceEditor*>(qworkspace->activeWindow()) ) ) + fw->setFocus(); +} + +void MainWindow::resetTool() +{ + actionPointerTool->setOn( TRUE ); +} + +void MainWindow::updateProperties( QObject * ) +{ + if ( propertyEditor ) + propertyEditor->refetchData(); +} + +bool MainWindow::eventFilter( QObject *o, QEvent *e ) +{ + if ( ::qt_cast<MenuBarEditor*>(o) || ::qt_cast<PopupMenuEditor*>(o) || + ( o && + ( ::qt_cast<MenuBarEditor*>(o->parent()) || + ::qt_cast<PopupMenuEditor*>(o->parent()) ) ) ) { + + if ( e->type() == QEvent::Accel && ::qt_cast<PopupMenuEditor*>(o) ) { + return TRUE; // consume accel events + } else if ( e->type() == QEvent::MouseButtonPress && ::qt_cast<MenuBarEditor*>(o) ) { + QPoint pos = ((QMouseEvent*)e)->pos(); + MenuBarEditor *m = ::qt_cast<MenuBarEditor*>(o); + showProperties( o ); + if ( m->findItem( pos ) >= m->count() ) + m->setFocus(); + } else if ( e->type() == QEvent::MouseButtonPress && ::qt_cast<PopupMenuEditor*>(o) ) { + PopupMenuEditor *m = ::qt_cast<PopupMenuEditor*>(o); + PopupMenuEditorItem *i = m->at( ((QMouseEvent*)e)->pos() ); + if ( m->find( i->action() ) != -1 && !i->isSeparator() ) + showProperties( i->action() ); + } + return QMainWindow::eventFilter( o, e ); + } + + if ( !o || !e || !o->isWidgetType() ) + return QMainWindow::eventFilter( o, e ); + + QWidget *w = 0; + bool passiveInteractor; + switch ( e->type() ) { + case QEvent::AccelOverride: + if ( ( (QKeyEvent*)e )->key() == Key_F1 && + ( ( (QKeyEvent*)e )->state() & ShiftButton ) != ShiftButton ) { + w = (QWidget*)o; + while ( w ) { + if ( ::qt_cast<PropertyList*>(w) ) + break; + w = w->parentWidget( TRUE ); + } + if ( w ) { + propertyEditor->propertyList()->showCurrentWhatsThis(); + ( (QKeyEvent*)e )->accept(); + return TRUE; + } + } + break; + case QEvent::Accel: + if ( ( ( (QKeyEvent*)e )->key() == Key_A || + ( (QKeyEvent*)e )->key() == Key_E ) && + ( (QKeyEvent*)e )->state() & ControlButton ) { + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (QKeyEvent*)e )->ignore(); + return TRUE; + } + } + break; + case QEvent::ContextMenu: + case QEvent::MouseButtonPress: + if ( o && currentTool() == POINTER_TOOL && + ( ::qt_cast<MenuBarEditor*>(o) || + ::qt_cast<PopupMenuEditor*>(o) || + ::qt_cast<QDesignerToolBar*>(o) || + ( ::qt_cast<QComboBox*>(o) || + ::qt_cast<QToolButton*>(o) || + ::qt_cast<QDesignerToolBarSeparator*>(o) ) && + o->parent() + && ( ::qt_cast<QDesignerToolBar*>(o->parent()) + || ::qt_cast<QDesignerWidgetStack*>(o->parent())) ) ) { + QWidget *w = (QWidget*)o; + if ( ::qt_cast<QToolButton*>(w) || + ::qt_cast<QComboBox*>(w) || + ::qt_cast<PopupMenuEditor*>(w) || + ::qt_cast<QDesignerToolBarSeparator*>(w) ) + w = w->parentWidget(); + QWidget *pw = w->parentWidget(); + while ( pw ) { + if ( ::qt_cast<FormWindow*>(pw) ) { + ( (FormWindow*)pw )->emitShowProperties( w ); + if ( !::qt_cast<QDesignerToolBar*>(o) ) + return ( !::qt_cast<QToolButton*>(o) && + !::qt_cast<MenuBarEditor*>(o) && + !::qt_cast<QComboBox*>(o) && + !::qt_cast<QDesignerToolBarSeparator*>(o) ); + } + pw = pw->parentWidget(); + } + } + if ( o && ( ::qt_cast<QDesignerToolBar*>(o) || o->inherits("QDockWindowHandle") ) + && e->type() == QEvent::ContextMenu ) + break; + if ( isAToolBarChild( o ) && currentTool() != CONNECT_TOOL && currentTool() != BUDDY_TOOL ) + break; + if ( ::qt_cast<QSizeGrip*>(o) ) + break; + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + if ( !w->hasFocus() ) + w->setFocus(); + passiveInteractor = WidgetFactory::isPassiveInteractor( o ); + if ( !passiveInteractor || currentTool() != ORDER_TOOL ) { + if( e->type() == QEvent::ContextMenu ) { + ( (FormWindow*)w )->handleContextMenu( (QContextMenuEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + return TRUE; + } else { + ( (FormWindow*)w )->handleMousePress( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + } + } + lastPressWidget = (QWidget*)o; + if ( passiveInteractor ) + QTimer::singleShot( 0, formWindow(), SLOT( visibilityChanged() ) ); + if ( currentTool() == CONNECT_TOOL || currentTool() == BUDDY_TOOL ) + return TRUE; + return !passiveInteractor; + case QEvent::MouseButtonRelease: + lastPressWidget = 0; + if ( isAToolBarChild( o ) && currentTool() != CONNECT_TOOL && currentTool() != BUDDY_TOOL ) + break; + if ( ::qt_cast<QSizeGrip*>(o) ) + break; + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + passiveInteractor = WidgetFactory::isPassiveInteractor( o ); + if ( !passiveInteractor ) + ( (FormWindow*)w )->handleMouseRelease( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + if ( passiveInteractor ) { + QTimer::singleShot( 0, this, SLOT( selectionChanged() ) ); + QTimer::singleShot( 0, formWindow(), SLOT( visibilityChanged() ) ); + } + return !passiveInteractor; + case QEvent::MouseMove: + if ( isAToolBarChild( o ) && currentTool() != CONNECT_TOOL && currentTool() != BUDDY_TOOL ) + break; + w = isAFormWindowChild( o ); + if ( lastPressWidget != (QWidget*)o && w && + !::qt_cast<SizeHandle*>(o) && !::qt_cast<OrderIndicator*>(o) && + !::qt_cast<PopupMenuEditor*>(o) && !::qt_cast<QMenuBar*>(o) && + !::qt_cast<QSizeGrip*>(o) ) + return TRUE; + if ( o && ::qt_cast<QSizeGrip*>(o) ) + break; + if ( lastPressWidget != (QWidget*)o || + ( !w || ::qt_cast<SizeHandle*>(o) ) || + ::qt_cast<OrderIndicator*>(o) ) + break; + passiveInteractor = WidgetFactory::isPassiveInteractor( o ); + if ( !passiveInteractor ) + ( (FormWindow*)w )->handleMouseMove( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + return !passiveInteractor; + case QEvent::KeyPress: + if ( ( (QKeyEvent*)e )->key() == Key_Escape && currentTool() != POINTER_TOOL ) { + resetTool(); + return FALSE; + } + if ( ( (QKeyEvent*)e )->key() == Key_Escape && incrementalSearch->hasFocus() ) { + if ( ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + qWorkspace()->activeWindow()->setFocus(); + return TRUE; + } + } + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + ( (FormWindow*)w )->handleKeyPress( (QKeyEvent*)e, ( (FormWindow*)w )->designerWidget( o ) ); + if ( ((QKeyEvent*)e)->isAccepted() ) + return TRUE; + break; + case QEvent::MouseButtonDblClick: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) { + if ( ::qt_cast<QToolButton*>(o) && ((QToolButton*)o)->isOn() && + o->parent() && ::qt_cast<QToolBar*>(o->parent()) && formWindow() ) + formWindow()->setToolFixed(); + break; + } + if ( currentTool() == ORDER_TOOL ) { + ( (FormWindow*)w )->handleMouseDblClick( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + return TRUE; + } + if ( !WidgetFactory::isPassiveInteractor( o ) && ( (FormWindow*)w )->formFile() ) + return openEditor( ( (FormWindow*)w )->designerWidget( o ), (FormWindow*)w ); + return TRUE; + case QEvent::KeyRelease: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + ( (FormWindow*)w )->handleKeyRelease( (QKeyEvent*)e, ( (FormWindow*)w )->designerWidget( o ) ); + if ( ((QKeyEvent*)e)->isAccepted() ) + return TRUE; + break; + case QEvent::Hide: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + if ( ( (FormWindow*)w )->isWidgetSelected( (QWidget*)o ) ) + ( (FormWindow*)w )->selectWidget( (QWidget*)o, FALSE ); + break; + case QEvent::Enter: + case QEvent::Leave: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) || + ::qt_cast<MenuBarEditor*>(o) ) + break; + return TRUE; + case QEvent::Resize: + case QEvent::Move: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + if ( WidgetFactory::layoutType( (QWidget*)o->parent() ) != WidgetFactory::NoLayout ) { + ( (FormWindow*)w )->updateSelection( (QWidget*)o ); + if ( e->type() != QEvent::Resize ) + ( (FormWindow*)w )->updateChildSelections( (QWidget*)o ); + } + break; + case QEvent::Close: + if ( o->isWidgetType() && (QWidget*)o == (QWidget*)previewedForm ) { + if ( lastActiveFormWindow && lastActiveFormWindow->project() ) { + QStringList lst = + MetaDataBase::fakeProperty( lastActiveFormWindow, "database" ).toStringList(); + lastActiveFormWindow->project()->closeDatabase( lst[ 0 ] ); + } + } + break; + case QEvent::DragEnter: + if ( o == qWorkspace() || o == workspace() || o == workspace()->viewport() ) { + workspace()->contentsDragEnterEvent( (QDragEnterEvent*)e ); + return TRUE; + } + break; + case QEvent::DragMove: + if ( o == qWorkspace() || o == workspace() || o == workspace()->viewport() ) { + workspace()->contentsDragMoveEvent( (QDragMoveEvent*)e ); + return TRUE; + } + break; + case QEvent::Drop: + if ( o == qWorkspace() || o == workspace() || o == workspace()->viewport() ) { + workspace()->contentsDropEvent( (QDropEvent*)e ); + return TRUE; + } + break; + case QEvent::Show: + if ( o != this ) + break; + if ( ((QShowEvent*)e)->spontaneous() ) + break; + QApplication::sendPostedEvents( qworkspace, QEvent::ChildInserted ); + showEvent( (QShowEvent*)e ); + checkTempFiles(); + return TRUE; + case QEvent::Wheel: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast<SizeHandle*>(o) || + ::qt_cast<OrderIndicator*>(o) ) + break; + return TRUE; + case QEvent::FocusIn: + if ( !::qt_cast<FormWindow*>(o) && isAFormWindowChild( o ) ) + return TRUE; //FIXME + if ( hierarchyView->formDefinitionView()->isRenaming() + && ( o->inherits( "Editor" ) || ::qt_cast<FormWindow*>(o) ) ) + QApplication::sendPostedEvents(); + if ( o->inherits( "Editor" ) ) { + QWidget *w = (QWidget*)o; + while ( w ) { + if ( ::qt_cast<SourceEditor*>(w) ) + break; + w = w->parentWidget( TRUE ); + } + if ( ::qt_cast<SourceEditor*>(w) ) + ( (SourceEditor*)w )->checkTimeStamp(); + } else if ( ::qt_cast<FormWindow*>(o) ) { + FormWindow *fw = (FormWindow*)o; + if ( fw->formFile() && fw->formFile()->editor() ) + fw->formFile()->editor()->checkTimeStamp(); + } + break; + case QEvent::FocusOut: + if ( !::qt_cast<FormWindow*>(o) && isAFormWindowChild( o ) ) + return TRUE; + break; + default: + return QMainWindow::eventFilter( o, e ); + } + + return QMainWindow::eventFilter( o, e ); +} + +QWidget *MainWindow::isAFormWindowChild( QObject *o ) const +{ + if ( ::qt_cast<QWizard*>(o->parent()) && !::qt_cast<QPushButton*>(o) ) + return 0; + while ( o ) { + if ( ::qt_cast<FormWindow*>(o) ) + return (QWidget*)o; + o = o->parent(); + } + return 0; +} + +QWidget *MainWindow::isAToolBarChild( QObject *o ) const +{ + while ( o ) { + if ( ::qt_cast<QDesignerToolBar*>(o) ) + return (QWidget*)o; + if ( ::qt_cast<FormWindow*>(o) ) + return 0; + o = o->parent(); + } + return 0; +} + +FormWindow *MainWindow::formWindow() +{ + if ( qworkspace->activeWindow() ) { + FormWindow *fw = 0; + if ( ::qt_cast<FormWindow*>(qworkspace->activeWindow()) ) + fw = (FormWindow*)qworkspace->activeWindow(); + else if ( lastActiveFormWindow && + qworkspace->windowList().find( lastActiveFormWindow ) != -1) + fw = lastActiveFormWindow; + return fw; + } + return 0; +} + +void MainWindow::emitProjectSignals() +{ + emit hasNonDummyProject( !currentProject->isDummy() ); + emit hasActiveWindowOrProject( !!qworkspace->activeWindow() || !currentProject->isDummy() ); +} + +void MainWindow::insertFormWindow( FormWindow *fw ) +{ + if ( fw ) + QWhatsThis::add( fw, i18n( "<b>The Form Window</b>" + "<p>Use the various tools to add widgets or to change the layout " + "and behavior of the components in the form. Select one or multiple " + "widgets to move them or lay them out. If a single widget is chosen it can " + "be resized using the resize handles.</p>" + "<p>Changes in the <b>Property Editor</b> are visible at design time, " + "and you can preview the form in different styles.</p>" + "<p>You can change the grid resolution, or turn the grid off in the " + "<b>Preferences</b> dialog in the <b>Edit</b> menu." + "<p>You can have several forms open, and all open forms are listed " + "in the <b>Form List</b>.") ); + + connect( fw, SIGNAL( showProperties( QObject * ) ), + this, SLOT( showProperties( QObject * ) ) ); + connect( fw, SIGNAL( updateProperties( QObject * ) ), + this, SLOT( updateProperties( QObject * ) ) ); + connect( this, SIGNAL( currentToolChanged() ), + fw, SLOT( currentToolChanged() ) ); + connect( fw, SIGNAL( selectionChanged() ), + this, SLOT( selectionChanged() ) ); + connect( fw, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ), + this, SLOT( updateUndoRedo( bool, bool, const QString &, const QString & ) ) ); + + if ( !mblockNewForms ) { + } else { + fw->setProject( currentProject ); + } + fw->show(); + fw->currentToolChanged(); + if ( fw->caption().isEmpty() && qstrlen( fw->name() ) ) + fw->setCaption( fw->name() ); + fw->mainContainer()->setCaption( fw->caption() ); + WidgetFactory::saveDefaultProperties( fw->mainContainer(), + WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( fw->mainContainer() ) ) ); + activeWindowChanged( fw ); + emit formWindowsChanged(); + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->project() == fw->project() ) + e->resetContext(); + } +} + +void MainWindow::createNewProject( const QString &lang ) +{ + Project *pro = new Project( "", "", projectSettingsPluginManager ); + pro->setLanguage( lang ); + + + if ( !openProjectSettings( pro ) ) { + delete pro; + return; + } + + if ( !pro->isValid() ) { + QMessageBox::information( this, i18n("New Project"), i18n( "Cannot create an invalid project." ) ); + delete pro; + return; + } + + QAction *a = new QAction( pro->makeRelative( pro->fileName() ), + pro->makeRelative( pro->fileName() ), 0, actionGroupProjects, 0, TRUE ); + projects.insert( a, pro ); + addRecentlyOpened( pro->makeAbsolute( pro->fileName() ), recentlyProjects ); + projectSelected( a ); +} + + +bool MainWindow::unregisterClient( FormWindow *w ) +{ + propertyEditor->closed( w ); + objectHierarchy()->closed( w ); + if ( w == lastActiveFormWindow ) + lastActiveFormWindow = 0; + + QPtrList<SourceEditor> waitingForDelete; + waitingForDelete.setAutoDelete( TRUE ); + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->object() == w ) + waitingForDelete.append( e ); + } + + if ( actionEditor->form() == w ) { + actionEditor->setFormWindow( 0 ); + actionEditor->parentWidget()->hide(); + } + + return TRUE; +} + +void MainWindow::activeWindowChanged( QWidget *w ) +{ + QWidget *old = formWindow(); + if ( ::qt_cast<FormWindow*>(w) ) { + FormWindow *fw = (FormWindow*)w; + FormWindow *ofw = lastActiveFormWindow; + lastActiveFormWindow = fw; + lastActiveFormWindow->updateUndoInfo(); + emit hasActiveForm( TRUE ); + if ( formWindow() ) { + formWindow()->emitShowProperties(); + emit formModified( formWindow()->commandHistory()->isModified() ); + if ( currentTool() != POINTER_TOOL ) + formWindow()->clearSelection(); + } + workspace()->activeFormChanged( fw ); + setAppropriate( (QDockWindow*)actionEditor->parentWidget(), + ::qt_cast<QMainWindow*>(lastActiveFormWindow->mainContainer()) ); + if ( appropriate( (QDockWindow*)actionEditor->parentWidget() ) ) { + if ( actionEditor->wantToBeShown() ) + actionEditor->parentWidget()->show(); + } else { + QWidget *mc = 0; + if ( ofw && (mc = ofw->mainContainer()) && ::qt_cast<QMainWindow*>(mc) ) + actionEditor->setWantToBeShown( !actionEditor->parentWidget()->isHidden() ); + actionEditor->parentWidget()->hide(); + } + + actionEditor->setFormWindow( lastActiveFormWindow ); + if ( wspace && fw->project() && fw->project() != currentProject ) { + for ( QMap<QAction*, Project *>::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( *it == fw->project() ) { + projectSelected( it.key() ); + break; + } + } + } + emit formWindowChanged(); + + } else if ( w == propertyEditor ) { + propertyEditor->resetFocus(); + } else if ( !lastActiveFormWindow ) { + emit formWindowChanged(); + emit hasActiveForm( FALSE ); + actionEditUndo->setEnabled( FALSE ); + actionEditRedo->setEnabled( FALSE ); + } + + if ( !w ) { + emit formWindowChanged(); + emit hasActiveForm( FALSE ); + propertyEditor->clear(); + hierarchyView->clear(); + updateUndoRedo( FALSE, FALSE, QString::null, QString::null ); + } + + selectionChanged(); + + if ( ::qt_cast<SourceEditor*>(w) ) { + SourceEditor *se = (SourceEditor*)w; + QGuardedPtr<FormWindow> fw = se->formWindow(); + if ( se->formWindow() && + lastActiveFormWindow != fw ) { + activeWindowChanged( se->formWindow() ); + } + actionSearchFind->setEnabled( TRUE ); + actionSearchIncremetal->setEnabled( TRUE ); + actionSearchReplace->setEnabled( TRUE ); + actionSearchGotoLine->setEnabled( TRUE ); + incrementalSearch->setEnabled( TRUE ); + + actionEditUndo->setEnabled( FALSE ); + actionEditRedo->setEnabled( FALSE ); + actionEditCut->setEnabled( TRUE ); + actionEditCopy->setEnabled( TRUE ); + actionEditPaste->setEnabled( TRUE ); + actionEditSelectAll->setEnabled( TRUE ); + actionEditUndo->setMenuText( i18n( "&Undo" ) ); + actionEditUndo->setToolTip( textNoAccel( actionEditUndo->menuText()) ); + actionEditRedo->setMenuText( i18n( "&Redo" ) ); + actionEditRedo->setToolTip( textNoAccel( actionEditRedo->menuText()) ); + if ( hierarchyView->sourceEditor() != w ) + hierarchyView->showClasses( se ); + actionEditor->setFormWindow( 0 ); + if ( wspace && se->project() && se->project() != currentProject ) { + for ( QMap<QAction*, Project *>::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( *it == se->project() ) { + projectSelected( it.key() ); + break; + } + } + } + workspace()->activeEditorChanged( se ); + } else { + actionSearchFind->setEnabled( FALSE ); + actionSearchIncremetal->setEnabled( FALSE ); + actionSearchReplace->setEnabled( FALSE ); + actionSearchGotoLine->setEnabled( FALSE ); + incrementalSearch->setEnabled( FALSE ); + } + + if ( currentTool() == ORDER_TOOL && w != old ) + emit currentToolChanged(); + + emit hasActiveWindow( !!qworkspace->activeWindow() ); +} + +void MainWindow::updateUndoRedo( bool undoAvailable, bool redoAvailable, + const QString &undoCmd, const QString &redoCmd ) +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; // do not set a formWindow related command + actionEditUndo->setEnabled( undoAvailable ); + actionEditRedo->setEnabled( redoAvailable ); + if ( !undoCmd.isEmpty() ) + actionEditUndo->setMenuText( i18n( "&Undo: %1" ).arg( undoCmd ) ); + else + actionEditUndo->setMenuText( i18n( "&Undo: Not Available" ) ); + if ( !redoCmd.isEmpty() ) + actionEditRedo->setMenuText( i18n( "&Redo: %1" ).arg( redoCmd ) ); + else + actionEditRedo->setMenuText( i18n( "&Redo: Not Available" ) ); + + actionEditUndo->setToolTip( textNoAccel( actionEditUndo->menuText()) ); + actionEditRedo->setToolTip( textNoAccel( actionEditRedo->menuText()) ); + + if ( currentTool() == ORDER_TOOL ) { + actionEditUndo->setEnabled( FALSE ); + actionEditRedo->setEnabled( FALSE ); + } +} + +void MainWindow::updateEditorUndoRedo() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + SourceEditor *editor = (SourceEditor*)qWorkspace()->activeWindow(); + actionEditUndo->setEnabled( editor->editIsUndoAvailable() ); + actionEditRedo->setEnabled( editor->editIsRedoAvailable() ); +} + +QWorkspace *MainWindow::qWorkspace() const +{ + return qworkspace; +} + +void MainWindow::popupFormWindowMenu( const QPoint & gp, FormWindow *fw ) +{ + QValueList<uint> ids; + QMap<QString, int> commands; + + setupRMBSpecialCommands( ids, commands, fw ); + setupRMBProperties( ids, commands, fw ); + + qApp->processEvents(); + int r = rmbFormWindow->exec( gp ); + + handleRMBProperties( r, commands, fw ); + handleRMBSpecialCommands( r, commands, fw ); + + for ( QValueList<uint>::ConstIterator i = ids.begin(); i != ids.end(); ++i ) + rmbFormWindow->removeItem( *i ); +} + +void MainWindow::popupWidgetMenu( const QPoint &gp, FormWindow * /*fw*/, QWidget * w) +{ + QValueList<uint> ids; + QMap<QString, int> commands; + + setupRMBSpecialCommands( ids, commands, w ); + setupRMBProperties( ids, commands, w ); + + qApp->processEvents(); + int r = rmbWidgets->exec( gp ); + + handleRMBProperties( r, commands, w ); + handleRMBSpecialCommands( r, commands, w ); + + for ( QValueList<uint>::ConstIterator i = ids.begin(); i != ids.end(); ++i ) + rmbWidgets->removeItem( *i ); +} + +void MainWindow::setupRMBProperties( QValueList<uint> &ids, QMap<QString, int> &props, QWidget *w ) +{ + const QMetaProperty* text = w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE ); + if ( text && qstrcmp( text->type(), "QString") != 0 ) + text = 0; + const QMetaProperty* title = w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE ); + if ( title && qstrcmp( title->type(), "QString") != 0 ) + title = 0; + const QMetaProperty* pagetitle = + w->metaObject()->property( w->metaObject()->findProperty( "pageTitle", TRUE ), TRUE ); + if ( pagetitle && qstrcmp( pagetitle->type(), "QString") != 0 ) + pagetitle = 0; + const QMetaProperty* pixmap = + w->metaObject()->property( w->metaObject()->findProperty( "pixmap", TRUE ), TRUE ); + if ( pixmap && qstrcmp( pixmap->type(), "QPixmap") != 0 ) + pixmap = 0; + + if ( text && text->designable(w) || + title && title->designable(w) || + pagetitle && pagetitle->designable(w) || + pixmap && pixmap->designable(w) ) { + int id = 0; + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator(0); + if ( pixmap && pixmap->designable(w) ) { + ids << ( id = rmbWidgets->insertItem( i18n("Choose Pixmap..."), -1, 0) ); + props.insert( "pixmap", id ); + } + if ( text && text->designable(w) && !::qt_cast<QTextEdit*>(w) ) { + ids << ( id = rmbWidgets->insertItem( i18n("Edit Text..."), -1, 0) ); + props.insert( "text", id ); + } + if ( title && title->designable(w) ) { + ids << ( id = rmbWidgets->insertItem( i18n("Edit Title..."), -1, 0) ); + props.insert( "title", id ); + } + if ( pagetitle && pagetitle->designable(w) ) { + ids << ( id = rmbWidgets->insertItem( i18n("Edit Page Title..."), -1, 0) ); + props.insert( "pagetitle", id ); + } + } +} + +#ifdef QT_CONTAINER_CUSTOM_WIDGETS +static QWidgetContainerInterfacePrivate *containerWidgetInterface( QWidget *w ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( w ), &iface ); + if ( !iface ) + return 0; + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( !iface2 ) + return 0; + iface->release(); + return iface2; +} +#endif + +void MainWindow::setupRMBSpecialCommands( QValueList<uint> &ids, + QMap<QString, int> &commands, QWidget *w ) +{ + int id; + + if ( ::qt_cast<QTabWidget*>(w) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + if ( ( (QDesignerTabWidget*)w )->count() > 1) { + ids << ( id = rmbWidgets->insertItem( i18n("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( i18n("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + } else if ( ::qt_cast<QDesignerWidgetStack*>(w) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + if ( ( (QDesignerWidgetStack*)w )->count() > 1) { + ids << ( id = rmbWidgets->insertItem( i18n("Previous Page"), -1, 0 ) ); + commands.insert( "prevpage", id ); + ids << ( id = rmbWidgets->insertItem( i18n("Next Page"), -1, 0 ) ); + ids << rmbWidgets->insertSeparator( 0 ); + commands.insert( "nextpage", id ); + ids << ( id = rmbWidgets->insertItem( i18n("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( i18n("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + } else if ( ::qt_cast<QToolBox*>(w) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + if ( ( (QToolBox*)w )->count() > 1 ) { + ids << ( id = rmbWidgets->insertItem( i18n("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( i18n("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( WidgetDatabase:: + isCustomPluginWidget( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + QWidgetContainerInterfacePrivate *iface = containerWidgetInterface( w ); + if ( iface && iface->supportsPages( WidgetFactory::classNameOf( w ) ) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + + if ( iface->count( WidgetFactory::classNameOf( w ), w ) > 1 ) { + ids << ( id = rmbWidgets->insertItem( i18n( "Delete Page" ), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( i18n("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + if ( iface->currentIndex( WidgetFactory::classNameOf( w ), w ) != -1 ) { + ids << ( id = rmbWidgets->insertItem( i18n("Rename Current Page..."), -1, 0 ) ); + commands.insert( "rename", id ); + } + } + if ( iface ) + iface->release(); +#endif // QT_CONTAINER_CUSTOM_WIDGETS + } + + if ( WidgetFactory::hasSpecialEditor( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + ids << ( id = rmbWidgets->insertItem( i18n("Edit..."), -1, 0 ) ); + commands.insert( "edit", id ); + } +} + +void MainWindow::setupRMBSpecialCommands( QValueList<uint> &ids, + QMap<QString, int> &commands, FormWindow *fw ) +{ + int id; + + if ( ::qt_cast<QWizard*>(fw->mainContainer()) ) { + if ( ids.isEmpty() ) + ids << rmbFormWindow->insertSeparator( 0 ); + + if ( ( (QWizard*)fw->mainContainer() )->pageCount() > 1) { + ids << ( id = rmbFormWindow->insertItem( i18n("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + + ids << ( id = rmbFormWindow->insertItem( i18n("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + + ids << ( id = rmbFormWindow->insertItem( i18n("Edit Page Title..."), -1, 0 ) ); + commands.insert( "rename", id ); + + ids << ( id = rmbFormWindow->insertItem( i18n("Edit Pages..."), -1, 0 ) ); + commands.insert( "edit", id ); + + } else if ( ::qt_cast<QMainWindow*>(fw->mainContainer()) ) { + if ( ids.isEmpty() ) + ids << rmbFormWindow->insertSeparator( 0 ); + ids << ( id = rmbFormWindow->insertItem( i18n( "Add Menu Item" ), -1, 0 ) ); + commands.insert( "add_menu_item", id ); + ids << ( id = rmbFormWindow->insertItem( i18n( "Add Toolbar" ), -1, 0 ) ); + commands.insert( "add_toolbar", id ); + } +} + +void MainWindow::handleRMBProperties( int id, QMap<QString, int> &props, QWidget *w ) +{ + if ( id == props[ "text" ] ) { + bool ok = FALSE; + bool oldDoWrap = FALSE; + if ( ::qt_cast<QLabel*>(w) ) { + int align = w->property( "alignment" ).toInt(); + if ( align & WordBreak ) + oldDoWrap = TRUE; + } + bool doWrap = oldDoWrap; + + QString text; + if ( ::qt_cast<QTextView*>(w) || ::qt_cast<QLabel*>(w) || ::qt_cast<QButton*>(w) ) { + text = MultiLineEditor::getText( this, w->property( "text" ).toString(), !::qt_cast<QButton*>(w), &doWrap ); + ok = !text.isNull(); + } else { + text = QInputDialog::getText( i18n("Text"), i18n( "New text" ), + QLineEdit::Normal, w->property("text").toString(), &ok, this ); + } + if ( ok ) { + if ( oldDoWrap != doWrap ) { + QString pn( i18n( "Set 'wordwrap' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "wordwrap", QVariant( oldDoWrap, 0 ), + QVariant( doWrap, 0 ), QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "wordwrap", TRUE ); + } + + QString pn( i18n( "Set the 'text' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "text", w->property( "text" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "text", TRUE ); + } + } else if ( id == props[ "title" ] ) { + bool ok = FALSE; + QString title = QInputDialog::getText( i18n("Title"), i18n( "New title" ), + QLineEdit::Normal, w->property("title").toString(), &ok, this ); + if ( ok ) { + QString pn( i18n( "Set the 'title' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "title", w->property( "title" ), + title, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "title", TRUE ); + } + } else if ( id == props[ "pagetitle" ] ) { + bool ok = FALSE; + QString text = QInputDialog::getText( i18n("Page Title"), i18n( "New page title" ), + QLineEdit::Normal, w->property("pageTitle").toString(), &ok, this ); + if ( ok ) { + QString pn( i18n( "Set the 'pageTitle' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "pageTitle", + w->property( "pageTitle" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "pageTitle", TRUE ); + } + } else if ( id == props[ "pixmap" ] ) { + QPixmap oldPix = w->property( "pixmap" ).toPixmap(); + QPixmap pix = qChoosePixmap( this, formWindow(), oldPix ); + if ( !pix.isNull() ) { + QString pn( i18n( "Set the 'pixmap' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "pixmap", w->property( "pixmap" ), + pix, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "pixmap", TRUE ); + } + } +} + +void MainWindow::handleRMBSpecialCommands( int id, QMap<QString, int> &commands, QWidget *w ) +{ + if ( ::qt_cast<QTabWidget*>(w) ) { + QTabWidget *tw = (QTabWidget*)w; + if ( id == commands[ "add" ] ) { + AddTabPageCommand *cmd = + new AddTabPageCommand( i18n( "Add Page to %1" ).arg( tw->name() ), formWindow(), + tw, "Tab" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( tw->currentPage() ) { + QDesignerTabWidget *dtw = (QDesignerTabWidget*)tw; + DeleteTabPageCommand *cmd = + new DeleteTabPageCommand( i18n( "Delete Page %1 of %2" ). + arg( dtw->pageTitle() ).arg( tw->name() ), + formWindow(), tw, tw->currentPage() ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } + } else if ( ::qt_cast<QToolBox*>(w) ) { + QToolBox *tb = (QToolBox*)w; + if ( id == commands[ "add" ] ) { + AddToolBoxPageCommand *cmd = + new AddToolBoxPageCommand( i18n( "Add Page to %1" ).arg( tb->name() ), + formWindow(), + tb, "Page" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( tb->currentItem() ) { + DeleteToolBoxPageCommand *cmd = + new DeleteToolBoxPageCommand( i18n( "Delete Page %1 of %2" ). + arg( tb->itemLabel( tb->currentIndex() ) ). + arg( tb->name() ), + formWindow(), tb, tb->currentItem() ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } + } else if ( ::qt_cast<QWidgetStack*>(w) ) { + QDesignerWidgetStack *ws = (QDesignerWidgetStack*)w; + if ( id == commands[ "add" ] ) { + AddWidgetStackPageCommand *cmd = + new AddWidgetStackPageCommand( i18n( "Add Page to %1" ).arg( ws->name() ), + formWindow(), ws ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( ws->visibleWidget() ) { + DeleteWidgetStackPageCommand *cmd = + new DeleteWidgetStackPageCommand( i18n( "Delete Page %1 of %2" ). + arg( ws->currentPage() ).arg( ws->name() ), + formWindow(), ws, ws->visibleWidget() ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( id == commands[ "nextpage" ] ) { + int currentPage = w->property( "currentPage" ).toInt(); + QString pn( i18n( "Raise next page of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = + new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "currentPage", currentPage, + currentPage + 1, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "currentPage", TRUE ); + } else if ( id == commands[ "prevpage" ] ) { + int currentPage = w->property( "currentPage" ).toInt(); + QString pn( i18n( "Raise previous page of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = + new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "currentPage", currentPage, + currentPage -1, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "currentPage", TRUE ); + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( WidgetDatabase:: + isCustomPluginWidget( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + if ( id == commands[ "add" ] ) { + AddContainerPageCommand *cmd = + new AddContainerPageCommand( i18n( "Add Page to %1" ).arg( w->name() ), + formWindow(), w, "Page" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + QWidgetContainerInterfacePrivate *iface = containerWidgetInterface( w ); + if ( iface ) { + QString wClassName = WidgetFactory::classNameOf( w ); + int index = iface->currentIndex( wClassName, w ); + DeleteContainerPageCommand *cmd = + new DeleteContainerPageCommand( i18n( "Delete Page %1 of %2" ). + arg( iface->pageLabel( wClassName, + w, index ) ). + arg( w->name() ), + formWindow(), w, index ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + iface->release(); + } + } else if ( id == commands[ "rename" ] ) { + QWidgetContainerInterfacePrivate *iface = containerWidgetInterface( w ); + if ( iface ) { + bool ok = FALSE; + QString wClassName = WidgetFactory::classNameOf( w ); + int index = iface->currentIndex( wClassName, w ); + QString text = QInputDialog::getText( i18n("Page Title"), i18n( "New page title" ), + QLineEdit::Normal, + iface->pageLabel( wClassName, w, + index ), + &ok, this ); + if ( ok ) { + RenameContainerPageCommand *cmd = + new RenameContainerPageCommand( i18n( "Rename Page %1 to %2" ). + arg( iface-> + pageLabel( wClassName, w, + index ) ). + arg( text ), formWindow(), + w, index, text ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + iface->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + } + + if ( WidgetFactory::hasSpecialEditor( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) { + if ( id == commands[ "edit" ] ) + WidgetFactory::editWidget( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), this, w, formWindow() ); + } +} + +void MainWindow::handleRMBSpecialCommands( int id, QMap<QString, int> &commands, FormWindow *fw ) +{ + if ( ::qt_cast<QWizard*>(fw->mainContainer()) ) { + QWizard *wiz = (QWizard*)fw->mainContainer(); + if ( id == commands[ "add" ] ) { + AddWizardPageCommand *cmd = + new AddWizardPageCommand( i18n( "Add Page to %1" ).arg( wiz->name() ), + formWindow(), wiz, "WizardPage" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( wiz->currentPage() ) { + QDesignerWizard *dw = (QDesignerWizard*)wiz; + DeleteWizardPageCommand *cmd = + new DeleteWizardPageCommand( i18n( "Delete Page %1 of %2" ). + arg( dw->pageTitle() ).arg( wiz->name() ), + formWindow(), wiz, + wiz->indexOf( wiz->currentPage() ) ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( id == commands[ "edit" ] ) { + WizardEditor *e = new WizardEditor( this, wiz, fw ); + e->exec(); + delete e; + } else if ( id == commands[ "rename" ] ) { + + bool ok = FALSE; + QDesignerWizard *dw = (QDesignerWizard*)wiz; + QString text = QInputDialog::getText( i18n("Page Title"), i18n( "New page title" ), + QLineEdit::Normal, dw->pageTitle(), &ok, this ); + if ( ok ) { + QString pn( i18n( "Rename page %1 of %2" ).arg( dw->pageTitle() ).arg( wiz->name() ) ); + RenameWizardPageCommand *cmd = + new RenameWizardPageCommand( pn, formWindow() + , wiz, wiz->indexOf( wiz->currentPage() ), text ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } + } else if ( ::qt_cast<QMainWindow*>(fw->mainContainer()) ) { + QMainWindow *mw = (QMainWindow*)fw->mainContainer(); + if ( id == commands[ "add_toolbar" ] ) { + AddToolBarCommand *cmd = + new AddToolBarCommand( i18n( "Add Toolbar to '%1'" ).arg( formWindow()->name() ), + formWindow(), mw ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "add_menu_item" ] ) { + AddMenuCommand *cmd = + new AddMenuCommand( i18n( "Add Menu to '%1'" ).arg( formWindow()->name() ), + formWindow(), mw ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } +} + +void MainWindow::clipboardChanged() +{ + QString text( qApp->clipboard()->text() ); + QString start( "<!DOCTYPE UI-SELECTION>" ); + actionEditPaste->setEnabled( text.left( start.length() ) == start ); +} + +void MainWindow::selectionChanged() +{ + layoutChilds = FALSE; + layoutSelected = FALSE; + breakLayout = FALSE; + if ( !formWindow() ) { + actionEditCut->setEnabled( FALSE ); + actionEditCopy->setEnabled( FALSE ); + actionEditDelete->setEnabled( FALSE ); + actionEditAdjustSize->setEnabled( FALSE ); + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditSplitHorizontal->setEnabled( FALSE ); + actionEditSplitVertical->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + actionEditLower->setEnabled( FALSE ); + actionEditRaise->setEnabled( FALSE ); + actionEditAdjustSize->setEnabled( FALSE ); + return; + } + + int selectedWidgets = formWindow()->numSelectedWidgets(); + bool enable = selectedWidgets > 0; + actionEditCut->setEnabled( enable ); + actionEditCopy->setEnabled( enable ); + actionEditDelete->setEnabled( enable ); + actionEditLower->setEnabled( enable ); + actionEditRaise->setEnabled( enable ); + + actionEditAdjustSize->setEnabled( FALSE ); + actionEditSplitHorizontal->setEnabled( FALSE ); + actionEditSplitVertical->setEnabled( FALSE ); + + enable = FALSE; + QWidgetList widgets = formWindow()->selectedWidgets(); + if ( selectedWidgets > 1 ) { + int unlaidout = 0; + int laidout = 0; + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) + unlaidout++; + else + laidout++; + } + actionEditHLayout->setEnabled( unlaidout > 1 ); + actionEditVLayout->setEnabled( unlaidout > 1 ); + actionEditSplitHorizontal->setEnabled( unlaidout > 1 ); + actionEditSplitVertical->setEnabled( unlaidout > 1 ); + actionEditGridLayout->setEnabled( unlaidout > 1 ); + actionEditBreakLayout->setEnabled( laidout > 0 ); + actionEditAdjustSize->setEnabled( laidout > 0 ); + layoutSelected = unlaidout > 1; + breakLayout = laidout > 0; + } else if ( selectedWidgets == 1 ) { + QWidget *w = widgets.first(); + bool isContainer = WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) || + w == formWindow()->mainContainer(); + actionEditAdjustSize->setEnabled( !w->parentWidget() || + WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ); + + if ( !isContainer ) { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) { + actionEditBreakLayout->setEnabled( !isAToolBarChild( w ) ); + breakLayout = TRUE; + } else { + actionEditBreakLayout->setEnabled( FALSE ); + } + } else { + if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) { + if ( !formWindow()->hasInsertedChildren( w ) ) { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + } else { + actionEditHLayout->setEnabled( TRUE ); + actionEditVLayout->setEnabled( TRUE ); + actionEditGridLayout->setEnabled( TRUE ); + actionEditBreakLayout->setEnabled( FALSE ); + layoutChilds = TRUE; + } + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) { + actionEditBreakLayout->setEnabled( !isAToolBarChild( w ) ); + breakLayout = TRUE; + } + } else { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( !isAToolBarChild( w ) ); + breakLayout = TRUE; + } + } + } else if ( selectedWidgets == 0 ) { + actionEditAdjustSize->setEnabled( TRUE ); + QWidget *w = formWindow()->mainContainer(); + if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) { + if ( !formWindow()->hasInsertedChildren( w ) ) { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + } else { + actionEditHLayout->setEnabled( TRUE ); + actionEditVLayout->setEnabled( TRUE ); + actionEditGridLayout->setEnabled( TRUE ); + actionEditBreakLayout->setEnabled( FALSE ); + layoutChilds = TRUE; + } + } else { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( TRUE ); + breakLayout = TRUE; + } + } else { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + } +} + +static QString fixArgs( const QString &s2 ) +{ + QString s = s2; + return s.replace( ',', ';' ); +} + +void MainWindow::writeConfig() +{ + QSettings config; + + // No search path for unix, only needs application name + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + QString keybase = DesignerApplication::settingsKey(); + + if (savePluginPaths) { + QStringList pluginPaths = QApplication::libraryPaths(); + config.writeEntry( keybase + "PluginPaths", pluginPaths ); + } + config.writeEntry( keybase + "RestoreWorkspace", restoreConfig ); + config.writeEntry( keybase + "SplashScreen", splashScreen ); + config.writeEntry( keybase + "ShowStartDialog", shStartDialog ); + config.writeEntry( keybase + "FileFilter", fileFilter ); + config.writeEntry( keybase + "TemplatePath", templPath ); + config.writeEntry( keybase + "RecentlyOpenedFiles", recentlyFiles ); + config.writeEntry( keybase + "RecentlyOpenedProjects", recentlyProjects ); + config.writeEntry( keybase + "DatabaseAutoEdit", databaseAutoEdit ); + + config.writeEntry( keybase + "AutoSave/Enabled", autoSaveEnabled ); + config.writeEntry( keybase + "AutoSave/Interval", autoSaveInterval ); + + config.writeEntry( keybase + "Grid/Snap", snGrid ); + config.writeEntry( keybase + "Grid/Show", sGrid ); + config.writeEntry( keybase + "Grid/x", grid().x() ); + config.writeEntry( keybase + "Grid/y", grid().y() ); + config.writeEntry( keybase + "LastToolPage", + toolBox->itemLabel( toolBox->currentIndex() ) ); + + config.writeEntry( keybase + "Background/UsePixmap", backPix ); + config.writeEntry( keybase + "Background/Color", (int)qworkspace->backgroundColor().rgb() ); + if ( qworkspace->backgroundPixmap() ) + qworkspace->backgroundPixmap()->save( QDir::home().absPath() + "/.designer/" + "background.xpm", "PNG" ); + + config.writeEntry( keybase + "Geometries/MainwindowX", x() ); + config.writeEntry( keybase + "Geometries/MainwindowY", y() ); + config.writeEntry( keybase + "Geometries/MainwindowWidth", width() ); + config.writeEntry( keybase + "Geometries/MainwindowHeight", height() ); + config.writeEntry( keybase + "Geometries/MainwindowMaximized", isMaximized() ); + config.writeEntry( keybase + "Geometries/PropertyEditorX", propertyEditor->parentWidget()->x() ); + config.writeEntry( keybase + "Geometries/PropertyEditorY", propertyEditor->parentWidget()->y() ); + config.writeEntry( keybase + "Geometries/PropertyEditorWidth", propertyEditor->parentWidget()->width() ); + config.writeEntry( keybase + "Geometries/PropertyEditorHeight", propertyEditor->parentWidget()->height() ); + config.writeEntry( keybase + "Geometries/HierarchyViewX", hierarchyView->parentWidget()->x() ); + config.writeEntry( keybase + "Geometries/HierarchyViewY", hierarchyView->parentWidget()->y() ); + config.writeEntry( keybase + "Geometries/HierarchyViewWidth", hierarchyView->parentWidget()->width() ); + config.writeEntry( keybase + "Geometries/HierarchyViewHeight", hierarchyView->parentWidget()->height() ); + config.writeEntry( keybase + "Geometries/WorkspaceX", wspace->parentWidget()->x() ); + config.writeEntry( keybase + "Geometries/WorkspaceY", wspace->parentWidget()->y() ); + config.writeEntry( keybase + "Geometries/WorkspaceWidth", wspace->parentWidget()->width() ); + config.writeEntry( keybase + "Geometries/WorkspaceHeight", wspace->parentWidget()->height() ); + + config.writeEntry( keybase + "View/TextLabels", usesTextLabel() ); + config.writeEntry( keybase + "View/BigIcons", usesBigPixmaps() ); + + QString mwlKey = "MainwindowLayout"; + if ( singleProjectMode() ) + mwlKey += "S"; + QString mainWindowLayout; + QTextStream ts( &mainWindowLayout, IO_WriteOnly ); + ts << *this; + config.writeEntry( keybase + mwlKey, mainWindowLayout ); + + + QPtrList<MetaDataBase::CustomWidget> *lst = MetaDataBase::customWidgets(); + config.writeEntry( keybase + "CustomWidgets/num", (int)lst->count() ); + int j = 0; + QDir::home().mkdir( ".designer" ); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + QStringList l; + l << w->className; + l << w->includeFile; + l << QString::number( (int)w->includePolicy ); + l << QString::number( w->sizeHint.width() ); + l << QString::number( w->sizeHint.height() ); + l << QString::number( w->lstSignals.count() ); + for ( QValueList<QCString>::ConstIterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + l << QString( fixArgs( *it ) ); + l << QString::number( w->lstSlots.count() ); + for ( QValueList<MetaDataBase::Function>::ConstIterator it2 = w->lstSlots.begin(); it2 != w->lstSlots.end(); ++it2 ) { + l << fixArgs( (*it2).function ); + l << (*it2).access; + } + l << QString::number( w->lstProperties.count() ); + for ( QValueList<MetaDataBase::Property>::ConstIterator it3 = w->lstProperties.begin(); it3 != w->lstProperties.end(); ++it3 ) { + l << (*it3).property; + l << (*it3).type; + } + l << QString::number( size_type_to_int( w->sizePolicy.horData() ) ); + l << QString::number( size_type_to_int( w->sizePolicy.verData() ) ); + l << QString::number( (int)w->isContainer ); + config.writeEntry( keybase + "CustomWidgets/Widget" + QString::number( j++ ), l, ',' ); + w->pixmap->save( QDir::home().absPath() + "/.designer/" + w->className, "XPM" ); + } + + QStringList l; + for ( QAction *a = commonWidgetsPage.first(); a; a = commonWidgetsPage.next() ) + l << a->text(); + config.writeEntry( keybase + "ToolBox/CommonWidgets", l ); +} + +static QString fixArgs2( const QString &s2 ) +{ + QString s = s2; + return s.replace( ';', ',' ); +} + +void MainWindow::readConfig() +{ + QString keybase = DesignerApplication::settingsKey(); + QSettings config; + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + bool ok; + bool readPreviousConfig = FALSE; + QString backPixName( QDir::home().absPath() + "/.designer/" + "background.xpm" ); + restoreConfig = config.readBoolEntry( keybase + "RestoreWorkspace", TRUE, &ok ); + if ( !ok ) { + keybase = DesignerApplication::oldSettingsKey(); + restoreConfig = config.readBoolEntry( keybase + "RestoreWorkspace", TRUE, &ok ); + if ( !ok ) { + if ( oWindow ) { + oWindow->shuttingDown(); + ( (QDockWindow*)oWindow->parent() )->hide(); + } + QPixmap pix; + pix.load( backPixName ); + if ( !pix.isNull() ) + qworkspace->setBackgroundPixmap( pix ); + return; + } + readPreviousConfig = TRUE; + } + if ( !readPreviousConfig ) { + fileFilter = config.readEntry( keybase + "FileFilter", fileFilter ); + templPath = config.readEntry( keybase + "TemplatePath", QString::null ); + databaseAutoEdit = config.readBoolEntry( keybase + "DatabaseAutoEdit", databaseAutoEdit ); + shStartDialog = config.readBoolEntry( keybase + "ShowStartDialog", shStartDialog ); + autoSaveEnabled = config.readBoolEntry( keybase + "AutoSave/Enabled", autoSaveEnabled ); + autoSaveInterval = config.readNumEntry( keybase + "AutoSave/Interval", autoSaveInterval ); + } + + if ( restoreConfig || readPreviousConfig ) { + QString s = config.readEntry( keybase + "LastToolPage" ); + for ( int i = 0; i < toolBox->count(); ++i ) { + if ( toolBox->itemLabel(i) == s ) { + toolBox->setCurrentIndex( i ); + break; + } + } + // We know that the oldSettingsKey() will return 3.1 + if ( keybase == DesignerApplication::oldSettingsKey() ) { + if (keybase.contains("3.1")) + recentlyFiles = config.readListEntry( keybase + "RecentlyOpenedFiles", ',' ); + else + recentlyFiles = config.readListEntry(keybase + "RecentlyOpenedFiles"); + + if ( recentlyFiles.count() == 1 && recentlyFiles[0].isNull() ) + recentlyFiles.clear(); + if (keybase.contains("3.1")) + recentlyProjects = config.readListEntry( keybase + "RecentlyOpenedProjects", ',' ); + else + recentlyProjects = config.readListEntry( keybase + "RecentlyOpenedProjects"); + if ( recentlyProjects.count() == 1 && recentlyProjects[0].isNull() ) + recentlyProjects.clear(); + } else { + recentlyFiles = config.readListEntry( keybase + "RecentlyOpenedFiles" ); + recentlyProjects = config.readListEntry( keybase + "RecentlyOpenedProjects" ); + } + + backPix = config.readBoolEntry( keybase + "Background/UsePixmap", TRUE ) | readPreviousConfig; + if ( backPix ) { + QPixmap pix; + pix.load( backPixName ); + if ( !pix.isNull() ) + qworkspace->setBackgroundPixmap( pix ); + } else { + qworkspace->setBackgroundColor( QColor( (QRgb)config.readNumEntry( keybase + "Background/Color" ) ) ); + } + + if ( !readPreviousConfig ) { + splashScreen = config.readBoolEntry( keybase + "SplashScreen", TRUE ); + + sGrid = config.readBoolEntry( keybase + "Grid/Show", TRUE ); + snGrid = config.readBoolEntry( keybase + "Grid/Snap", TRUE ); + grd.setX( config.readNumEntry( keybase + "Grid/x", 10 ) ); + grd.setY( config.readNumEntry( keybase + "Grid/y", 10 ) ); + + if ( !config.readBoolEntry( DesignerApplication::settingsKey() + "Geometries/MainwindowMaximized", FALSE ) ) { + QRect r( pos(), size() ); + r.setX( config.readNumEntry( keybase + "Geometries/MainwindowX", r.x() ) ); + r.setY( config.readNumEntry( keybase + "Geometries/MainwindowY", r.y() ) ); + r.setWidth( config.readNumEntry( keybase + "Geometries/MainwindowWidth", r.width() ) ); + r.setHeight( config.readNumEntry( keybase + "Geometries/MainwindowHeight", r.height() ) ); + + QRect desk = QApplication::desktop()->geometry(); + QRect inter = desk.intersect( r ); + resize( r.size() ); + if ( inter.width() * inter.height() > ( r.width() * r.height() / 20 ) ) { + move( r.topLeft() ); + } + } + setUsesTextLabel( config.readBoolEntry( keybase + "View/TextLabels", FALSE ) ); + setUsesBigPixmaps( FALSE /*config.readBoolEntry( "BigIcons", FALSE )*/ ); // ### disabled for now + } + } + int num = config.readNumEntry( keybase + "CustomWidgets/num" ); + for ( int j = 0; j < num; ++j ) { + MetaDataBase::CustomWidget *w = new MetaDataBase::CustomWidget; + QStringList l = config.readListEntry( keybase + "CustomWidgets/Widget" + QString::number( j ), ',' ); + w->className = l[ 0 ]; + w->includeFile = l[ 1 ]; + w->includePolicy = (MetaDataBase::CustomWidget::IncludePolicy)l[ 2 ].toInt(); + w->sizeHint.setWidth( l[ 3 ].toInt() ); + w->sizeHint.setHeight( l[ 4 ].toInt() ); + uint c = 5; + if ( l.count() > c ) { + int numSignals = l[ c ].toInt(); + c++; + for ( int i = 0; i < numSignals; ++i, c++ ) + w->lstSignals.append( fixArgs2( l[ c ] ).latin1() ); + } + if ( l.count() > c ) { + int numSlots = l[ c ].toInt(); + c++; + for ( int i = 0; i < numSlots; ++i ) { + MetaDataBase::Function slot; + slot.function = fixArgs2( l[ c ] ); + c++; + slot.access = l[ c ]; + c++; + w->lstSlots.append( slot ); + } + } + if ( l.count() > c ) { + int numProperties = l[ c ].toInt(); + c++; + for ( int i = 0; i < numProperties; ++i ) { + MetaDataBase::Property prop; + prop.property = l[ c ]; + c++; + prop.type = l[ c ]; + c++; + w->lstProperties.append( prop ); + } + } if ( l.count() > c ) { + QSizePolicy::SizeType h, v; + h = int_to_size_type( l[ c++ ].toInt() ); + v = int_to_size_type( l[ c++ ].toInt() ); + w->sizePolicy = QSizePolicy( h, v ); + } + if ( l.count() > c ) { + w->isContainer = (bool)l[ c++ ].toInt(); + } + w->pixmap = new QPixmap( BarIcon( QDir::home().absPath() + "/.designer/" + w->className , KDevDesignerPartFactory::instance()) ); + MetaDataBase::addCustomWidget( w ); + } + if ( num > 0 ) + rebuildCustomWidgetGUI(); + + if ( !restoreConfig ) + return; + +#ifndef Q_WS_MAC + /* I'm sorry to make this not happen on the Mac, but it seems to hang somewhere deep + in QLayout, it gets into a very large loop - and seems it has to do with clever + things the designer does ###Sam */ + QApplication::sendPostedEvents(); +#endif + + if ( !readPreviousConfig ) { + QString mwlKey = "MainwindowLayout"; + if ( singleProjectMode() ) + mwlKey += "S"; + QString mainWindowLayout = config.readEntry( keybase + mwlKey ); + QTextStream ts( &mainWindowLayout, IO_ReadOnly ); + ts >> *this; + } + if ( readPreviousConfig && oWindow ) { + oWindow->shuttingDown(); + ( (QDockWindow*)oWindow->parent() )->hide(); + } + + rebuildCustomWidgetGUI(); + + QStringList l = config.readListEntry( keybase + "ToolBox/CommonWidgets" ); + if ( !l.isEmpty() ) { + QPtrList<QAction> lst; + commonWidgetsPage.clear(); + for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + for ( QAction *a = toolActions.first(); a; a = toolActions.next() ) { + if ( *it == a->text() ) { + lst.append( a ); + break; + } + } + } + if ( lst != commonWidgetsPage ) { + commonWidgetsPage = lst; + rebuildCommonWidgetsToolBoxPage(); + } + } +} + +HierarchyView *MainWindow::objectHierarchy() const +{ + if ( !hierarchyView ) + ( (MainWindow*)this )->setupHierarchyView(); + return hierarchyView; +} + +QPopupMenu *MainWindow::setupNormalHierarchyMenu( QWidget *parent ) +{ + QPopupMenu *menu = new QPopupMenu( parent ); + + actionEditCut->addTo( menu ); + actionEditCopy->addTo( menu ); + actionEditPaste->addTo( menu ); + actionEditDelete->addTo( menu ); + + return menu; +} + +QPopupMenu *MainWindow::setupTabWidgetHierarchyMenu( QWidget *parent, const char *addSlot, const char *removeSlot ) +{ + QPopupMenu *menu = new QPopupMenu( parent ); + + menu->insertItem( i18n( "Add Page" ), parent, addSlot ); + menu->insertItem( i18n( "Delete Page" ), parent, removeSlot ); + menu->insertSeparator(); + actionEditCut->addTo( menu ); + actionEditCopy->addTo( menu ); + actionEditPaste->addTo( menu ); + actionEditDelete->addTo( menu ); + + return menu; +} + +void MainWindow::closeEvent( QCloseEvent *e ) +{ + if ( singleProject ) { + hide(); + e->ignore(); + return; + } + + QWidgetList windows = qWorkspace()->windowList(); + QWidgetListIt wit( windows ); + while ( wit.current() ) { + QWidget *w = wit.current(); + ++wit; + if ( ::qt_cast<FormWindow*>(w) ) { + if ( ( (FormWindow*)w )->formFile()->editor() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->editor() ); + if ( ( (FormWindow*)w )->formFile()->formWindow() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->formWindow() ); + if ( !( (FormWindow*)w )->formFile()->close() ) { + e->ignore(); + return; + } + } else if ( ::qt_cast<SourceEditor*>(w) ) { + if ( !( (SourceEditor*)w )->close() ) { + e->ignore(); + return; + } + } + w->close(); + } + + QMapConstIterator<QAction*, Project*> it = projects.begin(); + while( it != projects.end() ) { + Project *pro = it.data(); + ++it; + if ( pro->isModified() ) { + switch ( QMessageBox::warning( this, i18n( "Save Project Settings" ), + i18n( "Save changes to '%1'?" ).arg( pro->fileName() ), + i18n( "&Yes" ), i18n( "&No" ), i18n( "&Cancel" ), 0, 2 ) ) { + case 0: // save + pro->save(); + break; + case 1: // don't save + break; + case 2: // cancel + e->ignore(); + return; + default: + break; + } + } + } + + writeConfig(); + hide(); + e->accept(); + + if ( client ) { + QDir home( QDir::homeDirPath() ); + home.remove( ".designerpid" ); + } +} + +Workspace *MainWindow::workspace() const +{ + if ( !wspace ) + ( (MainWindow*)this )->setupWorkspace(); + return wspace; +} + +PropertyEditor *MainWindow::propertyeditor() const +{ + if ( !propertyEditor ) + ( (MainWindow*)this )->setupPropertyEditor(); + return propertyEditor; +} + +ActionEditor *MainWindow::actioneditor() const +{ + if ( !actionEditor ) + ( (MainWindow*)this )->setupActionEditor(); + return actionEditor; +} + +bool MainWindow::openEditor( QWidget *w, FormWindow *f ) +{ + if ( f && !f->project()->isCpp() && !WidgetFactory::isPassiveInteractor( w ) ) { + QString defSignal = WidgetFactory::defaultSignal( w ); + if ( defSignal.isEmpty() ) { + editSource(); + } else { + QString s = QString( w->name() ) + "_" + defSignal; + LanguageInterface *iface = MetaDataBase::languageInterface( f->project()->language() ); + if ( iface ) { + QStrList sigs = iface->signalNames( w ); + QString fullSignal; + for ( int i = 0; i < (int)sigs.count(); ++i ) { + QString sig = sigs.at( i ); + if ( sig.left( sig.find( '(' ) ) == defSignal ) { + fullSignal = sig; + break; + } + } + + if ( !fullSignal.isEmpty() ) { + QString signl = fullSignal; + fullSignal = fullSignal.mid( fullSignal.find( '(' ) + 1 ); + fullSignal.remove( (int)fullSignal.length() - 1, 1 ); + fullSignal = iface->createArguments( fullSignal.simplifyWhiteSpace() ); + s += "(" + fullSignal + ")"; + if ( !MetaDataBase::hasFunction( f, s.latin1() ) ) + MetaDataBase::addFunction( f, s.latin1(), "", "public", "slot", + f->project()->language(), "void" ); + s = s.left( s.find( '(' ) ).latin1(); + if ( !MetaDataBase::hasConnection( f, w, defSignal.latin1(), f->mainContainer(), s.latin1() ) ) { + MetaDataBase::Connection conn; + conn.sender = w; + conn.receiver = f->mainContainer(); + conn.signal = signl; + conn.slot = s; + AddConnectionCommand *cmd = + new AddConnectionCommand( i18n( "Add Connection" ), f, conn ); + f->commandHistory()->addCommand( cmd ); + cmd->execute(); + f->formFile()->setModified( TRUE ); + } + } + } + editFunction( s, TRUE ); + } + return TRUE; + } + if ( WidgetFactory::hasSpecialEditor( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) { + statusMessage( i18n( "Edit %1..." ).arg( w->className() ) ); + WidgetFactory::editWidget( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ), + this, w, formWindow() ); + statusBar()->clear(); + return TRUE; + } + + const QMetaProperty* text = w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE ); + const QMetaProperty* title = w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE ); + if ( text && text->designable(w) ) { + bool ok = FALSE; + bool oldDoWrap = FALSE; + if ( ::qt_cast<QLabel*>(w) ) { + int align = w->property( "alignment" ).toInt(); + if ( align & WordBreak ) + oldDoWrap = TRUE; + } + bool doWrap = oldDoWrap; + + QString text; + if ( ::qt_cast<QTextEdit*>(w) || ::qt_cast<QLabel*>(w) || ::qt_cast<QButton*>(w) ) { + text = MultiLineEditor::getText( this, w->property( "text" ).toString(), + !::qt_cast<QButton*>(w), &doWrap ); + ok = !text.isNull(); + } else { + text = QInputDialog::getText( i18n("Text"), i18n( "New text" ), + QLineEdit::Normal, w->property("text").toString(), &ok, this ); + } + if ( ok ) { + if ( oldDoWrap != doWrap ) { + QString pn( i18n( "Set 'wordwrap' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "wordwrap", QVariant( oldDoWrap, 0 ), + QVariant( doWrap, 0 ), QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "wordwrap", TRUE ); + } + + QString pn( i18n( "Set the 'text' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "text", w->property( "text" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "text", TRUE ); + } + return TRUE; + } + if ( title && title->designable(w) ) { + bool ok = FALSE; + QString text; + text = QInputDialog::getText( i18n("Title"), i18n( "New title" ), QLineEdit::Normal, w->property("title").toString(), &ok, this ); + if ( ok ) { + QString pn( i18n( "Set the 'title' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "title", w->property( "title" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "title", TRUE ); + } + return TRUE; + } + + if ( !WidgetFactory::isPassiveInteractor( w ) ) + editSource(); + + return TRUE; +} + +void MainWindow::rebuildCustomWidgetGUI() +{ + customWidgetToolBar->clear(); + customWidgetMenu->clear(); + customWidgetToolBar2->clear(); + int count = 0; + + QPtrListIterator<QAction> it( toolActions ); + QAction *action; + while ( ( action = it.current() ) ) { + ++it; + if ( ( (WidgetAction*)action )->group() == "Custom Widgets" ) + delete action; + } + + QPtrList<MetaDataBase::CustomWidget> *lst = MetaDataBase::customWidgets(); + + actionToolsCustomWidget->addTo( customWidgetMenu ); + customWidgetMenu->insertSeparator(); + + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + WidgetAction* a = new WidgetAction( "Custom Widgets", actionGroupTools, QString::number( w->id ).latin1() ); + a->setToggleAction( TRUE ); + a->setText( w->className ); + a->setIconSet( *w->pixmap ); + a->setStatusTip( i18n( "Insert a %1 (custom widget)" ).arg( w->className ) ); + a->setWhatsThis( i18n("<b>%1 (custom widget)</b>" + "<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> menu to " + "add and change custom widgets. You can add properties as well as " + "signals and slots to integrate them into Qt Designer, " + "and provide a pixmap which will be used to represent the widget on the form.</p>").arg( w->className ) ); + + a->addTo( customWidgetToolBar ); + a->addTo( customWidgetToolBar2 ); + a->addTo( customWidgetMenu ); + count++; + } + QWidget *wid; + customWidgetToolBar2->setStretchableWidget( ( wid = new QWidget( customWidgetToolBar2 ) ) ); + wid->setBackgroundMode( customWidgetToolBar2->backgroundMode() ); + + if ( count == 0 ) + customWidgetToolBar->hide(); + else if ( customWidgetToolBar->isVisible() ) + customWidgetToolBar->show(); +} + +void MainWindow::rebuildCommonWidgetsToolBoxPage() +{ + toolBox->setUpdatesEnabled( FALSE ); + commonWidgetsToolBar->setUpdatesEnabled( FALSE ); + commonWidgetsToolBar->clear(); + for ( QAction *a = commonWidgetsPage.first(); a; a = commonWidgetsPage.next() ) + a->addTo( commonWidgetsToolBar ); + QWidget *w; + commonWidgetsToolBar->setStretchableWidget( ( w = new QWidget( commonWidgetsToolBar ) ) ); + w->setBackgroundMode( commonWidgetsToolBar->backgroundMode() ); + toolBox->setUpdatesEnabled( TRUE ); + commonWidgetsToolBar->setUpdatesEnabled( TRUE ); +} + +bool MainWindow::isCustomWidgetUsed( MetaDataBase::CustomWidget *wid ) +{ + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( ::qt_cast<FormWindow*>(w) ) { + if ( ( (FormWindow*)w )->isCustomWidgetUsed( wid ) ) + return TRUE; + } + } + return FALSE; +} + +void MainWindow::setGrid( const QPoint &p ) +{ + if ( p == grd ) + return; + grd = p; + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( !::qt_cast<FormWindow*>(w) ) + continue; + ( (FormWindow*)w )->mainContainer()->update(); + } +} + +void MainWindow::setShowGrid( bool b ) +{ + if ( b == sGrid ) + return; + sGrid = b; + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( !::qt_cast<FormWindow*>(w) ) + continue; + ( (FormWindow*)w )->mainContainer()->update(); + } +} + +void MainWindow::setSnapGrid( bool b ) +{ + if ( b == snGrid ) + return; + snGrid = b; +} + +QString MainWindow::documentationPath() const +{ + return QString( qInstallPathDocs() ) + "/html/"; +} + +void MainWindow::windowsMenuActivated( int id ) +{ + QWidget* w = qworkspace->windowList().at( id ); + if ( w ) + w->setFocus(); +} + +void MainWindow::projectSelected( QAction *a ) +{ + a->setOn( TRUE ); + if ( currentProject ) + currentProject->setActive( FALSE ); + Project *p = *projects.find( a ); + p->setActive( TRUE ); + if ( currentProject == p ) + return; + currentProject = p; + if ( wspace ) + wspace->setCurrentProject( currentProject ); +} + +void MainWindow::openProject( const QString &fn ) +{ + for ( QMap<QAction*, Project*>::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( (*it)->fileName() == fn ) { + projectSelected( it.key() ); + return; + } + } + QApplication::setOverrideCursor( waitCursor ); + Project *pro = new Project( fn, "", projectSettingsPluginManager ); + pro->setModified( FALSE ); + QAction *a = new QAction( pro->projectName(), pro->projectName(), 0, actionGroupProjects, 0, TRUE ); + projects.insert( a, pro ); + projectSelected( a ); + QApplication::restoreOverrideCursor(); +} + +void MainWindow::checkTempFiles() +{ + QString s = QDir::homeDirPath() + "/.designer"; + QString baseName = s+ "/saved-form-"; + if ( !QFile::exists( baseName + "1.ui" ) ) + return; + DesignerApplication::closeSplash(); + QDir d( s ); + d.setNameFilter( "*.ui" ); + QStringList lst = d.entryList(); + QApplication::restoreOverrideCursor(); + bool load = QMessageBox::information( this, i18n( "Restoring Last Session" ), + i18n( "Qt Designer found some temporary saved files, which were\n" + "written when Qt Designer crashed last time. Do you want to\n" + "load these files?" ), i18n( "&Yes" ), i18n( "&No" ) ) == 0; + QApplication::setOverrideCursor( waitCursor ); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + if ( load ) + openFormWindow( s + "/" + *it, FALSE ); + d.remove( *it ); + } +} + +void MainWindow::showDialogHelp() +{ + QWidget *w = (QWidget*)sender(); + w = w->topLevelWidget(); + + QString link = documentationPath() + "/designer-manual-13.html#"; + + if ( ::qt_cast<NewFormBase*>(w) || ::qt_cast<StartDialogBase*>(w) ) // own doc for startdialog? + link += "dialog-file-new"; + else if ( ::qt_cast<CreateTemplate*>(w) ) + link += "dialog-file-create-template"; + else if ( ::qt_cast<EditFunctionsBase*>(w) ) + link += "dialog-edit-functions"; +// else if ( ::qt_cast<ConnectionViewerBase*>(w) ) + else if ( w->inherits("ConnectionViewerBase") ) + link += "dialog-view-connections"; + else if ( ::qt_cast<FormSettingsBase*>(w) ) + link += "dialog-edit-form-settings"; + else if ( ::qt_cast<Preferences*>(w) ) + link += "dialog-edit-preferences"; + else if ( ::qt_cast<PixmapCollectionEditor*>(w) ) + link += "dialog-image-collection"; +// else if ( ::qt_cast<DatabaseConnectionBase*>(w) ) + else if ( w->inherits( "DatabaseConnectionBase" ) ) + link += "dialog-edit-database-connections"; + else if ( ::qt_cast<ProjectSettingsBase*>(w) ) + link += "dialog-project-settings"; + else if ( ::qt_cast<FindDialog*>(w) ) + link += "dialog-find-text"; + else if ( ::qt_cast<ReplaceDialog*>(w) ) + link += "dialog-replace-text"; + else if ( ::qt_cast<GotoLineDialog*>(w) ) + link += "dialog-go-to-line"; +// else if ( ::qt_cast<ConnectionEditorBase*>(w) ) + else if ( w->inherits("ConnectionEditorBase") ) + link += "dialog-edit-connections"; + else if ( ::qt_cast<CustomWidgetEditorBase*>(w) ) + link += "dialog-edit-custom-widgets"; + else if ( ::qt_cast<PaletteEditorBase*>(w) ) + link += "dialog-edit-palette"; + else if ( ::qt_cast<ListBoxEditorBase*>(w) ) + link += "dialog-edit-listbox"; + else if ( ::qt_cast<ListViewEditorBase*>(w) ) + link += "dialog-edit-listview"; + else if ( ::qt_cast<IconViewEditorBase*>(w) ) + link += "dialog-edit-iconview"; + else if ( ::qt_cast<TableEditorBase*>(w) ) + link += "dialog-edit-table"; + else if ( ::qt_cast<MultiLineEditor*>(w) ) + link += "dialog-text"; + + else { + QMessageBox::information( this, i18n( "Help" ), + i18n( "There is no help available for this dialog at the moment." ) ); + return; + } + + assistant->showPage( link ); +} + +void MainWindow::setupActionManager() +{ + actionPluginManager = new QPluginManager<ActionInterface>( IID_Action, QApplication::libraryPaths(), pluginDirectory() ); + + QStringList lst = actionPluginManager->featureList(); + for ( QStringList::ConstIterator ait = lst.begin(); ait != lst.end(); ++ait ) { + ActionInterface *iface = 0; + actionPluginManager->queryInterface( *ait, &iface ); + if ( !iface ) + continue; + + iface->connectTo( desInterface ); + QAction *a = iface->create( *ait, this ); + if ( !a ) + continue; + + QString grp = iface->group( *ait ); + if ( grp.isEmpty() ) + grp = "3rd party actions"; + QPopupMenu *menu = 0; + QToolBar *tb = 0; + + if ( !( menu = (QPopupMenu*)child( grp.latin1(), "QPopupMenu" ) ) ) { + menu = new QPopupMenu( this, grp.latin1() ); + menuBar()->insertItem( i18n( grp ), menu ); + } + if ( !( tb = (QToolBar*)child( grp.latin1(), "QToolBar" ) ) ) { + tb = new QToolBar( this, grp.latin1() ); + tb->setCloseMode( QDockWindow::Undocked ); + addToolBar( tb, grp ); + } + + if ( iface->location( *ait, ActionInterface::Menu ) ) + a->addTo( menu ); + if ( iface->location( *ait, ActionInterface::Toolbar ) ) + a->addTo( tb ); + + iface->release(); + } +} + +void MainWindow::editFunction( const QString &func, bool rereadSource ) +{ + if ( !formWindow() ) + return; + + if ( formWindow()->formFile()->codeFileState() != FormFile::Ok ) + if ( !formWindow()->formFile()->setupUihFile(FALSE) ) + return; + + QString lang = currentProject->language(); + if ( !MetaDataBase::hasEditor( lang ) ) { + QMessageBox::information( this, i18n( "Edit Source" ), + i18n( "There is no plugin for editing %1 code installed.\n" + "Note: Plugins are not available in static Qt configurations." ).arg( lang ) ); + return; + } + + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->language() == lang && e->formWindow() == formWindow() ) { + e->show(); + e->setFunction( func ); + return; + } + } + + createSourceEditor( formWindow(), formWindow()->project(), lang, func, rereadSource ); +} + +void MainWindow::setupRecentlyFilesMenu() +{ + recentlyFilesMenu->clear(); + int id = 0; + for ( QStringList::ConstIterator it = recentlyFiles.begin(); it != recentlyFiles.end(); ++it ) { + recentlyFilesMenu->insertItem( *it, id ); + id++; + } +} + +void MainWindow::setupRecentlyProjectsMenu() +{ + recentlyProjectsMenu->clear(); + int id = 0; + for ( QStringList::ConstIterator it = recentlyProjects.begin(); it != recentlyProjects.end(); ++it ) { + recentlyProjectsMenu->insertItem( *it, id ); + id++; + } +} + +QPtrList<DesignerProject> MainWindow::projectList() const +{ + QPtrList<DesignerProject> list; + QMapConstIterator<QAction*, Project*> it = projects.begin(); + + while( it != projects.end() ) { + Project *p = it.data(); + ++it; + list.append( p->iFace() ); + } + + return list; +} + +QStringList MainWindow::projectNames() const +{ + QStringList res; + for ( QMap<QAction*, Project* >::ConstIterator it = projects.begin(); it != projects.end(); ++it ) + res << (*it)->projectName(); + return res; +} + +QStringList MainWindow::projectFileNames() const +{ + QStringList res; + for ( QMap<QAction*, Project* >::ConstIterator it = projects.begin(); it != projects.end(); ++it ) + res << (*it)->makeRelative( (*it)->fileName() ); + return res; +} + +Project *MainWindow::findProject( const QString &projectName ) const +{ + for ( QMap<QAction*, Project* >::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( (*it)->projectName() == projectName ) + return *it; + } + return 0; +} + +void MainWindow::setCurrentProject( Project *pro ) +{ + for ( QMap<QAction*, Project* >::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( *it == pro ) { + projectSelected( it.key() ); + return; + } + } +} + +void MainWindow::setCurrentProjectByFilename( const QString& proFilename ) +{ + for ( QMap<QAction*, Project* >::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( (*it)->makeRelative( (*it)->fileName() ) == proFilename ) { + projectSelected( it.key() ); + return; + } + } +} + + +void MainWindow::recentlyFilesMenuActivated( int id ) +{ + if ( id != -1 ) { + if ( !QFile::exists( *recentlyFiles.at( id ) ) ) { + QMessageBox::warning( this, i18n( "Open File" ), + i18n( "Could not open '%1'. File does not exist." ). + arg( *recentlyFiles.at( id ) ) ); + recentlyFiles.remove( recentlyFiles.at( id ) ); + return; + } + fileOpen( "", "", *recentlyFiles.at( id ) ); + QString fn( *recentlyFiles.at( id ) ); + addRecentlyOpened( fn, recentlyFiles ); + } +} + +void MainWindow::recentlyProjectsMenuActivated( int id ) +{ + if ( id != -1 ) { + if ( !QFile::exists( *recentlyProjects.at( id ) ) ) { + QMessageBox::warning( this, i18n( "Open Project" ), + i18n( "Could not open '%1'. File does not exist." ). + arg( *recentlyProjects.at( id ) ) ); + recentlyProjects.remove( recentlyProjects.at( id ) ); + return; + } + openProject( *recentlyProjects.at( id ) ); + QString fn( *recentlyProjects.at( id ) ); + addRecentlyOpened( fn, recentlyProjects ); + } +} + +void MainWindow::addRecentlyOpened( const QString &fn, QStringList &lst ) +{ + QFileInfo fi( fn ); + fi.convertToAbs(); + QString f = fi.filePath(); + if ( lst.find( f ) != lst.end() ) + lst.remove( f ); + if ( lst.count() >= 10 ) + lst.pop_back(); + lst.prepend( f ); +} + +TemplateWizardInterface * MainWindow::templateWizardInterface( const QString& className ) +{ + TemplateWizardInterface* iface = 0; + templateWizardPluginManager->queryInterface( className, & iface ); + return iface; +} + +void MainWindow::setupPluginManagers() +{ + editorPluginManager = new QPluginManager<EditorInterface>( IID_Editor, QApplication::libraryPaths(), "/kdevdesigner" ); + MetaDataBase::setEditor( editorPluginManager->featureList() ); + + templateWizardPluginManager = + new QPluginManager<TemplateWizardInterface>( IID_TemplateWizard, QApplication::libraryPaths(), pluginDirectory() ); + + MetaDataBase::setupInterfaceManagers( "/designer" ); + preferencePluginManager = + new QPluginManager<PreferenceInterface>( IID_Preference, QApplication::libraryPaths(), pluginDirectory() ); + projectSettingsPluginManager = + new QPluginManager<ProjectSettingsInterface>( IID_ProjectSettings, QApplication::libraryPaths(), pluginDirectory() ); + sourceTemplatePluginManager = + new QPluginManager<SourceTemplateInterface>( IID_SourceTemplate, QApplication::libraryPaths(), pluginDirectory() ); + + if ( preferencePluginManager ) { + QStringList lst = preferencePluginManager->featureList(); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + PreferenceInterface *i = 0; + preferencePluginManager->queryInterface( *it, &i ); + if ( !i ) + continue; + i->connectTo( designerInterface() ); + PreferenceInterface::Preference *pf = i->preference(); + if ( pf ) + addPreferencesTab( pf->tab, pf->title, pf->receiver, pf->init_slot, pf->accept_slot ); + i->deletePreferenceObject( pf ); + + i->release(); + } + } + if ( projectSettingsPluginManager ) { + QStringList lst = projectSettingsPluginManager->featureList(); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + ProjectSettingsInterface *i = 0; + projectSettingsPluginManager->queryInterface( *it, &i ); + if ( !i ) + continue; + i->connectTo( designerInterface() ); + + ProjectSettingsInterface::ProjectSettings *pf = i->projectSetting(); + if ( pf ) + addProjectTab( pf->tab, pf->title, pf->receiver, pf->init_slot, pf->accept_slot ); + i->deleteProjectSettingsObject( pf ); + i->release(); + } + } +} + +void MainWindow::addPreferencesTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ) +{ + Tab t; + t.w = tab; + t.title = title; + t.receiver = receiver; + t.init_slot = init_slot; + t.accept_slot = accept_slot; + preferenceTabs << t; +} + +void MainWindow::addProjectTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ) +{ + Tab t; + t.w = tab; + t.title = title; + t.receiver = receiver; + t.init_slot = init_slot; + t.accept_slot = accept_slot; + projectTabs << t; +} + +void MainWindow::setModified( bool b, QWidget *window ) +{ + QWidget *w = window; + while ( w ) { + if ( ::qt_cast<FormWindow*>(w) ) { + ( (FormWindow*)w )->modificationChanged( b ); + return; + } else if ( ::qt_cast<SourceEditor*>(w) ) { + FormWindow *fw = ( (SourceEditor*)w )->formWindow(); + if ( fw && !fw->isFake() ) { + //fw->commandHistory()->setModified( b ); + //fw->modificationChanged( b ); + fw->formFile()->setModified( b, FormFile::WFormCode ); + wspace->update( fw->formFile() ); + } else { + wspace->update(); + } + return; + } + w = w->parentWidget( TRUE ); + } +} + +void MainWindow::editorClosed( SourceEditor *e ) +{ + sourceEditors.take( sourceEditors.findRef( e ) ); +} + +void MainWindow::functionsChanged() +{ + updateFunctionsTimer->start( 0, TRUE ); +} + +void MainWindow::doFunctionsChanged() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->refresh( FALSE ); + hierarchyView->formDefinitionView()->refresh(); +} + +void MainWindow::updateFunctionList() +{ + if ( !qWorkspace()->activeWindow() || !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + SourceEditor *se = (SourceEditor*)qWorkspace()->activeWindow(); + se->save(); + hierarchyView->formDefinitionView()->refresh(); + if ( !currentProject->isCpp() && se->formWindow() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( currentProject->language() ); + if ( !iface ) + return; + QValueList<LanguageInterface::Connection> conns; + iface->connections( se->text(), &conns ); + MetaDataBase::setupConnections( se->formWindow(), conns ); + propertyEditor->eventList()->setup(); + } +} + +void MainWindow::updateWorkspace() +{ + wspace->setCurrentProject( currentProject ); +} + +void MainWindow::showDebugStep( QObject *o, int line ) +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->clearStep(); + if ( !o || line == -1 ) + return; + showSourceLine( o, line, Step ); +} + +void MainWindow::showStackFrame( QObject *o, int line ) +{ + if ( !o || line == -1 ) + return; + showSourceLine( o, line, StackFrame ); +} + +void MainWindow::showErrorMessage( QObject *o, int errorLine, const QString &errorMessage ) +{ + if ( o ) { + errorLine--; // ###### + QValueList<uint> l; + l << ( errorLine + 1 ); + QStringList l2; + l2 << errorMessage; + QObjectList ol; + ol.append( o ); + QStringList ll; + ll << currentProject->locationOfObject( o ); + oWindow->setErrorMessages( l2, l, TRUE, ll, ol ); + showSourceLine( o, errorLine, Error ); + } +} + +void MainWindow::finishedRun() +{ + inDebugMode = FALSE; + previewing = FALSE; + debuggingForms.clear(); + enableAll( TRUE ); + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->project() == currentProject ) + e->editorInterface()->setMode( EditorInterface::Editing ); + e->clearStackFrame(); + } + outputWindow()->clearErrorMessages(); +} + +void MainWindow::enableAll( bool enable ) +{ + menuBar()->setEnabled( enable ); + QObjectList *l = queryList( "QDockWindow" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o == wspace->parentWidget() || + o == oWindow->parentWidget() || + o == hierarchyView->parentWidget() ) + continue; + ( (QWidget*)o )->setEnabled( enable ); + } + delete l; +} + +void MainWindow::showSourceLine( QObject *o, int line, LineMode lm ) +{ + QWidgetList windows = qworkspace->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + FormWindow *fw = 0; + SourceEditor *se = 0; + SourceFile *sf = 0; + if ( ::qt_cast<FormWindow*>(w) ) { + fw = (FormWindow*)w; + } else if ( ::qt_cast<SourceEditor*>(w) ) { + se = (SourceEditor*)w; + if ( !se->object() ) + continue; + if ( se->formWindow() ) + fw = se->formWindow(); + else + sf = se->sourceFile(); + } + + if ( fw ) { + if ( fw->project() != currentProject ) + continue; + if ( qstrcmp( fw->name(), o->name() ) == 0 || + fw->isFake() && currentProject->objectForFakeForm( fw ) == o ) { + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + return; + } else { + fw->showNormal(); + fw->setFocus(); + lastActiveFormWindow = fw; + qApp->processEvents(); + se = editSource(); + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + return; + } + } + } + } else if ( se ) { + if ( o != sf ) + continue; + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + return; + } + } + + if ( ::qt_cast<SourceFile*>(o) ) { + for ( QPtrListIterator<SourceFile> sources = currentProject->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + if ( f == o ) { + SourceEditor *se = editSource( f ); + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + } + return; + } + } + } + + FormFile *ff = currentProject->fakeFormFileFor( o ); + FormWindow *fw = 0; + if ( ff ) + fw = ff->formWindow(); + + if ( !fw && !qwf_forms ) { + qWarning( "MainWindow::showSourceLine: qwf_forms is NULL!" ); + return; + } + + mblockNewForms = TRUE; + if ( !fw ) + openFormWindow( currentProject->makeAbsolute( *qwf_forms->find( (QWidget*)o ) ) ); + else + fw->formFile()->showEditor( FALSE ); + qApp->processEvents(); // give all views the chance to get the formwindow + SourceEditor *se = editSource(); + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + } + mblockNewForms = FALSE; +} + + +QObject *MainWindow::findRealObject( QObject *o ) +{ + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( ::qt_cast<FormWindow*>(w) && QString( w->name() ) == QString( o->name() ) ) + return w; + else if ( ::qt_cast<SourceEditor*>(w) && ( (SourceEditor*)w )->formWindow() && + QString( ( (SourceEditor*)w )->formWindow()->name() ) == QString( o->name() ) ) + return w; + else if ( ::qt_cast<SourceFile*>(w) && ( (SourceEditor*)w )->sourceFile() && + ( (SourceEditor*)w )->sourceFile() == o ) + return o; + } + return 0; +} + +void MainWindow::formNameChanged( FormWindow *fw ) +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->object() == fw ) + e->refresh( TRUE ); + if ( e->project() == fw->project() ) + e->resetContext(); + } +} + +void MainWindow::breakPointsChanged() +{ + if ( !inDebugMode ) + return; + if ( !qWorkspace()->activeWindow() || !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + SourceEditor *e = (SourceEditor*)qWorkspace()->activeWindow(); + if ( !e->object() || !e->project() ) + return; + if ( e->project() != currentProject ) + return; + + if ( !interpreterPluginManager ) { + interpreterPluginManager = + new QPluginManager<InterpreterInterface>( IID_Interpreter, + QApplication::libraryPaths(), + "/qsa" ); + } + + InterpreterInterface *iiface = 0; + if ( interpreterPluginManager ) { + QString lang = currentProject->language(); + iiface = 0; + interpreterPluginManager->queryInterface( lang, &iiface ); + if ( !iiface ) + return; + } + + e->saveBreakPoints(); + + for ( QObject *o = debuggingForms.first(); o; o = debuggingForms.next() ) { + if ( qstrcmp( o->name(), e->object()->name() ) == 0 ) { + iiface->setBreakPoints( o, MetaDataBase::breakPoints( e->object() ) ); + break; + } + } + + for ( e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->project() == currentProject && e->sourceFile() ) { + QValueList<uint> bps = MetaDataBase::breakPoints( e->sourceFile() ); + iiface->setBreakPoints( e->object(), bps ); + } + } + + iiface->release(); +} + +int MainWindow::currentLayoutDefaultSpacing() const +{ + if ( ( (MainWindow*)this )->formWindow() ) + return ( (MainWindow*)this )->formWindow()->layoutDefaultSpacing(); + return BOXLAYOUT_DEFAULT_SPACING; +} + +int MainWindow::currentLayoutDefaultMargin() const +{ + if ( ( (MainWindow*)this )->formWindow() ) + return ( (MainWindow*)this )->formWindow()->layoutDefaultMargin(); + return BOXLAYOUT_DEFAULT_MARGIN; +} + +void MainWindow::saveAllBreakPoints() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + e->save(); + e->saveBreakPoints(); + } +} + +void MainWindow::resetBreakPoints() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->resetBreakPoints(); +} + +SourceFile *MainWindow::sourceFile() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( qworkspace->activeWindow() == e ) { + if ( e->sourceFile() ) + return e->sourceFile(); + } + } + return 0; +} + +bool MainWindow::openProjectSettings( Project *pro ) +{ + ProjectSettings dia( pro, this, 0, TRUE ); + SenderObject *senderObject = new SenderObject( designerInterface() ); + QValueList<Tab>::ConstIterator it; + for ( it = projectTabs.begin(); it != projectTabs.end(); ++it ) { + Tab t = *it; + if ( t.title != pro->language() ) + continue; + dia.tabWidget->addTab( t.w, t.title ); + if ( t.receiver ) { + connect( dia.buttonOk, SIGNAL( clicked() ), senderObject, SLOT( emitAcceptSignal() ) ); + connect( senderObject, SIGNAL( acceptSignal( QUnknownInterface * ) ), t.receiver, t.accept_slot ); + connect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + senderObject->emitInitSignal(); + disconnect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + } + } + + if ( singleProject ) + dia.tabWidget->setTabEnabled( dia.tabSettings, FALSE ); + + int res = dia.exec(); + + delete senderObject; + + for ( it = projectTabs.begin(); it != projectTabs.end(); ++it ) { + Tab t = *it; + dia.tabWidget->removePage( t.w ); + t.w->reparent( 0, QPoint(0,0), FALSE ); + } + + return res == QDialog::Accepted; +} + +void MainWindow::popupProjectMenu( const QPoint &pos ) +{ + projectMenu->exec( pos ); +} + +QStringList MainWindow::sourceTemplates() const +{ + return sourceTemplatePluginManager->featureList(); +} + +SourceTemplateInterface* MainWindow::sourceTemplateInterface( const QString& templ ) +{ + SourceTemplateInterface *iface = 0; + sourceTemplatePluginManager->queryInterface( templ, &iface); + return iface; +} + +QString MainWindow::whatsThisFrom( const QString &key ) +{ + if ( menuHelpFile.isEmpty() ) { + QString fn( documentationPath() ); + fn += "/designer-manual-11.html"; + QFile f( fn ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + menuHelpFile = ts.read(); + } + } + + int i = menuHelpFile.find( key ); + if ( i == -1 ) + return QString::null; + int start = i; + int end = i; + start = menuHelpFile.findRev( "<li>", i ) + 4; + end = menuHelpFile.find( '\n', i ) - 1; + return menuHelpFile.mid( start, end - start + 1 ); +} + +void MainWindow::setSingleProject( Project *pro ) +{ + if ( eProject ) { + Project *pro = eProject; + pro->save(); + QWidgetList windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( TRUE ); + QWidgetListIt wit( windows ); + while ( wit.current() ) { + QWidget *w = wit.current(); + ++wit; + if ( ::qt_cast<FormWindow*>(w) ) { + if ( ( (FormWindow*)w )->project() == pro ) { + if ( ( (FormWindow*)w )->formFile()->editor() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->editor() ); + ( (FormWindow*)w )->formFile()->close(); + } + } else if ( ::qt_cast<SourceEditor*>(w) ) { + ( (SourceEditor*)w )->close(); + } + } + hierarchyView->clear(); + windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( FALSE ); + currentProject = 0; + updateUndoRedo( FALSE, FALSE, QString::null, QString::null ); + } + + singleProject = TRUE; + projects.clear(); + QAction *a = new QAction( i18n( pro->name() ), i18n( pro->name() ), 0, + actionGroupProjects, 0, TRUE ); + eProject = pro; + projects.insert( a, eProject ); + a->setOn( TRUE ); + actionGroupProjects->removeFrom( projectMenu ); + actionGroupProjects->removeFrom( projectToolBar ); + currentProject = eProject; + currentProject->designerCreated(); +} + +void MainWindow::shuttingDown() +{ + outputWindow()->shuttingDown(); +} + +void MainWindow::showGUIStuff( bool b ) +{ + if ( (bool)guiStuffVisible == b ) + return; + guiStuffVisible = b; + if ( !b ) { + setAppropriate( (QDockWindow*)toolBox->parentWidget(), FALSE ); + toolBox->parentWidget()->hide(); + for ( QToolBar *tb = widgetToolBars.first(); tb; tb = widgetToolBars.next() ) { + tb->hide(); + setAppropriate( tb, FALSE ); + } + propertyEditor->setPropertyEditorEnabled( FALSE ); + setAppropriate( layoutToolBar, FALSE ); + layoutToolBar->hide(); + setAppropriate( toolsToolBar, FALSE ); + toolsToolBar->hide(); + menubar->removeItem( toolsMenuId ); + menubar->removeItem( toolsMenuId + 1 ); + menubar->removeItem( toolsMenuId + 2 ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditAccels, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditFunctions, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditConnections, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditSource, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditFormSettings, SLOT( setEnabled(bool) ) ); + actionEditFormSettings->setEnabled( FALSE ); + actionEditSource->setEnabled( FALSE ); + actionEditConnections->setEnabled( FALSE ); + actionEditFunctions->setEnabled( FALSE ); + actionEditAccels->setEnabled( FALSE ); + ( (QDockWindow*)propertyEditor->parentWidget() )-> + setCaption( i18n( "Signal Handlers" ) ); + actionGroupNew->removeFrom( fileMenu ); + actionGroupNew->removeFrom( projectToolBar ); + actionFileSave->removeFrom( fileMenu ); + actionFileSave->removeFrom( projectToolBar ); + actionFileExit->removeFrom( fileMenu ); + actionNewFile->addTo( fileMenu ); + actionNewFile->addTo( projectToolBar ); + actionFileSave->addTo( fileMenu ); + actionFileSave->addTo( projectToolBar ); + actionFileExit->addTo( fileMenu ); + } else { + setAppropriate( (QDockWindow*)toolBox->parentWidget(), TRUE ); + toolBox->parentWidget()->show(); + for ( QToolBar *tb = widgetToolBars.first(); tb; tb = widgetToolBars.next() ) { + setAppropriate( tb, TRUE ); + tb->hide(); + } + propertyEditor->setPropertyEditorEnabled( TRUE ); + setAppropriate( layoutToolBar, TRUE ); + layoutToolBar->show(); + setAppropriate( toolsToolBar, TRUE ); + toolsToolBar->show(); + menubar->insertItem( i18n( "&Tools" ), toolsMenu, toolsMenuId, toolsMenuIndex ); + menubar->insertItem( i18n( "&Layout" ), layoutMenu, toolsMenuId + 1, toolsMenuIndex + 1 ); + menubar->insertItem( i18n( "&Preview" ), previewMenu, toolsMenuId + 2, toolsMenuIndex + 2 ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditAccels, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFunctions, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditConnections, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditSource, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFormSettings, SLOT( setEnabled(bool) ) ); + actionEditFormSettings->setEnabled( TRUE ); + actionEditSource->setEnabled( TRUE ); + actionEditConnections->setEnabled( TRUE ); + actionEditFunctions->setEnabled( TRUE ); + actionEditAccels->setEnabled( TRUE ); + ( (QDockWindow*)propertyEditor->parentWidget() )-> + setCaption( i18n( "Property Editor/Signal Handlers" ) ); + actionFileSave->removeFrom( fileMenu ); + actionFileSave->removeFrom( projectToolBar ); + actionFileExit->removeFrom( fileMenu ); + actionGroupNew->addTo( fileMenu ); + actionGroupNew->addTo( projectToolBar ); + actionFileSave->addTo( fileMenu ); + actionFileSave->addTo( projectToolBar ); + actionFileExit->addTo( fileMenu ); + } +} + +void MainWindow::setEditorsReadOnly( bool b ) +{ + editorsReadOnly = b; +} + +void MainWindow::setPluginDirectory( const QString &pd ) +{ + pluginDir = pd; + if ( !qwf_plugin_dir ) + qwf_plugin_dir = new QString( pd ); + else + *qwf_plugin_dir = pd; +} + +void MainWindow::toggleSignalHandlers( bool show ) +{ + if ( sSignalHandlers == show ) + return; + sSignalHandlers = show; + propertyEditor->setSignalHandlersEnabled( show ); +} + +void MainWindow::statusMessage( const QString &msg ) +{ + m_part->statusMessage(msg); +} diff --git a/kdevdesigner/designer/mainwindow.h b/kdevdesigner/designer/mainwindow.h new file mode 100644 index 00000000..43a4974a --- /dev/null +++ b/kdevdesigner/designer/mainwindow.h @@ -0,0 +1,511 @@ +/********************************************************************** +** 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 MAINWINDOW_H +#define MAINWINDOW_H + +#include "metadatabase.h" +#include "../interfaces/actioninterface.h" // for GCC 2.7.* compatibility +#include "../interfaces/editorinterface.h" +#include "../interfaces/templatewizardiface.h" +#include "../interfaces/languageinterface.h" +#include "../interfaces/filterinterface.h" +#include "../interfaces/interpreterinterface.h" +#include "../interfaces/preferenceinterface.h" +#include "../interfaces/projectsettingsiface.h" +#include "../interfaces/sourcetemplateiface.h" +#include "sourceeditor.h" + +#include <qaction.h> +#include <qmainwindow.h> +#include <qmap.h> +#include <qguardedptr.h> +#include <private/qpluginmanager_p.h> +#include <qobjectlist.h> + +class QToolBox; +class PropertyEditor; +class QWorkspace; +class QMenuBar; +class FormWindow; +class QPopupMenu; +class HierarchyView; +class QCloseEvent; +class Workspace; +class ActionEditor; +class Project; +class OutputWindow; +class QTimer; +class FindDialog; +struct DesignerProject; +class ReplaceDialog; +class GotoLineDialog; +class SourceFile; +class FormFile; +class QAssistantClient; +class DesignerAction; + +#if defined(Q_FULL_TEMPLATE_INSTANTIATION) +#include <qtoolbar.h> +#else +class QToolBar; +#endif +class Preferences; + +class KDevDesignerPart; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + enum LineMode { Error, Step, StackFrame }; + + MainWindow( KDevDesignerPart *part, bool asClient, bool single = FALSE, const QString &plgDir = "/designer" ); + ~MainWindow(); + + HierarchyView *objectHierarchy() const; + Workspace *workspace() const; + PropertyEditor *propertyeditor() const; + ActionEditor *actioneditor() const; + + void resetTool(); + int currentTool() const; + + FormWindow *formWindow(); + + bool unregisterClient( FormWindow *w ); + void editorClosed( SourceEditor *e ); + QWidget *isAFormWindowChild( QObject *o ) const; + QWidget *isAToolBarChild( QObject *o ) const; + + void insertFormWindow( FormWindow *fw ); + QWorkspace *qWorkspace() const; + + void popupFormWindowMenu( const QPoint &gp, FormWindow *fw ); + void popupWidgetMenu( const QPoint &gp, FormWindow *fw, QWidget *w ); + + QPopupMenu *setupNormalHierarchyMenu( QWidget *parent ); + QPopupMenu *setupTabWidgetHierarchyMenu( QWidget *parent, const char *addSlot, const char *removeSlot ); + + FormWindow *openFormWindow( const QString &fn, bool validFileName = TRUE, FormFile *ff = 0 ); + bool isCustomWidgetUsed( MetaDataBase::CustomWidget *w ); + + void setGrid( const QPoint &p ); + void setShowGrid( bool b ); + void setSnapGrid( bool b ); + QPoint grid() const { return grd; } + bool showGrid() const { return sGrid; } + bool snapGrid() const { return snGrid && sGrid; } + + QString documentationPath() const; + + static MainWindow *self; + + QString templatePath() const { return templPath; } + + void editFunction( const QString &func, bool rereadSource = FALSE ); + + bool isPreviewing() const { return previewing; } + + Project *currProject() const { return currentProject; } + + FormWindow *activeForm() const { return lastActiveFormWindow; } + + TemplateWizardInterface* templateWizardInterface( const QString& className ); + QStringList sourceTemplates() const; + SourceTemplateInterface* sourceTemplateInterface( const QString& templ ); + QUnknownInterface* designerInterface() const { return desInterface; } + QPtrList<DesignerProject> projectList() const; + QStringList projectNames() const; + QStringList projectFileNames() const; + Project *findProject( const QString &projectName ) const; + void setCurrentProject( Project *pro ); + void setCurrentProjectByFilename( const QString& proFilename ); + OutputWindow *outputWindow() const { return oWindow; } + void addPreferencesTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ); + void addProjectTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ); + void setModified( bool b, QWidget *window ); + void functionsChanged(); + void updateFunctionList(); + void updateWorkspace(); + void runProjectPrecondition(); + void runProjectPostcondition( QObjectList *l ); + + void formNameChanged( FormWindow *fw ); + + int currentLayoutDefaultSpacing() const; + int currentLayoutDefaultMargin() const; + + void saveAllBreakPoints(); + void resetBreakPoints(); + + SourceFile *sourceFile(); + void createNewProject( const QString &lang ); + + void popupProjectMenu( const QPoint &pos ); + QObject *findRealObject( QObject *o ); + + void setSingleProject( Project *pro ); + bool singleProjectMode() const { return singleProject; } + + void showSourceLine( QObject *o, int line, LineMode lm ); + + void shuttingDown(); + void showGUIStuff( bool b ); + void setEditorsReadOnly( bool b ); + bool areEditorsReadOnly() const { return editorsReadOnly; } + void toggleSignalHandlers( bool show ); + bool showSignalHandlers() const { return sSignalHandlers; } + void writeConfig(); + + void openProject( const QString &fn ); + void setPluginDirectory( const QString &pd ); + QString pluginDirectory() const { return pluginDir; } + + QAssistantClient* assistantClient() const { return assistant; } + + void addRecentlyOpenedFile( const QString &fn ) { addRecentlyOpened( fn, recentlyFiles ); } + + void statusMessage(const QString &msg); + + //integration + KDevDesignerPart *part() const { return m_part; } + +public slots: + void showProperties( QObject *w ); + void updateProperties( QObject *w ); + void showDialogHelp(); + void showDebugStep( QObject *o, int line ); + void showStackFrame( QObject *o, int line ); + void showErrorMessage( QObject *o, int line, const QString &errorMessage ); + void finishedRun(); + void breakPointsChanged(); + +signals: + void currentToolChanged(); + void hasActiveForm( bool ); + void hasActiveWindow( bool ); + void hasActiveWindowOrProject( bool ); + void hasNonDummyProject( bool ); + void formModified( bool ); + void formWindowsChanged(); + void formWindowChanged(); + void projectChanged(); + void editorChanged(); + +protected: + bool eventFilter( QObject *o, QEvent *e ); + void closeEvent( QCloseEvent *e ); + +public slots: + void fileNew(); + void fileNewDialog(); + void fileNewFile(); + void fileClose(); + void fileQuit(); + void fileCloseProject(); // not visible in menu, called from fileClose + void fileOpen(); + void fileOpen( const QString &filter, const QString &extension, const QString &filename = "" , bool inProject = TRUE ); + bool fileSave(); + bool fileSaveForm(); // not visible in menu, called from fileSave + bool fileSaveProject(); // not visible in menu, called from fileSaveProject + bool fileSaveAs(); + void fileSaveAll(); + void fileCreateTemplate(); + +public slots: + void editUndo(); + void editRedo(); + void editCut(); + void editCopy(); + void editPaste(); + void editDelete(); + void editSelectAll(); + void editLower(); + void editRaise(); + void editAdjustSize(); + void editLayoutHorizontal(); + void editLayoutVertical(); + void editLayoutHorizontalSplit(); + void editLayoutVerticalSplit(); + void editLayoutGrid(); + void editLayoutContainerHorizontal(); + void editLayoutContainerVertical(); + void editLayoutContainerGrid(); + void editBreakLayout(); + void editAccels(); + void editFunctions(); + void editConnections(); + SourceEditor *editSource(); + SourceEditor *editSource( SourceFile *f ); + SourceEditor *openSourceEditor(); + SourceEditor *createSourceEditor( QObject *object, Project *project, + const QString &lang = QString::null, + const QString &func = QString::null, + bool rereadSource = FALSE ); + void editFormSettings(); + void editProjectSettings(); + void editPixmapCollection(); + void editDatabaseConnections(); + void editPreferences(); + + void projectInsertFile(); + + void searchFind(); + void searchIncremetalFindMenu(); + void searchIncremetalFind(); + void searchIncremetalFindNext(); + void searchReplace(); + void searchGotoLine(); + + void previewForm(); + void previewForm( const QString& ); + + void toolsCustomWidget(); + void toolsConfigure(); + + void helpContents(); + void helpManual(); + void helpAbout(); + void helpAboutQt(); + void helpRegister(); + +private slots: + void activeWindowChanged( QWidget *w ); + void updateUndoRedo( bool, bool, const QString &, const QString & ); + void updateEditorUndoRedo(); + + void toolSelected( QAction* ); + + void clipboardChanged(); + void selectionChanged(); + + void windowsMenuActivated( int id ); + void setupWindowActions(); + + void createNewTemplate(); + void projectSelected( QAction *a ); + + void setupRecentlyFilesMenu(); + void setupRecentlyProjectsMenu(); + void recentlyFilesMenuActivated( int id ); + void recentlyProjectsMenuActivated( int id ); + + void emitProjectSignals(); + + void showStartDialog(); + +private: + void setupMDI(); + void setupMenuBar(); + void setupEditActions(); + void setupProjectActions(); + void setupSearchActions(); + void setupToolActions(); + void setupLayoutActions(); + void setupFileActions(); + void setupPreviewActions(); + void setupHelpActions(); + void setupRMBMenus(); + + void setupPropertyEditor(); + void setupHierarchyView(); + void setupWorkspace(); + void setupActionEditor(); + void setupOutputWindow(); + void setupToolbox(); + + void setupActionManager(); + void setupPluginManagers(); + + void enableAll( bool enable ); + + QWidget* previewFormInternal( QStyle* style = 0, QPalette* pal = 0 ); + + void readConfig(); + + void setupRMBProperties( QValueList<uint> &ids, QMap<QString, int> &props, QWidget *w ); + void handleRMBProperties( int id, QMap<QString, int> &props, QWidget *w ); + void setupRMBSpecialCommands( QValueList<uint> &ids, QMap<QString, int> &commands, QWidget *w ); + void handleRMBSpecialCommands( int id, QMap<QString, int> &commands, QWidget *w ); + void setupRMBSpecialCommands( QValueList<uint> &ids, QMap<QString, int> &commands, FormWindow *w ); + void handleRMBSpecialCommands( int id, QMap<QString, int> &commands, FormWindow *w ); + bool openEditor( QWidget *w, FormWindow *fw ); + void rebuildCustomWidgetGUI(); + void rebuildCommonWidgetsToolBoxPage(); + void checkTempFiles(); + + void addRecentlyOpened( const QString &fn, QStringList &lst ); + + QString whatsThisFrom( const QString &key ); + +private slots: + void doFunctionsChanged(); + bool openProjectSettings( Project *pro ); + +private: + struct Tab + { + QWidget *w; + QString title; + QObject *receiver; + const char *init_slot, *accept_slot; + Q_DUMMY_COMPARISON_OPERATOR( Tab ) + }; + +private: + PropertyEditor *propertyEditor; + HierarchyView *hierarchyView; + Workspace *wspace; + QWidget *lastPressWidget; + QWorkspace *qworkspace; + QMenuBar *menubar; + QGuardedPtr<FormWindow> lastActiveFormWindow; + bool breakLayout, layoutChilds, layoutSelected; + QPoint grd; + bool sGrid, snGrid; + bool restoreConfig; + bool backPix; + bool splashScreen; + QString fileFilter; + + QMap<QAction*, Project*> projects; + DesignerAction *actionEditUndo, *actionEditRedo, *actionEditCut, *actionEditCopy, + *actionEditPaste, *actionEditDelete, + *actionEditAdjustSize, + *actionEditHLayout, *actionEditVLayout, *actionEditGridLayout, + *actionEditSplitHorizontal, *actionEditSplitVertical, + *actionEditSelectAll, *actionEditBreakLayout, *actionEditFunctions, *actionEditConnections, + *actionEditLower, *actionEditRaise; + QAction *actionInsertSpacer; + QActionGroup *actionGroupTools, *actionGroupProjects; + QAction* actionPointerTool, *actionConnectTool, *actionOrderTool, *actionBuddyTool; + QAction* actionCurrentTool; + DesignerAction *actionHelpContents, *actionHelpAbout, *actionHelpAboutQt, *actionHelpWhatsThis; + DesignerAction *actionHelpManual; +#if defined(QT_NON_COMMERCIAL) + DesignerAction *actionHelpRegister; +#endif + DesignerAction *actionToolsCustomWidget, *actionEditPreferences; + DesignerAction *actionWindowTile, *actionWindowCascade, *actionWindowClose, *actionWindowCloseAll; + DesignerAction *actionWindowNext, *actionWindowPrevious; + DesignerAction *actionEditFormSettings, *actionEditAccels; + DesignerAction *actionEditSource, *actionNewFile, *actionFileSave, *actionFileExit; + DesignerAction *actionFileClose, *actionFileSaveAs, *actionFileSaveAll; + DesignerAction *actionSearchFind, *actionSearchIncremetal, *actionSearchReplace, *actionSearchGotoLine; + DesignerAction *actionProjectAddFile, *actionEditPixmapCollection, *actionEditDatabaseConnections, + *actionEditProjectSettings, *actionPreview; + QActionGroup *actionGroupNew; + + QPopupMenu *rmbWidgets; + QPopupMenu *rmbFormWindow; + QPopupMenu *customWidgetMenu, *windowMenu, *fileMenu, *recentlyFilesMenu, *recentlyProjectsMenu; + QPopupMenu *toolsMenu, *layoutMenu, *previewMenu; + QToolBar *customWidgetToolBar, *layoutToolBar, *projectToolBar, *customWidgetToolBar2, *toolsToolBar; + QToolBar *commonWidgetsToolBar; + QPtrList<QToolBar> widgetToolBars; + + Preferences *prefDia; + QMap<QString,QString> propertyDocumentation; + bool client; + QString templPath; + ActionEditor *actionEditor; + Project *currentProject; + QPluginManager<ActionInterface> *actionPluginManager; + QPluginManager<EditorInterface> *editorPluginManager; + QPluginManager<TemplateWizardInterface> *templateWizardPluginManager; + QPluginManager<InterpreterInterface> *interpreterPluginManager; + QPluginManager<PreferenceInterface> *preferencePluginManager; + QPluginManager<ProjectSettingsInterface> *projectSettingsPluginManager; + QPluginManager<SourceTemplateInterface> *sourceTemplatePluginManager; + QPtrList<SourceEditor> sourceEditors; + bool previewing; + QUnknownInterface *desInterface; + QStringList recentlyFiles; + QStringList recentlyProjects; + OutputWindow *oWindow; + QValueList<Tab> preferenceTabs; + QValueList<Tab> projectTabs; + bool databaseAutoEdit; + QTimer *updateFunctionsTimer; + QTimer *autoSaveTimer; + bool autoSaveEnabled; + int autoSaveInterval; + QLineEdit *incrementalSearch; + QGuardedPtr<FindDialog> findDialog; + QGuardedPtr<ReplaceDialog> replaceDialog; + QGuardedPtr<GotoLineDialog> gotoLineDialog; + Project *eProject; + bool inDebugMode; + QObjectList debuggingForms; + QString lastOpenFilter; + QGuardedPtr<QWidget> previewedForm; + QPopupMenu *projectMenu; + QString menuHelpFile; + bool singleProject; + QToolBox *toolBox; + int toolsMenuId, toolsMenuIndex; + uint guiStuffVisible : 1; + uint editorsReadOnly : 1; + uint savePluginPaths : 1; + QAssistantClient *assistant; + bool shStartDialog; + QString pluginDir; + bool sSignalHandlers; + + KDevDesignerPart *m_part; + +public: + QString lastSaveFilter; + QPtrList<QAction> toolActions; + QPtrList<QAction> commonWidgetsPage; + +friend class KDevDesignerPart; +}; + +class SenderObject : public QObject +{ + Q_OBJECT + +public: + SenderObject( QUnknownInterface *i ) : iface( i ) { iface->addRef(); } + ~SenderObject() { iface->release(); } + +public slots: + void emitInitSignal() { emit initSignal( iface ); } + void emitAcceptSignal() { emit acceptSignal( iface ); } + +signals: + void initSignal( QUnknownInterface * ); + void acceptSignal( QUnknownInterface * ); + +private: + QUnknownInterface *iface; + +}; + +#endif diff --git a/kdevdesigner/designer/mainwindowactions.cpp b/kdevdesigner/designer/mainwindowactions.cpp new file mode 100644 index 00000000..d6ed0982 --- /dev/null +++ b/kdevdesigner/designer/mainwindowactions.cpp @@ -0,0 +1,2067 @@ +/********************************************************************** +** 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. +** +** 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 "mainwindow.h" + +#include <kiconloader.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <klineedit.h> + +#include <stdlib.h> +#include <qaction.h> +#include <qwhatsthis.h> +#include <qpopupmenu.h> +#include <qmenubar.h> +#include <qtooltip.h> +#include <qapplication.h> +#include <qsignalmapper.h> +#include <qstylefactory.h> +#include <qworkspace.h> +#include <qmessagebox.h> +#include <qstatusbar.h> +#include <qlistbox.h> +#include <qclipboard.h> +#include <qcombobox.h> +#include <qspinbox.h> +#include <qinputdialog.h> +#include <qdatetimeedit.h> +#include <qtextedit.h> + +#include "defs.h" +#include "project.h" +#include "widgetdatabase.h" +#include "widgetfactory.h" +#include "preferences.h" +#include "formwindow.h" +#include "newformimpl.h" +#include "resource.h" +#include "projectsettingsimpl.h" +#include "workspace.h" +#include "createtemplate.h" +#include "hierarchyview.h" +#include "editfunctionsimpl.h" +#include "finddialog.h" +#include "replacedialog.h" +#include "gotolinedialog.h" +#include "formsettingsimpl.h" +#include "pixmapcollectioneditor.h" +#include "styledbutton.h" +#include "customwidgeteditorimpl.h" +#ifndef QT_NO_SQL +#include "dbconnectionsimpl.h" +#include "dbconnectionimpl.h" +#endif +#include "widgetaction.h" +#include <qtoolbox.h> +#include "startdialogimpl.h" +#include "designerappiface.h" +#include "connectiondialog.h" +#include "configtoolboxdialog.h" +#include "designeraction.h" + +#include "kdevdesigner_part.h" + +static const char * whatsthis_image[] = { + "16 16 3 1", + " c None", + "o c #000000", + "a c #000080", + "o aaaaa ", + "oo aaa aaa ", + "ooo aaa aaa", + "oooo aa aa", + "ooooo aa aa", + "oooooo a aaa", + "ooooooo aaa ", + "oooooooo aaa ", + "ooooooooo aaa ", + "ooooo aaa ", + "oo ooo ", + "o ooo aaa ", + " ooo aaa ", + " ooo ", + " ooo ", + " ooo "}; + +const QString toolbarHelp = "<p>Toolbars contain a number of buttons to " +"provide quick access to often used functions.%1" +"<br>Click on the toolbar handle to hide the toolbar, " +"or drag and place the toolbar to a different location.</p>"; + +static QIconSet createIconSet( const QString &name ) +{ + QIconSet ic( BarIcon( "" + name, KDevDesignerPartFactory::instance() ) ); + QString prefix = "designer_"; + int right = name.length() - prefix.length(); + ic.setPixmap( BarIcon( prefix + "d_" + name.right( right ), KDevDesignerPartFactory::instance() ), + QIconSet::Small, QIconSet::Disabled ); + return ic; +} + +void MainWindow::setupEditActions() +{ + actionEditUndo = new DesignerAction( i18n("Undo"), createIconSet( "designer_undo.png" ),i18n("&Undo: Not Available"), CTRL + Key_Z, this, 0 ); + actionEditUndo->setStatusTip( i18n( "Undoes the last action" ) ); + actionEditUndo->setWhatsThis( whatsThisFrom( "Edit|Undo" ) ); + connect( actionEditUndo, SIGNAL( activated() ), this, SLOT( editUndo() ) ); + actionEditUndo->setEnabled( FALSE ); + + actionEditRedo = new DesignerAction( i18n( "Redo" ), createIconSet("designer_redo.png"), i18n( "&Redo: Not Available" ), CTRL + Key_Y, this, 0 ); + actionEditRedo->setStatusTip( i18n( "Redoes the last undone operation") ); + actionEditRedo->setWhatsThis( whatsThisFrom( "Edit|Redo" ) ); + connect( actionEditRedo, SIGNAL( activated() ), this, SLOT( editRedo() ) ); + actionEditRedo->setEnabled( FALSE ); + + actionEditCut = new DesignerAction( i18n( "Cut" ), createIconSet("designer_editcut.png"), i18n( "Cu&t" ), CTRL + Key_X, this, 0 ); + actionEditCut->setStatusTip( i18n( "Cuts the selected widgets and puts them on the clipboard" ) ); + actionEditCut->setWhatsThis( whatsThisFrom( "Edit|Cut" ) ); + connect( actionEditCut, SIGNAL( activated() ), this, SLOT( editCut() ) ); + actionEditCut->setEnabled( FALSE ); + + actionEditCopy = new DesignerAction( i18n( "Copy" ), createIconSet("designer_editcopy.png"), i18n( "&Copy" ), CTRL + Key_C, this, 0 ); + actionEditCopy->setStatusTip( i18n( "Copies the selected widgets to the clipboard" ) ); + actionEditCopy->setWhatsThis( whatsThisFrom( "Edit|Copy" ) ); + connect( actionEditCopy, SIGNAL( activated() ), this, SLOT( editCopy() ) ); + actionEditCopy->setEnabled( FALSE ); + + actionEditPaste = new DesignerAction( i18n( "Paste" ), createIconSet("designer_editpaste.png"), i18n( "&Paste" ), CTRL + Key_V, this, 0 ); + actionEditPaste->setStatusTip( i18n( "Pastes the clipboard's contents" ) ); + actionEditPaste->setWhatsThis( whatsThisFrom( "Edit|Paste" ) ); + connect( actionEditPaste, SIGNAL( activated() ), this, SLOT( editPaste() ) ); + actionEditPaste->setEnabled( FALSE ); + + actionEditDelete = new DesignerAction( i18n( "Delete" ), QPixmap(), i18n( "&Delete" ), Key_Delete, this, 0 ); + actionEditDelete->setStatusTip( i18n( "Deletes the selected widgets" ) ); + actionEditDelete->setWhatsThis( whatsThisFrom( "Edit|Delete" ) ); + connect( actionEditDelete, SIGNAL( activated() ), this, SLOT( editDelete() ) ); + actionEditDelete->setEnabled( FALSE ); +#ifdef Q_WS_MAC + QAction *macDelete = new DesignerAction( i18n( "Delete" ), QPixmap(), i18n( "&Delete" ), Key_Backspace, this, 0 ); + connect( macDelete, SIGNAL( activated() ), this, SLOT( editDelete() ) ); +#endif + + actionEditSelectAll = new DesignerAction( i18n( "Select All" ), QPixmap(), i18n( "Select &All" ), CTRL + Key_A, this, 0 ); + actionEditSelectAll->setStatusTip( i18n( "Selects all widgets" ) ); + actionEditSelectAll->setWhatsThis( whatsThisFrom( "Edit|Select All" ) ); + connect( actionEditSelectAll, SIGNAL( activated() ), this, SLOT( editSelectAll() ) ); + actionEditSelectAll->setEnabled( TRUE ); + + actionEditRaise = new DesignerAction( i18n( "Bring to Front" ), createIconSet("designer_editraise.png"), i18n( "Bring to &Front" ), 0, this, 0 ); + actionEditRaise->setStatusTip( i18n( "Raises the selected widgets" ) ); + actionEditRaise->setWhatsThis( i18n( "Raises the selected widgets" ) ); + connect( actionEditRaise, SIGNAL( activated() ), this, SLOT( editRaise() ) ); + actionEditRaise->setEnabled( FALSE ); + + actionEditLower = new DesignerAction( i18n( "Send to Back" ), createIconSet("designer_editlower.png"), i18n( "Send to &Back" ), 0, this, 0 ); + actionEditLower->setStatusTip( i18n( "Lowers the selected widgets" ) ); + actionEditLower->setWhatsThis( i18n( "Lowers the selected widgets" ) ); + connect( actionEditLower, SIGNAL( activated() ), this, SLOT( editLower() ) ); + actionEditLower->setEnabled( FALSE ); + + actionEditAccels = new DesignerAction( i18n( "Check Accelerators" ), QPixmap(), + i18n( "Chec&k Accelerators" ), ALT + Key_R, this, 0 ); + actionEditAccels->setStatusTip( i18n("Checks if the accelerators used in the form are unique") ); + actionEditAccels->setWhatsThis( whatsThisFrom( "Edit|Check Accelerator" ) ); + connect( actionEditAccels, SIGNAL( activated() ), this, SLOT( editAccels() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditAccels, SLOT( setEnabled(bool) ) ); + + actionEditFunctions = new DesignerAction( i18n( "Slots" ), createIconSet("designer_editslots.png"), + i18n( "S&lots..." ), 0, this, 0 ); + actionEditFunctions->setStatusTip( i18n("Opens a dialog for editing slots") ); + actionEditFunctions->setWhatsThis( whatsThisFrom( "Edit|Slots" ) ); + connect( actionEditFunctions, SIGNAL( activated() ), this, SLOT( editFunctions() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFunctions, SLOT( setEnabled(bool) ) ); + + actionEditConnections = new DesignerAction( i18n( "Connections" ), createIconSet("designer_connecttool.png"), + i18n( "Co&nnections..." ), 0, this, 0 ); + actionEditConnections->setStatusTip( i18n("Opens a dialog for editing connections") ); + actionEditConnections->setWhatsThis( whatsThisFrom( "Edit|Connections" ) ); + connect( actionEditConnections, SIGNAL( activated() ), this, SLOT( editConnections() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditConnections, SLOT( setEnabled(bool) ) ); + + actionEditSource = new DesignerAction( i18n( "Source" ), QIconSet(), + i18n( "&Source..." ), CTRL + Key_E, this, 0 ); + actionEditSource->setStatusTip( i18n("Opens an editor to edit the form's source code") ); + actionEditSource->setWhatsThis( whatsThisFrom( "Edit|Source" ) ); + connect( actionEditSource, SIGNAL( activated() ), this, SLOT( editSource() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditSource, SLOT( setEnabled(bool) ) ); + + actionEditFormSettings = new DesignerAction( i18n( "Form Settings" ), QPixmap(), + i18n( "&Form Settings..." ), 0, this, 0 ); + actionEditFormSettings->setStatusTip( i18n("Opens a dialog to change the form's settings") ); + actionEditFormSettings->setWhatsThis( whatsThisFrom( "Edit|Form Settings" ) ); + connect( actionEditFormSettings, SIGNAL( activated() ), this, SLOT( editFormSettings() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFormSettings, SLOT( setEnabled(bool) ) ); + + actionEditPreferences = new DesignerAction( i18n( "Preferences" ), QPixmap(), + i18n( "Preferences..." ), 0, this, 0 ); + actionEditPreferences->setStatusTip( i18n("Opens a dialog to change preferences") ); + actionEditPreferences->setWhatsThis( whatsThisFrom( "Edit|Preferences" ) ); + connect( actionEditPreferences, SIGNAL( activated() ), this, SLOT( editPreferences() ) ); + +/* QToolBar *tb = new QToolBar( this, "Edit" ); + tb->setCloseMode( QDockWindow::Undocked ); + QWhatsThis::add( tb, i18n( "<b>The Edit toolbar</b>%1").arg(i18n(toolbarHelp).arg("")) ); + addToolBar( tb, i18n( "Edit" ) ); + actionEditUndo->addTo( tb ); + actionEditRedo->addTo( tb ); + tb->addSeparator(); + actionEditCut->addTo( tb ); + actionEditCopy->addTo( tb ); + actionEditPaste->addTo( tb );*/ +#if 0 + tb->addSeparator(); + actionEditLower->addTo( tb ); + actionEditRaise->addTo( tb ); +#endif + + QPopupMenu *menu = new QPopupMenu( this, "Edit" ); + connect( menu, SIGNAL( aboutToShow() ), this, SLOT( updateEditorUndoRedo() ) ); + menubar->insertItem( i18n( "&Edit" ), menu ); + actionEditUndo->addTo( menu ); + actionEditRedo->addTo( menu ); + menu->insertSeparator(); + actionEditCut->addTo( menu ); + actionEditCopy->addTo( menu ); + actionEditPaste->addTo( menu ); + actionEditDelete->addTo( menu ); + actionEditSelectAll->addTo( menu ); + actionEditAccels->addTo( menu ); +#if 0 + menu->insertSeparator(); + actionEditLower->addTo( menu ); + actionEditRaise->addTo( menu ); +#endif + menu->insertSeparator(); + if ( !singleProjectMode() ) { + actionEditFunctions->addTo( menu ); + actionEditConnections->addTo( menu ); + } + actionEditFormSettings->addTo( menu ); + menu->insertSeparator(); + actionEditPreferences->addTo( menu ); +} + +void MainWindow::setupSearchActions() +{ + actionSearchFind = new DesignerAction( i18n( "Find" ), createIconSet( "designer_searchfind.png" ), + i18n( "&Find..." ), CTRL + Key_F, this, 0 ); + connect( actionSearchFind, SIGNAL( activated() ), this, SLOT( searchFind() ) ); + actionSearchFind->setEnabled( FALSE ); + actionSearchFind->setWhatsThis( whatsThisFrom( "Search|Find" ) ); + + actionSearchIncremetal = new DesignerAction( i18n( "Find Incremental" ), QIconSet(), + i18n( "Find &Incremental" ), ALT + Key_I, this, 0 ); + connect( actionSearchIncremetal, SIGNAL( activated() ), this, SLOT( searchIncremetalFindMenu() ) ); + actionSearchIncremetal->setEnabled( FALSE ); + actionSearchIncremetal->setWhatsThis( whatsThisFrom( "Search|Find Incremental" ) ); + + actionSearchReplace = new DesignerAction( i18n( "Replace" ), QIconSet(), + i18n( "&Replace..." ), CTRL + Key_R, this, 0 ); + connect( actionSearchReplace, SIGNAL( activated() ), this, SLOT( searchReplace() ) ); + actionSearchReplace->setEnabled( FALSE ); + actionSearchReplace->setWhatsThis( whatsThisFrom( "Search|Replace" ) ); + + actionSearchGotoLine = new DesignerAction( i18n( "Goto Line" ), QIconSet(), + i18n( "&Goto Line..." ), ALT + Key_G, this, 0 ); + connect( actionSearchGotoLine, SIGNAL( activated() ), this, SLOT( searchGotoLine() ) ); + actionSearchGotoLine->setEnabled( FALSE ); + actionSearchGotoLine->setWhatsThis( whatsThisFrom( "Search|Goto line" ) ); + +/* QToolBar *tb = new QToolBar( this, "Search" ); + tb->setCloseMode( QDockWindow::Undocked ); + addToolBar( tb, i18n( "Search" ) ); + + actionSearchFind->addTo( tb );*/ + incrementalSearch = new QLineEdit( 0 ); + incrementalSearch->hide(); + QToolTip::add( incrementalSearch, i18n( "Incremental search (Alt+I)" ) ); + connect( incrementalSearch, SIGNAL( textChanged( const QString & ) ), + this, SLOT( searchIncremetalFind() ) ); + connect( incrementalSearch, SIGNAL( returnPressed() ), + this, SLOT( searchIncremetalFindNext() ) ); + incrementalSearch->setEnabled( FALSE ); + + QPopupMenu *menu = new QPopupMenu( this, "Search" ); + menubar->insertItem( i18n( "&Search" ), menu ); + actionSearchFind->addTo( menu ); + actionSearchIncremetal->addTo( menu ); + actionSearchReplace->addTo( menu ); + menu->insertSeparator(); + actionSearchGotoLine->addTo( menu ); +} + +void MainWindow::setupLayoutActions() +{ + if ( !actionGroupTools ) { + actionGroupTools = new QActionGroup( this ); + actionGroupTools->setExclusive( TRUE ); + connect( actionGroupTools, SIGNAL( selected(QAction*) ), this, SLOT( toolSelected(QAction*) ) ); + } + + actionEditAdjustSize = new DesignerAction( i18n( "Adjust Size" ), createIconSet("designer_adjustsize.png"), + i18n( "Adjust &Size" ), CTRL + Key_J, this, 0 ); + actionEditAdjustSize->setStatusTip(i18n("Adjusts the size of the selected widget") ); + actionEditAdjustSize->setWhatsThis( whatsThisFrom( "Layout|Adjust Size" ) ); + connect( actionEditAdjustSize, SIGNAL( activated() ), this, SLOT( editAdjustSize() ) ); + actionEditAdjustSize->setEnabled( FALSE ); + + actionEditHLayout = new DesignerAction( i18n( "Lay Out Horizontally" ), createIconSet("designer_edithlayout.png"), + i18n( "Lay Out &Horizontally" ), CTRL + Key_H, this, 0 ); + actionEditHLayout->setStatusTip(i18n("Lays out the selected widgets horizontally") ); + actionEditHLayout->setWhatsThis( whatsThisFrom( "Layout|Lay Out Horizontally" ) ); + connect( actionEditHLayout, SIGNAL( activated() ), this, SLOT( editLayoutHorizontal() ) ); + actionEditHLayout->setEnabled( FALSE ); + + actionEditVLayout = new DesignerAction( i18n( "Lay Out Vertically" ), createIconSet("designer_editvlayout.png"), + i18n( "Lay Out &Vertically" ), CTRL + Key_L, this, 0 ); + actionEditVLayout->setStatusTip(i18n("Lays out the selected widgets vertically") ); + actionEditVLayout->setWhatsThis( whatsThisFrom( "Layout|Lay Out Vertically" ) ); + connect( actionEditVLayout, SIGNAL( activated() ), this, SLOT( editLayoutVertical() ) ); + actionEditVLayout->setEnabled( FALSE ); + + actionEditGridLayout = new DesignerAction( i18n( "Lay Out in a Grid" ), createIconSet("designer_editgrid.png"), + i18n( "Lay Out in a &Grid" ), CTRL + Key_G, this, 0 ); + actionEditGridLayout->setStatusTip(i18n("Lays out the selected widgets in a grid") ); + actionEditGridLayout->setWhatsThis( whatsThisFrom( "Layout|Lay Out in a Grid" ) ); + connect( actionEditGridLayout, SIGNAL( activated() ), this, SLOT( editLayoutGrid() ) ); + actionEditGridLayout->setEnabled( FALSE ); + + actionEditSplitHorizontal = new DesignerAction( i18n( "Lay Out Horizontally (in Splitter)" ), createIconSet("designer_editvlayoutsplit.png"), + i18n( "Lay Out Horizontally (in S&plitter)" ), 0, this, 0 ); + actionEditSplitHorizontal->setStatusTip(i18n("Lays out the selected widgets horizontally in a splitter") ); + actionEditSplitHorizontal->setWhatsThis( whatsThisFrom( "Layout|Lay Out Horizontally (in Splitter)" ) ); + connect( actionEditSplitHorizontal, SIGNAL( activated() ), this, SLOT( editLayoutHorizontalSplit() ) ); + actionEditSplitHorizontal->setEnabled( FALSE ); + + actionEditSplitVertical = new DesignerAction( i18n( "Lay Out Vertically (in Splitter)" ), createIconSet("designer_edithlayoutsplit.png"), + i18n( "Lay Out Vertically (in Sp&litter)" ), 0, this, 0 ); + actionEditSplitVertical->setStatusTip(i18n("Lays out the selected widgets vertically in a splitter") ); + actionEditSplitVertical->setWhatsThis( whatsThisFrom( "Layout|Lay Out Vertically (in Splitter)" ) ); + connect( actionEditSplitVertical, SIGNAL( activated() ), this, SLOT( editLayoutVerticalSplit() ) ); + actionEditSplitVertical->setEnabled( FALSE ); + + actionEditBreakLayout = new DesignerAction( i18n( "Break Layout" ), createIconSet("designer_editbreaklayout.png"), + i18n( "&Break Layout" ), CTRL + Key_B, this, 0 ); + actionEditBreakLayout->setStatusTip(i18n("Breaks the selected layout") ); + actionEditBreakLayout->setWhatsThis( whatsThisFrom( "Layout|Break Layout" ) ); + connect( actionEditBreakLayout, SIGNAL( activated() ), this, SLOT( editBreakLayout() ) ); + actionEditBreakLayout->setEnabled( FALSE ); + + int id = WidgetDatabase::idFromClassName( "Spacer" ); + actionInsertSpacer = new WidgetAction( i18n( "Layout" ), actionGroupTools, QString::number( id ).latin1() ); + actionInsertSpacer->setToggleAction( TRUE ); + actionInsertSpacer->setText( WidgetDatabase::className( id ) ); + actionInsertSpacer->setMenuText( i18n( "Add %1").arg( WidgetDatabase::className( id ) ) ); + actionInsertSpacer->setIconSet( WidgetDatabase::iconSet( id ) ); + actionInsertSpacer->setToolTip( WidgetDatabase::toolTip( id ) ); + actionInsertSpacer->setStatusTip( i18n( "Insert a %1").arg(WidgetDatabase::toolTip( id )) ); + actionInsertSpacer->setWhatsThis( i18n("<b>A %1</b><p>%2</p>" + "<p>Click to insert a single %3," + "or double click to keep the tool selected.") + .arg(WidgetDatabase::toolTip( id )) + .arg(WidgetDatabase::whatsThis( id )) + .arg(WidgetDatabase::toolTip( id ) )); + + actionInsertSpacer->addTo( commonWidgetsToolBar ); + commonWidgetsPage.append( actionInsertSpacer ); + QWidget *w; + commonWidgetsToolBar->setStretchableWidget( ( w = new QWidget( commonWidgetsToolBar ) ) ); + w->setBackgroundMode( commonWidgetsToolBar->backgroundMode() ); + QWhatsThis::add( layoutToolBar, i18n( "<b>The Layout toolbar</b>%1" ).arg(i18n(toolbarHelp).arg("")) ); + actionEditAdjustSize->addTo( layoutToolBar ); + layoutToolBar->addSeparator(); + actionEditHLayout->addTo( layoutToolBar ); + actionEditVLayout->addTo( layoutToolBar ); + actionEditGridLayout->addTo( layoutToolBar ); + actionEditSplitHorizontal->addTo( layoutToolBar ); + actionEditSplitVertical->addTo( layoutToolBar ); + actionEditBreakLayout->addTo( layoutToolBar ); + layoutToolBar->addSeparator(); + actionInsertSpacer->addTo( layoutToolBar ); + + QPopupMenu *menu = new QPopupMenu( this, "Layout" ); + layoutMenu = menu; + menubar->insertItem( i18n( "&Layout" ), menu, toolsMenuId + 1 ); + actionEditAdjustSize->addTo( menu ); + menu->insertSeparator(); + actionEditHLayout->addTo( menu ); + actionEditVLayout->addTo( menu ); + actionEditGridLayout->addTo( menu ); + actionEditSplitHorizontal->addTo( menu ); + actionEditSplitVertical->addTo( menu ); + actionEditBreakLayout->addTo( menu ); + menu->insertSeparator(); + actionInsertSpacer->addTo( menu ); +} + +void MainWindow::setupToolActions() +{ + if ( !actionGroupTools ) { + actionGroupTools = new QActionGroup( this ); + actionGroupTools->setExclusive( TRUE ); + connect( actionGroupTools, SIGNAL( selected(QAction*) ), + this, SLOT( toolSelected(QAction*) ) ); + } + + actionPointerTool = new DesignerAction( i18n("Pointer"), createIconSet("designer_pointer.png"), + i18n("&Pointer"), Key_F2, + actionGroupTools, + QString::number(POINTER_TOOL).latin1(), TRUE ); + actionPointerTool->setStatusTip( i18n("Selects the pointer tool") ); + actionPointerTool->setWhatsThis( whatsThisFrom( "Tools|Pointer" ) ); + + actionConnectTool = new DesignerAction( i18n("Connect Signal/Slots"), + createIconSet("designer_connecttool.png"), + i18n("&Connect Signal/Slots"), + singleProjectMode() ? 0 : Key_F3, + actionGroupTools, + QString::number(CONNECT_TOOL).latin1(), TRUE ); + actionConnectTool->setStatusTip( i18n("Selects the connection tool") ); + actionConnectTool->setWhatsThis( whatsThisFrom( "Tools|Connect Signals and Slots" ) ); + + actionOrderTool = new DesignerAction( i18n("Tab Order"), createIconSet("designer_ordertool.png"), + i18n("Tab &Order"), Key_F4, + actionGroupTools, + QString::number(ORDER_TOOL).latin1(), TRUE ); + actionOrderTool->setStatusTip( i18n("Selects the tab order tool") ); + actionOrderTool->setWhatsThis( whatsThisFrom( "Tools|Tab Order" ) ); + + actionBuddyTool = new DesignerAction( i18n( "Set Buddy" ), createIconSet( "designer_setbuddy.png" ), + i18n( "Set &Buddy" ), Key_F12, + actionGroupTools, QString::number( BUDDY_TOOL ).latin1(), + TRUE ); + actionBuddyTool->setStatusTip( i18n( "Sets a buddy to a label" ) ); + actionBuddyTool->setWhatsThis( whatsThisFrom( "Tools|Set Buddy" ) ); + + QToolBar *tb = new QToolBar( this, "Tools" ); + tb->setCloseMode( QDockWindow::Undocked ); + toolsToolBar = tb; + QWhatsThis::add( tb, i18n( "<b>The Tools toolbar</b>%1" ).arg(i18n(toolbarHelp).arg("")) ); + + addToolBar( tb, i18n( "Tools" ), QMainWindow::DockTop, FALSE ); + actionPointerTool->addTo( tb ); + if ( !singleProjectMode() ) + actionConnectTool->addTo( tb ); + actionOrderTool->addTo( tb ); + actionBuddyTool->addTo( tb ); + + QPopupMenu *mmenu = new QPopupMenu( this, "Tools" ); + toolsMenu = mmenu; + toolsMenuId = 100; + menubar->insertItem( i18n( "&Tools" ), mmenu, toolsMenuId ); + toolsMenuIndex = menubar->indexOf( toolsMenuId ); + actionPointerTool->addTo( mmenu ); + if ( !singleProjectMode() ) + actionConnectTool->addTo( mmenu ); + actionOrderTool->addTo( mmenu ); + actionBuddyTool->addTo( mmenu ); + mmenu->insertSeparator(); + + customWidgetToolBar = 0; + customWidgetMenu = 0; + + actionToolsCustomWidget = new DesignerAction( i18n("Custom Widgets"), + createIconSet( "designer_customwidget.png" ), + i18n("Edit &Custom Widgets..."), 0, this, 0 ); + actionToolsCustomWidget->setStatusTip( i18n("Opens a dialog to add and change " + "custom widgets") ); + actionToolsCustomWidget->setWhatsThis( whatsThisFrom( "Tools|Custom|Edit Custom" + "Widgets" ) ); + connect( actionToolsCustomWidget, SIGNAL( activated() ), + this, SLOT( toolsCustomWidget() ) ); + + for ( int j = 0; j < WidgetDatabase::numWidgetGroups(); ++j ) { + QString grp = WidgetDatabase::widgetGroup( j ); + if ( !WidgetDatabase::isGroupVisible( grp ) || + WidgetDatabase::isGroupEmpty( grp ) ) + continue; + QToolBar *tb = new QToolBar( this, grp.latin1() ); + tb->setCloseMode( QDockWindow::Undocked ); + widgetToolBars.append( tb ); + bool plural = grp[(int)grp.length()-1] == 's'; + if ( plural ) { + QWhatsThis::add( tb, i18n( "<b>The %1</b>%2" ).arg(grp).arg(i18n(toolbarHelp). + arg( i18n(" Click on a button to insert a single widget, " + "or double click to insert multiple %1.") ).arg(grp)) ); + } else { + QWhatsThis::add( tb, i18n( "<b>The %1 Widgets</b>%2" ).arg(grp).arg(i18n(toolbarHelp). + arg( i18n(" Click on a button to insert a single %1 widget, " + "or double click to insert multiple widgets.") ).arg(grp)) ); + } + addToolBar( tb, grp ); + tb->hide(); + QPopupMenu *menu = new QPopupMenu( this, grp.latin1() ); + mmenu->insertItem( grp, menu ); + + QToolBar *tb2 = new QToolBar( grp, 0, toolBox, FALSE, grp.latin1() ); + tb2->setFrameStyle( QFrame::NoFrame ); + tb2->setOrientation( Qt::Vertical ); + tb2->setBackgroundMode( PaletteBase ); + toolBox->addItem( tb2, grp ); + + if ( grp == "Custom" ) { + if ( !customWidgetMenu ) + actionToolsCustomWidget->addTo( menu ); + else + menu->insertSeparator(); + customWidgetMenu = menu; + customWidgetToolBar = tb; + } + + for ( int i = 0; i < WidgetDatabase::count(); ++i ) { + if ( WidgetDatabase::group( i ) != grp ) + continue; // only widgets, i.e. not forms and temp stuff + WidgetAction* a = + new WidgetAction( grp, actionGroupTools, QString::number( i ).latin1() ); + a->setToggleAction( TRUE ); + QString atext = WidgetDatabase::className( i ); + if ( atext[0] == 'Q' ) + atext = atext.mid(1); + while ( atext.length() && atext[0] >= 'a' && atext[0] <= 'z' ) + atext = atext.mid(1); + if ( atext.isEmpty() ) + atext = WidgetDatabase::className( i ); + a->setText( atext ); + QString ttip = WidgetDatabase::toolTip( i ); + a->setIconSet( WidgetDatabase::iconSet( i ) ); + a->setToolTip( ttip ); + if ( !WidgetDatabase::isWhatsThisLoaded() ) + WidgetDatabase::loadWhatsThis( documentationPath() ); + a->setStatusTip( i18n( "Insert a %1").arg(WidgetDatabase::className( i )) ); + + QString whats = i18n("<b>A %1</b>").arg( WidgetDatabase::className( i ) ); + if ( !WidgetDatabase::whatsThis( i ).isEmpty() ) + whats += QString("<p>%1</p>").arg(WidgetDatabase::whatsThis( i )); + a->setWhatsThis( whats+ i18n("<p>Double click on this tool to keep it selected.</p>") ); + + if ( grp != "KDE" ) + a->addTo( tb ); + a->addTo( menu ); + a->addTo( tb2 ); + if ( WidgetDatabase::isCommon( i ) ) { + a->addTo( commonWidgetsToolBar ); + commonWidgetsPage.append( a ); + } + } + QWidget *w; + tb2->setStretchableWidget( ( w = new QWidget( tb2 ) ) ); + w->setBackgroundMode( tb2->backgroundMode() ); + } + + if ( !customWidgetToolBar ) { + QToolBar *tb = new QToolBar( this, "Custom Widgets" ); + tb->setCloseMode( QDockWindow::Undocked ); + QWhatsThis::add( tb, i18n( "<b>The Custom Widgets toolbar</b>%1" + "<p>Click <b>Edit Custom Widgets...</b>" + "in the <b>Tools|Custom</b> menu to " + "add and change custom widgets</p>" ). + arg(i18n(toolbarHelp). + arg( i18n(" Click on the buttons to insert a single widget, " + "or double click to insert multiple widgets.") )) ); + addToolBar( tb, i18n( "Custom" ) ); + tb->hide(); + widgetToolBars.append( tb ); + customWidgetToolBar = tb; + QPopupMenu *menu = new QPopupMenu( this, "Custom Widgets" ); + mmenu->insertItem( "Custom", menu ); + customWidgetMenu = menu; + customWidgetToolBar->hide(); + actionToolsCustomWidget->addTo( customWidgetMenu ); + customWidgetMenu->insertSeparator(); + QToolBar *tb2 = new QToolBar( "Custom Widgets", 0, + toolBox, FALSE, "Custom Widgets" ); + tb2->setBackgroundMode(PaletteBase); + tb2->setOrientation( Qt::Vertical ); + tb2->setFrameStyle( QFrame::NoFrame ); + toolBox->addItem( tb2, "Custom Widgets" ); + customWidgetToolBar2 = tb2; + } + + QAction *a = new DesignerAction( i18n( "Configure Toolbox" ), i18n( "Configure Toolbox..." ), 0, this ); + a->setStatusTip( i18n( "Opens a dialog to configure the common " + "widgets page of the toolbox") ); + connect( a, SIGNAL( activated() ), this, SLOT( toolsConfigure() ) ); + mmenu->insertSeparator(); + a->addTo( mmenu ); + resetTool(); +} + +void MainWindow::setupFileActions() +{ + QToolBar* tb = new QToolBar( this, "File" ); + tb->setCloseMode( QDockWindow::Undocked ); + projectToolBar = tb; + + QWhatsThis::add( tb, i18n( "<b>The File toolbar</b>%1" ).arg(i18n(toolbarHelp).arg("")) ); + addToolBar( tb, i18n( "File" ) ); + fileMenu = new QPopupMenu( this, "File" ); + menubar->insertItem( i18n( "&File" ), fileMenu ); + + DesignerAction *a = 0; + + if ( !singleProject ) { + DesignerAction *a = new DesignerAction( this, 0 ); + a->setText( i18n( "New" ) ); + a->setToolTip( i18n( "New dialog or file" ) ); + a->setMenuText( i18n( "&New..." ) ); + a->setIconSet( createIconSet("designer_filenew.png") ); + a->setAccel( CTRL + Key_N ); + a->setStatusTip( i18n( "Creates a new project, form or source file." ) ); + a->setWhatsThis( whatsThisFrom( "File|New" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) ); + a->addTo( tb ); + a->addTo( fileMenu ); + actionNewFile = a; + } else { + actionGroupNew = new QActionGroup( this, 0, FALSE ); + QActionGroup* a = actionGroupNew; + ( (QActionGroup*)a )->setUsesDropDown( TRUE ); + a->setText( i18n( "New" ) ); + a->setMenuText( i18n( "&New..." ) ); + a->setIconSet( createIconSet("designer_form.png") ); + a->setStatusTip( i18n( "Creates a new dialog or file" ) ); + a->setWhatsThis( whatsThisFrom( "File|New" ) ); + + QAction *newForm = new DesignerAction( a, 0 ); + newForm->setText( i18n( "New Dialog" ) ); + newForm->setMenuText( i18n( "&Dialog..." ) ); + newForm->setIconSet( createIconSet("designer_form.png") ); + newForm->setAccel( CTRL + Key_N ); + newForm->setStatusTip( i18n( "Creates a new dialog." ) ); + connect( newForm, SIGNAL( activated() ), this, SLOT( fileNewDialog() ) ); + + DesignerAction *newFile = new DesignerAction( a, 0 ); + newFile->setText( i18n( "New File" ) ); + newFile->setMenuText( i18n( "&File..." ) ); + newFile->setIconSet( createIconSet("designer_filenew.png") ); + newFile->setAccel( ALT + Key_N ); + newFile->setStatusTip( i18n( "Creates a new file." ) ); + connect( newFile, SIGNAL( activated() ), this, SLOT( fileNewFile() ) ); + actionNewFile = newFile; + + a->addTo( tb ); + a->addTo( fileMenu ); + + fileMenu->insertSeparator(); + } + + a = new DesignerAction( this, 0 ); + a->setText( i18n( "Open" ) ); + a->setMenuText( i18n( "&Open..." ) ); + a->setIconSet( createIconSet("designer_fileopen.png") ); + a->setAccel( CTRL + Key_O ); + a->setStatusTip( i18n( "Opens an existing project, form or source file ") ); + a->setWhatsThis( whatsThisFrom( "File|Open" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) ); + if ( !singleProject ) { + a->addTo( tb ); + a->addTo( fileMenu ); + fileMenu->insertSeparator(); + } + + + a = new DesignerAction( this, 0 ); + actionFileClose = a; + a->setText( i18n( "Close" ) ); + a->setMenuText( i18n( "&Close" ) ); + a->setStatusTip( i18n( "Closes the current project or document" ) ); + a->setWhatsThis(whatsThisFrom( "File|Close" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileClose() ) ); + connect( this, SIGNAL( hasActiveWindowOrProject(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) { + a->addTo( fileMenu ); + fileMenu->insertSeparator(); + } + + a = new DesignerAction( this, 0 ); + actionFileSave = a; + a->setText( i18n( "Save" ) ); + a->setMenuText( i18n( "&Save" ) ); + a->setIconSet( createIconSet("designer_filesave.png") ); + a->setAccel( CTRL + Key_S ); + a->setStatusTip( i18n( "Saves the current project or document" ) ); + a->setWhatsThis(whatsThisFrom( "File|Save" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSave() ) ); + connect( this, SIGNAL( hasActiveWindowOrProject(bool) ), a, SLOT( setEnabled(bool) ) ); + a->addTo( tb ); + a->addTo( fileMenu ); + + a = new DesignerAction( this, 0 ); + actionFileSaveAs = a; + a->setText( i18n( "Save As" ) ); + a->setMenuText( i18n( "Save &As..." ) ); + a->setStatusTip( i18n( "Saves the current form with a new filename" ) ); + a->setWhatsThis( whatsThisFrom( "File|Save As" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSaveAs() ) ); + connect( this, SIGNAL( hasActiveWindow(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) + a->addTo( fileMenu ); + + a = new DesignerAction( this, 0 ); + actionFileSaveAll = a; + a->setText( i18n( "Save All" ) ); + a->setMenuText( i18n( "Sa&ve All" ) ); + a->setStatusTip( i18n( "Saves all open documents" ) ); + a->setWhatsThis( whatsThisFrom( "File|Save All" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSaveAll() ) ); + connect( this, SIGNAL( hasActiveWindowOrProject(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) { + a->addTo( fileMenu ); + fileMenu->insertSeparator(); + } + + a = new DesignerAction( this, 0 ); + a->setText( i18n( "Create Template" ) ); + a->setMenuText( i18n( "Create &Template..." ) ); + a->setStatusTip( i18n( "Creates a new template" ) ); + a->setWhatsThis( whatsThisFrom( "File|Create Template" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileCreateTemplate() ) ); + if ( !singleProject ) + a->addTo( fileMenu ); + + if ( !singleProject ) + fileMenu->insertSeparator(); + + recentlyFilesMenu = new QPopupMenu( this ); + recentlyProjectsMenu = new QPopupMenu( this ); + + if ( !singleProject ) { + fileMenu->insertItem( i18n( "Recently Opened Files " ), recentlyFilesMenu ); + fileMenu->insertItem( i18n( "Recently Opened Projects" ), recentlyProjectsMenu ); + } + + connect( recentlyFilesMenu, SIGNAL( aboutToShow() ), + this, SLOT( setupRecentlyFilesMenu() ) ); + connect( recentlyProjectsMenu, SIGNAL( aboutToShow() ), + this, SLOT( setupRecentlyProjectsMenu() ) ); + connect( recentlyFilesMenu, SIGNAL( activated( int ) ), + this, SLOT( recentlyFilesMenuActivated( int ) ) ); + connect( recentlyProjectsMenu, SIGNAL( activated( int ) ), + this, SLOT( recentlyProjectsMenuActivated( int ) ) ); + + if ( !singleProject ) + fileMenu->insertSeparator(); + + a = new DesignerAction( this, 0 ); + actionFileExit = a; + if ( !singleProjectMode() ) { + a->setText( i18n( "Exit" ) ); + a->setMenuText( i18n( "E&xit" ) ); + a->setStatusTip( i18n( "Quits the application and prompts to save any changed forms, source files or project settings" ) ); + a->setWhatsThis( whatsThisFrom( "File|Exit" ) ); + } else { + a->setText( i18n( "Close" ) ); + a->setMenuText( i18n( "&Close" ) ); + } + connect( a, SIGNAL( activated() ), this, SLOT( fileQuit() ) ); + a->addTo( fileMenu ); +} + +void MainWindow::setupProjectActions() +{ + projectMenu = new QPopupMenu( this, "Project" ); + menubar->insertItem( i18n( "Pr&oject" ), projectMenu ); + + QActionGroup *ag = new QActionGroup( this, 0 ); + ag->setText( i18n( "Active Project" ) ); + ag->setMenuText( i18n( "Active Project" ) ); + ag->setExclusive( TRUE ); + ag->setUsesDropDown( TRUE ); + connect( ag, SIGNAL( selected( QAction * ) ), this, SLOT( projectSelected( QAction * ) ) ); + connect( ag, SIGNAL( selected( QAction * ) ), this, SIGNAL( projectChanged() ) ); + DesignerAction *a = new DesignerAction( i18n( "<No Project>" ), i18n( "<No Project>" ), 0, ag, 0, TRUE ); + eProject = new Project( "", i18n( "<No Project>" ), projectSettingsPluginManager, TRUE ); + projects.insert( a, eProject ); + a->setOn( TRUE ); + ag->addTo( projectMenu ); + ag->addTo( projectToolBar ); + actionGroupProjects = ag; + + if ( !singleProject ) + projectMenu->insertSeparator(); + + a = new DesignerAction( i18n( "Add File" ), QPixmap(), i18n( "&Add File..." ), 0, this, 0 ); + actionProjectAddFile = a; + a->setStatusTip( i18n("Adds a file to the current project") ); + a->setWhatsThis( whatsThisFrom( "Project|Add File" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( projectInsertFile() ) ); + a->setEnabled( FALSE ); + connect( this, SIGNAL( hasNonDummyProject(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) + a->addTo( projectMenu ); + + actionEditPixmapCollection = new DesignerAction( i18n( "Image Collection..." ), QPixmap(), + i18n( "&Image Collection..." ), 0, this, 0 ); + actionEditPixmapCollection->setStatusTip( i18n("Opens a dialog for editing the current project's image collection") ); + actionEditPixmapCollection->setWhatsThis( whatsThisFrom( "Project|Image Collection" ) ); + connect( actionEditPixmapCollection, SIGNAL( activated() ), this, SLOT( editPixmapCollection() ) ); + actionEditPixmapCollection->setEnabled( FALSE ); + connect( this, SIGNAL( hasNonDummyProject(bool) ), actionEditPixmapCollection, SLOT( setEnabled(bool) ) ); + actionEditPixmapCollection->addTo( projectMenu ); + +#ifndef QT_NO_SQL + actionEditDatabaseConnections = new DesignerAction( i18n( "Database Connections..." ), QPixmap(), + i18n( "&Database Connections..." ), 0, this, 0 ); + actionEditDatabaseConnections->setStatusTip( i18n("Opens a dialog for editing the current project's database connections") ); + actionEditDatabaseConnections->setWhatsThis( whatsThisFrom( "Project|Database Connections" ) ); + connect( actionEditDatabaseConnections, SIGNAL( activated() ), this, SLOT( editDatabaseConnections() ) ); + //actionEditDatabaseConnections->setEnabled( FALSE ); + //connect( this, SIGNAL( hasNonDummyProject(bool) ), actionEditDatabaseConnections, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) + actionEditDatabaseConnections->addTo( projectMenu ); +#endif + + actionEditProjectSettings = new DesignerAction( i18n( "Project Settings..." ), QPixmap(), + i18n( "&Project Settings..." ), 0, this, 0 ); + actionEditProjectSettings->setStatusTip( i18n("Opens a dialog to change the project's settings") ); + actionEditProjectSettings->setWhatsThis( whatsThisFrom( "Project|Project Settings" ) ); + connect( actionEditProjectSettings, SIGNAL( activated() ), this, SLOT( editProjectSettings() ) ); + actionEditProjectSettings->setEnabled( FALSE ); + connect( this, SIGNAL( hasNonDummyProject(bool) ), actionEditProjectSettings, SLOT( setEnabled(bool) ) ); + actionEditProjectSettings->addTo( projectMenu ); + +} + +void MainWindow::setupPreviewActions() +{ + DesignerAction* a = 0; + QPopupMenu *menu = new QPopupMenu( this, "Preview" ); + layoutMenu = menu; + menubar->insertItem( i18n( "&Preview" ), menu, toolsMenuId + 2 ); + + a = new DesignerAction( i18n( "Preview Form" ), QPixmap(), i18n( "Preview &Form" ), 0, this, 0 ); + actionPreview = a; + a->setAccel( CTRL + Key_T ); + a->setStatusTip( i18n("Opens a preview") ); + a->setWhatsThis( whatsThisFrom( "Preview|Preview Form" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( previewForm() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), a, SLOT( setEnabled(bool) ) ); + a->addTo( menu ); + + menu->insertSeparator(); + + QSignalMapper *mapper = new QSignalMapper( this ); + connect( mapper, SIGNAL(mapped(const QString&)), this, SLOT(previewForm(const QString&)) ); + QStringList styles = QStyleFactory::keys(); + for ( QStringList::Iterator it = styles.begin(); it != styles.end(); ++it ) { + QString info; + if ( *it == "Motif" ) + info = i18n( "The preview will use the Motif look and feel which is used as the default style on most UNIX systems." ); + else if ( *it == "Windows" ) + info = i18n( "The preview will use the Windows look and feel." ); + else if ( *it == "Platinum" ) + info = i18n( "The preview will use the Platinum look and feel which is similar to the Macintosh GUI style." ); + else if ( *it == "CDE" ) + info = i18n( "The preview will use the CDE look and feel which is similar to some versions of the Common Desktop Environment." ); + else if ( *it == "SGI" ) + info = i18n( "The preview will use the Motif look and feel which is used as the default style on SGI systems." ); + else if ( *it == "MotifPlus" ) + info = i18n( "The preview will use the advanced Motif look and feel used by the GIMP toolkit (GTK) on Linux." ); + + a = new DesignerAction( i18n( "Preview Form in %1 Style" ).arg( *it ), QPixmap(), + i18n( "... in %1 Style" ).arg( *it ), 0, this, 0 ); + a->setStatusTip( i18n("Opens a preview in %1 style").arg( *it ) ); + a->setWhatsThis( i18n("<b>Open a preview in %1 style.</b>" + "<p>Use the preview to test the design and " + "signal-slot connections of the current form. %2</p>").arg( *it ).arg( info ) ); + mapper->setMapping( a, *it ); + connect( a, SIGNAL(activated()), mapper, SLOT(map()) ); + connect( this, SIGNAL( hasActiveForm(bool) ), a, SLOT( setEnabled(bool) ) ); + a->addTo( menu ); + } +} + +void MainWindow::setupWindowActions() +{ +/* static bool windowActionsSetup = FALSE; + if ( !windowActionsSetup ) { + windowActionsSetup = TRUE; +*/ + actionWindowTile = new DesignerAction( i18n( "Tile" ), i18n( "&Tile" ), 0, this ); + actionWindowTile->setStatusTip( i18n("Tiles the windows so that they are all visible") ); + actionWindowTile->setWhatsThis( whatsThisFrom( "Window|Tile" ) ); + connect( actionWindowTile, SIGNAL( activated() ), qworkspace, SLOT( tile() ) ); + actionWindowCascade = new DesignerAction( i18n( "Cascade" ), i18n( "&Cascade" ), 0, this ); + actionWindowCascade->setStatusTip( i18n("Cascades the windows so that all their title bars are visible") ); + actionWindowCascade->setWhatsThis( whatsThisFrom( "Window|Cascade" ) ); + connect( actionWindowCascade, SIGNAL( activated() ), qworkspace, SLOT( cascade() ) ); + + actionWindowClose = new DesignerAction( i18n( "Close" ), i18n( "Cl&ose" ), CTRL + Key_F4, this ); + actionWindowClose->setStatusTip( i18n( "Closes the active window") ); + actionWindowClose->setWhatsThis( whatsThisFrom( "Window|Close" ) ); + connect( actionWindowClose, SIGNAL( activated() ), qworkspace, SLOT( closeActiveWindow() ) ); + + actionWindowCloseAll = new DesignerAction( i18n( "Close All" ), i18n( "Close Al&l" ), 0, this ); + actionWindowCloseAll->setStatusTip( i18n( "Closes all form windows") ); + actionWindowCloseAll->setWhatsThis( whatsThisFrom( "Window|Close All" ) ); + connect( actionWindowCloseAll, SIGNAL( activated() ), qworkspace, SLOT( closeAllWindows() ) ); + + actionWindowNext = new DesignerAction( i18n( "Next" ), i18n( "Ne&xt" ), CTRL + Key_F6, this ); + actionWindowNext->setStatusTip( i18n( "Activates the next window" ) ); + actionWindowNext->setWhatsThis( whatsThisFrom( "Window|Next" ) ); + connect( actionWindowNext, SIGNAL( activated() ), qworkspace, SLOT( activateNextWindow() ) ); + + actionWindowPrevious = new DesignerAction( i18n( "Previous" ), i18n( "Pre&vious" ), CTRL + SHIFT + Key_F6, this ); + actionWindowPrevious->setStatusTip( i18n( "Activates the previous window" ) ); + actionWindowPrevious->setWhatsThis( whatsThisFrom( "Window|Previous" ) ); + connect( actionWindowPrevious, SIGNAL( activated() ), qworkspace, SLOT( activatePreviousWindow() ) ); + // } + + if ( !windowMenu ) { + windowMenu = new QPopupMenu( this, "Window" ); + menubar->insertItem( i18n( "&Window" ), windowMenu ); + connect( windowMenu, SIGNAL( aboutToShow() ), + this, SLOT( setupWindowActions() ) ); + } else { + windowMenu->clear(); + } + + actionWindowClose->addTo( windowMenu ); + actionWindowCloseAll->addTo( windowMenu ); + windowMenu->insertSeparator(); + actionWindowNext->addTo( windowMenu ); + actionWindowPrevious->addTo( windowMenu ); + windowMenu->insertSeparator(); + actionWindowTile->addTo( windowMenu ); + actionWindowCascade->addTo( windowMenu ); + windowMenu->insertSeparator(); + windowMenu->insertItem( i18n( "Vie&ws" ), createDockWindowMenu( NoToolBars ) ); + windowMenu->insertItem( i18n( "Tool&bars" ), createDockWindowMenu( OnlyToolBars ) ); + QWidgetList windows = qworkspace->windowList(); + if ( windows.count() && formWindow() ) + windowMenu->insertSeparator(); + int j = 0; + for ( int i = 0; i < int( windows.count() ); ++i ) { + QWidget *w = windows.at( i ); + if ( !::qt_cast<FormWindow*>(w) && !::qt_cast<SourceEditor*>(w) ) + continue; + if ( ::qt_cast<FormWindow*>(w) && ( ( (FormWindow*)w )->isFake() ) ) + continue; + j++; + QString itemText; + if ( j < 10 ) + itemText = QString("&%1 ").arg( j ); + if ( ::qt_cast<FormWindow*>(w) ) + itemText += w->name(); + else + itemText += w->caption(); + + int id = windowMenu->insertItem( itemText, this, SLOT( windowsMenuActivated( int ) ) ); + windowMenu->setItemParameter( id, i ); + windowMenu->setItemChecked( id, qworkspace->activeWindow() == windows.at( i ) ); + } +} + +void MainWindow::setupHelpActions() +{ + actionHelpContents = new DesignerAction( i18n( "Contents" ), i18n( "&Contents" ), Key_F1, this, 0 ); + actionHelpContents->setStatusTip( i18n("Opens the online help") ); + actionHelpContents->setWhatsThis( whatsThisFrom( "Help|Contents" ) ); + connect( actionHelpContents, SIGNAL( activated() ), this, SLOT( helpContents() ) ); + + actionHelpManual = new DesignerAction( i18n( "Manual" ), i18n( "&Manual" ), CTRL + Key_M, this, 0 ); + actionHelpManual->setStatusTip( i18n("Opens the Qt Designer manual") ); + actionHelpManual->setWhatsThis( whatsThisFrom( "Help|Manual" ) ); + connect( actionHelpManual, SIGNAL( activated() ), this, SLOT( helpManual() ) ); + + actionHelpAbout = new DesignerAction( i18n("About"), QPixmap(), i18n("&About"), 0, this, 0 ); + actionHelpAbout->setStatusTip( i18n("Displays information about Qt Designer") ); + actionHelpAbout->setWhatsThis( whatsThisFrom( "Help|About" ) ); + connect( actionHelpAbout, SIGNAL( activated() ), this, SLOT( helpAbout() ) ); + + actionHelpAboutQt = new DesignerAction( i18n("About Qt"), QPixmap(), i18n("About &Qt"), 0, this, 0 ); + actionHelpAboutQt->setStatusTip( i18n("Displays information about the Qt Toolkit") ); + actionHelpAboutQt->setWhatsThis( whatsThisFrom( "Help|About Qt" ) ); + connect( actionHelpAboutQt, SIGNAL( activated() ), this, SLOT( helpAboutQt() ) ); + +#if 0 //defined(QT_NON_COMMERCIAL) + // ### not used anymore -- should be deleted? + actionHelpRegister = new DesignerAction( i18n("Register Qt"), QPixmap(), i18n("&Register Qt..."), 0, this, 0 ); + actionHelpRegister->setStatusTip( i18n("Opens a web browser at the evaluation form on www.trolltech.com") ); + actionHelpRegister->setWhatsThis( i18n("Register with Trolltech") ); + connect( actionHelpRegister, SIGNAL( activated() ), this, SLOT( helpRegister() ) ); +#endif + + actionHelpWhatsThis = new DesignerAction( i18n("What's This?"), QIconSet( whatsthis_image, whatsthis_image ), + i18n("What's This?"), SHIFT + Key_F1, this, 0 ); + actionHelpWhatsThis->setStatusTip( i18n("\"What's This?\" context sensitive help") ); + actionHelpWhatsThis->setWhatsThis( whatsThisFrom( "Help|What's This?" ) ); + connect( actionHelpWhatsThis, SIGNAL( activated() ), this, SLOT( whatsThis() ) ); + +/* QToolBar *tb = new QToolBar( this, "Help" ); + tb->setCloseMode( QDockWindow::Undocked ); + QWhatsThis::add( tb, i18n( "<b>The Help toolbar</b>%1" ).arg(i18n(toolbarHelp).arg("") )); + addToolBar( tb, i18n( "Help" ) ); + actionHelpWhatsThis->addTo( tb );*/ + + QPopupMenu *menu = new QPopupMenu( this, "Help" ); + menubar->insertSeparator(); + menubar->insertItem( i18n( "&Help" ), menu ); + actionHelpContents->addTo( menu ); + actionHelpManual->addTo( menu ); + menu->insertSeparator(); + actionHelpAbout->addTo( menu ); + actionHelpAboutQt->addTo( menu ); +#if 0 //defined(QT_NON_COMMERCIAL) + // ### not used anymore -- should be deleted? + actionHelpRegister->addTo( menu ); +#endif + + menu->insertSeparator(); + actionHelpWhatsThis->addTo( menu ); +} + +void MainWindow::fileNew() +{ + statusMessage( i18n( "Create a new project, form or source file...") ); + NewForm dlg( this, projectNames(), currentProject->projectName(), templatePath() ); + dlg.exec(); + statusBar()->clear(); +} + +void MainWindow::fileNewDialog() +{ + static int forms = 0; + QString n = "Dialog" + QString::number( ++forms ); + while ( currentProject->findFormFile( n + ".ui" ) ) + n = "Dialog" + QString::number( ++forms ); + FormWindow *fw = 0; + FormFile *ff = new FormFile( n + ".ui", FALSE, currentProject ); + fw = new FormWindow( ff, MainWindow::self, MainWindow::self->qWorkspace(), n ); + ff->setModified( TRUE ); + currentProject->setModified( TRUE ); + workspace()->update(); + fw->setProject( currentProject ); + MetaDataBase::addEntry( fw ); + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QDialog" ), fw, n.latin1() ); + fw->setMainContainer( w ); + fw->setCaption( n ); + fw->resize( 600, 480 ); + insertFormWindow( fw ); + fw->killAccels( fw ); + fw->project()->setModified( TRUE ); + fw->setFocus(); + fw->setSavePixmapInProject( TRUE ); + fw->setSavePixmapInline( FALSE ); +} + +void MainWindow::fileNewFile() +{ + QString name = QInputDialog::getText( i18n( "Name of File" ), i18n( "Enter the name of the new source file:" ) ); + if ( name.isEmpty() ) + return; + if ( name.right( 3 ) != ".qs" ) + name += ".qs"; + SourceFile *f = new SourceFile( name, FALSE, currentProject ); + MainWindow::self->editSource( f ); + f->setModified( TRUE ); + currentProject->setModified( TRUE ); + workspace()->update(); +} + +void MainWindow::fileQuit() +{ + close(); + if ( !singleProjectMode() ) + qApp->closeAllWindows(); +} + +void MainWindow::fileClose() +{ + if ( !currentProject->isDummy() ) { + fileCloseProject(); + } else { + QWidget *w = qworkspace->activeWindow(); + if ( w ) { + if ( ::qt_cast<FormWindow*>(w) ) + ( (FormWindow*)w )->formFile()->close(); + else if ( ::qt_cast<SourceEditor*>(w) ) + ( (SourceEditor*)w )->close(); + } + } +} + + +void MainWindow::fileCloseProject() +{ + if ( currentProject->isDummy() ) + return; + Project *pro = currentProject; + QAction* a = 0; + QAction* lastValid = 0; + for ( QMap<QAction*, Project* >::Iterator it = projects.begin(); it != projects.end(); ++it ) { + if ( it.data() == pro ) { + a = it.key(); + if ( lastValid ) + break; + } + lastValid = it.key(); + } + if ( a ) { + if ( pro->isModified() ) { + switch ( QMessageBox::warning( this, i18n( "Save Project Settings" ), + i18n( "Save changes to '%1'?" ).arg( pro->fileName() ), + i18n( "&Yes" ), i18n( "&No" ), i18n( "&Cancel" ), 0, 2 ) ) { + case 0: // save + pro->save(); + break; + case 1: // don't save + break; + case 2: // cancel + return; + default: + break; + } + } + + QWidgetList windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( TRUE ); + QWidgetListIt wit( windows ); + while ( wit.current() ) { + QWidget *w = wit.current(); + ++wit; + if ( ::qt_cast<FormWindow*>(w) ) { + if ( ( (FormWindow*)w )->project() == pro ) { + if ( ( (FormWindow*)w )->formFile()->editor() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->editor() ); + if ( !( (FormWindow*)w )->formFile()->close() ) + return; + } + } else if ( ::qt_cast<SourceEditor*>(w) ) { + if ( !( (SourceEditor*)w )->close() ) + return; + } + } + hierarchyView->clear(); + windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( FALSE ); + actionGroupProjects->removeChild( a ); + projects.remove( a ); + delete a; + currentProject = 0; + if ( lastValid ) { + projectSelected( lastValid ); + statusMessage( i18n( "Selected project '%1'" ).arg( currentProject->projectName() ) ); + } + if ( !windows.isEmpty() ) { + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( !::qt_cast<FormWindow*>(w) ) + continue; + w->setFocus(); + activeWindowChanged( w ); + break; + } + } else { + emit hasActiveWindow( FALSE ); + emit hasActiveForm( FALSE ); + updateUndoRedo( FALSE, FALSE, QString::null, QString::null ); + } + } +} + +void MainWindow::fileOpen() // as called by the menu +{ + fileOpen( "", "", "", FALSE ); +} + +void MainWindow::projectInsertFile() +{ + fileOpen( "", "" ); +} + +void MainWindow::fileOpen( const QString &filter, const QString &extension, const QString &fn, bool inProject ) +{ + statusMessage( i18n( "Open a file...") ); + + QPluginManager<ImportFilterInterface> manager( IID_ImportFilter, QApplication::libraryPaths(), pluginDirectory() ); + + Project* project = inProject ? currentProject : eProject; + + QStringList additionalSources; + + { + QStringList filterlist; + if ( filter.isEmpty() ) { + if ( !inProject ) + filterlist << i18n( "*.ui *.pro|Designer Files" ); + filterlist << i18n( "*.ui|Qt User-Interface Files" ); + if ( !inProject ) + filterlist << i18n( "*.pro|QMAKE Project Files" ); + QStringList list = manager.featureList(); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) + filterlist << *it; + LanguageInterface *iface = MetaDataBase::languageInterface( project->language() ); + if ( iface ) { + filterlist += iface->fileFilterList(); + additionalSources += iface->fileExtensionList(); + } + filterlist << i18n( "*|All Files" ); + } else { + filterlist << filter; + } + + QString filters = filterlist.join( "\n" ); + + QStringList filenames; + if ( fn.isEmpty() ) { + if ( !inProject ) { + QString f = KFileDialog::getOpenFileName( QString::null, filters, this, /*0,*/ + i18n("Open" )/*, &lastOpenFilter */); + filenames << f; + } else { + filenames = KFileDialog::getOpenFileNames( QString::null, filters, this, /*0,*/ + i18n("Add")/*, &lastOpenFilter */); + } + } else { + filenames << fn; + } + + for ( QStringList::Iterator fit = filenames.begin(); fit != filenames.end(); ++fit ) { + QString filename = *fit; + if ( !filename.isEmpty() ) { + QFileInfo fi( filename ); + + if ( fi.extension( FALSE ) == "pro" && ( extension.isEmpty() || extension.find( ";pro" ) != -1 ) ) { + addRecentlyOpened( filename, recentlyProjects ); + openProject( filename ); + } else if ( fi.extension( FALSE ) == "ui" && ( extension.isEmpty() || extension.find( ";ui" ) != -1 ) ) { + if ( !inProject ) + setCurrentProject( eProject ); + openFormWindow( filename ); + addRecentlyOpened( filename, recentlyFiles ); + } else if ( !extension.isEmpty() && extension.find( ";" + fi.extension( FALSE ) ) != -1 || + additionalSources.find( fi.extension( FALSE ) ) != additionalSources.end() ) { + SourceFile *sf = project->findSourceFile( project->makeRelative( filename ) ); + if ( !sf ) + sf = new SourceFile( project->makeRelative( filename ), FALSE, project ); + editSource( sf ); + } else if ( extension.isEmpty() ) { + QString filter; + for ( QStringList::Iterator it2 = filterlist.begin(); it2 != filterlist.end(); ++it2 ) { + if ( (*it2).contains( "." + fi.extension( FALSE ), FALSE ) ) { + filter = *it2; + break; + } + } + + ImportFilterInterface* iface = 0; + manager.queryInterface( filter, &iface ); + if ( !iface ) { + statusMessage( i18n( "No import filter is available to import '%1'"). + arg( filename )/*, 3000*/ ); + return; + } + statusMessage( i18n( "Importing '%1' using import filter ...").arg( filename ) ); + QStringList list = iface->import( filter, filename ); + iface->release(); + if ( list.isEmpty() ) { + statusMessage( i18n( "Nothing to load in '%1'").arg( filename )/*, 3000*/ ); + return; + } + if ( !inProject ) + setCurrentProject( eProject ); + addRecentlyOpened( filename, recentlyFiles ); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + openFormWindow( *it, FALSE ); + QFile::remove( *it ); + } + statusBar()->clear(); + } + } + } + } +} + +FormWindow *MainWindow::openFormWindow( const QString &filename, bool validFileName, FormFile *ff ) +{ + if ( filename.isEmpty() ) + return 0; + + bool makeNew = FALSE; + + if ( !QFile::exists( filename ) ) { + makeNew = TRUE; + } else { + QFile f( filename ); + f.open( IO_ReadOnly ); + QTextStream ts( &f ); + makeNew = ts.read().length() < 2; + } + if ( makeNew ) { + fileNew(); + if ( formWindow() ) + formWindow()->setFileName( filename ); + return formWindow(); + } + + statusMessage( i18n( "Reading file '%1'...").arg( filename ) ); + FormFile *ff2 = currentProject->findFormFile( currentProject->makeRelative(filename) ); + if ( ff2 && ff2->formWindow() ) { + ff2->formWindow()->setFocus(); + return ff2->formWindow(); + } + + if ( ff2 ) + ff = ff2; + QApplication::setOverrideCursor( WaitCursor ); + Resource resource( this ); + if ( !ff ) + ff = new FormFile( currentProject->makeRelative( filename ), FALSE, currentProject ); + bool b = resource.load( ff ) && (FormWindow*)resource.widget(); + if ( !validFileName && resource.widget() ) + ( (FormWindow*)resource.widget() )->setFileName( QString::null ); + QApplication::restoreOverrideCursor(); + if ( b ) { + rebuildCustomWidgetGUI(); + statusMessage( i18n( "Loaded file '%1'").arg( filename )/*, 3000 */); + } else { + statusMessage( i18n( "Failed to load file '%1'").arg( filename )/*, 5000 */); + QMessageBox::information( this, i18n("Load File"), i18n("Could not load file '%1'.").arg( filename ) ); + delete ff; + } + return (FormWindow*)resource.widget(); +} + +bool MainWindow::fileSave() +{ + + if ( !currentProject->isDummy() ) + return fileSaveProject(); + return fileSaveForm(); +} + +bool MainWindow::fileSaveForm() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->object() == formWindow() || e == qWorkspace()->activeWindow() ) { + e->save(); + } + } + + FormWindow *fw = 0; + + QWidget *w = qWorkspace()->activeWindow(); + if ( w ) { + if ( ::qt_cast<SourceEditor*>(w) ) { + SourceEditor *se = (SourceEditor*)w; + if ( se->formWindow() ) + fw = se->formWindow(); + else if ( se->sourceFile() ) { + se->sourceFile()->save(); + return TRUE; + } + } + } + + if ( !fw ) + fw = formWindow(); + if ( !fw || !fw->formFile()->save() ) + return FALSE; + QApplication::restoreOverrideCursor(); + return TRUE; +} + +bool MainWindow::fileSaveProject() +{ + currentProject->save(); + statusMessage( i18n( "Project '%1' saved.").arg( currentProject->projectName() )/*, 3000 */); + return TRUE; +} + +bool MainWindow::fileSaveAs() +{ + statusMessage( i18n( "Enter a filename..." ) ); + + QWidget *w = qworkspace->activeWindow(); + if ( !w ) + return TRUE; + if ( ::qt_cast<FormWindow*>(w) ) + return ( (FormWindow*)w )->formFile()->saveAs(); + else if ( ::qt_cast<SourceEditor*>(w) ) + return ( (SourceEditor*)w )->saveAs(); + return FALSE; +} + +void MainWindow::fileSaveAll() +{ + for ( QMap<QAction*, Project* >::Iterator it = projects.begin(); it != projects.end(); ++it ) + (*it)->save(); +} + +void MainWindow::fileCreateTemplate() +{ + CreateTemplate dia( this, 0, TRUE ); + + int i = 0; + for ( i = 0; i < WidgetDatabase::count(); ++i ) { + if ( WidgetDatabase::isForm( i ) && WidgetDatabase::group( i ) != "Temp") { + dia.listClass->insertItem( WidgetDatabase::className( i ) ); + } + } + for ( i = 0; i < WidgetDatabase::count(); ++i ) { + if ( WidgetDatabase::isContainer( i ) && !WidgetDatabase::isForm(i) && + WidgetDatabase::className( i ) != "QTabWidget" && WidgetDatabase::group( i ) != "Temp" ) { + dia.listClass->insertItem( WidgetDatabase::className( i ) ); + } + } + + QPtrList<MetaDataBase::CustomWidget> *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + if ( w->isContainer ) + dia.listClass->insertItem( w->className ); + } + + dia.editName->setText( i18n( "NewTemplate" ) ); + connect( dia.buttonCreate, SIGNAL( clicked() ), + this, SLOT( createNewTemplate() ) ); + dia.exec(); +} + +void MainWindow::createNewTemplate() +{ + CreateTemplate *dia = (CreateTemplate*)sender()->parent(); + QString fn = dia->editName->text(); + QString cn = dia->listClass->currentText(); + if ( fn.isEmpty() || cn.isEmpty() ) { + QMessageBox::information( this, i18n( "Create Template" ), i18n( "Could not create the template." ) ); + return; + } + + QStringList templRoots; + const char *qtdir = getenv( "QTDIR" ); + if(qtdir) + templRoots << qtdir; + templRoots << qInstallPathData(); + if(qtdir) //try the tools/designer directory last! + templRoots << (QString(qtdir) + "/tools/designer"); + QFile f; + for ( QStringList::Iterator it = templRoots.begin(); it != templRoots.end(); ++it ) { + if ( QFile::exists( (*it) + "/templates/" )) { + QString tmpfn = (*it) + "/templates/" + fn + ".ui"; + f.setName(tmpfn); + if(f.open(IO_WriteOnly)) + break; + } + } + if ( !f.isOpen() ) { + QMessageBox::information( this, i18n( "Create Template" ), i18n( "Could not create the template." ) ); + return; + } + QTextStream ts( &f ); + + ts << "<!DOCTYPE UI><UI>" << endl; + ts << "<widget>" << endl; + ts << "<class>" << cn << "</class>" << endl; + ts << "<property stdset=\"1\">" << endl; + ts << " <name>name</name>" << endl; + ts << " <cstring>" << cn << "Form</cstring>" << endl; + ts << "</property>" << endl; + ts << "<property stdset=\"1\">" << endl; + ts << " <name>geometry</name>" << endl; + ts << " <rect>" << endl; + ts << " <width>300</width>" << endl; + ts << " <height>400</height>" << endl; + ts << " </rect>" << endl; + ts << "</property>" << endl; + ts << "</widget>" << endl; + ts << "</UI>" << endl; + + dia->editName->setText( i18n( "NewTemplate" ) ); + + f.close(); +} + +void MainWindow::editUndo() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editUndo(); + return; + } + if ( formWindow() ) + formWindow()->undo(); +} + +void MainWindow::editRedo() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editRedo(); + return; + } + if ( formWindow() ) + formWindow()->redo(); +} + +void MainWindow::editCut() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editCut(); + return; + } + editCopy(); + editDelete(); +} + +void MainWindow::editCopy() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editCopy(); + return; + } + if ( formWindow() ) + qApp->clipboard()->setText( formWindow()->copy() ); +} + +void MainWindow::editPaste() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editPaste(); + return; + } + if ( !formWindow() ) + return; + + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) { + w = l.first(); + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) && + w != formWindow()->mainContainer() ) ) + w = formWindow()->mainContainer(); + } + + if ( w && WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) { + formWindow()->paste( qApp->clipboard()->text(), WidgetFactory::containerOfWidget( w ) ); + hierarchyView->widgetInserted( 0 ); + formWindow()->commandHistory()->setModified( TRUE ); + } else { + QMessageBox::information( this, i18n( "Paste Error" ), + i18n( "Cannot paste widgets. Designer could not find a container\n" + "to paste into which does not contain a layout. Break the layout\n" + "of the container you want to paste into and select this container\n" + "and then paste again." ) ); + } +} + +void MainWindow::editDelete() +{ + if ( formWindow() ) + formWindow()->deleteWidgets(); +} + +void MainWindow::editSelectAll() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editSelectAll(); + return; + } + if ( formWindow() ) + formWindow()->selectAll(); +} + + +void MainWindow::editLower() +{ + if ( formWindow() ) + formWindow()->lowerWidgets(); +} + +void MainWindow::editRaise() +{ + if ( formWindow() ) + formWindow()->raiseWidgets(); +} + +void MainWindow::editAdjustSize() +{ + if ( formWindow() ) + formWindow()->editAdjustSize(); +} + +void MainWindow::editLayoutHorizontal() +{ + if ( layoutChilds ) + editLayoutContainerHorizontal(); + else if ( layoutSelected && formWindow() ) + formWindow()->layoutHorizontal(); +} + +void MainWindow::editLayoutVertical() +{ + if ( layoutChilds ) + editLayoutContainerVertical(); + else if ( layoutSelected && formWindow() ) + formWindow()->layoutVertical(); +} + +void MainWindow::editLayoutHorizontalSplit() +{ + if ( layoutChilds ) + ; // no way to do that + else if ( layoutSelected && formWindow() ) + formWindow()->layoutHorizontalSplit(); +} + +void MainWindow::editLayoutVerticalSplit() +{ + if ( layoutChilds ) + ; // no way to do that + else if ( layoutSelected && formWindow() ) + formWindow()->layoutVerticalSplit(); +} + +void MainWindow::editLayoutGrid() +{ + if ( layoutChilds ) + editLayoutContainerGrid(); + else if ( layoutSelected && formWindow() ) + formWindow()->layoutGrid(); +} + +void MainWindow::editLayoutContainerVertical() +{ + if ( !formWindow() ) + return; + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) + w = l.first(); + if ( w ) + formWindow()->layoutVerticalContainer( w ); +} + +void MainWindow::editLayoutContainerHorizontal() +{ + if ( !formWindow() ) + return; + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) + w = l.first(); + if ( w ) + formWindow()->layoutHorizontalContainer( w ); +} + +void MainWindow::editLayoutContainerGrid() +{ + if ( !formWindow() ) + return; + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) + w = l.first(); + if ( w ) + formWindow()->layoutGridContainer( w ); +} + +void MainWindow::editBreakLayout() +{ + if ( !formWindow() || !breakLayout ) + return; + QWidget *w = formWindow()->mainContainer(); + if ( formWindow()->currentWidget() ) + w = formWindow()->currentWidget(); + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) { + formWindow()->breakLayout( w ); + return; + } else { + QWidgetList widgets = formWindow()->selectedWidgets(); + for ( w = widgets.first(); w; w = widgets.next() ) { + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + break; + } + if ( w ) { + formWindow()->breakLayout( w ); + return; + } + } + + w = formWindow()->mainContainer(); + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + formWindow()->breakLayout( w ); +} + +void MainWindow::editAccels() +{ + if ( !formWindow() ) + return; + formWindow()->checkAccels(); +} + +void MainWindow::editFunctions() +{ + if ( !formWindow() ) + return; + + statusMessage( i18n( "Edit the current form's slots..." ) ); + EditFunctions dlg( this, formWindow(), TRUE ); + dlg.exec(); + statusBar()->clear(); +} + +void MainWindow::editConnections() +{ + if ( !formWindow() ) + return; + + statusMessage( i18n( "Edit the current form's connections..." ) ); + ConnectionDialog dlg( this ); + dlg.exec(); + + statusBar()->clear(); +} + +SourceEditor *MainWindow::editSource() +{ + if ( !formWindow() ) + return 0; + return formWindow()->formFile()->showEditor(); +} + +SourceEditor *MainWindow::openSourceEditor() +{ + if ( !formWindow() ) + return 0; + + QString lang = currentProject->language(); + if ( !MetaDataBase::hasEditor( lang ) ) { + QMessageBox::information( this, i18n( "Edit Source" ), + i18n( "There is no plugin for editing %1 code installed.\n" + "Note: Plugins are not available in static Qt configurations." ).arg( lang ) ); + return 0; + } + + SourceEditor *editor = 0; + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->language() == lang && e->formWindow() == formWindow() ) { + editor = e; + break; + } + } + + if ( !editor ) + editor = createSourceEditor( formWindow(), formWindow()->project(), lang ); + return editor; +} + +SourceEditor *MainWindow::editSource( SourceFile *f ) +{ + QString lang = currentProject->language(); + if ( !MetaDataBase::hasEditor( lang ) ) { + QMessageBox::information( this, i18n( "Edit Source" ), + i18n( "There is no plugin for editing %1 code installed.\n" + "Note: Plugins are not available in static Qt configurations." ).arg( lang ) ); + return 0; + } + + SourceEditor *editor = 0; + if ( f ) + editor = f->editor(); + if ( !editor ) + editor = createSourceEditor( f, currentProject, lang ); + editor->setActiveWindow(); + editor->setFocus(); + return editor; +} + +SourceEditor *MainWindow::createSourceEditor( QObject *object, Project *project, + const QString &lang, const QString &func, + bool rereadSource ) +{ + SourceEditor *editor = 0; + EditorInterface *eIface = 0; + editorPluginManager->queryInterface( lang, &eIface ); + if ( !eIface ) + return 0; + LanguageInterface *lIface = MetaDataBase::languageInterface( lang ); + if ( !lIface ) + return 0; + QApplication::setOverrideCursor( WaitCursor ); + editor = new SourceEditor( qWorkspace(), eIface, lIface ); + eIface->release(); + lIface->release(); + + editor->setLanguage( lang ); + sourceEditors.append( editor ); + QApplication::restoreOverrideCursor(); + + if ( editor->object() != object ) + editor->setObject( object, project ); + else if ( rereadSource ) + editor->refresh( FALSE ); + + editor->show(); + editor->setFocus(); + if ( !func.isEmpty() ) + editor->setFunction( func ); + emit editorChanged(); + + return editor; +} + +void MainWindow::editFormSettings() +{ + if ( !formWindow() ) + return; + + statusMessage( i18n( "Edit the current form's settings..." ) ); + FormSettings dlg( this, formWindow() ); + dlg.exec(); + statusBar()->clear(); +} + +void MainWindow::editProjectSettings() +{ + openProjectSettings( currentProject ); + wspace->setCurrentProject( currentProject ); +} + +void MainWindow::editPixmapCollection() +{ + PixmapCollectionEditor dia( this, 0, TRUE ); + dia.setProject( currentProject ); + dia.exec(); +} + +void MainWindow::editDatabaseConnections() +{ +#ifndef QT_NO_SQL + DatabaseConnectionsEditor dia( currentProject, this, 0, TRUE ); + dia.exec(); +#endif +} + +void MainWindow::editPreferences() +{ + statusMessage( i18n( "Edit preferences..." ) ); + Preferences *dia = new Preferences( this, 0, TRUE ); + prefDia = dia; + connect( dia->helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + dia->buttonColor->setEditor( StyledButton::ColorEditor ); + dia->buttonPixmap->setEditor( StyledButton::PixmapEditor ); + dia->groupBoxGrid->setChecked( sGrid ); + dia->checkBoxSnapGrid->setChecked( snGrid ); + dia->spinGridX->setValue( grid().x() ); + dia->spinGridY->setValue( grid().y() ); + dia->checkBoxWorkspace->setChecked( restoreConfig ); + dia->checkBoxTextLabels->setChecked( usesTextLabel() ); + dia->buttonColor->setColor( qworkspace->backgroundColor() ); + QString pluginPaths = QApplication::libraryPaths().join("\n"); + dia->textEditPluginPaths->setText(pluginPaths); + if ( qworkspace->backgroundPixmap() ) + dia->buttonPixmap->setPixmap( *qworkspace->backgroundPixmap() ); + if ( backPix ) + dia->radioPixmap->setChecked( TRUE ); + else + dia->radioColor->setChecked( TRUE ); + dia->checkBoxSplash->setChecked( splashScreen ); + dia->checkAutoEdit->setChecked( !databaseAutoEdit ); + dia->checkBoxStartDialog->setChecked( shStartDialog ); + dia->checkBoxAutoSave->setChecked( autoSaveEnabled ); + int h = autoSaveInterval / 3600; + int m = ( autoSaveInterval - h * 3600 ) / 60; + int s = autoSaveInterval - ( h * 3600 + m * 60 ); + QTime t( h, m, s ); + dia->timeEditAutoSave->setTime( t ); + + SenderObject *senderObject = new SenderObject( designerInterface() ); + QValueList<Tab>::Iterator it; + for ( it = preferenceTabs.begin(); it != preferenceTabs.end(); ++it ) { + Tab t = *it; + dia->tabWidget->addTab( t.w, t.title ); + if ( t.receiver ) { + connect( dia->buttonOk, SIGNAL( clicked() ), senderObject, SLOT( emitAcceptSignal() ) ); + connect( senderObject, SIGNAL( acceptSignal( QUnknownInterface * ) ), t.receiver, t.accept_slot ); + connect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + senderObject->emitInitSignal(); + disconnect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + } + } + + if ( dia->exec() == QDialog::Accepted ) { + setSnapGrid( dia->checkBoxSnapGrid->isChecked() ); + setShowGrid( dia->groupBoxGrid->isChecked() ); + setGrid( QPoint( dia->spinGridX->value(), + dia->spinGridY->value() ) ); + restoreConfig = dia->checkBoxWorkspace->isChecked(); + setUsesTextLabel( dia->checkBoxTextLabels->isChecked() ); + if (dia->textEditPluginPaths->isModified()) { + pluginPaths = dia->textEditPluginPaths->text(); + QApplication::setLibraryPaths(QStringList::split("\n", pluginPaths)); + savePluginPaths = TRUE; + } + + if ( dia->radioPixmap->isChecked() && dia->buttonPixmap->pixmap() ) { + qworkspace->setBackgroundPixmap( *dia->buttonPixmap->pixmap() ); + backPix = TRUE; + } else { + qworkspace->setBackgroundColor( dia->buttonColor->color() ); + backPix = FALSE; + } + splashScreen = dia->checkBoxSplash->isChecked(); + databaseAutoEdit = !dia->checkAutoEdit->isChecked(); + shStartDialog = dia->checkBoxStartDialog->isChecked(); + autoSaveEnabled = dia->checkBoxAutoSave->isChecked(); + QTime time = dia->timeEditAutoSave->time(); + autoSaveInterval = time.hour() * 3600 + time.minute() * 60 + time.second(); + if ( autoSaveEnabled ) + autoSaveTimer->start( autoSaveInterval * 1000 ); + else + autoSaveTimer->stop(); + } + delete senderObject; + for ( it = preferenceTabs.begin(); it != preferenceTabs.end(); ++it ) { + Tab t = *it; + dia->tabWidget->removePage( t.w ); + t.w->reparent( 0, QPoint(0,0), FALSE ); + } + + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->configChanged(); + + delete dia; + prefDia = 0; + statusBar()->clear(); +} + +void MainWindow::searchFind() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + + if ( !findDialog ) + findDialog = new FindDialog( this, 0, FALSE ); + findDialog->show(); + findDialog->raise(); + findDialog->setEditor( ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface(), + ( (SourceEditor*)qWorkspace()->activeWindow() )->object() ); + findDialog->comboFind->setFocus(); + findDialog->comboFind->lineEdit()->selectAll(); +} + +void MainWindow::searchIncremetalFindMenu() +{ + incrementalSearch->selectAll(); + incrementalSearch->setFocus(); +} + +void MainWindow::searchIncremetalFind() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + + ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface()->find( incrementalSearch->text(), + FALSE, FALSE, TRUE, FALSE ); +} + +void MainWindow::searchIncremetalFindNext() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + + ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface()->find( incrementalSearch->text(), + FALSE, FALSE, TRUE, TRUE ); +} + +void MainWindow::searchReplace() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + + if ( !replaceDialog ) + replaceDialog = new ReplaceDialog( this, 0, FALSE ); + replaceDialog->show(); + replaceDialog->raise(); + replaceDialog->setEditor( ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface(), + ( (SourceEditor*)qWorkspace()->activeWindow() )->object() ); + replaceDialog->comboFind->setFocus(); + replaceDialog->comboFind->lineEdit()->selectAll(); +} + +void MainWindow::searchGotoLine() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast<SourceEditor*>(qWorkspace()->activeWindow()) ) + return; + + if ( !gotoLineDialog ) + gotoLineDialog = new GotoLineDialog( this, 0, FALSE ); + gotoLineDialog->show(); + gotoLineDialog->raise(); + gotoLineDialog->setEditor( ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface() ); + gotoLineDialog->spinLine->setFocus(); + gotoLineDialog->spinLine->setMinValue( 1 ); + gotoLineDialog->spinLine->setMaxValue( ( (SourceEditor*)qWorkspace()->activeWindow() )->numLines() ); + gotoLineDialog->spinLine->selectAll(); +} + +void MainWindow::toolsCustomWidget() +{ + statusMessage( i18n( "Edit custom widgets..." ) ); + CustomWidgetEditor edit( this, this ); + edit.exec(); + rebuildCustomWidgetGUI(); + statusBar()->clear(); +} + +void MainWindow::toolsConfigure() +{ + ConfigToolboxDialog dlg( this ); + if ( dlg.exec() != QDialog::Accepted ) + return; + rebuildCommonWidgetsToolBoxPage(); +} + +void MainWindow::showStartDialog() +{ + if ( singleProjectMode() ) + return; + for ( int i = 1; i < qApp->argc(); ++i ) { + QString arg = qApp->argv()[i]; + if ( arg[0] != '-' ) + return; + } + StartDialog *sd = new StartDialog( this, templatePath() ); + sd->setRecentlyFiles( recentlyFiles ); + sd->setRecentlyProjects( recentlyProjects ); + sd->exec(); + shStartDialog = sd->showDialogInFuture(); +} diff --git a/kdevdesigner/designer/menubareditor.cpp b/kdevdesigner/designer/menubareditor.cpp new file mode 100644 index 00000000..33cf923e --- /dev/null +++ b/kdevdesigner/designer/menubareditor.cpp @@ -0,0 +1,1129 @@ +/********************************************************************** +** Copyright (C) 2003 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 <qaction.h> +#include <qapplication.h> +#include <qbitmap.h> +#include <qdragobject.h> +#include <qlineedit.h> +#include <qmainwindow.h> +#include <qpainter.h> +#include <qstyle.h> +#include "command.h" +#include "formwindow.h" +#include "menubareditor.h" +#include "popupmenueditor.h" + +#include <klocale.h> + +extern void find_accel( const QString &txt, QMap<QChar, QWidgetList > &accels, QWidget *w ); + +// Drag Object Declaration ------------------------------------------- + +class MenuBarEditorItemPtrDrag : public QStoredDrag +{ +public: + MenuBarEditorItemPtrDrag( MenuBarEditorItem * item, + QWidget * parent = 0, + const char * name = 0 ); + ~MenuBarEditorItemPtrDrag() {}; + static bool canDecode( QDragMoveEvent * e ); + static bool decode( QDropEvent * e, MenuBarEditorItem ** i ); +}; + +// Drag Object Implementation --------------------------------------- + +MenuBarEditorItemPtrDrag::MenuBarEditorItemPtrDrag( MenuBarEditorItem * item, + QWidget * parent, + const char * name ) + : QStoredDrag( "qt/menubareditoritemptr", parent, name ) +{ + QByteArray data( sizeof( Q_LONG ) ); + QDataStream stream( data, IO_WriteOnly ); + stream << ( Q_LONG ) item; + setEncodedData( data ); +} + +bool MenuBarEditorItemPtrDrag::canDecode( QDragMoveEvent * e ) +{ + return e->provides( "qt/menubareditoritemptr" ); +} + +bool MenuBarEditorItemPtrDrag::decode( QDropEvent * e, MenuBarEditorItem ** i ) +{ + QByteArray data = e->encodedData( "qt/menubareditoritemptr" ); + QDataStream stream( data, IO_ReadOnly ); + + if ( !data.size() ) + return FALSE; + + Q_LONG p = 0; + stream >> p; + *i = ( MenuBarEditorItem *) p; + + return TRUE; +} + +// MenuBarEditorItem --------------------------------------------------- + +MenuBarEditorItem::MenuBarEditorItem( MenuBarEditor * bar, QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( bar ), + popupMenu( 0 ), + visible( TRUE ), + separator( FALSE ), + removable( FALSE ) +{ } + +MenuBarEditorItem::MenuBarEditorItem( PopupMenuEditor * menu, MenuBarEditor * bar, + QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( bar ), + popupMenu( menu ), + visible( TRUE ), + separator( FALSE ), + removable( TRUE ) +{ + text = menu->name(); +} + +MenuBarEditorItem::MenuBarEditorItem( QActionGroup * actionGroup, MenuBarEditor * bar, + QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( bar ), + popupMenu( 0 ), + visible( TRUE ), + separator( FALSE ), + removable( TRUE ) +{ + text = actionGroup->menuText(); + popupMenu = new PopupMenuEditor( menuBar->formWindow(), menuBar ); + popupMenu->insert( actionGroup ); +} + +MenuBarEditorItem::MenuBarEditorItem( MenuBarEditorItem * item, QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( item->menuBar ), + popupMenu( 0 ), + text( item->text ), + visible( item->visible ), + separator( item->separator ), + removable( item->removable ) +{ + popupMenu = new PopupMenuEditor( menuBar->formWindow(), item->popupMenu, menuBar ); +} + +// MenuBarEditor -------------------------------------------------------- + +int MenuBarEditor::clipboardOperation = 0; +MenuBarEditorItem * MenuBarEditor::clipboardItem = 0; + +MenuBarEditor::MenuBarEditor( FormWindow * fw, QWidget * parent, const char * name ) + : QMenuBar( parent, name ), + formWnd( fw ), + draggedItem( 0 ), + currentIndex( 0 ), + itemHeight( 0 ), + separatorWidth( 32 ), + hideWhenEmpty( TRUE ), + hasSeparator( FALSE ) +{ + setAcceptDrops( TRUE ); + setFocusPolicy( StrongFocus ); + + addItem.setMenuText( i18n("new menu") ); + addSeparator.setMenuText( i18n("new separator") ); + + lineEdit = new QLineEdit( this, "menubar lineedit" ); + lineEdit->hide(); + lineEdit->setFrameStyle(QFrame::Plain | QFrame::NoFrame); + lineEdit->polish(); + lineEdit->setBackgroundMode(PaletteButton); + lineEdit->setBackgroundOrigin(ParentOrigin); + lineEdit->installEventFilter( this ); + + dropLine = new QWidget( this, "menubar dropline", Qt::WStyle_NoBorder | WStyle_StaysOnTop ); + dropLine->setBackgroundColor( Qt::red ); + dropLine->hide(); + + setMinimumHeight( fontMetrics().height() + 2 * borderSize() ); +} + +MenuBarEditor::~MenuBarEditor() +{ + itemList.setAutoDelete( TRUE ); +} + +FormWindow * MenuBarEditor::formWindow() +{ + return formWnd; +} + +MenuBarEditorItem * MenuBarEditor::createItem( int index, bool addToCmdStack ) +{ + MenuBarEditorItem * i = + new MenuBarEditorItem( new PopupMenuEditor( formWnd, ( QWidget * ) parent() ), this ); + if ( addToCmdStack ) { + AddMenuCommand * cmd = new AddMenuCommand( i18n( "Add Menu" ), formWnd, this, i, index ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else { + AddMenuCommand cmd( i18n( "Add Menu" ), formWnd, this, i, index ); + cmd.execute(); + } + return i; +} + +void MenuBarEditor::insertItem( MenuBarEditorItem * item, int index ) +{ + item->menu()->parentMenu = this; + + if ( index != -1 ) + itemList.insert( index, item ); + else + itemList.append( item ); + + if ( hideWhenEmpty && itemList.count() == 1 ) + show(); // calls resizeInternals(); + else + resizeInternals(); + + if ( isVisible() ) + update(); +} + +void MenuBarEditor::insertItem( QString text, PopupMenuEditor * menu, int index ) +{ + MenuBarEditorItem * item = new MenuBarEditorItem( menu, this ); + if ( !text.isNull() ) + item->setMenuText( text ); + insertItem( item, index ); +} + +void MenuBarEditor::insertItem( QString text, QActionGroup * group, int index ) +{ + MenuBarEditorItem * item = new MenuBarEditorItem( group, this ); + if ( !text.isNull() ) + item->setMenuText( text ); + insertItem( item, index ); +} + + +void MenuBarEditor::insertSeparator( int index ) +{ + if ( hasSeparator ) + return; + + MenuBarEditorItem * i = createItem( index ); + i->setSeparator( TRUE ); + i->setMenuText( i18n( "separator" ) ); + hasSeparator = TRUE; +} + +void MenuBarEditor::removeItemAt( int index ) +{ + removeItem( item( index ) ); +} + +void MenuBarEditor::removeItem( MenuBarEditorItem * item ) +{ + if ( item && + item->isRemovable() && + itemList.removeRef( item ) ) { + + if ( item->isSeparator() ) + hasSeparator = FALSE; + + if ( hideWhenEmpty && itemList.count() == 0 ) + hide(); + else + resizeInternals(); + + int n = count() + 1; + if ( currentIndex >= n ) + currentIndex = n; + + if ( isVisible() ) + update(); + } +} + +int MenuBarEditor::findItem( MenuBarEditorItem * item ) +{ + return itemList.findRef( item ); +} + +int MenuBarEditor::findItem( PopupMenuEditor * menu ) +{ + MenuBarEditorItem * i = itemList.first(); + + while ( i ) { + if ( i->menu() == menu ) + return itemList.at(); + i = itemList.next(); + } + + return -1; +} + +int MenuBarEditor::findItem( QPoint & pos ) +{ + int x = borderSize(); + int dx = 0; + int y = 0; + int w = width(); + QSize s; + QRect r; + + MenuBarEditorItem * i = itemList.first(); + + while ( i ) { + + if ( i->isVisible() ) { + + s = itemSize( i ); + dx = s.width(); + + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + + r = QRect( x, y, s.width(), s.height() ); + + if ( r.contains( pos ) ) + return itemList.at(); + + addItemSizeToCoords( i, x, y, w ); + } + + i = itemList.next(); + } + + // check add item + s = itemSize( &addItem ); + dx = s.width(); + + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + + r = QRect( x, y, s.width(), s.height() ); + + if ( r.contains( pos ) ) + return itemList.count(); + + return itemList.count() + 1; +} + +MenuBarEditorItem * MenuBarEditor::item( int index ) +{ + if ( index == -1 ) + return itemList.at( currentIndex ); + + int c = itemList.count(); + if ( index == c ) + return &addItem; + else if ( index > c ) + return &addSeparator; + + return itemList.at( index ); +} + +int MenuBarEditor::count() +{ + return itemList.count(); +} + +int MenuBarEditor::current() +{ + return currentIndex; +} + +void MenuBarEditor::cut( int index ) +{ + if ( clipboardItem && clipboardOperation == Cut ) + delete clipboardItem; + + clipboardOperation = Cut; + clipboardItem = itemList.at( index ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + return; // do nothing + } + + RemoveMenuCommand * cmd = new RemoveMenuCommand( i18n( "Cut Menu" ), formWnd, this, index ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void MenuBarEditor::copy( int index ) +{ + if ( clipboardItem && clipboardOperation == Cut ) + delete clipboardItem; + + clipboardOperation = Copy; + clipboardItem = itemList.at( index ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + } +} + +void MenuBarEditor::paste( int index ) +{ + if ( clipboardItem && clipboardOperation ) { + MenuBarEditorItem * i = new MenuBarEditorItem( clipboardItem ); + AddMenuCommand * cmd = new AddMenuCommand( i18n( "Paste Menu" ), formWnd, this, i, index ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void MenuBarEditor::exchange( int a, int b ) +{ + MenuBarEditorItem * ia = itemList.at( a ); + MenuBarEditorItem * ib = itemList.at( b ); + if ( !ia || !ib || + ia == &addItem || ia == &addSeparator || + ib == &addItem || ib == &addSeparator ) + return; // do nothing + itemList.replace( b, ia ); + itemList.replace( a, ib ); +} + +void MenuBarEditor::showLineEdit( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + MenuBarEditorItem * i = 0; + + if ( (uint) index >= itemList.count() ) + i = &addItem; + else + i = itemList.at( index ); + + if ( i && i->isSeparator() ) + return; + + // open edit field for item name + lineEdit->setText( i->menuText() ); + lineEdit->selectAll(); + QPoint pos = itemPos( index ); + lineEdit->move( pos.x() + borderSize(), pos.y() - ( borderSize() / 2 ) ); + lineEdit->resize( itemSize( i ) ); + lineEdit->show(); + lineEdit->setFocus(); +} + +void MenuBarEditor::showItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + MenuBarEditorItem * i = itemList.at( index ); + if ( i->isSeparator() || draggedItem ) + return; + PopupMenuEditor * m = i->menu(); + QPoint pos = itemPos( index ); + m->move( pos.x(), pos.y() + itemHeight - 1 ); + m->raise(); + m->show(); + setFocus(); + } +} + +void MenuBarEditor::hideItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + PopupMenuEditor * m = itemList.at( index )->menu(); + m->hideSubMenu(); + m->hide(); + } +} + +void MenuBarEditor::focusItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + PopupMenuEditor * m = itemList.at( index )->menu(); + m->setFocus(); + m->update(); + update(); + } +} + +void MenuBarEditor::deleteItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + RemoveMenuCommand * cmd = new RemoveMenuCommand( i18n( "Delete Menu" ), + formWnd, + this, + currentIndex ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +QSize MenuBarEditor::sizeHint() const +{ + return QSize( parentWidget()->width(), heightForWidth( parentWidget()->width() ) ); +} + +int MenuBarEditor::heightForWidth( int max_width ) const +{ + MenuBarEditor * that = ( MenuBarEditor * ) this; + int x = borderSize(); + int y = 0; + + QPainter p( this ); + that->itemHeight = that->itemSize( &(that->addItem) ).height(); + + MenuBarEditorItem * i = that->itemList.first(); + while ( i ) { + if ( i->isVisible() ) + that->addItemSizeToCoords( i, x, y, max_width ); + i = that->itemList.next(); + } + + that->addItemSizeToCoords( &(that->addItem), x, y, max_width ); + that->addItemSizeToCoords( &(that->addSeparator), x, y, max_width ); + + return y + itemHeight; +} + +void MenuBarEditor::show() +{ + QWidget::show(); + resizeInternals(); + + QResizeEvent e( parentWidget()->size(), parentWidget()->size() ); + QApplication::sendEvent( parentWidget(), &e ); +} + +void MenuBarEditor::checkAccels( QMap<QChar, QWidgetList > &accels ) +{ + QString t; + MenuBarEditorItem * i = itemList.first(); + while ( i ) { + t = i->menuText(); + find_accel( t, accels, this ); + // do not check the accelerators in the popup menus + i = itemList.next(); + } +} + +// public slots + +void MenuBarEditor::cut() +{ + cut( currentIndex ); +} + +void MenuBarEditor::copy() +{ + copy( currentIndex ); +} + +void MenuBarEditor::paste() +{ + paste( currentIndex ); +} + +// protected + +bool MenuBarEditor::eventFilter( QObject * o, QEvent * e ) +{ + if ( o == lineEdit && e->type() == QEvent::FocusOut ) { + leaveEditMode(); + lineEdit->hide(); + update(); + } else if ( e->type() == QEvent::LayoutHint ) { + resize( sizeHint() ); + } + return QMenuBar::eventFilter( o, e ); +} + +void MenuBarEditor::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + QRect r = rect(); + style().drawPrimitive( QStyle::PE_PanelMenuBar, &p, + r, colorGroup() ); + drawItems( p ); +} + +void MenuBarEditor::mousePressEvent( QMouseEvent * e ) +{ + mousePressPos = e->pos(); + hideItem(); + lineEdit->hide(); + currentIndex = findItem( mousePressPos ); + showItem(); + update(); + e->accept(); +} + +void MenuBarEditor::mouseDoubleClickEvent( QMouseEvent * e ) +{ + mousePressPos = e->pos(); + currentIndex = findItem( mousePressPos ); + lineEdit->hide(); + if ( currentIndex > (int)itemList.count() ) { + insertSeparator(); + update(); + } else { + showLineEdit(); + } +} + +void MenuBarEditor::mouseMoveEvent( QMouseEvent * e ) +{ + if ( e->state() & Qt::LeftButton ) { + if ( ( e->pos() - mousePressPos ).manhattanLength() > 3 ) { + bool itemCreated = FALSE; + bool isSeparator = FALSE; + draggedItem = item( findItem( mousePressPos ) ); + if ( draggedItem == &addItem ) { + draggedItem = createItem(); + itemCreated = TRUE; + } else if ( draggedItem == &addSeparator ) { + if (hasSeparator) // we can only have one separator + return; + draggedItem = createItem(); + draggedItem->setSeparator( TRUE ); + draggedItem->setMenuText( "separator" ); + isSeparator = TRUE; + itemCreated = TRUE; + } else { + isSeparator = draggedItem->isSeparator(); + } + + MenuBarEditorItemPtrDrag * d = + new MenuBarEditorItemPtrDrag( draggedItem, this ); + d->setPixmap( createTextPixmap( draggedItem->menuText() ) ); + hideItem(); + draggedItem->setVisible( FALSE ); + update(); + + // If the item is dropped in the same list, + // we will have two instances of the same pointer + // in the list. + itemList.find( draggedItem ); + QLNode * node = itemList.currentNode(); + dropConfirmed = FALSE; + d->dragCopy(); // dragevents and stuff happens + if ( draggedItem ) { // item was not dropped + if ( itemCreated ) { + removeItem( draggedItem ); + } else { + hideItem(); + draggedItem->setVisible( TRUE ); + draggedItem = 0; + showItem(); + } + } else if ( dropConfirmed ) { // item was dropped + dropConfirmed = FALSE; + hideItem(); + itemList.takeNode( node )->setVisible( TRUE ); + hasSeparator = isSeparator || hasSeparator; + showItem(); + } else { + hasSeparator = isSeparator || hasSeparator; + } + update(); + } + } +} + +void MenuBarEditor::dragEnterEvent( QDragEnterEvent * e ) +{ + if ( MenuBarEditorItemPtrDrag::canDecode( e ) ) { + e->accept(); + dropLine->show(); + } +} + +void MenuBarEditor::dragLeaveEvent( QDragLeaveEvent * ) +{ + dropLine->hide(); +} + +void MenuBarEditor::dragMoveEvent( QDragMoveEvent * e ) +{ + + QPoint pos = e->pos(); + dropLine->move( snapToItem( pos ) ); + + int idx = findItem( pos ); + if ( currentIndex != idx ) { + hideItem(); + currentIndex = idx; + showItem(); + } +} + +void MenuBarEditor::dropEvent( QDropEvent * e ) +{ + MenuBarEditorItem * i = 0; + + if ( MenuBarEditorItemPtrDrag::decode( e, &i ) ) { + draggedItem = 0; + hideItem(); + dropInPlace( i, e->pos() ); + e->accept(); + } + + dropLine->hide(); +} + +void MenuBarEditor::keyPressEvent( QKeyEvent * e ) +{ + if ( lineEdit->isHidden() ) { // In navigation mode + switch ( e->key() ) { + + case Qt::Key_Delete: + hideItem(); + deleteItem(); + showItem(); + break; + + case Qt::Key_Left: + e->accept(); + navigateLeft( e->state() & Qt::ControlButton ); + return; + + case Qt::Key_Right: + e->accept(); + navigateRight( e->state() & Qt::ControlButton ); + return; // no update + + case Qt::Key_Down: + e->accept(); + focusItem(); + return; // no update + + case Qt::Key_PageUp: + currentIndex = 0; + break; + + case Qt::Key_PageDown: + currentIndex = itemList.count(); + break; + + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_F2: + e->accept(); + enterEditMode(); + return; // no update + + case Qt::Key_Up: + case Qt::Key_Alt: + case Qt::Key_Shift: + case Qt::Key_Control: + case Qt::Key_Escape: + e->ignore(); + setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed + return; // no update + + case Qt::Key_C: + if ( e->state() & Qt::ControlButton && currentIndex < (int)itemList.count() ) { + copy( currentIndex ); + break; + } + + case Qt::Key_X: + if ( e->state() & Qt::ControlButton && currentIndex < (int)itemList.count() ) { + hideItem(); + cut( currentIndex ); + showItem(); + break; + } + + case Qt::Key_V: + if ( e->state() & Qt::ControlButton ) { + hideItem(); + paste( currentIndex < (int)itemList.count() ? currentIndex + 1: itemList.count() ); + showItem(); + break; + } + + default: + if ( e->ascii() >= 32 || e->ascii() == 0 ) { + showLineEdit(); + QApplication::sendEvent( lineEdit, e ); + e->accept(); + } else { + e->ignore(); + } + return; + } + } else { // In edit mode + + switch ( e->key() ) { + case Qt::Key_Control: + e->ignore(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + leaveEditMode(); + case Qt::Key_Escape: + lineEdit->hide(); + setFocus(); + break; + } + } + e->accept(); + update(); +} + +void MenuBarEditor::focusOutEvent( QFocusEvent * e ) +{ + QWidget * fw = qApp->focusWidget(); + if ( e->lostFocus() && !::qt_cast<PopupMenuEditor*>(fw) ) + hideItem(); + update(); +} + +void MenuBarEditor::resizeInternals() +{ + dropLine->resize( 2, itemHeight ); + updateGeometry(); +} + +void MenuBarEditor::drawItems( QPainter & p ) +{ + QPoint pos( borderSize(), 0 ); + uint c = 0; + + p.setPen( colorGroup().buttonText() ); + + MenuBarEditorItem * i = itemList.first(); + while ( i ) { + if ( i->isVisible() ) + drawItem( p, i, c++, pos ); // updates x y + i = itemList.next(); + } + + p.setPen( darkBlue ); + drawItem( p, &addItem, c++, pos ); + if ( !hasSeparator ) + drawItem( p, &addSeparator, c, pos ); +} + +void MenuBarEditor::drawItem( QPainter & p, + MenuBarEditorItem * i, + int idx, + QPoint & pos ) +{ + int w = itemSize( i ).width(); + + // If the item passes the right border, and it is not the first item on the line + if ( pos.x() + w > width() && pos.x() > borderSize() ) { // wrap + pos.ry() += itemHeight; + pos.setX( borderSize() ); + } + + if ( i->isSeparator() ) { + drawSeparator( p, pos ); + } else { + int flags = QPainter::AlignLeft | QPainter::AlignVCenter | + Qt::ShowPrefix | Qt::SingleLine; + p.drawText( pos.x() + borderSize(), pos.y(), w - borderSize(), itemHeight, + flags, i->menuText() ); + } + + if ( hasFocus() && idx == currentIndex && !draggedItem ) + p.drawWinFocusRect( pos.x(), pos.y() + 1, w, itemHeight - 2 ); + + pos.rx() += w; +} + +void MenuBarEditor::drawSeparator( QPainter & p, QPoint & pos ) +{ + p.save(); + p.setPen( darkBlue ); + + int left = pos.x(); + int top = pos.y() + 2; + int right = left + separatorWidth - 1; + int bottom = pos.y() + itemHeight - 4; + + p.drawLine( left, top, left, bottom ); + p.drawLine( right, top, right, bottom ); + + p.fillRect( left, pos.y() + borderSize() * 2, + separatorWidth - 1, itemHeight - borderSize() * 4, + QBrush( darkBlue, Qt::Dense5Pattern ) ); + + p.restore(); +} + +QSize MenuBarEditor::itemSize( MenuBarEditorItem * i ) +{ + if ( i->isSeparator() ) + return QSize( separatorWidth, itemHeight ); + QRect r = fontMetrics().boundingRect( i->menuText().remove( "&") ); + return QSize( r.width() + borderSize() * 2, r.height() + borderSize() * 4 ); +} + +void MenuBarEditor::addItemSizeToCoords( MenuBarEditorItem * i, int & x, int & y, int w ) +{ + int dx = itemSize( i ).width(); + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + x += dx; +} + +QPoint MenuBarEditor::itemPos( int index ) +{ + int x = borderSize(); + int y = 0; + int w = width(); + int dx = 0; + int c = 0; + + MenuBarEditorItem * i = itemList.first(); + + while ( i ) { + if ( i->isVisible() ) { + dx = itemSize( i ).width(); + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + if ( c == index ) + return QPoint( x, y ); + x += dx; + c++; + } + i = itemList.next(); + } + dx = itemSize( &addItem ).width(); + if ( x + dx > width() && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + + return QPoint( x, y ); +} + +QPoint MenuBarEditor::snapToItem( const QPoint & pos ) +{ + int x = borderSize(); + int y = 0; + int dx = 0; + + MenuBarEditorItem * n = itemList.first(); + + while ( n ) { + if ( n->isVisible() ) { + dx = itemSize( n ).width(); + if ( x + dx > width() && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + if ( pos.y() > y && + pos.y() < y + itemHeight && + pos.x() < x + dx / 2 ) { + return QPoint( x, y ); + } + x += dx; + } + n = itemList.next(); + } + + return QPoint( x, y ); +} + +void MenuBarEditor::dropInPlace( MenuBarEditorItem * i, const QPoint & pos ) +{ + int x = borderSize(); + int y = 0; + int dx = 0; + int idx = 0; + + MenuBarEditorItem * n = itemList.first(); + + while ( n ) { + if ( n->isVisible() ) { + dx = itemSize( n ).width(); + if ( x + dx > width() && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + if ( pos.y() > y && + pos.y() < y + itemHeight && + pos.x() < x + dx / 2 ) + break; + x += dx; + } + n = itemList.next(); + idx++; + } + + hideItem(); + Command * cmd = 0; + int iidx = itemList.findRef( i ); + if ( iidx != -1 ) { // internal dnd + cmd = new MoveMenuCommand( i18n( "Item Dragged" ), formWnd, this, iidx, idx ); + item( iidx )->setVisible( TRUE ); + } else { + cmd = new AddMenuCommand( i18n( "Add Menu" ), formWnd, this, i, idx ); + dropConfirmed = TRUE; // let mouseMoveEvent set the item visible + } + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + currentIndex = ( iidx >= 0 && iidx < idx ) ? idx - 1 : idx; + showItem(); +} + + +void MenuBarEditor::safeDec() +{ + do { + currentIndex--; + } while ( currentIndex > 0 && !( item( currentIndex )->isVisible() ) ); +} + +void MenuBarEditor::safeInc() +{ + int max = (int)itemList.count(); + if ( !hasSeparator ) + max += 1; + if ( currentIndex < max ) { + do { + currentIndex++; + // skip invisible items + } while ( currentIndex < max && !( item( currentIndex )->isVisible() ) ); + } +} + +void MenuBarEditor::navigateLeft( bool ctrl ) +{ + // FIXME: handle invisible items + if ( currentIndex > 0 ) { + hideItem(); + if ( ctrl ) { + ExchangeMenuCommand * cmd = new ExchangeMenuCommand( i18n( "Move Menu Left" ), + formWnd, + this, + currentIndex, + currentIndex - 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeDec(); + } else { + safeDec(); + } + showItem(); + } + update(); +} + +void MenuBarEditor::navigateRight( bool ctrl ) +{ +// FIXME: handle invisible items + hideItem(); + if ( ctrl ) { + if ( currentIndex < ( (int)itemList.count() - 1 ) ) { + ExchangeMenuCommand * cmd = new ExchangeMenuCommand( i18n( "Move Menu Right" ), + formWnd, + this, + currentIndex, + currentIndex + 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeInc(); + } + } else { + safeInc(); + } + showItem(); + update(); +} + +void MenuBarEditor::enterEditMode() +{ + if ( currentIndex > (int)itemList.count() ) { + insertSeparator(); + } else { + showLineEdit(); + } +} + +void MenuBarEditor::leaveEditMode() +{ + MenuBarEditorItem * i = 0; + if ( currentIndex >= (int)itemList.count() ) { + i = createItem(); + // do not put rename on cmd stack + RenameMenuCommand rename( i18n( "Rename Menu" ), formWnd, this, lineEdit->text(), i ); + rename.execute(); + } else { + i = itemList.at( currentIndex ); + RenameMenuCommand * cmd = + new RenameMenuCommand( i18n( "Rename Menu" ), formWnd, this, lineEdit->text(), i ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + showItem(); +} + +QPixmap MenuBarEditor::createTextPixmap( const QString &text ) +{ + QSize sz( fontMetrics().boundingRect( text ).size() ); + QPixmap pix( sz.width() + 20, sz.height() * 2 ); + pix.fill( white ); + QPainter p( &pix, this ); + p.drawText( 2, 0, pix.width(), pix.height(), 0, text ); + p.end(); + QBitmap bm( pix.size() ); + bm.fill( color0 ); + p.begin( &bm ); + p.setPen( color1 ); + p.drawText( 2, 0, pix.width(), pix.height(), 0, text ); + p.end(); + pix.setMask( bm ); + return pix; +} diff --git a/kdevdesigner/designer/menubareditor.h b/kdevdesigner/designer/menubareditor.h new file mode 100644 index 00000000..c8dc2b63 --- /dev/null +++ b/kdevdesigner/designer/menubareditor.h @@ -0,0 +1,198 @@ +/********************************************************************** +** Copyright (C) 2003 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 MENUBAREDITOR_H +#define MENUBAREDITOR_H + +#include <qmenubar.h> +#include <qptrlist.h> + +class PopupMenuEditor; +class MenuBarEditor; +class QActionGroup; + +class MenuBarEditorItem : public QObject +{ + Q_OBJECT + + friend class MenuBarEditor; + + MenuBarEditorItem( MenuBarEditor * bar = 0, QObject * parent = 0, const char * name = 0 ); + +public: + MenuBarEditorItem( PopupMenuEditor * menu, MenuBarEditor * bar, + QObject * parent = 0, const char * name = 0); + MenuBarEditorItem( QActionGroup * actionGroup, MenuBarEditor * bar, + QObject * parent = 0, const char * name = 0); + MenuBarEditorItem( MenuBarEditorItem * item, + QObject * parent = 0, const char * name = 0); + ~MenuBarEditorItem() { }; + + PopupMenuEditor * menu() { return popupMenu; } + + void setMenuText( const QString t ) { text = t; }; + QString menuText() { return text; } + + void setVisible( bool enable ) { visible = enable; } + bool isVisible() { return visible; } + + void setRemovable( bool enable ) { removable = enable; } + bool isRemovable() { return removable; } + + bool isSeparator() { return separator; } +protected: + void setSeparator( bool enable ) { separator = enable; } + +private: + MenuBarEditor * menuBar; + PopupMenuEditor * popupMenu; + QString text; + uint visible : 1; + uint separator : 1; + uint removable : 1; +}; + +class QLineEdit; +class FormWindow; + +class MenuBarEditor : public QMenuBar +{ + Q_OBJECT + +public: + MenuBarEditor( FormWindow * fw, QWidget * parent = 0, const char * name = 0 ); + ~MenuBarEditor(); + + FormWindow * formWindow(); + + MenuBarEditorItem * createItem( int index = -1, bool addToCmdStack = TRUE ); + void insertItem( MenuBarEditorItem * item, int index = -1 ); + void insertItem( QString text, PopupMenuEditor * menu, int index = -1 ); + void insertItem( QString text, QActionGroup * group, int index = -1 ); + + void insertSeparator( int index = -1 ); + + void removeItemAt( int index ); + void removeItem( MenuBarEditorItem * item ); + + int findItem( MenuBarEditorItem * item ); + int findItem( PopupMenuEditor * menu ); + int findItem( QPoint & pos ); + + MenuBarEditorItem * item( int index = -1 ); + + int count(); + int current(); + + void cut( int index ); + void copy( int index ); + void paste( int index ); + void exchange( int a, int b ); + + void showLineEdit( int index = -1); + void showItem( int index = -1 ); + void hideItem( int index = -1 ); + void focusItem( int index = -1 ); + void deleteItem( int index = -1 ); + + QSize sizeHint() const; + QSize minimumSize() const { return sizeHint(); } + QSize minimumSizeHint() const { return sizeHint(); } + int heightForWidth( int max_width ) const; + + void show(); + + void checkAccels( QMap<QChar, QWidgetList > &accels ); + +public slots: + void cut(); + void copy(); + void paste(); + +protected: + bool eventFilter( QObject * o, QEvent * e ); + void paintEvent( QPaintEvent * e ); + void mousePressEvent( QMouseEvent * e ); + void mouseDoubleClickEvent( QMouseEvent * e ); + void mouseMoveEvent( QMouseEvent * e ); + void dragEnterEvent( QDragEnterEvent * e ); + void dragLeaveEvent( QDragLeaveEvent * e ); + void dragMoveEvent( QDragMoveEvent * e ); + void dropEvent( QDropEvent * e ); + void keyPressEvent( QKeyEvent * e ); + void focusOutEvent( QFocusEvent * e ); + void resizeEvent( QResizeEvent * e ) { QFrame::resizeEvent( e ); } + + void resizeInternals(); + + void drawItems( QPainter & p ); + void drawItem( QPainter & p, MenuBarEditorItem * i, int idx, QPoint & pos ); + void drawSeparator( QPainter & p, QPoint & pos ); + + QSize itemSize( MenuBarEditorItem * i ); + void addItemSizeToCoords( MenuBarEditorItem * i, int & x, int & y, int w ); + + QPoint itemPos( int index ); + QPoint snapToItem( const QPoint & pos ); + void dropInPlace( MenuBarEditorItem * i, const QPoint & pos ); + + void safeDec(); + void safeInc(); + + void navigateLeft( bool ctrl ); + void navigateRight( bool ctrl ); + void enterEditMode(); + void leaveEditMode(); + + QPixmap createTextPixmap( const QString &text ); + int borderSize() const { return margin() + 4; } // add 4 pixels to the margin + +private: + FormWindow * formWnd; + QLineEdit * lineEdit; + QWidget * dropLine; + QPtrList<MenuBarEditorItem> itemList; + MenuBarEditorItem addItem; + MenuBarEditorItem addSeparator; + MenuBarEditorItem * draggedItem; + QPoint mousePressPos; + int currentIndex; + int itemHeight; + int separatorWidth; + bool hideWhenEmpty; + bool hasSeparator; + bool dropConfirmed; + + enum ClipboardOperation { + None = 0, + Cut = 1, + Copy = 2 + }; + static int clipboardOperation; + static MenuBarEditorItem * clipboardItem; +}; + +#endif //MENUBAREDITOR_H diff --git a/kdevdesigner/designer/metadatabase.cpp b/kdevdesigner/designer/metadatabase.cpp new file mode 100644 index 00000000..3a97b680 --- /dev/null +++ b/kdevdesigner/designer/metadatabase.cpp @@ -0,0 +1,1692 @@ +/********************************************************************** +** 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 "metadatabase.h" +#include "widgetfactory.h" +#include "formwindow.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "formfile.h" +#include "propertyobject.h" +#include "project.h" +#include "mainwindow.h" + +#include "kdevdesigner_part.h" + +#include <kiconloader.h> +#include <kapplication.h> +#include <kstandarddirs.h> + +#include <qapplication.h> +#include <qobject.h> +#include <qlayout.h> +#include <qptrdict.h> +#include <qobjectlist.h> +#include <qstrlist.h> +#include <qmetaobject.h> +#include <qwidgetlist.h> +#include <qmainwindow.h> +#include <qregexp.h> +#include <private/qpluginmanager_p.h> +#include <qdatetime.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qtextstream.h> + +#include <stdlib.h> + +class MetaDataBaseRecord +{ +public: + QObject *object; + QStringList changedProperties; + QMap<QString,QVariant> fakeProperties; + QMap<QString, QString> propertyComments; + int spacing, margin; + QString resizeMode; + QValueList<MetaDataBase::Connection> connections; + QValueList<MetaDataBase::Function> functionList; + QValueList<MetaDataBase::Include> includes; + QValueList<MetaDataBase::Variable> variables; + QStringList forwards, sigs; + QWidgetList tabOrder; + MetaDataBase::MetaInfo metaInfo; + QCursor cursor; + QMap<int, QString> pixmapArguments; + QMap<int, QString> pixmapKeys; + QMap<QString, QString> columnFields; + QValueList<uint> breakPoints; + QMap<int, QString> breakPointConditions; + QString exportMacro; +}; + +static QPtrDict<MetaDataBaseRecord> *db = 0; +static QPtrList<MetaDataBase::CustomWidget> *cWidgets = 0; +static bool doUpdate = TRUE; +static QStringList langList; +static QStringList editorLangList; +static QPluginManager<LanguageInterface> *languageInterfaceManager = 0; + +/*! + \class MetaDataBase metadatabase.h + \brief Database which stores meta data of widgets + + The MetaDataBase stores meta information of widgets, which are not + stored directly in widgets (properties). This is e.g. the + information which properties have been modified. +*/ + +MetaDataBase::MetaDataBase() +{ +} + +inline void setupDataBase() +{ + if ( !db || !cWidgets ) { + db = new QPtrDict<MetaDataBaseRecord>( 1481 ); + db->setAutoDelete( TRUE ); + cWidgets = new QPtrList<MetaDataBase::CustomWidget>; + cWidgets->setAutoDelete( TRUE ); + } +} + +void MetaDataBase::clearDataBase() +{ + delete db; + db = 0; + delete cWidgets; + cWidgets = 0; +} + +void MetaDataBase::addEntry( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + if ( db->find( o ) ) + return; + MetaDataBaseRecord *r = new MetaDataBaseRecord; + r->object = o; + r->spacing = r->margin = -1; + db->insert( (void*)o, r ); + + WidgetFactory::initChangedProperties( o ); +} + +void MetaDataBase::removeEntry( QObject *o ) +{ + setupDataBase(); + db->remove( o ); +} + +void MetaDataBase::setPropertyChanged( QObject *o, const QString &property, bool changed ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdPropertyChanged( property, changed ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + if ( changed ) { + if ( r->changedProperties.findIndex( property ) == -1 ) + r->changedProperties.append( property ); + } else { + if ( r->changedProperties.findIndex( property ) != -1 ) + r->changedProperties.remove( property ); + } + + if ( doUpdate && + ( property == "hAlign" || property == "vAlign" || property == "wordwrap" ) ) { + doUpdate = FALSE; + setPropertyChanged( o, "alignment", changed || + isPropertyChanged( o, "hAlign" ) || + isPropertyChanged( o, "vAlign" ) || + isPropertyChanged( o, "wordwrap" ) ); + doUpdate = TRUE; + } + + if ( doUpdate && property == "alignment" ) { + doUpdate = FALSE; + setPropertyChanged( o, "hAlign", changed ); + setPropertyChanged( o, "vAlign", changed ); + setPropertyChanged( o, "wordwrap", changed ); + doUpdate = TRUE; + } +} + +bool MetaDataBase::isPropertyChanged( QObject *o, const QString &property ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdIsPropertyChanged( property ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + return r->changedProperties.findIndex( property ) != -1; +} + +QStringList MetaDataBase::changedProperties( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QStringList(); + } + + QStringList lst( r->changedProperties ); + return lst; +} + +void MetaDataBase::setPropertyComment( QObject *o, const QString &property, const QString &comment ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetPropertyComment( property, comment ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->propertyComments.insert( property, comment ); +} + +QString MetaDataBase::propertyComment( QObject *o, const QString &property ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdPropertyComment( property ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + return *r->propertyComments.find( property ); +} + +void MetaDataBase::setFakeProperty( QObject *o, const QString &property, const QVariant& value ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetFakeProperty( property, value ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + r->fakeProperties[property] = value; +} + +QVariant MetaDataBase::fakeProperty( QObject * o, const QString &property) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdFakeProperty( property ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QVariant(); + } + QMap<QString, QVariant>::Iterator it = r->fakeProperties.find( property ); + if ( it != r->fakeProperties.end() ) + return r->fakeProperties[property]; + return WidgetFactory::defaultValue( o, property ); + +} + +QMap<QString,QVariant>* MetaDataBase::fakeProperties( QObject* o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return 0; + } + return &r->fakeProperties; +} + +void MetaDataBase::setSpacing( QObject *o, int spacing ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->spacing = spacing; + QLayout * layout = 0; + WidgetFactory::layoutType( (QWidget*)o, layout ); + if ( layout ) { + int spadef = 6; + if ( MainWindow::self->formWindow() ) + spadef = MainWindow::self->formWindow()->layoutDefaultSpacing(); + if ( spacing == -1 ) + layout->setSpacing( spadef ); + else + layout->setSpacing( spacing ); + } +} + +int MetaDataBase::spacing( QObject *o ) +{ + if ( !o ) + return -1; + setupDataBase(); + if ( ::qt_cast<QMainWindow*>(o) ) + o = ( (QMainWindow*)o )->centralWidget(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return -1; + } + + return r->spacing; +} + +void MetaDataBase::setMargin( QObject *o, int margin ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->margin = margin; + QLayout * layout = 0; + WidgetFactory::layoutType( (QWidget*)o, layout ); + + bool isInnerLayout = TRUE; + + QWidget *widget = (QWidget*)o; + if ( widget && !::qt_cast<QLayoutWidget*>(widget) && + ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( widget ) ) ) || + widget && widget->parentWidget() && ::qt_cast<FormWindow*>(widget->parentWidget()) ) ) + isInnerLayout = FALSE; + + + if ( layout ) { + int mardef = 11; + if ( MainWindow::self->formWindow() ) + mardef = MainWindow::self->formWindow()->layoutDefaultMargin(); + if ( margin == -1 ) { + if ( isInnerLayout ) + layout->setMargin( 1 ); + else + layout->setMargin( QMAX( 1, mardef ) ); + } + else + layout->setMargin( QMAX( 1, margin ) ); + } +} + +int MetaDataBase::margin( QObject *o ) +{ + if ( !o ) + return -1; + setupDataBase(); + if ( ::qt_cast<QMainWindow*>(o) ) + o = ( (QMainWindow*)o )->centralWidget(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return -1; + } + return r->margin; +} + +void MetaDataBase::setResizeMode( QObject *o, const QString &mode ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->resizeMode = mode; +} + +QString MetaDataBase::resizeMode( QObject *o ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + if ( ::qt_cast<QMainWindow*>(o) ) + o = ( (QMainWindow*)o )->centralWidget(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + return r->resizeMode; +} + +void MetaDataBase::addConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot, bool addCode ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + if ( !(sender && receiver) ) + return; + Connection conn; + conn.sender = sender; + conn.signal = signal; + conn.receiver = receiver; + conn.slot = slot; + r->connections.append( conn ); + if ( addCode ) { + QString rec = receiver->name(); + if ( ::qt_cast<FormWindow*>(o) && receiver == ( (FormWindow*)o )->mainContainer() ) + rec = "this"; + QString sen = sender->name(); + if ( ::qt_cast<FormWindow*>(o) && sender == ( (FormWindow*)o )->mainContainer() ) + sen = "this"; + FormFile *ff = 0; + if ( ::qt_cast<FormFile*>(o) ) + ff = (FormFile*)o; + else if ( ::qt_cast<FormWindow*>(o) ) + ff = ( (FormWindow*)o )->formFile(); + ff->addConnection( sen, signal, rec, slot ); + } +} + +void MetaDataBase::removeConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + if ( !(sender && receiver) ) + return; + for ( QValueList<Connection>::Iterator it = r->connections.begin(); it != r->connections.end(); ++it ) { + Connection conn = *it; + if ( conn.sender == sender && + conn.signal == signal && + conn.receiver == receiver && + conn.slot == slot ) { + r->connections.remove( it ); + break; + } + } + if ( ::qt_cast<FormWindow*>(o) ) { + QString rec = receiver->name(); + if ( receiver == ( (FormWindow*)o )->mainContainer() ) + rec = "this"; + ( (FormWindow*)o )->formFile()->removeConnection( sender->name(), signal, rec, slot ); + } +} + +void MetaDataBase::setupConnections( QObject *o, const QValueList<LanguageInterface::Connection> &conns ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + if ( !::qt_cast<FormFile*>(o) ) + return; + + FormFile *formfile = (FormFile*)o; + + r->connections.clear(); + + for ( QValueList<LanguageInterface::Connection>::ConstIterator cit = conns.begin(); + cit != conns.end(); ++cit ) { + // #### get the correct sender object out of Bla.Blub.sender + QString senderName = (*cit).sender; + if ( senderName.find( '.' ) != -1 ) + senderName = senderName.mid( senderName.findRev( '.' ) + 1 ); + QObject *sender = 0; + if ( formfile->formWindow() ) + sender = formfile->formWindow()->child( senderName ); + if ( !sender && formfile->isFake() ) + sender = formfile->project()->objectForFakeFormFile( formfile ); + if ( !sender && senderName == "this" ) + sender = formfile->formWindow() ? + formfile->formWindow()->mainContainer() : + formfile->project()->objectForFakeFormFile( formfile ); + if ( !sender ) + continue; + MetaDataBase::addConnection( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + sender, + (*cit).signal.latin1(), + formfile->formWindow() ? + formfile->formWindow()->mainContainer() : + formfile->project()->objectForFakeFormFile( formfile ), + (*cit).slot.latin1(), + FALSE ); + } +} + +bool MetaDataBase::hasConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + for ( QValueList<Connection>::Iterator it = r->connections.begin(); it != r->connections.end(); ++it ) { + Connection conn = *it; + if ( conn.sender == sender && + conn.signal == signal && + conn.receiver == receiver && + conn.slot == slot ) + return TRUE; + } + return FALSE; +} + + +QValueList<MetaDataBase::Connection> MetaDataBase::connections( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<Connection>(); + } + return r->connections; +} + +QValueList<MetaDataBase::Connection> MetaDataBase::connections( QObject *o, QObject *sender, + QObject *receiver ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<Connection>(); + } + QValueList<Connection>::Iterator it = r->connections.begin(); + QValueList<Connection> ret; + QValueList<Connection>::Iterator conn; + while ( ( conn = it ) != r->connections.end() ) { + ++it; + if ( (*conn).sender == sender && + (*conn).receiver == receiver ) + ret << *conn; + } + + return ret; +} + +QValueList<MetaDataBase::Connection> MetaDataBase::connections( QObject *o, QObject *object ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<Connection>(); + } + QValueList<Connection>::Iterator it = r->connections.begin(); + QValueList<Connection> ret; + QValueList<Connection>::Iterator conn; + while ( ( conn = it ) != r->connections.end() ) { + ++it; + if ( (*conn).sender == object || + (*conn).receiver == object ) + ret << *conn; + } + return ret; +} + +void MetaDataBase::doConnections( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + QObject *sender = 0, *receiver = 0; + QObjectList *l = 0; + QValueList<Connection>::Iterator it = r->connections.begin(); + for ( ; it != r->connections.end(); ++it ) { + Connection conn = *it; + if ( qstrcmp( conn.sender->name(), o->name() ) == 0 ) { + sender = o; + } else { + l = o->queryList( 0, conn.sender->name(), FALSE ); + if ( !l || !l->first() ) { + delete l; + continue; + } + sender = l->first(); + delete l; + } + if ( qstrcmp( conn.receiver->name(), o->name() ) == 0 ) { + receiver = o; + } else { + l = o->queryList( 0, conn.receiver->name(), FALSE ); + if ( !l || !l->first() ) { + delete l; + continue; + } + receiver = l->first(); + delete l; + } + QString s = "2""%1"; + s = s.arg( conn.signal ); + QString s2 = "1""%1"; + s2 = s2.arg( conn.slot ); + + QStrList signalList = sender->metaObject()->signalNames( TRUE ); + QStrList slotList = receiver->metaObject()->slotNames( TRUE ); + + // avoid warnings + if ( signalList.find( conn.signal ) == -1 || + slotList.find( conn.slot ) == -1 ) + continue; + + QObject::connect( sender, s, receiver, s2 ); + } +} + +bool MetaDataBase::hasSlot( QObject *o, const QCString &slot, bool onlyCustom ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + if ( !onlyCustom ) { + QStrList slotList = o->metaObject()->slotNames( TRUE ); + if ( slotList.find( slot ) != -1 ) + return TRUE; + + if ( ::qt_cast<FormWindow*>(o) ) { + o = ( (FormWindow*)o )->mainContainer(); + slotList = o->metaObject()->slotNames( TRUE ); + if ( slotList.find( slot ) != -1 ) + return TRUE; + } + + //if ( ::qt_cast<CustomWidget*>(o) ) { + if ( o->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *w = ( (::CustomWidget*)o )->customWidget(); + for ( QValueList<Function>::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + if ( s == slot ) + return TRUE; + } + } + } + + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( slot ) && f.type == "slot" ) + return TRUE; + } + + return FALSE; +} + +bool MetaDataBase::isSlotUsed( QObject *o, const QCString &slot ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + QValueList<Connection> conns = connections( o ); + for ( QValueList<Connection>::Iterator it = conns.begin(); it != conns.end(); ++it ) { + if ( (*it).slot == slot ) + return TRUE; + } + return FALSE; +} + + +void MetaDataBase::addFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + Function f; + f.function = function; + f.specifier = specifier; + f.access = access; + f.type = type; + f.language = language; + f.returnType = returnType; + QValueList<MetaDataBase::Function>::Iterator it = r->functionList.find( f ); + if ( it != r->functionList.end() ) + r->functionList.remove( it ); + r->functionList.append( f ); + ( (FormWindow*)o )->formFile()->addFunctionCode( f ); +} + +void MetaDataBase::setFunctionList( QObject *o, const QValueList<Function> &functionList ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + r->functionList = functionList; +} + +void MetaDataBase::removeFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).function ) == + MetaDataBase::normalizeFunction( function ) && + (*it).specifier == specifier && + (*it).access == access && + (*it).type == type && + ( language.isEmpty() || (*it).language == language ) && + ( returnType.isEmpty() || (*it).returnType == returnType ) ) { + ( (FormWindow*)o )->formFile()->removeFunctionCode( *it ); + r->functionList.remove( it ); + break; + } + } +} + +void MetaDataBase::removeFunction( QObject *o, const QString &function ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( normalizeFunction( (*it).function ) == normalizeFunction( function ) ) { + ( (FormWindow*)o )->formFile()->removeFunctionCode( *it ); + r->functionList.remove( it ); + break; + } + } +} + +QValueList<MetaDataBase::Function> MetaDataBase::functionList( QObject *o, bool onlyFunctions ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<Function>(); + } + if ( !onlyFunctions ) + return r->functionList; + QValueList<Function> fList; + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( (*it).type == "function" ) + fList.append( *it ); + } + return fList; +} + +QValueList<MetaDataBase::Function> MetaDataBase::slotList( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<Function>(); + } + QValueList<Function> slotList; + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( (*it).type == "slot" ) + slotList.append( *it ); + } + return slotList; +} + +void MetaDataBase::changeFunction( QObject *o, const QString &function, const QString &newName, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( function ) ) { + (*it).function = newName; + if ( !returnType.isNull() ) + (*it).returnType = returnType; + return; + } + } +} + +void MetaDataBase::changeFunctionAttributes( QObject *o, const QString &oldName, const QString &newName, + const QString &specifier, const QString &access, + const QString &type, const QString &language, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( oldName ) ) { + (*it).function = newName; + (*it).specifier = specifier; + (*it).access = access; + (*it).type = type; + (*it).language = language; + (*it).returnType = returnType; + return; + } + } +} + +bool MetaDataBase::hasFunction( QObject *o, const QCString &function, bool onlyCustom ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + if ( !onlyCustom ) { + QStrList functionList = o->metaObject()->slotNames( TRUE ); + if ( functionList.find( function ) != -1 ) + return TRUE; + + if ( ::qt_cast<FormWindow*>(o) ) { + o = ( (FormWindow*)o )->mainContainer(); + functionList = o->metaObject()->slotNames( TRUE ); + if ( functionList.find( function ) != -1 ) + return TRUE; + } + + //if ( ::qt_cast<CustomWidget*>(o) ) { + if ( o->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *w = ( (::CustomWidget*)o )->customWidget(); + for ( QValueList<Function>::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + if ( s == function ) + return TRUE; + } + } + } + + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( function ) ) + return TRUE; + } + + return FALSE; +} + +QString MetaDataBase::languageOfFunction( QObject *o, const QCString &function ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + QString fu = normalizeFunction( function ); + for ( QValueList<Function>::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( fu == normalizeFunction( (*it).function ) ) + return (*it).language; + } + return QString::null; +} + +bool MetaDataBase::addCustomWidget( CustomWidget *wid ) +{ + setupDataBase(); + + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( *wid == *w ) { + for ( QValueList<QCString>::ConstIterator it = wid->lstSignals.begin(); it != wid->lstSignals.end(); ++it ) { + if ( !w->hasSignal( *it ) ) + w->lstSignals.append( *it ); + } + for ( QValueList<Function>::ConstIterator it2 = wid->lstSlots.begin(); it2 != wid->lstSlots.end(); ++it2 ) { + if ( !w->hasSlot( MetaDataBase::normalizeFunction( (*it2).function ).latin1() ) ) + w->lstSlots.append( *it2 ); + } + for ( QValueList<Property>::ConstIterator it3 = wid->lstProperties.begin(); it3 != wid->lstProperties.end(); ++it3 ) { + if ( !w->hasProperty( (*it3).property ) ) + w->lstProperties.append( *it3 ); + } + delete wid; + return FALSE; + } + } + + + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + r->name = wid->className; + r->group = WidgetDatabase::widgetGroup( "Custom" ); + r->toolTip = wid->className; + r->icon = new QIconSet( *wid->pixmap, *wid->pixmap ); + r->isContainer = wid->isContainer; + wid->id = WidgetDatabase::addCustomWidget( r ); + cWidgets->append( wid ); + return TRUE; +} + +void MetaDataBase::removeCustomWidget( CustomWidget *w ) +{ + cWidgets->removeRef( w ); +} + +QPtrList<MetaDataBase::CustomWidget> *MetaDataBase::customWidgets() +{ + setupDataBase(); + return cWidgets; +} + +MetaDataBase::CustomWidget *MetaDataBase::customWidget( int id ) +{ + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( id == w->id ) + return w; + } + return 0; +} + +bool MetaDataBase::isWidgetNameUsed( CustomWidget *wid ) +{ + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( w == wid ) + continue; + if ( wid->className == w->className ) + return TRUE; + } + return FALSE; +} + +bool MetaDataBase::hasCustomWidget( const QString &className ) +{ + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( w->className == className ) + return TRUE; + } + return FALSE; +} + +void MetaDataBase::setTabOrder( QWidget *w, const QWidgetList &order ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*) w ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + w, w->name(), w->className() ); + return; + } + + r->tabOrder = order; +} + +QWidgetList MetaDataBase::tabOrder( QWidget *w ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*) w ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + w, w->name(), w->className() ); + return QWidgetList(); + } + + return r->tabOrder; +} + +void MetaDataBase::setIncludes( QObject *o, const QValueList<Include> &incs ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->includes = incs; +} + +QValueList<MetaDataBase::Include> MetaDataBase::includes( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<Include>(); + } + + return r->includes; +} + +void MetaDataBase::setForwards( QObject *o, const QStringList &fwds ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->forwards = fwds; +} + +QStringList MetaDataBase::forwards( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QStringList(); + } + + return r->forwards; +} + +void MetaDataBase::setVariables( QObject *o, const QValueList<Variable> &vars ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->variables = vars; +} + +void MetaDataBase::addVariable( QObject *o, const QString &name, const QString &access ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + Variable v; + v.varName = name; + v.varAccess = access; + r->variables << v; +} + +void MetaDataBase::removeVariable( QObject *o, const QString &name ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + QValueList<Variable>::Iterator it = r->variables.begin(); + for ( ; it != r->variables.end(); ++it ) { + if ( (*it).varName == name ) { + r->variables.remove( it ); + break; + } + } +} + +QValueList<MetaDataBase::Variable> MetaDataBase::variables( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<MetaDataBase::Variable>(); + } + + return r->variables; +} + +bool MetaDataBase::hasVariable( QObject *o, const QString &name ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + QValueList<Variable>::Iterator it = r->variables.begin(); + for ( ; it != r->variables.end(); ++it ) { + if ( extractVariableName( name ) == extractVariableName( (*it).varName ) ) + return TRUE; + } + return FALSE; +} + +QString MetaDataBase::extractVariableName( const QString &name ) +{ + QString n = name.right( name.length() - name.findRev( ' ' ) - 1 ); + if ( n[ 0 ] == '*' || n[ 0 ] == '&' ) + n[ 0 ] = ' '; + if ( n[ (int)n.length() - 1 ] == ';' ) + n[ (int)n.length() - 1 ] = ' '; + return n.simplifyWhiteSpace(); +} + +void MetaDataBase::setSignalList( QObject *o, const QStringList &sigs ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->sigs.clear(); + + for ( QStringList::ConstIterator it = sigs.begin(); it != sigs.end(); ++it ) { + QString s = (*it).simplifyWhiteSpace(); + bool hasSemicolon = s.endsWith( ";" ); + if ( hasSemicolon ) + s = s.left( s.length() - 1 ); + int p = s.find( '(' ); + if ( p < 0 ) + p = s.length(); + int sp = s.find( ' ' ); + if ( sp >= 0 && sp < p ) { + s = s.mid( sp+1 ); + p -= sp + 1; + } + if ( p == (int) s.length() ) + s += "()"; + if ( hasSemicolon ) + s += ";"; + r->sigs << s; + } +} + +QStringList MetaDataBase::signalList( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QStringList(); + } + + return r->sigs; +} + +void MetaDataBase::setMetaInfo( QObject *o, MetaInfo mi ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->metaInfo = mi; +} + +MetaDataBase::MetaInfo MetaDataBase::metaInfo( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return MetaInfo(); + } + + return r->metaInfo; +} + + + + +MetaDataBase::CustomWidget::CustomWidget() +{ + className = "MyCustomWidget"; + includeFile = "mywidget.h"; + includePolicy = Local; + sizeHint = QSize( -1, -1 ); + pixmap = new QPixmap( BarIcon( "designer_customwidget.png", KDevDesignerPartFactory::instance() ) ); + id = -1; + sizePolicy = QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + isContainer = FALSE; +} + +MetaDataBase::CustomWidget::CustomWidget( const CustomWidget &w ) +{ + className = w.className; + includeFile = w.includeFile; + includePolicy = w.includePolicy; + sizeHint = w.sizeHint; + if ( w.pixmap ) + pixmap = new QPixmap( *w.pixmap ); + else + pixmap = 0; + id = w.id; + isContainer = w.isContainer; +} + +void MetaDataBase::setCursor( QWidget *w, const QCursor &c ) +{ + setupDataBase(); + if ( w->isA( "PropertyObject" ) ) { + ( (PropertyObject*)w )->mdSetCursor( c ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)w ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + w, w->name(), w->className() ); + return; + } + + r->cursor = c; +} + +QCursor MetaDataBase::cursor( QWidget *w ) +{ + setupDataBase(); + if ( w->isA( "PropertyObject" ) ) + return ( (PropertyObject*)w )->mdCursor(); + MetaDataBaseRecord *r = db->find( (void*)w ); + if ( !r ) { + w->unsetCursor(); + return w->cursor(); + } + + return r->cursor; +} + +bool MetaDataBase::CustomWidget::operator==( const CustomWidget &w ) const +{ + return className == w.className; +} + +MetaDataBase::CustomWidget &MetaDataBase::CustomWidget::operator=( const CustomWidget &w ) +{ + delete pixmap; + className = w.className; + includeFile = w.includeFile; + includePolicy = w.includePolicy; + sizeHint = w.sizeHint; + if ( w.pixmap ) + pixmap = new QPixmap( *w.pixmap ); + else + pixmap = 0; + lstSignals = w.lstSignals; + lstSlots = w.lstSlots; + lstProperties = w.lstProperties; + id = w.id; + isContainer = w.isContainer; + return *this; +} + +bool MetaDataBase::CustomWidget::hasSignal( const QCString &signal ) const +{ + QStrList sigList = QWidget::staticMetaObject()->signalNames( TRUE ); + if ( sigList.find( signal ) != -1 ) + return TRUE; + for ( QValueList<QCString>::ConstIterator it = lstSignals.begin(); it != lstSignals.end(); ++it ) { + if ( normalizeFunction( *it ) == normalizeFunction( signal ) ) + return TRUE; + } + return FALSE; +} + +bool MetaDataBase::CustomWidget::hasSlot( const QCString &slot ) const +{ + QStrList slotList = QWidget::staticMetaObject()->slotNames( TRUE ); + if ( slotList.find( normalizeFunction( slot ) ) != -1 ) + return TRUE; + + for ( QValueList<MetaDataBase::Function>::ConstIterator it = lstSlots.begin(); it != lstSlots.end(); ++it ) { + if ( normalizeFunction( (*it).function ) == normalizeFunction( slot ) ) + return TRUE; + } + return FALSE; +} + +bool MetaDataBase::CustomWidget::hasProperty( const QCString &prop ) const +{ + QStrList propList = QWidget::staticMetaObject()->propertyNames( TRUE ); + if ( propList.find( prop ) != -1 ) + return TRUE; + + for ( QValueList<MetaDataBase::Property>::ConstIterator it = lstProperties.begin(); it != lstProperties.end(); ++it ) { + if ( (*it).property == prop ) + return TRUE; + } + return FALSE; +} + +void MetaDataBase::setPixmapArgument( QObject *o, int pixmap, const QString &arg ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapArguments.remove( pixmap ); + r->pixmapArguments.insert( pixmap, arg ); +} + +QString MetaDataBase::pixmapArgument( QObject *o, int pixmap ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + return *r->pixmapArguments.find( pixmap ); +} + +void MetaDataBase::clearPixmapArguments( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapArguments.clear(); +} + + +void MetaDataBase::setPixmapKey( QObject *o, int pixmap, const QString &arg ) +{ + if ( !o ) + return; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetPixmapKey( pixmap, arg ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapKeys.remove( pixmap ); + r->pixmapKeys.insert( pixmap, arg ); +} + +QString MetaDataBase::pixmapKey( QObject *o, int pixmap ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdPixmapKey( pixmap ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + QString s = *r->pixmapKeys.find( pixmap ); + if ( !s.isNull() ) + return s; + if ( !o->isWidgetType() ) + return s; + QWidget *w = (QWidget*)o; + if ( w->icon() ) + return *r->pixmapKeys.find( w->icon()->serialNumber() ); + return s; +} + +void MetaDataBase::clearPixmapKeys( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapKeys.clear(); +} + + + +void MetaDataBase::setColumnFields( QObject *o, const QMap<QString, QString> &columnFields ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->columnFields = columnFields; +} + +QMap<QString, QString> MetaDataBase::columnFields( QObject *o ) +{ + if ( !o ) + return QMap<QString, QString>(); + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QMap<QString, QString>(); + } + + return r->columnFields; +} + +void MetaDataBase::setEditor( const QStringList &langs ) +{ + editorLangList = langs; +} + +bool MetaDataBase::hasEditor( const QString &lang ) +{ + return editorLangList.find( lang ) != editorLangList.end(); +} + +void MetaDataBase::setupInterfaceManagers( const QString &plugDir ) +{ + if ( !languageInterfaceManager ) { + languageInterfaceManager = + new QPluginManager<LanguageInterface>( IID_Language, + QApplication::libraryPaths(), +// kapp->dirs()->resourceDirs("qtplugins"), + plugDir ); + + langList = languageInterfaceManager->featureList(); + langList.remove( "C++" ); + langList << "C++"; + } +} + +QStringList MetaDataBase::languages() +{ + return langList; +} + +QString MetaDataBase::normalizeFunction( const QString &f ) +{ + return Parser::cleanArgs( f ); +} + +LanguageInterface *MetaDataBase::languageInterface( const QString &lang ) +{ + LanguageInterface* iface = 0; + languageInterfaceManager->queryInterface( lang, &iface ); + return iface; +} + +void MetaDataBase::clear( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + db->remove( (void*)o ); + for ( QPtrDictIterator<QWidget> it( *( (FormWindow*)o )->widgets() ); it.current(); ++it ) + db->remove( (void*)it.current() ); +} + +void MetaDataBase::setBreakPoints( QObject *o, const QValueList<uint> &l ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->breakPoints = l; + + QMap<int, QString>::Iterator it = r->breakPointConditions.begin(); + while ( it != r->breakPointConditions.end() ) { + int line = it.key(); + ++it; + if ( r->breakPoints.find( line ) == r->breakPoints.end() ) + r->breakPointConditions.remove( r->breakPointConditions.find( line ) ); + } +} + +QValueList<uint> MetaDataBase::breakPoints( QObject *o ) +{ + if ( !o ) + return QValueList<uint>(); + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList<uint>(); + } + + return r->breakPoints; +} + +void MetaDataBase::setBreakPointCondition( QObject *o, int line, const QString &condition ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + r->breakPointConditions.replace( line, condition ); +} + +QString MetaDataBase::breakPointCondition( QObject *o, int line ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + QMap<int, QString>::Iterator it = r->breakPointConditions.find( line ); + if ( it == r->breakPointConditions.end() ) + return QString::null; + return *it; +} + +void MetaDataBase::setExportMacro( QObject *o, const QString ¯o ) +{ + if ( !o ) + return; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetExportMacro( macro ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->exportMacro = macro; +} + +QString MetaDataBase::exportMacro( QObject *o ) +{ + if ( !o ) + return ""; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdExportMacro(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return ""; + } + + return r->exportMacro; +} + +bool MetaDataBase::hasObject( QObject *o ) +{ + return !!db->find( o ); +} diff --git a/kdevdesigner/designer/metadatabase.h b/kdevdesigner/designer/metadatabase.h new file mode 100644 index 00000000..f7ce5088 --- /dev/null +++ b/kdevdesigner/designer/metadatabase.h @@ -0,0 +1,269 @@ +/********************************************************************** +** 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 METADATABASE_H +#define METADATABASE_H + +#include <qvariant.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qptrlist.h> +#include <qsizepolicy.h> +#include <qsize.h> +#include <qwidgetlist.h> +#include <qcursor.h> + +#include "pixmapchooser.h" +#include "../interfaces/languageinterface.h" + +class QObject; +class QPixmap; +struct LanguageInterface; + +class MetaDataBase +{ +public: + struct Connection + { + QObject *sender, *receiver; + QCString signal, slot; + bool operator==( const Connection &c ) const { + return sender == c.sender && receiver == c.receiver && + signal == c.signal && slot == c.slot ; + } + }; + + struct Function + { + QString returnType; + QCString function; + QString specifier; + QString access; + QString type; + QString language; + bool operator==( const Function &f ) const { + return ( returnType == f.returnType && + function == f.function && + specifier == f.specifier && + access == f.access && + type == f.type && + language == f.language + ); + } + }; + + struct Property + { + QCString property; + QString type; + bool operator==( const Property &p ) const { + return property == p.property && + type == p.type; + } + }; + + struct CustomWidget + { + CustomWidget(); + CustomWidget( const CustomWidget &w ); + ~CustomWidget() { delete pixmap; } // inlined to work around 2.7.2.3 bug + bool operator==( const CustomWidget &w ) const; + CustomWidget &operator=( const CustomWidget &w ); + + bool hasSignal( const QCString &signal ) const; + bool hasSlot( const QCString &slot ) const; + bool hasProperty( const QCString &prop ) const; + + enum IncludePolicy { Global, Local }; + QString className; + QString includeFile; + IncludePolicy includePolicy; + QSize sizeHint; + QSizePolicy sizePolicy; + QPixmap *pixmap; + QValueList<QCString> lstSignals; + QValueList<Function> lstSlots; + QValueList<Property> lstProperties; + int id; + bool isContainer; + }; + + struct Include + { + Include() : header(), location(), implDecl( "in implementation" ) {} + QString header; + QString location; + bool operator==( const Include &i ) const { + return header == i.header && location == i.location; + } + QString implDecl; + }; + + struct Variable + { + QString varName; + QString varAccess; + bool operator==( const Variable &v ) const { + return varName == v.varName && + varAccess == v.varAccess; + } + }; + + struct MetaInfo + { + MetaInfo() : classNameChanged( FALSE ) { } + QString className; + bool classNameChanged; + QString comment; + QString author; + }; + + MetaDataBase(); + static void clearDataBase(); + + static void addEntry( QObject *o ); + static void removeEntry( QObject *o ); + static void setPropertyChanged( QObject *o, const QString &property, bool changed ); + static bool isPropertyChanged( QObject *o, const QString &property ); + static void setPropertyComment( QObject *o, const QString &property, const QString &comment ); + static QString propertyComment( QObject *o, const QString &property ); + static QStringList changedProperties( QObject *o ); + + static void setFakeProperty( QObject *o, const QString &property, const QVariant& value ); + static QVariant fakeProperty( QObject * o, const QString &property ); + static QMap<QString,QVariant>* fakeProperties( QObject* o ); + + static void setSpacing( QObject *o, int spacing ); + static int spacing( QObject *o ); + static void setMargin( QObject *o, int margin ); + static int margin( QObject *o ); + + static void setResizeMode( QObject *o, const QString &mode ); + static QString resizeMode( QObject *o ); + + static void addConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot, bool addCode = TRUE ); + static void removeConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ); + static bool hasConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ); + static void setupConnections( QObject *o, const QValueList<LanguageInterface::Connection> &conns ); + static QValueList<Connection> connections( QObject *o ); + static QValueList<Connection> connections( QObject *o, QObject *sender, QObject *receiver ); + static QValueList<Connection> connections( QObject *o, QObject *object ); + static void doConnections( QObject *o ); + + static void addFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ); + static void removeFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ); + static void removeFunction( QObject *o, const QString &function ); + static QValueList<Function> functionList( QObject *o, bool onlyFunctions = FALSE ); + static QValueList<Function> slotList( QObject *o ); + static bool isSlotUsed( QObject *o, const QCString &slot ); + static bool hasFunction( QObject *o, const QCString &function, bool onlyCustom = FALSE ); + static bool hasSlot( QObject *o, const QCString &slot, bool onlyCustom = FALSE ); + static void changeFunction( QObject *o, const QString &function, const QString &newName, + const QString &returnType ); + static void changeFunctionAttributes( QObject *o, const QString &oldName, const QString &newName, + const QString &specifier, const QString &access, + const QString &type, const QString &language, + const QString &returnType ); + static QString languageOfFunction( QObject *o, const QCString &function ); + static void setFunctionList( QObject *o, const QValueList<Function> &functionList ); + + + static bool addCustomWidget( CustomWidget *w ); + static void removeCustomWidget( CustomWidget *w ); + static QPtrList<CustomWidget> *customWidgets(); + static CustomWidget *customWidget( int id ); + static bool isWidgetNameUsed( CustomWidget *w ); + static bool hasCustomWidget( const QString &className ); + + static void setTabOrder( QWidget *w, const QWidgetList &order ); + static QWidgetList tabOrder( QWidget *w ); + + static void setIncludes( QObject *o, const QValueList<Include> &incs ); + static QValueList<Include> includes( QObject *o ); + + static void setForwards( QObject *o, const QStringList &fwds ); + static QStringList forwards( QObject *o ); + + static void setVariables( QObject *o, const QValueList<Variable> &vars ); + static void addVariable( QObject *o, const QString &name, const QString &access ); + static void removeVariable( QObject *o, const QString &name ); + static QValueList<Variable> variables( QObject *o ); + static bool hasVariable( QObject *o, const QString &name ); + static QString extractVariableName( const QString &name ); + + static void setSignalList( QObject *o, const QStringList &sigs ); + static QStringList signalList( QObject *o ); + + static void setMetaInfo( QObject *o, MetaInfo mi ); + static MetaInfo metaInfo( QObject *o ); + + static void setCursor( QWidget *w, const QCursor &c ); + static QCursor cursor( QWidget *w ); + + static void setPixmapArgument( QObject *o, int pixmap, const QString &arg ); + static QString pixmapArgument( QObject *o, int pixmap ); + static void clearPixmapArguments( QObject *o ); + + static void setPixmapKey( QObject *o, int pixmap, const QString &arg ); + static QString pixmapKey( QObject *o, int pixmap ); + static void clearPixmapKeys( QObject *o ); + + static void setColumnFields( QObject *o, const QMap<QString, QString> &columnFields ); + static QMap<QString, QString> columnFields( QObject *o ); + + static void setEditor( const QStringList &langs ); + static bool hasEditor( const QString &lang ); + + static void setupInterfaceManagers( const QString &plugDir ); + static QStringList languages(); + + static LanguageInterface *languageInterface( const QString &lang ); + + static QString normalizeFunction( const QString &f ); + + static void clear( QObject *o ); + + static void setBreakPoints( QObject *o, const QValueList<uint> &l ); + static void setBreakPointCondition( QObject *o, int line, const QString &condition ); + static QValueList<uint> breakPoints( QObject *o ); + static QString breakPointCondition( QObject *o, int line ); + + static void setExportMacro( QObject *o, const QString ¯o ); + static QString exportMacro( QObject *o ); + + static bool hasObject( QObject *o ); + +}; + +#endif diff --git a/kdevdesigner/designer/multilineeditor.ui b/kdevdesigner/designer/multilineeditor.ui new file mode 100644 index 00000000..3a28f795 --- /dev/null +++ b/kdevdesigner/designer/multilineeditor.ui @@ -0,0 +1,181 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>MultiLineEditorBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +*********************************************************************</comment> +<widget class="QMainWindow"> + <property name="name"> + <cstring>MultiLineEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>598</width> + <height>307</height> + </rect> + </property> + <property name="caption"> + <string>Edit Text</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Multiline Edit</b><p>This is a simple richtext editor. To improve its usability it provides toolbar items for the most common html tags: by clicking on a toolbar item, the corresponding tag will be written to the editor, where you can insert your text. If you have already written some text and want to format it, hilight it and click on the desired button. To improve visualization this editor also supports a simple html-syntax-highlighting scheme.</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>OkButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="on"> + <bool>false</bool> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>applyButton</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + </hbox> +</widget> +<menubar> + <property name="name"> + <cstring>menuBar</cstring> + </property> +</menubar> +<toolbars> +</toolbars> +<connections> + <connection> + <sender>OkButton</sender> + <signal>clicked()</signal> + <receiver>MultiLineEditorBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>applyButton</sender> + <signal>clicked()</signal> + <receiver>MultiLineEditorBase</receiver> + <slot>applyClicked()</slot> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>MultiLineEditorBase</receiver> + <slot>cancelClicked()</slot> + </connection> +</connections> +<slots> + <slot>applyClicked()</slot> + <slot>okClicked()</slot> + <slot>cancelClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/multilineeditorimpl.cpp b/kdevdesigner/designer/multilineeditorimpl.cpp new file mode 100644 index 00000000..3d7f5afc --- /dev/null +++ b/kdevdesigner/designer/multilineeditorimpl.cpp @@ -0,0 +1,415 @@ +/********************************************************************** +** 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 "multilineeditorimpl.h" +#include "formwindow.h" +#include "command.h" +#include "mainwindow.h" +#include "richtextfontdialog.h" +#include "syntaxhighlighter_html.h" +#include "widgetfactory.h" + +#include <kiconloader.h> +#include "kdevdesigner_part.h" + +#include <qtextedit.h> +#include <./private/qrichtext_p.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qtoolbutton.h> +#include <qapplication.h> +#include <qaction.h> +#include <qmetaobject.h> + +#include <klocale.h> + +ToolBarItem::ToolBarItem( QWidget *parent, QWidget *toolBar, + const QString &label, const QString &tagstr, + const QIconSet &icon, const QKeySequence &key ) + : QAction( parent ) +{ + setIconSet( icon ); + setText( label ); + setAccel( key ); + addTo( toolBar ); + tag = tagstr; + connect( this, SIGNAL( activated() ), this, SLOT( wasActivated() ) ); +} + +ToolBarItem::~ToolBarItem() +{ + +} + +void ToolBarItem::wasActivated() +{ + emit clicked( tag ); +} + +TextEdit::TextEdit( QWidget *parent, const char *name ) + : QTextEdit( parent, name ) +{ + setTextFormat( Qt::PlainText ); +} + +QTextParagraph* TextEdit::paragraph() +{ + QTextCursor *tc = new QTextCursor( QTextEdit::document() ); + return tc->paragraph(); +} + + +MultiLineEditor::MultiLineEditor( bool call_static, bool richtextMode, QWidget *parent, QWidget *editWidget, + FormWindow *fw, const QString &text ) + : MultiLineEditorBase( parent, 0, WType_Dialog | WShowModal ), formwindow( fw ), doWrap( FALSE ) +{ + callStatic = call_static; + + if ( callStatic ) + applyButton->hide(); + + textEdit = new TextEdit( centralWidget(), "textedit" ); + Layout4->insertWidget( 0, textEdit ); + + if ( richtextMode ) { + QPopupMenu *stylesMenu = new QPopupMenu( this ); + menuBar->insertItem( i18n( "&Styles" ), stylesMenu ); + + basicToolBar = new QToolBar( i18n( "Basics" ), this, DockTop ); + + ToolBarItem *it = new ToolBarItem( this, basicToolBar, i18n( "Italic" ), + "i", BarIcon( "designer_textitalic.png", KDevDesignerPartFactory::instance() ), CTRL+Key_I ); + it->addTo( stylesMenu ); + connect( it, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *b = new ToolBarItem( this, basicToolBar, i18n( "Bold" ), + "b", BarIcon( "designer_textbold.png", KDevDesignerPartFactory::instance() ), CTRL+Key_B ); + b->addTo( stylesMenu ); + connect( b, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *ul = new ToolBarItem( this, basicToolBar, i18n( "Underline" ), + "u", BarIcon( "designer_textunderline.png" , KDevDesignerPartFactory::instance()), CTRL+Key_U ); + ul->addTo( stylesMenu ); + connect( ul, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *tt = new ToolBarItem( this, basicToolBar, i18n( "Typewriter" ), + "tt", BarIcon( "designer_textteletext.png", KDevDesignerPartFactory::instance() ) ); + tt->addTo( stylesMenu ); + connect( tt, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + basicToolBar->addSeparator(); + + QPopupMenu *layoutMenu = new QPopupMenu( this ); + menuBar->insertItem( i18n( "&Layout" ), layoutMenu ); + + QAction *brAction = new QAction( this ); + brAction->setIconSet( BarIcon( "designer_textlinebreak.png", KDevDesignerPartFactory::instance() ) ); + brAction->setText( i18n("Break" ) ); + brAction->addTo( basicToolBar ); + brAction->addTo( layoutMenu ); + connect( brAction, SIGNAL( activated() ) , this, SLOT( insertBR() ) ); + + ToolBarItem *p = new ToolBarItem( this, basicToolBar, i18n( "Paragraph" ), + "p", BarIcon( "designer_textparagraph.png", KDevDesignerPartFactory::instance() ) ); + p->addTo( layoutMenu ); + connect( p, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + layoutMenu->insertSeparator(); + basicToolBar->addSeparator(); + + ToolBarItem *al = new ToolBarItem( this, basicToolBar, i18n( "Align left" ), + "p align=\"left\"", BarIcon( "designer_textleft.png", KDevDesignerPartFactory::instance() ) ); + al->addTo( layoutMenu ); + connect( al, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *ac = new ToolBarItem( this, basicToolBar, i18n( "Align center" ), + "p align=\"center\"", BarIcon( "designer_textcenter.png", KDevDesignerPartFactory::instance() ) ); + ac->addTo( layoutMenu ); + connect( ac, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *ar = new ToolBarItem( this, basicToolBar, i18n( "Align right" ), + "p align=\"right\"", BarIcon( "designer_textright.png", KDevDesignerPartFactory::instance() ) ); + ar->addTo( layoutMenu ); + connect( ar, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *block = new ToolBarItem( this, basicToolBar, i18n( "Blockquote" ), + "blockquote", BarIcon( "designer_textjustify.png", KDevDesignerPartFactory::instance() ) ); + block->addTo( layoutMenu ); + connect( block, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + + QPopupMenu *fontMenu = new QPopupMenu( this ); + menuBar->insertItem( i18n( "&Font" ), fontMenu ); + + fontToolBar = new QToolBar( "Fonts", this, DockTop ); + + QAction *fontAction = new QAction( this ); + fontAction->setIconSet( BarIcon( "designer_textfont.png", KDevDesignerPartFactory::instance() ) ); + fontAction->setText( i18n("Font" ) ); + fontAction->addTo( fontToolBar ); + fontAction->addTo( fontMenu ); + connect( fontAction, SIGNAL( activated() ) , this, SLOT( showFontDialog() ) ); + + + ToolBarItem *fp1 = new ToolBarItem( this, fontToolBar, i18n( "Fontsize +1" ), + "font size=\"+1\"", BarIcon( "designer_textlarger.png", KDevDesignerPartFactory::instance() ) ); + connect( fp1, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *fm1 = new ToolBarItem( this, fontToolBar, i18n( "Fontsize -1" ), + "font size=\"-1\"", BarIcon( "designer_textsmaller.png", KDevDesignerPartFactory::instance() ) ); + connect( fm1, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *h1 = new ToolBarItem( this, fontToolBar, i18n( "Headline 1" ), + "h1", BarIcon( "designer_texth1.png", KDevDesignerPartFactory::instance() ) ); + connect( h1, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *h2 = new ToolBarItem( this, fontToolBar, i18n( "Headline 2" ), + "h2", BarIcon( "designer_texth2.png", KDevDesignerPartFactory::instance() ) ); + connect( h2, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *h3 = new ToolBarItem( this, fontToolBar, i18n( "Headline 3" ), + "h3", BarIcon( "designer_texth3.png", KDevDesignerPartFactory::instance() ) ); + connect( h3, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + QPopupMenu *optionsMenu = new QPopupMenu( this ); + menuBar->insertItem( i18n( "O&ptions" ), optionsMenu ); + + optionsToolBar = new QToolBar( "Options", this, DockTop ); + wrapAction = new QAction( this ); + wrapAction->setToggleAction( TRUE ); + wrapAction->setIconSet( BarIcon( "designer_wordwrap.png", KDevDesignerPartFactory::instance() ) ); + wrapAction->setText( i18n( "Word Wrapping" ) ); + wrapAction->addTo( optionsToolBar ); + wrapAction->addTo( optionsMenu ); + connect( wrapAction, SIGNAL( toggled( bool ) ), this, SLOT( changeWrapMode( bool ) ) ); + + oldDoWrap = doWrap; + wrapAction->setOn( doWrap ); + + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + textEdit->document()->setFormatter( new QTextFormatterBreakInWords ); + textEdit->document()->setUseFormatCollection( FALSE ); + textEdit->document()->setPreProcessor( new SyntaxHighlighter_HTML ); + + if ( !callStatic && ::qt_cast<QTextEdit*>(editWidget) ) { + mlined = (QTextEdit*)editWidget; + mlined->setReadOnly( TRUE ); + + const QMetaProperty *wordWrap = mlined->metaObject()->property( + mlined->metaObject()->findProperty( "wordWrap", TRUE ), TRUE ); + oldWrapMode = 0; + oldWrapString = "NoWrap"; + if ( wordWrap ) { + oldWrapMode = mlined->property( "wordWrap" ); + oldWrapString = QString( wordWrap->valueToKey( oldWrapMode.toInt() ) ); + if ( oldWrapString != "NoWrap" ) + doWrap = TRUE; + } + textEdit->setAlignment( mlined->alignment() ); + textEdit->setWordWrap( mlined->wordWrap() ); + textEdit->setWrapColumnOrWidth( mlined->wrapColumnOrWidth() ); + textEdit->setWrapPolicy( mlined->wrapPolicy() ); + textEdit->setText( mlined->text() ); + if ( !mlined->text().isEmpty() ) + textEdit->selectAll(); + } else { + textEdit->setText( text ); + textEdit->selectAll(); + } + } else { + textEdit->setText( text ); + textEdit->selectAll(); + } + textEdit->setFocus(); +} + +int MultiLineEditor::exec() +{ + res = 1; + show(); + qApp->enter_loop(); + return res; +} + +void MultiLineEditor::okClicked() +{ + applyClicked(); + close(); +} + +void MultiLineEditor::applyClicked() +{ + if ( !callStatic ) { + PopulateMultiLineEditCommand *cmd = new PopulateMultiLineEditCommand( i18n( "Set the Text of '%1'" ).arg( mlined->name() ), + formwindow, mlined, textEdit->text() ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); + + if ( oldDoWrap != doWrap ) { + QString pn( i18n( "Set 'wordWrap' of '%2'" ).arg( mlined->name() ) ); + SetPropertyCommand *propcmd; + if ( doWrap ) + propcmd = new SetPropertyCommand( pn, formwindow, + mlined, MainWindow::self->propertyeditor(), + "wordWrap", WidgetFactory::property( mlined, "wordWrap" ), + QVariant( 1 ), "WidgetWidth", oldWrapString ); + else + propcmd = new SetPropertyCommand( pn, formwindow, + mlined, MainWindow::self->propertyeditor(), + "wordWrap", WidgetFactory::property( mlined, "wordWrap" ), + QVariant( 0 ), "NoWrap", oldWrapString ); + + propcmd->execute(); + formwindow->commandHistory()->addCommand( propcmd, TRUE ); + } + textEdit->setFocus(); + } + else { + staticText = textEdit->text(); + } +} + +void MultiLineEditor::cancelClicked() +{ + res = 0; + close(); +} + +void MultiLineEditor::closeEvent( QCloseEvent *e ) +{ + qApp->exit_loop(); + MultiLineEditorBase::closeEvent( e ); +} + +void MultiLineEditor::insertTags( const QString &tag ) +{ + int pfrom, pto, ifrom, ito; + QString tagend( tag.simplifyWhiteSpace() ); + tagend.remove( tagend.find( ' ', 0 ), tagend.length() ); + if ( textEdit->hasSelectedText() ) { + textEdit->getSelection( &pfrom, &ifrom, &pto, &ito ); + QString buf = textEdit->selectedText(); + buf = QString( "<%1>%3</%2>" ).arg( tag ).arg( tagend ).arg( buf ); + textEdit->removeSelectedText(); + textEdit->insertAt( buf, pfrom, ifrom ); + textEdit->setCursorPosition( pto, ito + 2 + tag.length() ); + } + else { + int para, index; + textEdit->getCursorPosition( ¶, &index ); + textEdit->insert( QString( "<%1></%2>" ).arg( tag ).arg( tagend ) ); + index += 2 + tag.length(); + textEdit->setCursorPosition( para, index ); + } +} + +void MultiLineEditor::insertBR() +{ + textEdit->insert( "<br>" ); +} + +void MultiLineEditor::showFontDialog() +{ + bool selText = FALSE; + int pfrom, pto, ifrom, ito; + if ( textEdit->hasSelectedText() ) { + textEdit->getSelection( &pfrom, &ifrom, &pto, &ito ); + selText = TRUE; + } + RichTextFontDialog *fd = new RichTextFontDialog( this ); + if ( fd->exec() == QDialog::Accepted ) { + QString size, font; + if ( fd->getSize() != "0" ) + size = "size=\"" + fd->getSize() + "\""; + QString color; + if ( !fd->getColor().isEmpty() && fd->getColor() != "#000000" ) + color = "color=\"" + fd->getColor() + "\""; + if ( fd->getFont() != "default" ) + font = "face=\"" + fd->getFont() + "\""; + QString tag( QString( "font %1 %2 %3" ) + .arg( color ).arg( size ).arg( font ) ); + + if ( selText ) + textEdit->setSelection( pfrom, ifrom, pto, ito ); + insertTags( tag.simplifyWhiteSpace() ); + } + else if ( selText ) + textEdit->setSelection( pfrom, ifrom, pto, ito ); +} + +QString MultiLineEditor::getStaticText() +{ + return staticText.stripWhiteSpace(); +} + +QString MultiLineEditor::getText( QWidget *parent, const QString &text, bool richtextMode, bool *useWrap ) +{ + MultiLineEditor medit( TRUE, richtextMode, parent, 0, 0, text ); + if ( richtextMode ) + medit.setUseWrapping( *useWrap ); + if ( medit.exec() == QDialog::Accepted ) { + *useWrap = medit.useWrapping(); + return medit.getStaticText(); + } + return QString::null; +} + +void MultiLineEditor::changeWrapMode( bool b ) +{ + doWrap = b; + if ( doWrap && !callStatic ) { + if ( oldDoWrap ) + textEdit->setProperty( "wordWrap", oldWrapMode ); + else + textEdit->setWordWrap( QTextEdit::WidgetWidth ); + } else { + textEdit->setWordWrap( QTextEdit::NoWrap ); + } +} + +bool MultiLineEditor::useWrapping() const +{ + return doWrap; +} + +void MultiLineEditor::setUseWrapping( bool b ) +{ + doWrap = b; + wrapAction->setOn( doWrap ); +} diff --git a/kdevdesigner/designer/multilineeditorimpl.h b/kdevdesigner/designer/multilineeditorimpl.h new file mode 100644 index 00000000..5abf5339 --- /dev/null +++ b/kdevdesigner/designer/multilineeditorimpl.h @@ -0,0 +1,109 @@ +/********************************************************************** +** 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 MULTILINEEDITORIMPL_H +#define MULTILINEEDITORIMPL_H + +#include <qaction.h> +#include <qtextedit.h> +#include <private/qrichtext_p.h> +#include "multilineeditor.h" + +class FormWindow; +class QToolBar; +class QTextDocument; + +class TextEdit : public QTextEdit +{ + Q_OBJECT + +public: + TextEdit( QWidget *parent = 0, const char *name = 0 ); + QTextDocument *document() const { return QTextEdit::document(); } + QTextParagraph *paragraph(); + +}; + +class ToolBarItem : public QAction +{ + Q_OBJECT + +public: + ToolBarItem( QWidget *parent, QWidget *toolBar, + const QString &label, const QString &tagstr, + const QIconSet &icon, const QKeySequence &key = 0 ); + ~ToolBarItem(); +signals: + void clicked( const QString &t ); + +protected slots: + void wasActivated(); +private: + QString tag; +}; + + +class MultiLineEditor : public MultiLineEditorBase +{ + Q_OBJECT + +public: + MultiLineEditor( bool call_static, bool richtextMode, QWidget *parent, QWidget *editWidget, + FormWindow *fw, const QString &text = QString::null ); + bool useWrapping() const; + void setUseWrapping( bool ); + static QString getText( QWidget *parent, const QString &text, bool richtextMode, bool *useWrap ); + int exec(); + +protected slots: + void okClicked(); + void applyClicked(); + void cancelClicked(); + void insertTags( const QString& ); + void insertBR(); + void showFontDialog(); + void changeWrapMode( bool ); + + void closeEvent( QCloseEvent *e ); + +private: + QString getStaticText(); + TextEdit *textEdit; + QTextEdit *mlined; + FormWindow *formwindow; + QToolBar *basicToolBar; + QToolBar *fontToolBar; + QToolBar *optionsToolBar; + QAction *wrapAction; + int res; + QString staticText; + bool callStatic; + bool oldDoWrap, doWrap; + QVariant oldWrapMode; + QString oldWrapString; +}; + +#endif diff --git a/kdevdesigner/designer/myiconloader.cpp b/kdevdesigner/designer/myiconloader.cpp new file mode 100644 index 00000000..b33a6299 --- /dev/null +++ b/kdevdesigner/designer/myiconloader.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "myiconloader.h" +#include "kdevdesigner_part.h" +#include <kiconloader.h> + +QPixmap BarIcon2( const QString & name ) +{ + return BarIcon(name, KDevDesignerPartFactory::instance()); +} + +QPixmap SmallIcon2( const QString & name) +{ + return SmallIcon(name, KDevDesignerPartFactory::instance()); +} diff --git a/kdevdesigner/designer/myiconloader.h b/kdevdesigner/designer/myiconloader.h new file mode 100644 index 00000000..f93dee16 --- /dev/null +++ b/kdevdesigner/designer/myiconloader.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MY_ICON_LOADER +#define MY_ICON_LOADER + +#include <qpixmap.h> +#include <qstring.h> + +class KInstance; + +QPixmap BarIcon2 (const QString &name); +QPixmap SmallIcon2 (const QString &name); + + +#endif diff --git a/kdevdesigner/designer/newform.ui b/kdevdesigner/designer/newform.ui new file mode 100644 index 00000000..cdfae7e4 --- /dev/null +++ b/kdevdesigner/designer/newform.ui @@ -0,0 +1,238 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>NewFormBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>NewFormBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>557</width> + <height>436</height> + </rect> + </property> + <property name="caption"> + <string>New File</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>New Form</b><p>Select a template for the new form and click the <b>OK</b>-button to create it.</p></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Create a new form using the selected template.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog without creating a new form.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QIconView" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>templateView</cstring> + </property> + <property name="gridX"> + <number>120</number> + </property> + <property name="resizeMode"> + <enum>Adjust</enum> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + <property name="wordWrapIconText"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Displays a list of the available templates.</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>labelProject</cstring> + </property> + <property name="text"> + <string>&Insert into:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>projectCombo</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>projectCombo</cstring> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>NewFormBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>NewFormBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>projectCombo</sender> + <signal>activated(const QString&)</signal> + <receiver>NewFormBase</receiver> + <slot>projectChanged(const QString&)</slot> + </connection> + <connection> + <sender>templateView</sender> + <signal>currentChanged(QIconViewItem*)</signal> + <receiver>NewFormBase</receiver> + <slot>itemChanged(QIconViewItem*)</slot> + </connection> + <connection> + <sender>templateView</sender> + <signal>doubleClicked(QIconViewItem*)</signal> + <receiver>NewFormBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>templateView</sender> + <signal>returnPressed(QIconViewItem*)</signal> + <receiver>NewFormBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<tabstops> + <tabstop>templateView</tabstop> + <tabstop>helpButton</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot access="protected">itemChanged( QIconViewItem * )</slot> + <slot access="protected">projectChanged( const QString & )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/newformimpl.cpp b/kdevdesigner/designer/newformimpl.cpp new file mode 100644 index 00000000..9ff44d01 --- /dev/null +++ b/kdevdesigner/designer/newformimpl.cpp @@ -0,0 +1,414 @@ +/********************************************************************** +** 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. +** +** 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 "newformimpl.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "project.h" +#include "formwindow.h" +#include "widgetfactory.h" +#include "widgetdatabase.h" +#include "actioneditorimpl.h" +#include "hierarchyview.h" +#include "resource.h" +#include "projectsettingsimpl.h" +#include "sourcefile.h" + +#include <kiconloader.h> +#include "kdevdesigner_part.h" +#include <klocale.h> + +#include <qiconview.h> +#include <qlabel.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qpushbutton.h> +#include <stdlib.h> +#include <qcombobox.h> +#include <qworkspace.h> +#include <qmessagebox.h> + +static int forms = 0; + +ProjectItem::ProjectItem( QIconView *view, const QString &text ) + : NewItem( view, text ) +{ +} + +void ProjectItem::insert( Project * ) +{ + MainWindow::self->createNewProject( lang ); +} + + + +FormItem::FormItem( QIconView *view, const QString &text ) + : NewItem( view, text ) +{ +} + +void FormItem::insert( Project *pro ) +{ + QString n = "Form" + QString::number( ++forms ); + FormWindow *fw = 0; + FormFile *ff = new FormFile( FormFile::createUnnamedFileName(), TRUE, pro ); + fw = new FormWindow( ff, MainWindow::self, MainWindow::self->qWorkspace(), n ); + fw->setProject( pro ); + MetaDataBase::addEntry( fw ); + if ( fType == Widget ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QWidget" ), + fw, n.latin1() ); + fw->setMainContainer( w ); + } else if ( fType == Dialog ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QDialog" ), fw, n.latin1() ); + fw->setMainContainer( w ); + } else if ( fType == Wizard ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QWizard" ), + fw, n.latin1() ); + fw->setMainContainer( w ); + } else if ( fType == MainWindow ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QMainWindow" ), + fw, n.latin1() ); + fw->setMainContainer( w ); + } + + fw->setCaption( n ); + fw->resize( 600, 480 ); + MainWindow::self->insertFormWindow( fw ); + + TemplateWizardInterface *iface = + MainWindow::self->templateWizardInterface( fw->mainContainer()->className() ); + if ( iface ) { + iface->setup( fw->mainContainer()->className(), fw->mainContainer(), + fw->iFace(), MainWindow::self->designerInterface() ); + iface->release(); + } + + // the wizard might have changed a lot, lets update everything + MainWindow::self->actioneditor()->setFormWindow( fw ); + MainWindow::self->objectHierarchy()->setFormWindow( fw, fw ); + MainWindow::self->objectHierarchy()->formDefinitionView()->refresh(); + MainWindow::self->objectHierarchy()->rebuild(); + fw->killAccels( fw ); + fw->project()->setModified( TRUE ); + fw->setFocus(); + if ( !pro->isDummy() ) { + fw->setSavePixmapInProject( TRUE ); + fw->setSavePixmapInline( FALSE ); + } +} + + + +CustomFormItem::CustomFormItem( QIconView *view, const QString &text ) + : NewItem( view, text ) +{ +} + +static void unifyFormName( FormWindow *fw, QWorkspace *qworkspace ) +{ + QStringList lst; + QWidgetList windows = qworkspace->windowList(); + for ( QWidget *w =windows.first(); w; w = windows.next() ) { + if ( w == fw ) + continue; + lst << w->name(); + } + + if ( lst.findIndex( fw->name() ) == -1 ) + return; + QString origName = fw->name(); + QString n = origName; + int i = 1; + while ( lst.findIndex( n ) != -1 ) { + n = origName + QString::number( i++ ); + } + fw->setName( n ); + fw->setCaption( n ); +} + +void CustomFormItem::insert( Project *pro ) +{ + QString filename = templateFileName(); + if ( !filename.isEmpty() && QFile::exists( filename ) ) { + Resource resource( MainWindow::self ); + FormFile *ff = new FormFile( filename, TRUE, pro ); + if ( !resource.load( ff ) ) { + QMessageBox::information( MainWindow::self, i18n("Load Template"), + i18n("Could not load form description from template '%1'" ).arg( filename ) ); + delete ff; + return; + } + ff->setFileName( QString::null ); + if ( MainWindow::self->formWindow() ) { + MainWindow::self->formWindow()->setFileName( QString::null ); + unifyFormName( MainWindow::self->formWindow(), MainWindow::self->qWorkspace() ); + if ( !pro->isDummy() ) { + MainWindow::self->formWindow()->setSavePixmapInProject( TRUE ); + MainWindow::self->formWindow()->setSavePixmapInline( FALSE ); + } + } + } +} + + + +SourceFileItem::SourceFileItem( QIconView *view, const QString &text ) + : NewItem( view, text ), visible( TRUE ) +{ +} + +void SourceFileItem::insert( Project *pro ) +{ + SourceFile *f = new SourceFile( SourceFile::createUnnamedFileName( ext ), TRUE, pro ); + MainWindow::self->editSource( f ); +} + +void SourceFileItem::setProject( Project *pro ) +{ + QIconView *iv = iconView(); + bool v = lang == pro->language(); + if ( !iv || v == visible ) + return; + visible = v; + if ( !visible ) + iv->takeItem( this ); + else + iv->insertItem( this ); +} + + + +SourceTemplateItem::SourceTemplateItem( QIconView *view, const QString &text ) + : NewItem( view, text ), visible( TRUE ) +{ +} + +void SourceTemplateItem::insert( Project *pro ) +{ + SourceTemplateInterface *siface = MainWindow::self->sourceTemplateInterface( text() ); + if ( !siface ) + return; + SourceTemplateInterface::Source src = siface->create( text(), MainWindow::self->designerInterface() ); + SourceFile *f = 0; + if ( src.type == SourceTemplateInterface::Source::Invalid ) + return; + if ( src.type == SourceTemplateInterface::Source::FileName ) + f = new SourceFile( src.filename, FALSE, pro ); + else + f = new SourceFile( SourceFile::createUnnamedFileName( src.extension ), TRUE, pro ); + if ( f->isAccepted()) { + f->setText( src.code ); + MainWindow::self->editSource( f ); + f->setModified( TRUE ); + } else { + delete f; + } +} + +void SourceTemplateItem::setProject( Project *pro ) +{ + QIconView *iv = iconView(); + bool v = !pro->isDummy() && lang == pro->language(); + if ( !iv || v == visible ) + return; + visible = v; + if ( !visible ) + iv->takeItem( this ); + else + iv->insertItem( this ); +} + +void NewForm::insertTemplates( QIconView *tView, + const QString &templatePath ) +{ + QStringList::Iterator it; + QStringList languages = MetaDataBase::languages(); + if ( !MainWindow::self->singleProjectMode() ) { + for ( it = languages.begin(); it != languages.end(); ++it ) { + ProjectItem *pi = new ProjectItem( tView, i18n("%1 Project" ).arg( *it ) ); + allItems.append( pi ); + pi->setLanguage( *it ); + pi->setPixmap( BarIcon( "designer_project.png" , KDevDesignerPartFactory::instance()) ); + pi->setDragEnabled( FALSE ); + } + } + QIconViewItem *cur = 0; + FormItem *fi = new FormItem( tView,i18n( "Dialog" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::Dialog ); + fi->setPixmap( BarIcon( "designer_newform.png" , KDevDesignerPartFactory::instance()) ); + fi->setDragEnabled( FALSE ); + cur = fi; + if ( !MainWindow::self->singleProjectMode() ) { + fi = new FormItem( tView,i18n( "Wizard" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::Wizard ); + fi->setPixmap( BarIcon( "designer_newform.png" , KDevDesignerPartFactory::instance()) ); + fi->setDragEnabled( FALSE ); + fi = new FormItem( tView, i18n( "Widget" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::Widget ); + fi->setPixmap( BarIcon( "designer_newform.png" , KDevDesignerPartFactory::instance()) ); + fi->setDragEnabled( FALSE ); + fi = new FormItem( tView, i18n( "Main Window" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::MainWindow ); + fi->setPixmap( BarIcon( "designer_newform.png" , KDevDesignerPartFactory::instance()) ); + fi->setDragEnabled( FALSE ); + + QString templPath = templatePath; + QStringList templRoots; + const char *qtdir = getenv( "QTDIR" ); + if(qtdir) + templRoots << qtdir; + templRoots << qInstallPathData(); + if(qtdir) //try the tools/designer directory last! + templRoots << (QString(qtdir) + "/tools/designer"); + for ( QStringList::Iterator it = templRoots.begin(); it != templRoots.end(); ++it ) { + QString path = (*it) + "/templates"; + if ( QFile::exists( path )) { + templPath = path; + break; + } + } + if ( !templPath.isEmpty() ) { + QDir dir( templPath ); + const QFileInfoList *filist = dir.entryInfoList( QDir::DefaultFilter, QDir::DirsFirst | QDir::Name ); + if ( filist ) { + QFileInfoListIterator it( *filist ); + QFileInfo *fi; + while ( ( fi = it.current() ) != 0 ) { + ++it; + if ( !fi->isFile() || fi->extension() != "ui" ) + continue; + QString name = fi->baseName(); + name = name.replace( '_', ' ' ); + CustomFormItem *ci = new CustomFormItem( tView, name ); + allItems.append( ci ); + ci->setDragEnabled( FALSE ); + ci->setPixmap( BarIcon( "designer_newform.png" , KDevDesignerPartFactory::instance()) ); + ci->setTemplateFile( fi->absFilePath() ); + } + } + } + } + + for ( it = languages.begin(); it != languages.end(); ++it ) { + LanguageInterface *iface = MetaDataBase::languageInterface( *it ); + if ( iface ) { + QMap<QString, QString> extensionMap; + iface->preferedExtensions( extensionMap ); + for ( QMap<QString, QString>::Iterator eit = extensionMap.begin(); + eit != extensionMap.end(); ++eit ) { + SourceFileItem * si = new SourceFileItem( tView, *eit ); + allItems.append( si ); + si->setExtension( eit.key() ); + si->setLanguage( *it ); + si->setPixmap( BarIcon( "designer_filenew.png", KDevDesignerPartFactory::instance() ) ); + si->setDragEnabled( FALSE ); + } + iface->release(); + } + } + + if ( !MainWindow::self->singleProjectMode() ) { + QStringList sourceTemplates = MainWindow::self->sourceTemplates(); + for ( QStringList::Iterator sit = sourceTemplates.begin(); sit != sourceTemplates.end(); ++sit ) { + SourceTemplateInterface *siface = MainWindow::self->sourceTemplateInterface( *sit ); + if ( !siface ) + continue; + SourceTemplateItem * si = new SourceTemplateItem( tView, *sit ); + allItems.append( si ); + si->setTemplate( *sit ); + si->setLanguage( siface->language( *sit ) ); + si->setPixmap( BarIcon( "designer_filenew.png", KDevDesignerPartFactory::instance() ) ); + si->setDragEnabled( FALSE ); + siface->release(); + } + } + + tView->viewport()->setFocus(); + tView->setCurrentItem( cur ); + + if ( MainWindow::self->singleProjectMode() ) + adjustSize(); +} + +NewForm::NewForm( QIconView *templateView, const QString &templatePath ) +{ + insertTemplates( templateView, templatePath ); + projectChanged( i18n( "<No Project>" ) ); +} + +NewForm::NewForm( QWidget *parent, const QStringList& projects, + const QString& currentProject, const QString &templatePath ) + : NewFormBase( parent, 0, TRUE ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + projectCombo->insertStringList( projects ); + projectCombo->setCurrentText( currentProject ); + + insertTemplates( templateView, templatePath ); + + projectChanged( projectCombo->currentText() ); +} + +void NewForm::accept() +{ + if ( !templateView->currentItem() ) + return; + Project *pro = MainWindow::self->findProject( projectCombo->currentText() ); + if ( !pro ) + return; + MainWindow::self->setCurrentProject( pro ); + NewFormBase::accept(); + ( (NewItem*)templateView->currentItem() )->insert( pro ); +} + +void NewForm::projectChanged( const QString &project ) +{ + Project *pro = MainWindow::self->findProject( project ); + if ( !pro ) + return; + QIconViewItem *i; + for ( i = allItems.first(); i; i = allItems.next() ) + ( (NewItem*)i )->setProject( pro ); + templateView->setCurrentItem( templateView->firstItem() ); + templateView->arrangeItemsInGrid( TRUE ); +} + +void NewForm::itemChanged( QIconViewItem *item ) +{ + labelProject->setEnabled( item->rtti() != NewItem::ProjectType ); + projectCombo->setEnabled( item->rtti() != NewItem::ProjectType ); +} + +QPtrList<QIconViewItem> NewForm::allViewItems() +{ + return allItems; +} diff --git a/kdevdesigner/designer/newformimpl.h b/kdevdesigner/designer/newformimpl.h new file mode 100644 index 00000000..acd597bf --- /dev/null +++ b/kdevdesigner/designer/newformimpl.h @@ -0,0 +1,164 @@ +/********************************************************************** +** 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 NEWFORMIMPL_H +#define NEWFORMIMPL_H + +#include "newform.h" +#include <qiconview.h> + +class Project; + +class NewItem : public QIconViewItem +{ +public: + enum Type { + ProjectType, + Form, + CustomForm, + SourceFileType, + SourceTemplateType + }; + + NewItem( QIconView *view, const QString &text ) + : QIconViewItem( view, text ) {} + virtual void insert( Project *pro ) = 0; + virtual void setProject( Project * ) {} + +}; + +class ProjectItem : public NewItem +{ +public: + ProjectItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)ProjectType; } + + void setLanguage( const QString &l ) { lang = l; } + QString language() const { return lang; } + +private: + QString lang; + +}; + +class FormItem : public NewItem +{ +public: + enum FormType { + Widget, + Dialog, + Wizard, + MainWindow + }; + + FormItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)Form; } + + void setFormType( FormType ft ) { fType = ft; } + FormType formType() const { return fType; } + +private: + FormType fType; + +}; + +class CustomFormItem : public NewItem +{ +public: + CustomFormItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)CustomForm; } + + void setTemplateFile( const QString &tf ) { templFile = tf; } + QString templateFileName() const { return templFile; } + +private: + QString templFile; + +}; + +class SourceFileItem : public NewItem +{ +public: + SourceFileItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)SourceFileType; } + + void setExtension( const QString &e ) { ext = e; } + QString extension() const { return ext; } + void setLanguage( const QString &l ) { lang = l; } + void setProject( Project *pro ); + +private: + QString ext; + QString lang; + bool visible; + +}; + +class SourceTemplateItem : public NewItem +{ +public: + SourceTemplateItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)SourceTemplateType; } + + void setTemplate( const QString &t ) { templ = t; } + QString tenplate() const { return templ; } + void setLanguage( const QString &l ) { lang = l; } + void setProject( Project *pro ); + +private: + QString templ; + QString lang; + bool visible; + +}; + +class NewForm : public NewFormBase +{ + Q_OBJECT + +public: + NewForm( QIconView *templateView, const QString &templatePath ); + NewForm( QWidget *parent, const QStringList& projects, + const QString& currentProject, const QString &templatePath ); + void insertTemplates( QIconView*, const QString& ); + void accept(); + QPtrList<QIconViewItem> allViewItems(); + +protected slots: + void projectChanged( const QString &project ); + void itemChanged( QIconViewItem *item ); + +private: + QPtrList<QIconViewItem> allItems; + +}; + +#endif diff --git a/kdevdesigner/designer/orderindicator.cpp b/kdevdesigner/designer/orderindicator.cpp new file mode 100644 index 00000000..08ed16b8 --- /dev/null +++ b/kdevdesigner/designer/orderindicator.cpp @@ -0,0 +1,112 @@ +/********************************************************************** +** 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 <qvariant.h> // HP-UX compiler need this here + +#include "orderindicator.h" +#include "formwindow.h" + +#include <qpainter.h> +#include <qbitmap.h> +#include <qapplication.h> + +OrderIndicator::OrderIndicator( int i, QWidget* w, FormWindow *fw ) + : QWidget( fw, "order_indicator", WMouseNoMask ), formWindow( fw ) +{ + order = -1; + widget = w; + setBackgroundMode( NoBackground ); + setAutoMask( TRUE ); + setOrder( i, w ); +} + + +OrderIndicator::~OrderIndicator() +{ +} + + +void OrderIndicator::setOrder( int i, QWidget* wid ) +{ + if ( widget != wid ) + return; + if ( !wid->isVisibleTo( formWindow ) ) { + hide(); + return; + } + + if ( order == i ) { + show(); + raise(); + return; + } + order = i; + int w = fontMetrics().width( QString::number( i ) ) + 10; + int h = fontMetrics().lineSpacing() * 3 / 2; + QFont f( font() ); + f.setBold( TRUE ); + setFont( f ); + resize( QMAX( w, h ), h ); + update(); // in case the size didn't change + reposition(); + show(); + raise(); +} + +void OrderIndicator::reposition() +{ + QPoint p =parentWidget()->mapFromGlobal( widget->mapToGlobal( widget->rect().topLeft() ) ); + move( p - QPoint( width()/3, height()/3 ) ); +} + + +void OrderIndicator::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.setPen( white ); + p.setBrush( blue ); + p.drawEllipse( rect() ); + p.drawText( rect(), AlignCenter, QString::number( order ) ); +} + + +void OrderIndicator::updateMask() +{ + QBitmap bm( size() ); + bm.fill( color0 ); + { + QPainter p( &bm, this ); + p.setPen( color1 ); + p.setBrush( color1 ); + p.drawEllipse( rect() ); + } + setMask( bm ); +} + +void OrderIndicator::mousePressEvent( QMouseEvent *e ) +{ + QApplication::sendEvent( widget, e ); +} diff --git a/kdevdesigner/designer/orderindicator.h b/kdevdesigner/designer/orderindicator.h new file mode 100644 index 00000000..35962b7a --- /dev/null +++ b/kdevdesigner/designer/orderindicator.h @@ -0,0 +1,57 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef ORDERINDICATOR_H +#define ORDERINDICATOR_H + +#include <qwidget.h> + +class FormWindow; + +class OrderIndicator : public QWidget +{ + Q_OBJECT + +public: + OrderIndicator( int i, QWidget* w, FormWindow* fw ); + ~OrderIndicator(); + + void setOrder( int i, QWidget* w ); + void reposition(); + +protected: + void paintEvent( QPaintEvent * ); + void mousePressEvent( QMouseEvent *e ); + void updateMask(); + +private: + int order; + QWidget* widget; + FormWindow *formWindow; + +}; + +#endif diff --git a/kdevdesigner/designer/outputwindow.cpp b/kdevdesigner/designer/outputwindow.cpp new file mode 100644 index 00000000..f51a54a3 --- /dev/null +++ b/kdevdesigner/designer/outputwindow.cpp @@ -0,0 +1,209 @@ +/********************************************************************** +** Copyright (C) 2001-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 "outputwindow.h" +#include "designerappiface.h" +#include "metadatabase.h" +#include "mainwindow.h" + +#include <qlistview.h> +#include <qtextedit.h> +#include <qapplication.h> +#include <qheader.h> +#include <stdlib.h> +#include <stdio.h> +#include <qpainter.h> + +#include <klocale.h> + +static QTextEdit *debugoutput = 0; +bool debugToStderr = FALSE; + +QtMsgHandler OutputWindow::oldMsgHandler = 0; + +OutputWindow::OutputWindow( QWidget *parent ) + : QTabWidget( parent, "output_window" ), debugView( 0 ), errorView( 0 ) +{ + setupDebug(); + setupError(); + iface = new DesignerOutputDockImpl( this ); +} + +OutputWindow::~OutputWindow() +{ + debugoutput = debugView = 0; + errorView = 0; + if ( !debugToStderr ) + qInstallMsgHandler( oldMsgHandler ); + delete iface; +} + +void OutputWindow::shuttingDown() +{ + if ( !debugToStderr ) + qInstallMsgHandler( oldMsgHandler ); +} + +void OutputWindow::setupError() +{ + errorView = new QListView( this, "OutputWindow::errorView" ); + errorView->setSorting( -1 ); + connect( errorView, SIGNAL( currentChanged( QListViewItem* ) ), + this, SLOT( currentErrorChanged( QListViewItem* ) ) ); + connect( errorView, SIGNAL( clicked( QListViewItem* ) ), + this, SLOT( currentErrorChanged( QListViewItem* ) ) ); + + if ( MetaDataBase::languages().count() > 1 ) + addTab( errorView, i18n( "Warnings/Errors" ) ); + else + errorView->hide(); + errorView->addColumn( i18n( "Type" ) ); + errorView->addColumn( i18n( "Message" ) ); + errorView->addColumn( i18n( "Line" ) ); + errorView->addColumn( i18n( "Location" ) ); + errorView->setResizeMode( QListView::LastColumn ); + errorView->setColumnWidth( 0, errorView->fontMetrics().width( "WARNING1234" ) ); + errorView->setColumnWidth( 1, errorView->fontMetrics().width( "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOP" ) ); + errorView->setColumnWidth( 2, errorView->fontMetrics().width( "9999999" ) ); + errorView->setColumnAlignment( 2, Qt::AlignRight ); + errorView->setAllColumnsShowFocus( TRUE ); +} + +static void debugMessageOutput( QtMsgType type, const char *msg ) +{ + QString s( msg ); + s += "\n"; + + if ( type != QtFatalMsg ) { + if ( debugoutput && debugoutput->isVisible() ) + debugoutput->append( s ); + else if ( OutputWindow::oldMsgHandler && OutputWindow::oldMsgHandler != debugMessageOutput ) + (*OutputWindow::oldMsgHandler)( type, msg ); + else + fputs( s.latin1(), stderr ); + } else { + fputs( s.latin1(), stderr ); + abort(); + } + + qApp->flush(); +} + +void OutputWindow::setupDebug() +{ + debugoutput = debugView = new QTextEdit( this, "OutputWindow::debugView" ); + //debugView->setReadOnly( TRUE ); + addTab( debugView, "Debug Output" ); + + if ( !debugToStderr ) + oldMsgHandler = qInstallMsgHandler( debugMessageOutput ); +} + +void OutputWindow::setErrorMessages( const QStringList &errors, const QValueList<uint> &lines, + bool clear, const QStringList &locations, + const QObjectList &locationObjects ) +{ + if ( clear ) + errorView->clear(); + QStringList::ConstIterator mit = errors.begin(); + QValueList<uint>::ConstIterator lit = lines.begin(); + QStringList::ConstIterator it = locations.begin(); + QObjectList objects = (QObjectList)locationObjects; + QObject *o = objects.first(); + QListViewItem *after = 0; + for ( ; lit != lines.end() && mit != errors.end(); ++lit, ++mit, ++it, o = objects.next() ) + after = new ErrorItem( errorView, after, *mit, *lit, *it, o ); + setCurrentPage( 1 ); +} + +DesignerOutputDock *OutputWindow::iFace() +{ + return iface; +} + +void OutputWindow::appendDebug( const QString &text ) +{ + debugView->append( text + "\n" ); +} + +void OutputWindow::clearErrorMessages() +{ + errorView->clear(); +} + +void OutputWindow::clearDebug() +{ + debugView->clear(); +} + +void OutputWindow::showDebugTab() +{ + showPage( debugView ); +} + +void OutputWindow::currentErrorChanged( QListViewItem *i ) +{ + if ( !i ) + return; + ErrorItem *ei = (ErrorItem*)i; + ei->setRead( TRUE ); + MainWindow::self->showSourceLine( ei->location(), ei->line() - 1, MainWindow::Error ); +} + + + +ErrorItem::ErrorItem( QListView *parent, QListViewItem *after, const QString &message, int line, + const QString &locationString, QObject *locationObject ) + : QListViewItem( parent, after ) +{ + setMultiLinesEnabled( TRUE ); + QString m( message ); + type = m.startsWith( "Warning: " ) ? Warning : Error; + m = m.mid( m.find( ':' ) + 1 ); + setText( 0, type == Error ? "Error" : "Warning" ); + setText( 1, m ); + setText( 2, QString::number( line ) ); + setText( 3, locationString ); + object = locationObject; + read = !after; + if ( !after ) { + parent->setSelected( this, TRUE ); + parent->setCurrentItem( this ); + } +} + +void ErrorItem::paintCell( QPainter *p, const QColorGroup & cg, + int column, int width, int alignment ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Text, type == Error ? Qt::red : Qt::darkYellow ); + if ( !read ) { + QFont f( p->font() ); + f.setBold( TRUE ); + p->setFont( f ); + } + QListViewItem::paintCell( p, g, column, width, alignment ); +} diff --git a/kdevdesigner/designer/outputwindow.h b/kdevdesigner/designer/outputwindow.h new file mode 100644 index 00000000..e61c92c0 --- /dev/null +++ b/kdevdesigner/designer/outputwindow.h @@ -0,0 +1,98 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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 OUTPUTWINDOW_H +#define OUTPUTWINDOW_H + +#include <qtabwidget.h> +#include <qstringlist.h> +#include <qvaluelist.h> +#include <qlistview.h> + +struct DesignerOutputDock; +class QTextEdit; +class QListView; + +class ErrorItem : public QListViewItem +{ +public: + enum Type { Error, Warning }; + + ErrorItem( QListView *parent, QListViewItem *after, const QString &message, int line, + const QString &locationString, QObject *locationObject ); + + void paintCell( QPainter *, const QColorGroup & cg, + int column, int width, int alignment ); + + void setRead( bool b ) { read = b; repaint(); } + + QObject *location() const { return object; } + int line() const { return text( 2 ).toInt(); } + +private: + QObject *object; + Type type; + bool read; + +}; + +class OutputWindow : public QTabWidget +{ + Q_OBJECT + +public: + OutputWindow( QWidget *parent ); + ~OutputWindow(); + + void setErrorMessages( const QStringList &errors, const QValueList<uint> &lines, + bool clear, const QStringList &locations, + const QObjectList &locationObjects ); + void appendDebug( const QString& ); + void clearErrorMessages(); + void clearDebug(); + void showDebugTab(); + + DesignerOutputDock *iFace(); + + void shuttingDown(); + + static QtMsgHandler oldMsgHandler; + +private slots: + void currentErrorChanged( QListViewItem *i ); + +private: + void setupError(); + void setupDebug(); + + QTextEdit *debugView; + QListView *errorView; + + DesignerOutputDock *iface; + +}; + +#endif diff --git a/kdevdesigner/designer/paletteeditor.ui b/kdevdesigner/designer/paletteeditor.ui new file mode 100644 index 00000000..8a87f0ea --- /dev/null +++ b/kdevdesigner/designer/paletteeditor.ui @@ -0,0 +1,496 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>PaletteEditorBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>PaletteEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>449</width> + <height>443</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property name="caption"> + <string>Edit Palette</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupAutoPalette</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>4</vsizetype> + </sizepolicy> + </property> + <property name="title"> + <string>Build Palette</string> + </property> + <property name="alignment"> + <set>AlignAuto</set> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelMainColor</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="lineWidth"> + <number>1</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="midLineWidth"> + <number>0</number> + </property> + <property name="text"> + <string>&3-D effects:</string> + </property> + <property name="alignment"> + <set>AlignAuto|AlignVCenter</set> + </property> + <property name="buddy" stdset="0"> + <cstring>buttonMainColor</cstring> + </property> + </widget> + <widget class="StyledButton"> + <property name="name"> + <cstring>buttonMainColor</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Choose a color</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose the effect-color for the generated palette.</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>labelMainColor2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="lineWidth"> + <number>1</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="midLineWidth"> + <number>0</number> + </property> + <property name="text"> + <string>Back&ground:</string> + </property> + <property name="alignment"> + <set>AlignAuto|AlignVCenter</set> + </property> + <property name="buddy" stdset="0"> + <cstring>buttonMainColor2</cstring> + </property> + </widget> + <widget class="StyledButton"> + <property name="name"> + <cstring>buttonMainColor2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Choose a color</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose the background color for the generated palette.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnAdvanced</cstring> + </property> + <property name="text"> + <string>&Tune Palette...</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox126</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property name="title"> + <string>Preview</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Select &palette:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>paletteCombo</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Active Palette</string> + </property> + </item> + <item> + <property name="text"> + <string>Inactive Palette</string> + </property> + </item> + <item> + <property name="text"> + <string>Disabled Palette</string> + </property> + </item> + <property name="name"> + <cstring>paletteCombo</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="PreviewFrame"> + <property name="name"> + <cstring>previewFrame</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing11</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>StyledButton</class> + <header location="local">styledbutton.h</header> + <sizehint> + <width>40</width> + <height>25</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + </sizepolicy> + <pixmap>"image0"</pixmap> + <signal>clicked()</signal> + <signal>changed()</signal> + <property type="Color">color</property> + <property type="Pixmap">pixmap</property> + <property type="Bool">scale</property> + </customwidget> + <customwidget> + <class>PreviewFrame</class> + <header location="local">previewframe.h</header> + <sizehint> + <width>200</width> + <height>200</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + </sizepolicy> + <pixmap>"image1"</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="1112">789c9dd2cb8e9b301406e07d9e0225bba89a09601350d505302c5b7559a9eac23e6672b363620c0ca9faeef53949da2e2a55eab123f9e38f2f217e5e475f3e7f8cd6cf8bde0b7f8008f6c2456b3518337ffdf6e1fb62992451e8691ac5cb778be55304d1277b6e71fc12c6ab0d157222e61bd8e4c812196f6216535a13f318624a6764b2495842e99558249014c81e99c6294b69d3376291424ae9806431638cd28628183081f4489e70ce13e4852878c129ad905992f18cd291283295517a466ed32ddfa64847945bb595c80e99a739cf29d54499ab9c528b2c58c10b86344428540148400a26b8a0541241b482d215523299494a0551c9562ae409091c32e0c82351410b942aa4e22a53941e882d36e41ed966d8903b2215f215f99a6143b6442afaafff5aff485658622584a091941256948443d1cabbdd6ebf3f28753c09a9e9cdc1fe703c9e4ea19f689a0430fa4c8908082be093d08d016bbb0bbd5e7ceafade5b30de19d083b3fa9e008cd39b9fafd69495b473af7fcfb15325c1d61eea0afaf005ddf97b5295c658a866338f97591babef7340fa396c6c5ca9e7fe650807d0bf566b4262299986ba335a3b4a2cc84b69ac85b1b673037d8fabf95b023a9c09cc7530e104dd5419ed6e27083fb09a7c752db5a9bd31cde4ec634ed8a39aebbe337618c3f6fdc5dee6d8b0bb0d6b5b8b1fad43d78fe4e14e3f6aace8e29d9d736777fea3c686eee0138c9726d4d00c548df7a315ff750f7ebc5ffc04a0e5308d</data> + </image> + <image name="image1"> + <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> + </image> +</images> +<connections> + <connection> + <sender>buttonMainColor2</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>onChoose2ndMainColor()</slot> + </connection> + <connection> + <sender>paletteCombo</sender> + <signal>activated(int)</signal> + <receiver>PaletteEditorBase</receiver> + <slot>paletteSelected(int)</slot> + </connection> + <connection> + <sender>btnAdvanced</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>onTune()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonMainColor</sender> + <signal>changed()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>onChooseMainColor()</slot> + </connection> + <connection> + <sender>buttonMainColor</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>onChooseMainColor()</slot> + </connection> + <connection> + <sender>buttonMainColor2</sender> + <signal>changed()</signal> + <receiver>PaletteEditorBase</receiver> + <slot>onChoose2ndMainColor()</slot> + </connection> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> + <slot access="protected" language="C++" returnType="void">onTune()</slot> + <slot access="protected" language="C++" returnType="void">onChoose2ndMainColor()</slot> + <slot access="protected" language="C++" returnType="void">onChooseMainColor()</slot> + <slot access="protected" language="C++" returnType="void">paletteSelected(int)</slot> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>buttonMainColor</tabstop> + <tabstop>buttonMainColor2</tabstop> + <tabstop>btnAdvanced</tabstop> + <tabstop>paletteCombo</tabstop> + <tabstop>buttonHelp</tabstop> +</tabstops> +</UI> diff --git a/kdevdesigner/designer/paletteeditoradvanced.ui b/kdevdesigner/designer/paletteeditoradvanced.ui new file mode 100644 index 00000000..faa211c1 --- /dev/null +++ b/kdevdesigner/designer/paletteeditoradvanced.ui @@ -0,0 +1,748 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>PaletteEditorAdvancedBase</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>PaletteEditorAdvancedBase</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>327</width> + <height>341</height> + </rect> + </property> + <property name="caption"> + <string>Tune Palette</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Edit Palette</b><p>Change the current widget or form's palette.</p><p>Use a generated palette or select colors for each color group and each color role.</p><p>The palette can be tested with different widget layouts in the preview section.</p></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout14</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="frameShape"> + <enum>MShape</enum> + </property> + <property name="frameShadow"> + <enum>MShadow</enum> + </property> + <property name="text"> + <string>Select &palette:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>paletteCombo</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Active Palette</string> + </property> + </item> + <item> + <property name="text"> + <string>Inactive Palette</string> + </property> + </item> + <item> + <property name="text"> + <string>Disabled Palette</string> + </property> + </item> + <property name="name"> + <cstring>paletteCombo</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>4</vsizetype> + </sizepolicy> + </property> + <property name="title"> + <string>Auto</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBuildInactive</cstring> + </property> + <property name="text"> + <string>Build the &inactive palette from the active palette</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBuildDisabled</cstring> + </property> + <property name="text"> + <string>Build the &disabled palette from the active palette</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupCentral</cstring> + </property> + <property name="title"> + <string>Central Color Roles</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Background</string> + </property> + </item> + <item> + <property name="text"> + <string>Foreground</string> + </property> + </item> + <item> + <property name="text"> + <string>Button</string> + </property> + </item> + <item> + <property name="text"> + <string>Base</string> + </property> + </item> + <item> + <property name="text"> + <string>Text</string> + </property> + </item> + <item> + <property name="text"> + <string>BrightText</string> + </property> + </item> + <item> + <property name="text"> + <string>ButtonText</string> + </property> + </item> + <item> + <property name="text"> + <string>Highlight</string> + </property> + </item> + <item> + <property name="text"> + <string>HighlightText</string> + </property> + </item> + <item> + <property name="text"> + <string>Link</string> + </property> + </item> + <item> + <property name="text"> + <string>LinkVisited</string> + </property> + </item> + <property name="name"> + <cstring>comboCentral</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Choose the central color role</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a color role.</b><p>Available central color roles are: <ul> <li>Background - general background color.</li> <li>Foreground - general foreground color. </li> <li>Base - used as the background color for example, for text entry widgets; it is usually white or another light color. </li> <li>Text - the forground color used with Base. Usually this is the same as the Foreground, in which case it must provide good contrast both with the Background and with the Base. </li> <li>Button - general button background color; useful where buttons need a background different from Background, as in the Macintosh style. </li> <li>ButtonText - a foreground color used with the Button color. </li> <li>Highlight - a color used to indicate a selected or highlighted item. </li> <li>HighlightedText - a text color that contrasts to Highlight. </li> <li>BrightText - a text color that is very different from Foreground and contrasts well with, for example, black. </li> </ul> </p></string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout32_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal_Spacing1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>labelPixmap</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property name="text"> + <string>Choose pi&xmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>buttonPixmap</cstring> + </property> + </widget> + <widget class="StyledButton"> + <property name="name"> + <cstring>buttonPixmap</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Select a pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose a pixmap file for the selected central color role.</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>labelCentral</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>&Select color:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>buttonCentral</cstring> + </property> + </widget> + <widget class="StyledButton"> + <property name="name"> + <cstring>buttonCentral</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Choose a color</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose a color for the selected central color role.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupEffect</cstring> + </property> + <property name="title"> + <string>3-D Shadow Effects</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout32_3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBuildEffect</cstring> + </property> + <property name="text"> + <string>Build &from button color:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Generate shadings</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Check to let 3D-effect colors be calculated from the button-color.</string> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Light</string> + </property> + </item> + <item> + <property name="text"> + <string>Midlight</string> + </property> + </item> + <item> + <property name="text"> + <string>Mid</string> + </property> + </item> + <item> + <property name="text"> + <string>Dark</string> + </property> + </item> + <item> + <property name="text"> + <string>Shadow</string> + </property> + </item> + <property name="name"> + <cstring>comboEffect</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Choose 3D-effect color role</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a color effect role.</b><p>Available effect roles are: <ul> <li>Light - lighter than Button color. </li> <li>Midlight - between Button and Light. </li> <li>Mid - between Button and Dark. </li> <li>Dark - darker than Button. </li> <li>Shadow - a very dark color. </li> </ul></string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout31_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal_Spacing3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>labelEffect</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Select co&lor:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>buttonEffect</cstring> + </property> + </widget> + <widget class="StyledButton"> + <property name="name"> + <cstring>buttonEffect</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Choose a color</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose a color for the selected effect color role.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal_Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>StyledButton</class> + <header location="local">styledbutton.h</header> + <sizehint> + <width>40</width> + <height>25</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + </sizepolicy> + <pixmap>"image0"</pixmap> + <signal>clicked()</signal> + <signal>changed()</signal> + <property type="Color">color</property> + <property type="Pixmap">pixmap</property> + <property type="Bool">scale</property> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="1112">789c9dd2cb8e9b301406e07d9e0225bba89a09601350d505302c5b7559a9eac23e6672b363620c0ca9faeef53949da2e2a55eab123f9e38f2f217e5e475f3e7f8cd6cf8bde0b7f8008f6c2456b3518337ffdf6e1fb62992451e8691ac5cb778be55304d1277b6e71fc12c6ab0d157222e61bd8e4c812196f6216535a13f318624a6764b2495842e99558249014c81e99c6294b69d3376291424ae9806431638cd28628183081f4489e70ce13e4852878c129ad905992f18cd291283295517a466ed32ddfa64847945bb595c80e99a739cf29d54499ab9c528b2c58c10b86344428540148400a26b8a0541241b482d215523299494a0551c9562ae409091c32e0c82351410b942aa4e22a53941e882d36e41ed966d8903b2215f215f99a6143b6442afaafff5aff485658622584a091941256948443d1cabbdd6ebf3f28753c09a9e9cdc1fe703c9e4ea19f689a0430fa4c8908082be093d08d016bbb0bbd5e7ceafade5b30de19d083b3fa9e008cd39b9fafd69495b473af7fcfb15325c1d61eea0afaf005ddf97b5295c658a866338f97591babef7340fa396c6c5ca9e7fe650807d0bf566b4262299986ba335a3b4a2cc84b69ac85b1b673037d8fabf95b023a9c09cc7530e104dd5419ed6e27083fb09a7c752db5a9bd31cde4ec634ed8a39aebbe337618c3f6fdc5dee6d8b0bb0d6b5b8b1fad43d78fe4e14e3f6aace8e29d9d736777fea3c686eee0138c9726d4d00c548df7a315ff750f7ebc5ffc04a0e5308d</data> + </image> +</images> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>paletteCombo</sender> + <signal>activated(int)</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>paletteSelected(int)</slot> + </connection> + <connection> + <sender>comboCentral</sender> + <signal>activated(int)</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onCentral(int)</slot> + </connection> + <connection> + <sender>buttonPixmap</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onChoosePixmap()</slot> + </connection> + <connection> + <sender>buttonCentral</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onChooseCentralColor()</slot> + </connection> + <connection> + <sender>buttonEffect</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onChooseEffectColor()</slot> + </connection> + <connection> + <sender>comboEffect</sender> + <signal>activated(int)</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onEffect(int)</slot> + </connection> + <connection> + <sender>checkBuildEffect</sender> + <signal>toggled(bool)</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onToggleBuildEffects(bool)</slot> + </connection> + <connection> + <sender>buttonHelp</sender> + <signal>clicked()</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>showHelp()</slot> + </connection> + <connection> + <sender>checkBuildEffect</sender> + <signal>toggled(bool)</signal> + <receiver>comboEffect</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>checkBuildEffect</sender> + <signal>toggled(bool)</signal> + <receiver>buttonEffect</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>checkBuildInactive</sender> + <signal>toggled(bool)</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onToggleBuildInactive(bool)</slot> + </connection> + <connection> + <sender>checkBuildDisabled</sender> + <signal>toggled(bool)</signal> + <receiver>PaletteEditorAdvancedBase</receiver> + <slot>onToggleBuildDisabled(bool)</slot> + </connection> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> + <slot access="protected" language="C++" returnType="void">onToggleBuildDisabled(bool)</slot> + <slot access="protected" language="C++" returnType="void">onCentral(int)</slot> + <slot access="protected" language="C++" returnType="void">onChooseCentralColor()</slot> + <slot access="protected" language="C++" returnType="void">onChooseEffectColor()</slot> + <slot access="protected" language="C++" returnType="void">onChoosePixmap()</slot> + <slot access="protected" language="C++" returnType="void">onEffect(int)</slot> + <slot access="protected" language="C++" returnType="void">onToggleBuildEffects(bool)</slot> + <slot access="protected" language="C++" returnType="void">onToggleBuildInactive(bool)</slot> + <slot access="protected" language="C++" returnType="void">paletteSelected(int)</slot> + <slot access="public" language="C++" returnType="void">showHelp()</slot> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>paletteCombo</tabstop> + <tabstop>checkBuildInactive</tabstop> + <tabstop>checkBuildDisabled</tabstop> + <tabstop>comboCentral</tabstop> + <tabstop>buttonPixmap</tabstop> + <tabstop>buttonCentral</tabstop> + <tabstop>checkBuildEffect</tabstop> + <tabstop>comboEffect</tabstop> + <tabstop>buttonEffect</tabstop> + <tabstop>buttonHelp</tabstop> +</tabstops> +</UI> diff --git a/kdevdesigner/designer/paletteeditoradvancedimpl.cpp b/kdevdesigner/designer/paletteeditoradvancedimpl.cpp new file mode 100644 index 00000000..8faebba4 --- /dev/null +++ b/kdevdesigner/designer/paletteeditoradvancedimpl.cpp @@ -0,0 +1,643 @@ +/********************************************************************** +** 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 "paletteeditoradvancedimpl.h" +#include "styledbutton.h" +#include "mainwindow.h" +#include "formwindow.h" + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qapplication.h> +#include <qpushbutton.h> +#include <qlistbox.h> +#include <qpainter.h> +#include <qgroupbox.h> + +/*! + Class used by PaletteEditor for bold combobox items +*/ + +class BoldListBoxText : public QListBoxText +{ +public: + BoldListBoxText( QString text, QListBox* lb = 0 ); + +protected: + virtual void paint( QPainter* ); +}; + +BoldListBoxText::BoldListBoxText( QString text, QListBox* lb ) + : QListBoxText( lb ) +{ + setText( text ); +} + +void BoldListBoxText::paint( QPainter* painter ) +{ + QFont f = painter->font(); + f.setBold( TRUE ); + painter->setFont( f ); + + QListBoxText::paint( painter ); +} + +PaletteEditorAdvanced::PaletteEditorAdvanced( FormWindow *fw, QWidget * parent, + const char * name, bool modal, WFlags f ) + : PaletteEditorAdvancedBase( parent, name, modal, f ), formWindow( fw ), selectedPalette(0) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + buttonPixmap->setEditor( StyledButton::PixmapEditor ); + + editPalette = QApplication::palette(); + setPreviewPalette( editPalette ); + + buttonPixmap->setFormWindow( formWindow ); + + // force toggle event + checkBuildEffect->setChecked(FALSE); + checkBuildEffect->setChecked(TRUE); +} + +PaletteEditorAdvanced::~PaletteEditorAdvanced() +{ +} + +void PaletteEditorAdvanced::onToggleBuildInactive( bool v ) +{ + if (selectedPalette == 1) { + groupCentral->setDisabled(v); + groupEffect->setDisabled(v); + } + + if (v) { + buildInactive(); + updateStyledButtons(); + } +} + +void PaletteEditorAdvanced::onToggleBuildDisabled( bool v ) +{ + if (selectedPalette == 2) { + groupCentral->setDisabled(v); + groupEffect->setDisabled(v); + } + + if (v) { + buildDisabled(); + updateStyledButtons(); + } +} + +void PaletteEditorAdvanced::paletteSelected(int p) +{ + selectedPalette = p; + + if(p == 1) { // inactive + groupCentral->setDisabled(checkBuildInactive->isChecked()); + groupEffect->setDisabled(checkBuildInactive->isChecked()); + } + else if (p == 2) { // disabled + groupCentral->setDisabled(checkBuildDisabled->isChecked()); + groupEffect->setDisabled(checkBuildDisabled->isChecked()); + } + else { + groupCentral->setEnabled(TRUE); + groupEffect->setEnabled(TRUE); + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onChooseCentralColor() +{ + switch(selectedPalette) { + case 0: + default: + mapToActiveCentralRole( buttonCentral->color() ); + break; + case 1: + mapToInactiveCentralRole( buttonCentral->color() ); + break; + case 2: + mapToDisabledCentralRole( buttonCentral->color() ); + break; + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onChooseEffectColor() +{ + switch(selectedPalette) { + case 0: + default: + mapToActiveEffectRole( buttonEffect->color() ); + break; + case 1: + mapToInactiveEffectRole( buttonEffect->color() ); + break; + case 2: + mapToDisabledEffectRole( buttonEffect->color() ); + break; + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onChoosePixmap() +{ + if (buttonPixmap->pixmap()) { + switch(selectedPalette) { + case 0: + default: + mapToActivePixmapRole( *buttonPixmap->pixmap() ); + break; + case 1: + mapToInactivePixmapRole( *buttonPixmap->pixmap() ); + break; + case 2: + mapToDisabledPixmapRole( *buttonPixmap->pixmap() ); + break; + } + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onToggleBuildEffects( bool on ) +{ + if (!on) return; + buildActiveEffect(); + buildInactiveEffect(); + buildDisabledEffect(); +} + +QColorGroup::ColorRole PaletteEditorAdvanced::centralFromItem( int item ) +{ + switch( item ) { + case 0: + return QColorGroup::Background; + case 1: + return QColorGroup::Foreground; + case 2: + return QColorGroup::Button; + case 3: + return QColorGroup::Base; + case 4: + return QColorGroup::Text; + case 5: + return QColorGroup::BrightText; + case 6: + return QColorGroup::ButtonText; + case 7: + return QColorGroup::Highlight; + case 8: + return QColorGroup::HighlightedText; + case 9: + return QColorGroup::Link; + case 10: + return QColorGroup::LinkVisited; + default: + return QColorGroup::NColorRoles; + } +} + +QColorGroup::ColorRole PaletteEditorAdvanced::effectFromItem( int item ) +{ + switch( item ) { + case 0: + return QColorGroup::Light; + case 1: + return QColorGroup::Midlight; + case 2: + return QColorGroup::Mid; + case 3: + return QColorGroup::Dark; + case 4: + return QColorGroup::Shadow; + default: + return QColorGroup::NColorRoles; + } +} + +void PaletteEditorAdvanced::onCentral( int item ) +{ + QPixmap* p = 0; + QColor c; + + switch(selectedPalette) { + case 0: + default: + c = editPalette.active().color( centralFromItem(item) ); + p = editPalette.active().brush( centralFromItem(item) ).pixmap(); + break; + case 1: + c = editPalette.inactive().color( centralFromItem(item) ); + p = editPalette.inactive().brush( centralFromItem(item) ).pixmap(); + break; + case 2: + c = editPalette.disabled().color( centralFromItem(item) ); + p = editPalette.disabled().brush( centralFromItem(item) ).pixmap(); + break; + } + + buttonCentral->setColor(c); + + if (p) + buttonPixmap->setPixmap( *p ); + else + buttonPixmap->setPixmap( QPixmap() ); +} + +void PaletteEditorAdvanced::onEffect( int item ) +{ + QColor c; + switch(selectedPalette) { + case 0: + default: + c = editPalette.active().color( effectFromItem(item) ); + break; + case 1: + editPalette.inactive().color( effectFromItem(item) ); + break; + case 2: + editPalette.disabled().color( effectFromItem(item) ); + break; + } + buttonEffect->setColor(c); +} + +void PaletteEditorAdvanced::mapToActiveCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.active(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setActive( cg ); + + buildActiveEffect(); + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToActiveEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.active(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setActive( cg ); + + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToActivePixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.active(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + editPalette.setActive( cg ); + + + buildActiveEffect(); + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactiveCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.inactive(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setInactive( cg ); + + buildInactiveEffect(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactiveEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.inactive(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setInactive( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactivePixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.inactive(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + editPalette.setInactive( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.disabled(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.disabled(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setDisabled( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledPixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.disabled(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + + editPalette.setDisabled( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::buildActiveEffect() +{ + QColorGroup cg = editPalette.active(); + QColor btn = cg.color( QColorGroup::Button ); + + QPalette temp( btn, btn ); + + for (int i = 0; i<5; i++) + cg.setColor( effectFromItem(i), temp.active().color( effectFromItem(i) ) ); + + editPalette.setActive( cg ); + setPreviewPalette( editPalette ); + + updateStyledButtons(); +} + +void PaletteEditorAdvanced::buildInactive() +{ + editPalette.setInactive( editPalette.active() ); + buildInactiveEffect(); +} + +void PaletteEditorAdvanced::buildInactiveEffect() +{ + QColorGroup cg = editPalette.inactive(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setInactive( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditorAdvanced::buildDisabled() +{ + QColorGroup cg = editPalette.active(); + cg.setColor( QColorGroup::ButtonText, darkGray ); + cg.setColor( QColorGroup::Foreground, darkGray ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); +} + +void PaletteEditorAdvanced::buildDisabledEffect() +{ + QColorGroup cg = editPalette.disabled(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setDisabled( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditorAdvanced::setPreviewPalette( const QPalette& pal ) +{ + QColorGroup cg; + + switch (selectedPalette) { + case 0: + default: + cg = pal.active(); + break; + case 1: + cg = pal.inactive(); + break; + case 2: + cg = pal.disabled(); + break; + } + previewPalette.setActive( cg ); + previewPalette.setInactive( cg ); + previewPalette.setDisabled( cg ); +} + +void PaletteEditorAdvanced::updateStyledButtons() +{ + QColor central, effect; + QPixmap *pm = 0; + switch (selectedPalette) { + case 0: + default: + central = editPalette.active().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.active().color( effectFromItem( comboEffect->currentItem() ) ); + pm = editPalette.active().brush( centralFromItem( comboCentral->currentItem() ) ).pixmap(); + break; + case 1: + central = editPalette.inactive().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.inactive().color( effectFromItem( comboEffect->currentItem() ) ); + pm = editPalette.inactive().brush( centralFromItem( comboCentral->currentItem() ) ).pixmap(); + break; + case 2: + central = editPalette.disabled().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.disabled().color( effectFromItem( comboEffect->currentItem() ) ); + pm = editPalette.disabled().brush( centralFromItem( comboCentral->currentItem() ) ).pixmap(); + break; + } + + buttonCentral->setColor(central); + buttonEffect->setColor(effect); + if ( pm && !pm->isNull() ) + buttonPixmap->setPixmap( *pm ); + else + buttonPixmap->setPixmap(QPixmap()); +} + +void PaletteEditorAdvanced::setPal( const QPalette& pal ) +{ + editPalette = pal; + setPreviewPalette( pal ); + updateStyledButtons(); +} + +QPalette PaletteEditorAdvanced::pal() const +{ + return editPalette; +} + +void PaletteEditorAdvanced::setupBackgroundMode( BackgroundMode mode ) +{ + int initRole = 0; + + switch( mode ) { + case PaletteBackground: + initRole = 0; + break; + case PaletteForeground: + initRole = 1; + break; + case PaletteButton: + initRole = 2; + break; + case PaletteBase: + initRole = 3; + break; + case PaletteText: + initRole = 4; + break; + case PaletteBrightText: + initRole = 5; + break; + case PaletteButtonText: + initRole = 6; + break; + case PaletteHighlight: + initRole = 7; + break; + case PaletteHighlightedText: + initRole = 8; + break; + case PaletteLight: + initRole = 9; + break; + case PaletteMidlight: + initRole = 10; + break; + case PaletteDark: + initRole = 11; + break; + case PaletteMid: + initRole = 12; + break; + case PaletteShadow: + initRole = 13; + break; + default: + initRole = -1; + break; + } + + if ( initRole <= -1 ) return; + + if (initRole > 8 ) { + comboEffect->setCurrentItem( initRole - 9 ); + if ( comboEffect->listBox() ) { + QString text = comboEffect->currentText(); + comboEffect->listBox()->changeItem( new BoldListBoxText( text ), initRole - 9 ); + } + } + else { + comboCentral->setCurrentItem( initRole ); + if ( comboCentral->listBox() ) { + QString text = comboCentral->currentText(); + comboCentral->listBox()->changeItem( new BoldListBoxText( text ), initRole ); + } + } +} + +QPalette PaletteEditorAdvanced::getPalette( bool *ok, const QPalette &init, + BackgroundMode mode, QWidget* parent, + const char* name, FormWindow *fw ) +{ + PaletteEditorAdvanced* dlg = new PaletteEditorAdvanced( fw, parent, name, TRUE ); + dlg->setupBackgroundMode( mode ); + + if ( init != QPalette() ) + dlg->setPal( init ); + int resultCode = dlg->exec(); + + QPalette result = init; + if ( resultCode == QDialog::Accepted ) { + if ( ok ) + *ok = TRUE; + result = dlg->pal(); + } else { + if ( ok ) + *ok = FALSE; + } + delete dlg; + return result; +} diff --git a/kdevdesigner/designer/paletteeditoradvancedimpl.h b/kdevdesigner/designer/paletteeditoradvancedimpl.h new file mode 100644 index 00000000..4f7076df --- /dev/null +++ b/kdevdesigner/designer/paletteeditoradvancedimpl.h @@ -0,0 +1,96 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PALETTEEDITORADVANCEDIMPL_H +#define PALETTEEDITORADVANCEDIMPL_H + +#include "paletteeditoradvanced.h" + +class FormWindow; + +class PaletteEditorAdvanced : public PaletteEditorAdvancedBase +{ + Q_OBJECT +public: + PaletteEditorAdvanced( FormWindow *fw, QWidget * parent=0, const char * name=0, + bool modal=FALSE, WFlags f=0 ); + ~PaletteEditorAdvanced(); + + static QPalette getPalette( bool *ok, const QPalette &pal, BackgroundMode mode = PaletteBackground, + QWidget* parent = 0, const char* name = 0, FormWindow *fw = 0 ); + +protected slots: + void paletteSelected(int); + + void onCentral( int ); + void onEffect( int ); + + void onChooseCentralColor(); + void onChooseEffectColor(); + void onChoosePixmap(); + + void onToggleBuildEffects( bool ); + void onToggleBuildInactive( bool ); + void onToggleBuildDisabled( bool ); + +protected: + void mapToActiveCentralRole( const QColor& ); + void mapToActiveEffectRole( const QColor& ); + void mapToActivePixmapRole( const QPixmap& ); + void mapToInactiveCentralRole( const QColor& ); + void mapToInactiveEffectRole( const QColor& ); + void mapToInactivePixmapRole( const QPixmap& ); + void mapToDisabledCentralRole( const QColor& ); + void mapToDisabledEffectRole( const QColor& ); + void mapToDisabledPixmapRole( const QPixmap& ); + + + void buildPalette(); + void buildActiveEffect(); + void buildInactive(); + void buildInactiveEffect(); + void buildDisabled(); + void buildDisabledEffect(); + +private: + void setPreviewPalette( const QPalette& ); + void updateStyledButtons(); + void setupBackgroundMode( BackgroundMode ); + + QPalette pal() const; + void setPal( const QPalette& ); + + QColorGroup::ColorRole centralFromItem( int ); + QColorGroup::ColorRole effectFromItem( int ); + QPalette editPalette; + QPalette previewPalette; + + FormWindow *formWindow; + + int selectedPalette; +}; + +#endif diff --git a/kdevdesigner/designer/paletteeditorimpl.cpp b/kdevdesigner/designer/paletteeditorimpl.cpp new file mode 100644 index 00000000..56e6fd2f --- /dev/null +++ b/kdevdesigner/designer/paletteeditorimpl.cpp @@ -0,0 +1,304 @@ +/********************************************************************** +** 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 "paletteeditorimpl.h" +#include "paletteeditoradvancedimpl.h" +#include "previewframe.h" +#include "styledbutton.h" +#include "mainwindow.h" +#include "formwindow.h" + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qapplication.h> +#include <qpushbutton.h> + +PaletteEditor::PaletteEditor( FormWindow *fw, QWidget * parent, const char * name, bool modal, WFlags f ) + : PaletteEditorBase( parent, name, modal, f ), formWindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + editPalette = QApplication::palette(); + setPreviewPalette( editPalette ); + + buttonMainColor->setColor( editPalette.active().color( QColorGroup::Button ) ); + buttonMainColor2->setColor( editPalette.active().color( QColorGroup::Background ) ); +} + +PaletteEditor::~PaletteEditor() +{ +} + +void PaletteEditor::onTune() +{ + bool ok; + QPalette pal = PaletteEditorAdvanced::getPalette( &ok, editPalette, backgroundMode, this, "tune_palette", formWindow); + if (!ok) return; + + editPalette = pal; + setPreviewPalette( editPalette ); +} + +void PaletteEditor::onChooseMainColor() +{ + buildPalette(); +} + +void PaletteEditor::onChoose2ndMainColor() +{ + buildPalette(); +} + +void PaletteEditor::paletteSelected(int) +{ + setPreviewPalette(editPalette); +} + +QColorGroup::ColorRole PaletteEditor::centralFromItem( int item ) +{ + switch( item ) + { + case 0: + return QColorGroup::Background; + case 1: + return QColorGroup::Foreground; + case 2: + return QColorGroup::Button; + case 3: + return QColorGroup::Base; + case 4: + return QColorGroup::Text; + case 5: + return QColorGroup::BrightText; + case 6: + return QColorGroup::ButtonText; + case 7: + return QColorGroup::Highlight; + case 8: + return QColorGroup::HighlightedText; + default: + return QColorGroup::NColorRoles; + } +} + +QColorGroup::ColorRole PaletteEditor::effectFromItem( int item ) +{ + switch( item ) + { + case 0: + return QColorGroup::Light; + case 1: + return QColorGroup::Midlight; + case 2: + return QColorGroup::Mid; + case 3: + return QColorGroup::Dark; + case 4: + return QColorGroup::Shadow; + default: + return QColorGroup::NColorRoles; + } +} + +void PaletteEditor::buildPalette() +{ + int i; + QColorGroup cg; + QColor btn = buttonMainColor->color(); + QColor back = buttonMainColor2->color(); + QPalette automake( btn, back ); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), automake.active().color( centralFromItem(i) ) ); + + editPalette.setActive( cg ); + buildActiveEffect(); + + cg = editPalette.inactive(); + + QPalette temp( editPalette.active().color( QColorGroup::Button ), + editPalette.active().color( QColorGroup::Background ) ); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), temp.inactive().color( centralFromItem(i) ) ); + + editPalette.setInactive( cg ); + buildInactiveEffect(); + + cg = editPalette.disabled(); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), temp.disabled().color( centralFromItem(i) ) ); + + editPalette.setDisabled( cg ); + buildDisabledEffect(); + + updateStyledButtons(); +} + +void PaletteEditor::buildActiveEffect() +{ + QColorGroup cg = editPalette.active(); + QColor btn = cg.color( QColorGroup::Button ); + + QPalette temp( btn, btn ); + + for (int i = 0; i<5; i++) + cg.setColor( effectFromItem(i), temp.active().color( effectFromItem(i) ) ); + + editPalette.setActive( cg ); + setPreviewPalette( editPalette ); + + updateStyledButtons(); +} + +void PaletteEditor::buildInactive() +{ + editPalette.setInactive( editPalette.active() ); + buildInactiveEffect(); +} + +void PaletteEditor::buildInactiveEffect() +{ + QColorGroup cg = editPalette.inactive(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setInactive( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditor::buildDisabled() +{ + QColorGroup cg = editPalette.active(); + cg.setColor( QColorGroup::ButtonText, darkGray ); + cg.setColor( QColorGroup::Foreground, darkGray ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); +} + +void PaletteEditor::buildDisabledEffect() +{ + QColorGroup cg = editPalette.disabled(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setDisabled( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditor::setPreviewPalette( const QPalette& pal ) +{ + QColorGroup cg; + + switch (paletteCombo->currentItem()) { + case 0: + default: + cg = pal.active(); + break; + case 1: + cg = pal.inactive(); + break; + case 2: + cg = pal.disabled(); + break; + } + previewPalette.setActive( cg ); + previewPalette.setInactive( cg ); + previewPalette.setDisabled( cg ); + + previewFrame->setPreviewPalette(previewPalette); +} + +void PaletteEditor::updateStyledButtons() +{ + buttonMainColor->setColor( editPalette.active().color( QColorGroup::Button )); + buttonMainColor2->setColor( editPalette.active().color( QColorGroup::Background )); +} + +void PaletteEditor::setPal( const QPalette& pal ) +{ + editPalette = pal; + setPreviewPalette( pal ); + updateStyledButtons(); +} + +QPalette PaletteEditor::pal() const +{ + return editPalette; +} + +QPalette PaletteEditor::getPalette( bool *ok, const QPalette &init, BackgroundMode mode, + QWidget* parent, const char* name, FormWindow *fw ) +{ + PaletteEditor* dlg = new PaletteEditor( fw, parent, name, TRUE ); + dlg->setupBackgroundMode( mode ); + + if ( init != QPalette() ) + dlg->setPal( init ); + int resultCode = dlg->exec(); + + QPalette result = init; + if ( resultCode == QDialog::Accepted ) { + if ( ok ) + *ok = TRUE; + result = dlg->pal(); + } else { + if ( ok ) + *ok = FALSE; + } + delete dlg; + return result; +} diff --git a/kdevdesigner/designer/paletteeditorimpl.h b/kdevdesigner/designer/paletteeditorimpl.h new file mode 100644 index 00000000..fc3ee231 --- /dev/null +++ b/kdevdesigner/designer/paletteeditorimpl.h @@ -0,0 +1,76 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PALETTEEDITORIMPL_H +#define PALETTEEDITORIMPL_H + +#include "paletteeditor.h" + +class FormWindow; + +class PaletteEditor : public PaletteEditorBase +{ + Q_OBJECT + +public: + PaletteEditor( FormWindow *fw, QWidget * parent=0, const char * name=0, bool modal=FALSE, WFlags f=0 ); + ~PaletteEditor(); + + static QPalette getPalette( bool *ok, const QPalette &pal, BackgroundMode mode = PaletteBackground, + QWidget* parent = 0, const char* name = 0, FormWindow *fw = 0 ); + +protected slots: + void onChooseMainColor(); + void onChoose2ndMainColor(); + void onTune(); + void paletteSelected(int); + +protected: + void buildPalette(); + void buildActiveEffect(); + void buildInactive(); + void buildInactiveEffect(); + void buildDisabled(); + void buildDisabledEffect(); + +private: + void setPreviewPalette( const QPalette& ); + void updateStyledButtons(); + void setupBackgroundMode( BackgroundMode mode ) { backgroundMode = mode; } + + QPalette pal() const; + void setPal( const QPalette& ); + + QColorGroup::ColorRole centralFromItem( int ); + QColorGroup::ColorRole effectFromItem( int ); + QPalette editPalette; + QPalette previewPalette; + + FormWindow *formWindow; + BackgroundMode backgroundMode; +}; + +#endif diff --git a/kdevdesigner/designer/pics/Makefile.am b/kdevdesigner/designer/pics/Makefile.am new file mode 100644 index 00000000..8749186b --- /dev/null +++ b/kdevdesigner/designer/pics/Makefile.am @@ -0,0 +1,2 @@ +picsdirdir = $(kde_datadir)/kdevdesignerpart/pics +picsdir_DATA = designer_adjustsize.png designer_appicon.png designer_arrow.png designer_background.png designer_book.png designer_buttongroup.png designer_checkbox.png designer_combobox.png designer_connecttool.png designer_cross.png designer_customwidget.png designer_d_adjustsize.png designer_d_book.png designer_d_buttongroup.png designer_d_checkbox.png designer_d_combobox.png designer_d_connecttool.png designer_d_customwidget.png designer_d_databrowser.png designer_d_datatable.png designer_d_dataview.png designer_d_dateedit.png designer_d_datetimeedit.png designer_d_dial.png designer_d_down.png designer_d_editbreaklayout.png designer_d_editcopy.png designer_d_editcut.png designer_d_editdelete.png designer_d_editgrid.png designer_d_edithlayout.png designer_d_edithlayoutsplit.png designer_d_editlower.png designer_d_editpaste.png designer_d_editraise.png designer_d_editslots.png designer_d_editvlayout.png designer_d_editvlayoutsplit.png designer_d_filenew.png designer_d_fileopen.png designer_d_filesave.png designer_d_folder.png designer_d_form.png designer_d_frame.png designer_d_groupbox.png designer_d_help.png designer_d_home.png designer_d_iconview.png designer_d_image.png designer_d_label.png designer_d_layout.png designer_d_lcdnumber.png designer_d_left.png designer_d_line.png designer_d_lineedit.png designer_d_listbox.png designer_d_listview.png designer_d_multilineedit.png designer_d_newform.png designer_d_ordertool.png designer_d_pixlabel.png designer_d_pointer.png designer_d_print.png designer_d_progress.png designer_d_project.png designer_d_pushbutton.png designer_d_radiobutton.png designer_d_redo.png designer_d_richtextedit.png designer_d_right.png designer_d_scrollbar.png designer_d_searchfind.png designer_d_setbuddy.png designer_d_slider.png designer_d_spacer.png designer_d_spinbox.png designer_d_table.png designer_d_tabwidget.png designer_d_textbold.png designer_d_textbrowser.png designer_d_textcenter.png designer_d_textedit.png designer_d_textfont.png designer_d_texth1.png designer_d_texth2.png designer_d_texth3.png designer_d_textitalic.png designer_d_textjustify.png designer_d_textlarger.png designer_d_textleft.png designer_d_textlinebreak.png designer_d_textparagraph.png designer_d_textright.png designer_d_textsmaller.png designer_d_textteletext.png designer_d_textunderline.png designer_d_textview.png designer_d_timeedit.png designer_d_toolbox.png designer_d_toolbutton.png designer_d_undo.png designer_d_up.png designer_d_widgetstack.png designer_d_wizarddata.png designer_d_wizarddialog.png designer_d_wordwrap.png designer_databrowser.png designer_datatable.png designer_dataview.png designer_dateedit.png designer_datetimeedit.png designer_dial.png designer_down.png designer_editbreaklayout.png designer_editcopy.png designer_editcut.png designer_editdelete.png designer_editgrid.png designer_edithlayout.png designer_edithlayoutsplit.png designer_editlower.png designer_editpaste.png designer_editraise.png designer_editslots.png designer_editvlayout.png designer_editvlayoutsplit.png designer_filenew.png designer_fileopen.png designer_filesave.png designer_folder.png designer_form.png designer_frame.png designer_groupbox.png designer_hand.png designer_help.png designer_home.png designer_hsplit.png designer_ibeam.png designer_iconview.png designer_image.png designer_label.png designer_layout.png designer_lcdnumber.png designer_left.png designer_line.png designer_lineedit.png designer_listbox.png designer_listview.png designer_multilineedit.png designer_newform.png designer_no.png designer_object.png designer_ordertool.png designer_pixlabel.png designer_pointer.png designer_print.png designer_progress.png designer_project.png designer_pushbutton.png designer_qtlogo.png designer_radiobutton.png designer_redo.png designer_resetproperty.png designer_richtextedit.png designer_right.png designer_s_down.png designer_s_editcut.png designer_s_left.png designer_s_right.png designer_s_up.png designer_scrollbar.png designer_searchfind.png designer_setbuddy.png designer_sizeall.png designer_sizeb.png designer_sizef.png designer_sizeh.png designer_sizev.png designer_slider.png designer_spacer.png designer_spinbox.png designer_splash.png designer_table.png designer_tabwidget.png designer_textbold.png designer_textbrowser.png designer_textcenter.png designer_textedit.png designer_textfont.png designer_texth1.png designer_texth2.png designer_texth3.png designer_textitalic.png designer_textjustify.png designer_textlarger.png designer_textleft.png designer_textlinebreak.png designer_textparagraph.png designer_textright.png designer_textsmaller.png designer_textteletext.png designer_textunderline.png designer_textview.png designer_timeedit.png designer_toolbox.png designer_toolbutton.png designer_undo.png designer_up.png designer_uparrow.png designer_vsplit.png designer_wait.png designer_widgetstack.png designer_wizarddata.png designer_wizarddialog.png designer_wordwrap.png diff --git a/kdevdesigner/designer/pics/designer_adjustsize.png b/kdevdesigner/designer/pics/designer_adjustsize.png Binary files differnew file mode 100644 index 00000000..6ade1e22 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_adjustsize.png diff --git a/kdevdesigner/designer/pics/designer_appicon.png b/kdevdesigner/designer/pics/designer_appicon.png Binary files differnew file mode 100644 index 00000000..7aadcbad --- /dev/null +++ b/kdevdesigner/designer/pics/designer_appicon.png diff --git a/kdevdesigner/designer/pics/designer_arrow.png b/kdevdesigner/designer/pics/designer_arrow.png Binary files differnew file mode 100644 index 00000000..53921d83 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_arrow.png diff --git a/kdevdesigner/designer/pics/designer_background.png b/kdevdesigner/designer/pics/designer_background.png Binary files differnew file mode 100644 index 00000000..27d2e997 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_background.png diff --git a/kdevdesigner/designer/pics/designer_book.png b/kdevdesigner/designer/pics/designer_book.png Binary files differnew file mode 100644 index 00000000..dd850abb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_book.png diff --git a/kdevdesigner/designer/pics/designer_buttongroup.png b/kdevdesigner/designer/pics/designer_buttongroup.png Binary files differnew file mode 100644 index 00000000..d89e28fd --- /dev/null +++ b/kdevdesigner/designer/pics/designer_buttongroup.png diff --git a/kdevdesigner/designer/pics/designer_checkbox.png b/kdevdesigner/designer/pics/designer_checkbox.png Binary files differnew file mode 100644 index 00000000..ab6f53e0 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_checkbox.png diff --git a/kdevdesigner/designer/pics/designer_combobox.png b/kdevdesigner/designer/pics/designer_combobox.png Binary files differnew file mode 100644 index 00000000..7d4890a7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_combobox.png diff --git a/kdevdesigner/designer/pics/designer_connecttool.png b/kdevdesigner/designer/pics/designer_connecttool.png Binary files differnew file mode 100644 index 00000000..fca6748f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_connecttool.png diff --git a/kdevdesigner/designer/pics/designer_cross.png b/kdevdesigner/designer/pics/designer_cross.png Binary files differnew file mode 100644 index 00000000..d5e9f0c7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_cross.png diff --git a/kdevdesigner/designer/pics/designer_customwidget.png b/kdevdesigner/designer/pics/designer_customwidget.png Binary files differnew file mode 100644 index 00000000..ab790e1f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_customwidget.png diff --git a/kdevdesigner/designer/pics/designer_d_adjustsize.png b/kdevdesigner/designer/pics/designer_d_adjustsize.png Binary files differnew file mode 100644 index 00000000..d61ca7af --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_adjustsize.png diff --git a/kdevdesigner/designer/pics/designer_d_book.png b/kdevdesigner/designer/pics/designer_d_book.png Binary files differnew file mode 100644 index 00000000..5517f0c4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_book.png diff --git a/kdevdesigner/designer/pics/designer_d_buttongroup.png b/kdevdesigner/designer/pics/designer_d_buttongroup.png Binary files differnew file mode 100644 index 00000000..1e451a88 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_buttongroup.png diff --git a/kdevdesigner/designer/pics/designer_d_checkbox.png b/kdevdesigner/designer/pics/designer_d_checkbox.png Binary files differnew file mode 100644 index 00000000..1415eabb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_checkbox.png diff --git a/kdevdesigner/designer/pics/designer_d_combobox.png b/kdevdesigner/designer/pics/designer_d_combobox.png Binary files differnew file mode 100644 index 00000000..5fb44eff --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_combobox.png diff --git a/kdevdesigner/designer/pics/designer_d_connecttool.png b/kdevdesigner/designer/pics/designer_d_connecttool.png Binary files differnew file mode 100644 index 00000000..76a3b5f5 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_connecttool.png diff --git a/kdevdesigner/designer/pics/designer_d_customwidget.png b/kdevdesigner/designer/pics/designer_d_customwidget.png Binary files differnew file mode 100644 index 00000000..5ea648fb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_customwidget.png diff --git a/kdevdesigner/designer/pics/designer_d_databrowser.png b/kdevdesigner/designer/pics/designer_d_databrowser.png Binary files differnew file mode 100644 index 00000000..c1155c8c --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_databrowser.png diff --git a/kdevdesigner/designer/pics/designer_d_datatable.png b/kdevdesigner/designer/pics/designer_d_datatable.png Binary files differnew file mode 100644 index 00000000..7060dc3a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_datatable.png diff --git a/kdevdesigner/designer/pics/designer_d_dataview.png b/kdevdesigner/designer/pics/designer_d_dataview.png Binary files differnew file mode 100644 index 00000000..c507d416 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_dataview.png diff --git a/kdevdesigner/designer/pics/designer_d_dateedit.png b/kdevdesigner/designer/pics/designer_d_dateedit.png Binary files differnew file mode 100644 index 00000000..162e63a8 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_dateedit.png diff --git a/kdevdesigner/designer/pics/designer_d_datetimeedit.png b/kdevdesigner/designer/pics/designer_d_datetimeedit.png Binary files differnew file mode 100644 index 00000000..83dc2fc3 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_datetimeedit.png diff --git a/kdevdesigner/designer/pics/designer_d_dial.png b/kdevdesigner/designer/pics/designer_d_dial.png Binary files differnew file mode 100644 index 00000000..a84869e4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_dial.png diff --git a/kdevdesigner/designer/pics/designer_d_down.png b/kdevdesigner/designer/pics/designer_d_down.png Binary files differnew file mode 100644 index 00000000..57b407e4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_down.png diff --git a/kdevdesigner/designer/pics/designer_d_editbreaklayout.png b/kdevdesigner/designer/pics/designer_d_editbreaklayout.png Binary files differnew file mode 100644 index 00000000..2a36d67d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editbreaklayout.png diff --git a/kdevdesigner/designer/pics/designer_d_editcopy.png b/kdevdesigner/designer/pics/designer_d_editcopy.png Binary files differnew file mode 100644 index 00000000..500758d4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editcopy.png diff --git a/kdevdesigner/designer/pics/designer_d_editcut.png b/kdevdesigner/designer/pics/designer_d_editcut.png Binary files differnew file mode 100644 index 00000000..8d50ae0a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editcut.png diff --git a/kdevdesigner/designer/pics/designer_d_editdelete.png b/kdevdesigner/designer/pics/designer_d_editdelete.png Binary files differnew file mode 100644 index 00000000..f4d0f7a1 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editdelete.png diff --git a/kdevdesigner/designer/pics/designer_d_editgrid.png b/kdevdesigner/designer/pics/designer_d_editgrid.png Binary files differnew file mode 100644 index 00000000..ad2b87b9 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editgrid.png diff --git a/kdevdesigner/designer/pics/designer_d_edithlayout.png b/kdevdesigner/designer/pics/designer_d_edithlayout.png Binary files differnew file mode 100644 index 00000000..dacaf82e --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_edithlayout.png diff --git a/kdevdesigner/designer/pics/designer_d_edithlayoutsplit.png b/kdevdesigner/designer/pics/designer_d_edithlayoutsplit.png Binary files differnew file mode 100644 index 00000000..00a96055 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_edithlayoutsplit.png diff --git a/kdevdesigner/designer/pics/designer_d_editlower.png b/kdevdesigner/designer/pics/designer_d_editlower.png Binary files differnew file mode 100644 index 00000000..a0a16b40 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editlower.png diff --git a/kdevdesigner/designer/pics/designer_d_editpaste.png b/kdevdesigner/designer/pics/designer_d_editpaste.png Binary files differnew file mode 100644 index 00000000..d31071e9 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editpaste.png diff --git a/kdevdesigner/designer/pics/designer_d_editraise.png b/kdevdesigner/designer/pics/designer_d_editraise.png Binary files differnew file mode 100644 index 00000000..5f7f04b9 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editraise.png diff --git a/kdevdesigner/designer/pics/designer_d_editslots.png b/kdevdesigner/designer/pics/designer_d_editslots.png Binary files differnew file mode 100644 index 00000000..cd791b43 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editslots.png diff --git a/kdevdesigner/designer/pics/designer_d_editvlayout.png b/kdevdesigner/designer/pics/designer_d_editvlayout.png Binary files differnew file mode 100644 index 00000000..ed202af7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editvlayout.png diff --git a/kdevdesigner/designer/pics/designer_d_editvlayoutsplit.png b/kdevdesigner/designer/pics/designer_d_editvlayoutsplit.png Binary files differnew file mode 100644 index 00000000..54ee44c0 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_editvlayoutsplit.png diff --git a/kdevdesigner/designer/pics/designer_d_filenew.png b/kdevdesigner/designer/pics/designer_d_filenew.png Binary files differnew file mode 100644 index 00000000..d5e7061b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_filenew.png diff --git a/kdevdesigner/designer/pics/designer_d_fileopen.png b/kdevdesigner/designer/pics/designer_d_fileopen.png Binary files differnew file mode 100644 index 00000000..343f0039 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_fileopen.png diff --git a/kdevdesigner/designer/pics/designer_d_filesave.png b/kdevdesigner/designer/pics/designer_d_filesave.png Binary files differnew file mode 100644 index 00000000..5d1476d2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_filesave.png diff --git a/kdevdesigner/designer/pics/designer_d_folder.png b/kdevdesigner/designer/pics/designer_d_folder.png Binary files differnew file mode 100644 index 00000000..4bed3caf --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_folder.png diff --git a/kdevdesigner/designer/pics/designer_d_form.png b/kdevdesigner/designer/pics/designer_d_form.png Binary files differnew file mode 100644 index 00000000..9f89d654 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_form.png diff --git a/kdevdesigner/designer/pics/designer_d_frame.png b/kdevdesigner/designer/pics/designer_d_frame.png Binary files differnew file mode 100644 index 00000000..09b21b21 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_frame.png diff --git a/kdevdesigner/designer/pics/designer_d_groupbox.png b/kdevdesigner/designer/pics/designer_d_groupbox.png Binary files differnew file mode 100644 index 00000000..e7e01083 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_groupbox.png diff --git a/kdevdesigner/designer/pics/designer_d_help.png b/kdevdesigner/designer/pics/designer_d_help.png Binary files differnew file mode 100644 index 00000000..8f9d1826 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_help.png diff --git a/kdevdesigner/designer/pics/designer_d_home.png b/kdevdesigner/designer/pics/designer_d_home.png Binary files differnew file mode 100644 index 00000000..b3906a4f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_home.png diff --git a/kdevdesigner/designer/pics/designer_d_iconview.png b/kdevdesigner/designer/pics/designer_d_iconview.png Binary files differnew file mode 100644 index 00000000..a07b2b75 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_iconview.png diff --git a/kdevdesigner/designer/pics/designer_d_image.png b/kdevdesigner/designer/pics/designer_d_image.png Binary files differnew file mode 100644 index 00000000..f7cb29c3 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_image.png diff --git a/kdevdesigner/designer/pics/designer_d_label.png b/kdevdesigner/designer/pics/designer_d_label.png Binary files differnew file mode 100644 index 00000000..bfbd5b88 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_label.png diff --git a/kdevdesigner/designer/pics/designer_d_layout.png b/kdevdesigner/designer/pics/designer_d_layout.png Binary files differnew file mode 100644 index 00000000..090b4bb2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_layout.png diff --git a/kdevdesigner/designer/pics/designer_d_lcdnumber.png b/kdevdesigner/designer/pics/designer_d_lcdnumber.png Binary files differnew file mode 100644 index 00000000..786747e6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_lcdnumber.png diff --git a/kdevdesigner/designer/pics/designer_d_left.png b/kdevdesigner/designer/pics/designer_d_left.png Binary files differnew file mode 100644 index 00000000..50d03bbe --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_left.png diff --git a/kdevdesigner/designer/pics/designer_d_line.png b/kdevdesigner/designer/pics/designer_d_line.png Binary files differnew file mode 100644 index 00000000..25b0daeb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_line.png diff --git a/kdevdesigner/designer/pics/designer_d_lineedit.png b/kdevdesigner/designer/pics/designer_d_lineedit.png Binary files differnew file mode 100644 index 00000000..9d34ce97 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_lineedit.png diff --git a/kdevdesigner/designer/pics/designer_d_listbox.png b/kdevdesigner/designer/pics/designer_d_listbox.png Binary files differnew file mode 100644 index 00000000..d80c7900 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_listbox.png diff --git a/kdevdesigner/designer/pics/designer_d_listview.png b/kdevdesigner/designer/pics/designer_d_listview.png Binary files differnew file mode 100644 index 00000000..c5d9be3e --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_listview.png diff --git a/kdevdesigner/designer/pics/designer_d_multilineedit.png b/kdevdesigner/designer/pics/designer_d_multilineedit.png Binary files differnew file mode 100644 index 00000000..a62e6622 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_multilineedit.png diff --git a/kdevdesigner/designer/pics/designer_d_newform.png b/kdevdesigner/designer/pics/designer_d_newform.png Binary files differnew file mode 100644 index 00000000..ace61302 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_newform.png diff --git a/kdevdesigner/designer/pics/designer_d_ordertool.png b/kdevdesigner/designer/pics/designer_d_ordertool.png Binary files differnew file mode 100644 index 00000000..61bdc7ef --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_ordertool.png diff --git a/kdevdesigner/designer/pics/designer_d_pixlabel.png b/kdevdesigner/designer/pics/designer_d_pixlabel.png Binary files differnew file mode 100644 index 00000000..21e1f492 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_pixlabel.png diff --git a/kdevdesigner/designer/pics/designer_d_pointer.png b/kdevdesigner/designer/pics/designer_d_pointer.png Binary files differnew file mode 100644 index 00000000..e6903eb6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_pointer.png diff --git a/kdevdesigner/designer/pics/designer_d_print.png b/kdevdesigner/designer/pics/designer_d_print.png Binary files differnew file mode 100644 index 00000000..6a72a764 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_print.png diff --git a/kdevdesigner/designer/pics/designer_d_progress.png b/kdevdesigner/designer/pics/designer_d_progress.png Binary files differnew file mode 100644 index 00000000..25d857a6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_progress.png diff --git a/kdevdesigner/designer/pics/designer_d_project.png b/kdevdesigner/designer/pics/designer_d_project.png Binary files differnew file mode 100644 index 00000000..b265eae0 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_project.png diff --git a/kdevdesigner/designer/pics/designer_d_pushbutton.png b/kdevdesigner/designer/pics/designer_d_pushbutton.png Binary files differnew file mode 100644 index 00000000..635f35cb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_pushbutton.png diff --git a/kdevdesigner/designer/pics/designer_d_radiobutton.png b/kdevdesigner/designer/pics/designer_d_radiobutton.png Binary files differnew file mode 100644 index 00000000..e86eb8c1 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_radiobutton.png diff --git a/kdevdesigner/designer/pics/designer_d_redo.png b/kdevdesigner/designer/pics/designer_d_redo.png Binary files differnew file mode 100644 index 00000000..6e993cc6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_redo.png diff --git a/kdevdesigner/designer/pics/designer_d_richtextedit.png b/kdevdesigner/designer/pics/designer_d_richtextedit.png Binary files differnew file mode 100644 index 00000000..ba7ada19 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_richtextedit.png diff --git a/kdevdesigner/designer/pics/designer_d_right.png b/kdevdesigner/designer/pics/designer_d_right.png Binary files differnew file mode 100644 index 00000000..9dbf2dd6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_right.png diff --git a/kdevdesigner/designer/pics/designer_d_scrollbar.png b/kdevdesigner/designer/pics/designer_d_scrollbar.png Binary files differnew file mode 100644 index 00000000..9a818970 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_scrollbar.png diff --git a/kdevdesigner/designer/pics/designer_d_searchfind.png b/kdevdesigner/designer/pics/designer_d_searchfind.png Binary files differnew file mode 100644 index 00000000..e85e33fe --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_searchfind.png diff --git a/kdevdesigner/designer/pics/designer_d_setbuddy.png b/kdevdesigner/designer/pics/designer_d_setbuddy.png Binary files differnew file mode 100644 index 00000000..fe816aa2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_setbuddy.png diff --git a/kdevdesigner/designer/pics/designer_d_slider.png b/kdevdesigner/designer/pics/designer_d_slider.png Binary files differnew file mode 100644 index 00000000..a1ad5d5b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_slider.png diff --git a/kdevdesigner/designer/pics/designer_d_spacer.png b/kdevdesigner/designer/pics/designer_d_spacer.png Binary files differnew file mode 100644 index 00000000..15319d99 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_spacer.png diff --git a/kdevdesigner/designer/pics/designer_d_spinbox.png b/kdevdesigner/designer/pics/designer_d_spinbox.png Binary files differnew file mode 100644 index 00000000..cafbe012 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_spinbox.png diff --git a/kdevdesigner/designer/pics/designer_d_table.png b/kdevdesigner/designer/pics/designer_d_table.png Binary files differnew file mode 100644 index 00000000..a95bde12 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_table.png diff --git a/kdevdesigner/designer/pics/designer_d_tabwidget.png b/kdevdesigner/designer/pics/designer_d_tabwidget.png Binary files differnew file mode 100644 index 00000000..0f0bad0d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_tabwidget.png diff --git a/kdevdesigner/designer/pics/designer_d_textbold.png b/kdevdesigner/designer/pics/designer_d_textbold.png Binary files differnew file mode 100644 index 00000000..6e8a5cf5 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textbold.png diff --git a/kdevdesigner/designer/pics/designer_d_textbrowser.png b/kdevdesigner/designer/pics/designer_d_textbrowser.png Binary files differnew file mode 100644 index 00000000..b4315f90 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textbrowser.png diff --git a/kdevdesigner/designer/pics/designer_d_textcenter.png b/kdevdesigner/designer/pics/designer_d_textcenter.png Binary files differnew file mode 100644 index 00000000..7a66036d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textcenter.png diff --git a/kdevdesigner/designer/pics/designer_d_textedit.png b/kdevdesigner/designer/pics/designer_d_textedit.png Binary files differnew file mode 100644 index 00000000..69314141 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textedit.png diff --git a/kdevdesigner/designer/pics/designer_d_textfont.png b/kdevdesigner/designer/pics/designer_d_textfont.png Binary files differnew file mode 100644 index 00000000..beb2112b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textfont.png diff --git a/kdevdesigner/designer/pics/designer_d_texth1.png b/kdevdesigner/designer/pics/designer_d_texth1.png Binary files differnew file mode 100644 index 00000000..87d7e157 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_texth1.png diff --git a/kdevdesigner/designer/pics/designer_d_texth2.png b/kdevdesigner/designer/pics/designer_d_texth2.png Binary files differnew file mode 100644 index 00000000..e90437b2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_texth2.png diff --git a/kdevdesigner/designer/pics/designer_d_texth3.png b/kdevdesigner/designer/pics/designer_d_texth3.png Binary files differnew file mode 100644 index 00000000..1c7eefe5 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_texth3.png diff --git a/kdevdesigner/designer/pics/designer_d_textitalic.png b/kdevdesigner/designer/pics/designer_d_textitalic.png Binary files differnew file mode 100644 index 00000000..d2c07fad --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textitalic.png diff --git a/kdevdesigner/designer/pics/designer_d_textjustify.png b/kdevdesigner/designer/pics/designer_d_textjustify.png Binary files differnew file mode 100644 index 00000000..3fb3cc34 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textjustify.png diff --git a/kdevdesigner/designer/pics/designer_d_textlarger.png b/kdevdesigner/designer/pics/designer_d_textlarger.png Binary files differnew file mode 100644 index 00000000..ecc35f54 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textlarger.png diff --git a/kdevdesigner/designer/pics/designer_d_textleft.png b/kdevdesigner/designer/pics/designer_d_textleft.png Binary files differnew file mode 100644 index 00000000..90dc0248 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textleft.png diff --git a/kdevdesigner/designer/pics/designer_d_textlinebreak.png b/kdevdesigner/designer/pics/designer_d_textlinebreak.png Binary files differnew file mode 100644 index 00000000..4566f59e --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textlinebreak.png diff --git a/kdevdesigner/designer/pics/designer_d_textparagraph.png b/kdevdesigner/designer/pics/designer_d_textparagraph.png Binary files differnew file mode 100644 index 00000000..a7ef75c7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textparagraph.png diff --git a/kdevdesigner/designer/pics/designer_d_textright.png b/kdevdesigner/designer/pics/designer_d_textright.png Binary files differnew file mode 100644 index 00000000..ee89b93b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textright.png diff --git a/kdevdesigner/designer/pics/designer_d_textsmaller.png b/kdevdesigner/designer/pics/designer_d_textsmaller.png Binary files differnew file mode 100644 index 00000000..d4251de0 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textsmaller.png diff --git a/kdevdesigner/designer/pics/designer_d_textteletext.png b/kdevdesigner/designer/pics/designer_d_textteletext.png Binary files differnew file mode 100644 index 00000000..d80af143 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textteletext.png diff --git a/kdevdesigner/designer/pics/designer_d_textunderline.png b/kdevdesigner/designer/pics/designer_d_textunderline.png Binary files differnew file mode 100644 index 00000000..cab0b788 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textunderline.png diff --git a/kdevdesigner/designer/pics/designer_d_textview.png b/kdevdesigner/designer/pics/designer_d_textview.png Binary files differnew file mode 100644 index 00000000..05ce9c69 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_textview.png diff --git a/kdevdesigner/designer/pics/designer_d_timeedit.png b/kdevdesigner/designer/pics/designer_d_timeedit.png Binary files differnew file mode 100644 index 00000000..955144ec --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_timeedit.png diff --git a/kdevdesigner/designer/pics/designer_d_toolbox.png b/kdevdesigner/designer/pics/designer_d_toolbox.png Binary files differnew file mode 100644 index 00000000..e1f84471 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_toolbox.png diff --git a/kdevdesigner/designer/pics/designer_d_toolbutton.png b/kdevdesigner/designer/pics/designer_d_toolbutton.png Binary files differnew file mode 100644 index 00000000..08e309a7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_toolbutton.png diff --git a/kdevdesigner/designer/pics/designer_d_undo.png b/kdevdesigner/designer/pics/designer_d_undo.png Binary files differnew file mode 100644 index 00000000..22ac97f2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_undo.png diff --git a/kdevdesigner/designer/pics/designer_d_up.png b/kdevdesigner/designer/pics/designer_d_up.png Binary files differnew file mode 100644 index 00000000..4c3ab7c9 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_up.png diff --git a/kdevdesigner/designer/pics/designer_d_widgetstack.png b/kdevdesigner/designer/pics/designer_d_widgetstack.png Binary files differnew file mode 100644 index 00000000..c62f8e15 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_widgetstack.png diff --git a/kdevdesigner/designer/pics/designer_d_wizarddata.png b/kdevdesigner/designer/pics/designer_d_wizarddata.png Binary files differnew file mode 100644 index 00000000..fb540b87 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_wizarddata.png diff --git a/kdevdesigner/designer/pics/designer_d_wizarddialog.png b/kdevdesigner/designer/pics/designer_d_wizarddialog.png Binary files differnew file mode 100644 index 00000000..b83ca7e6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_wizarddialog.png diff --git a/kdevdesigner/designer/pics/designer_d_wordwrap.png b/kdevdesigner/designer/pics/designer_d_wordwrap.png Binary files differnew file mode 100644 index 00000000..8a299033 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_d_wordwrap.png diff --git a/kdevdesigner/designer/pics/designer_databrowser.png b/kdevdesigner/designer/pics/designer_databrowser.png Binary files differnew file mode 100644 index 00000000..1dd95782 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_databrowser.png diff --git a/kdevdesigner/designer/pics/designer_datatable.png b/kdevdesigner/designer/pics/designer_datatable.png Binary files differnew file mode 100644 index 00000000..5b3bfc76 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_datatable.png diff --git a/kdevdesigner/designer/pics/designer_dataview.png b/kdevdesigner/designer/pics/designer_dataview.png Binary files differnew file mode 100644 index 00000000..5f6aad33 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_dataview.png diff --git a/kdevdesigner/designer/pics/designer_dateedit.png b/kdevdesigner/designer/pics/designer_dateedit.png Binary files differnew file mode 100644 index 00000000..48286bec --- /dev/null +++ b/kdevdesigner/designer/pics/designer_dateedit.png diff --git a/kdevdesigner/designer/pics/designer_datetimeedit.png b/kdevdesigner/designer/pics/designer_datetimeedit.png Binary files differnew file mode 100644 index 00000000..68a56737 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_datetimeedit.png diff --git a/kdevdesigner/designer/pics/designer_dial.png b/kdevdesigner/designer/pics/designer_dial.png Binary files differnew file mode 100644 index 00000000..260033c2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_dial.png diff --git a/kdevdesigner/designer/pics/designer_down.png b/kdevdesigner/designer/pics/designer_down.png Binary files differnew file mode 100644 index 00000000..3269deca --- /dev/null +++ b/kdevdesigner/designer/pics/designer_down.png diff --git a/kdevdesigner/designer/pics/designer_editbreaklayout.png b/kdevdesigner/designer/pics/designer_editbreaklayout.png Binary files differnew file mode 100644 index 00000000..badbb8e7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editbreaklayout.png diff --git a/kdevdesigner/designer/pics/designer_editcopy.png b/kdevdesigner/designer/pics/designer_editcopy.png Binary files differnew file mode 100644 index 00000000..2f931cb2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editcopy.png diff --git a/kdevdesigner/designer/pics/designer_editcut.png b/kdevdesigner/designer/pics/designer_editcut.png Binary files differnew file mode 100644 index 00000000..a911482d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editcut.png diff --git a/kdevdesigner/designer/pics/designer_editdelete.png b/kdevdesigner/designer/pics/designer_editdelete.png Binary files differnew file mode 100644 index 00000000..9f0491dd --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editdelete.png diff --git a/kdevdesigner/designer/pics/designer_editgrid.png b/kdevdesigner/designer/pics/designer_editgrid.png Binary files differnew file mode 100644 index 00000000..f2b18e8a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editgrid.png diff --git a/kdevdesigner/designer/pics/designer_edithlayout.png b/kdevdesigner/designer/pics/designer_edithlayout.png Binary files differnew file mode 100644 index 00000000..1a2b1504 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_edithlayout.png diff --git a/kdevdesigner/designer/pics/designer_edithlayoutsplit.png b/kdevdesigner/designer/pics/designer_edithlayoutsplit.png Binary files differnew file mode 100644 index 00000000..cba102bc --- /dev/null +++ b/kdevdesigner/designer/pics/designer_edithlayoutsplit.png diff --git a/kdevdesigner/designer/pics/designer_editlower.png b/kdevdesigner/designer/pics/designer_editlower.png Binary files differnew file mode 100644 index 00000000..50605f27 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editlower.png diff --git a/kdevdesigner/designer/pics/designer_editpaste.png b/kdevdesigner/designer/pics/designer_editpaste.png Binary files differnew file mode 100644 index 00000000..b1b7f853 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editpaste.png diff --git a/kdevdesigner/designer/pics/designer_editraise.png b/kdevdesigner/designer/pics/designer_editraise.png Binary files differnew file mode 100644 index 00000000..f1572517 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editraise.png diff --git a/kdevdesigner/designer/pics/designer_editslots.png b/kdevdesigner/designer/pics/designer_editslots.png Binary files differnew file mode 100644 index 00000000..b86bddb6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editslots.png diff --git a/kdevdesigner/designer/pics/designer_editvlayout.png b/kdevdesigner/designer/pics/designer_editvlayout.png Binary files differnew file mode 100644 index 00000000..f4cd3f9c --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editvlayout.png diff --git a/kdevdesigner/designer/pics/designer_editvlayoutsplit.png b/kdevdesigner/designer/pics/designer_editvlayoutsplit.png Binary files differnew file mode 100644 index 00000000..0180cf5a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_editvlayoutsplit.png diff --git a/kdevdesigner/designer/pics/designer_filenew.png b/kdevdesigner/designer/pics/designer_filenew.png Binary files differnew file mode 100644 index 00000000..9520080e --- /dev/null +++ b/kdevdesigner/designer/pics/designer_filenew.png diff --git a/kdevdesigner/designer/pics/designer_fileopen.png b/kdevdesigner/designer/pics/designer_fileopen.png Binary files differnew file mode 100644 index 00000000..30052901 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_fileopen.png diff --git a/kdevdesigner/designer/pics/designer_filesave.png b/kdevdesigner/designer/pics/designer_filesave.png Binary files differnew file mode 100644 index 00000000..c137165b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_filesave.png diff --git a/kdevdesigner/designer/pics/designer_folder.png b/kdevdesigner/designer/pics/designer_folder.png Binary files differnew file mode 100644 index 00000000..bab6df0f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_folder.png diff --git a/kdevdesigner/designer/pics/designer_form.png b/kdevdesigner/designer/pics/designer_form.png Binary files differnew file mode 100644 index 00000000..08268bf7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_form.png diff --git a/kdevdesigner/designer/pics/designer_frame.png b/kdevdesigner/designer/pics/designer_frame.png Binary files differnew file mode 100644 index 00000000..c070b9c4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_frame.png diff --git a/kdevdesigner/designer/pics/designer_groupbox.png b/kdevdesigner/designer/pics/designer_groupbox.png Binary files differnew file mode 100644 index 00000000..4025b4dc --- /dev/null +++ b/kdevdesigner/designer/pics/designer_groupbox.png diff --git a/kdevdesigner/designer/pics/designer_hand.png b/kdevdesigner/designer/pics/designer_hand.png Binary files differnew file mode 100644 index 00000000..ac01ee60 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_hand.png diff --git a/kdevdesigner/designer/pics/designer_help.png b/kdevdesigner/designer/pics/designer_help.png Binary files differnew file mode 100644 index 00000000..2ab2c25d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_help.png diff --git a/kdevdesigner/designer/pics/designer_home.png b/kdevdesigner/designer/pics/designer_home.png Binary files differnew file mode 100644 index 00000000..806d11d2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_home.png diff --git a/kdevdesigner/designer/pics/designer_hsplit.png b/kdevdesigner/designer/pics/designer_hsplit.png Binary files differnew file mode 100644 index 00000000..232faf14 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_hsplit.png diff --git a/kdevdesigner/designer/pics/designer_ibeam.png b/kdevdesigner/designer/pics/designer_ibeam.png Binary files differnew file mode 100644 index 00000000..6074c89f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_ibeam.png diff --git a/kdevdesigner/designer/pics/designer_iconview.png b/kdevdesigner/designer/pics/designer_iconview.png Binary files differnew file mode 100644 index 00000000..13b8f153 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_iconview.png diff --git a/kdevdesigner/designer/pics/designer_image.png b/kdevdesigner/designer/pics/designer_image.png Binary files differnew file mode 100644 index 00000000..29854df6 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_image.png diff --git a/kdevdesigner/designer/pics/designer_label.png b/kdevdesigner/designer/pics/designer_label.png Binary files differnew file mode 100644 index 00000000..5d7d7b4c --- /dev/null +++ b/kdevdesigner/designer/pics/designer_label.png diff --git a/kdevdesigner/designer/pics/designer_layout.png b/kdevdesigner/designer/pics/designer_layout.png Binary files differnew file mode 100644 index 00000000..168eb1f8 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_layout.png diff --git a/kdevdesigner/designer/pics/designer_lcdnumber.png b/kdevdesigner/designer/pics/designer_lcdnumber.png Binary files differnew file mode 100644 index 00000000..64eda5e4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_lcdnumber.png diff --git a/kdevdesigner/designer/pics/designer_left.png b/kdevdesigner/designer/pics/designer_left.png Binary files differnew file mode 100644 index 00000000..e58177f4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_left.png diff --git a/kdevdesigner/designer/pics/designer_line.png b/kdevdesigner/designer/pics/designer_line.png Binary files differnew file mode 100644 index 00000000..5c64dfb5 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_line.png diff --git a/kdevdesigner/designer/pics/designer_lineedit.png b/kdevdesigner/designer/pics/designer_lineedit.png Binary files differnew file mode 100644 index 00000000..75fc890f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_lineedit.png diff --git a/kdevdesigner/designer/pics/designer_listbox.png b/kdevdesigner/designer/pics/designer_listbox.png Binary files differnew file mode 100644 index 00000000..d467fc9f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_listbox.png diff --git a/kdevdesigner/designer/pics/designer_listview.png b/kdevdesigner/designer/pics/designer_listview.png Binary files differnew file mode 100644 index 00000000..d71cc1c9 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_listview.png diff --git a/kdevdesigner/designer/pics/designer_multilineedit.png b/kdevdesigner/designer/pics/designer_multilineedit.png Binary files differnew file mode 100644 index 00000000..e2f08995 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_multilineedit.png diff --git a/kdevdesigner/designer/pics/designer_newform.png b/kdevdesigner/designer/pics/designer_newform.png Binary files differnew file mode 100644 index 00000000..37779c13 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_newform.png diff --git a/kdevdesigner/designer/pics/designer_no.png b/kdevdesigner/designer/pics/designer_no.png Binary files differnew file mode 100644 index 00000000..8bacc044 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_no.png diff --git a/kdevdesigner/designer/pics/designer_object.png b/kdevdesigner/designer/pics/designer_object.png Binary files differnew file mode 100644 index 00000000..cc4192ed --- /dev/null +++ b/kdevdesigner/designer/pics/designer_object.png diff --git a/kdevdesigner/designer/pics/designer_ordertool.png b/kdevdesigner/designer/pics/designer_ordertool.png Binary files differnew file mode 100644 index 00000000..ad122839 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_ordertool.png diff --git a/kdevdesigner/designer/pics/designer_pixlabel.png b/kdevdesigner/designer/pics/designer_pixlabel.png Binary files differnew file mode 100644 index 00000000..32b90d82 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_pixlabel.png diff --git a/kdevdesigner/designer/pics/designer_pointer.png b/kdevdesigner/designer/pics/designer_pointer.png Binary files differnew file mode 100644 index 00000000..67e38a36 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_pointer.png diff --git a/kdevdesigner/designer/pics/designer_print.png b/kdevdesigner/designer/pics/designer_print.png Binary files differnew file mode 100644 index 00000000..57e3e532 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_print.png diff --git a/kdevdesigner/designer/pics/designer_progress.png b/kdevdesigner/designer/pics/designer_progress.png Binary files differnew file mode 100644 index 00000000..44ae094e --- /dev/null +++ b/kdevdesigner/designer/pics/designer_progress.png diff --git a/kdevdesigner/designer/pics/designer_project.png b/kdevdesigner/designer/pics/designer_project.png Binary files differnew file mode 100644 index 00000000..6a0fb96f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_project.png diff --git a/kdevdesigner/designer/pics/designer_pushbutton.png b/kdevdesigner/designer/pics/designer_pushbutton.png Binary files differnew file mode 100644 index 00000000..61f779ce --- /dev/null +++ b/kdevdesigner/designer/pics/designer_pushbutton.png diff --git a/kdevdesigner/designer/pics/designer_qtlogo.png b/kdevdesigner/designer/pics/designer_qtlogo.png Binary files differnew file mode 100644 index 00000000..4e1a1472 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_qtlogo.png diff --git a/kdevdesigner/designer/pics/designer_radiobutton.png b/kdevdesigner/designer/pics/designer_radiobutton.png Binary files differnew file mode 100644 index 00000000..10c1d8c3 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_radiobutton.png diff --git a/kdevdesigner/designer/pics/designer_redo.png b/kdevdesigner/designer/pics/designer_redo.png Binary files differnew file mode 100644 index 00000000..abdad26c --- /dev/null +++ b/kdevdesigner/designer/pics/designer_redo.png diff --git a/kdevdesigner/designer/pics/designer_resetproperty.png b/kdevdesigner/designer/pics/designer_resetproperty.png Binary files differnew file mode 100644 index 00000000..cc0d6a26 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_resetproperty.png diff --git a/kdevdesigner/designer/pics/designer_richtextedit.png b/kdevdesigner/designer/pics/designer_richtextedit.png Binary files differnew file mode 100644 index 00000000..73573a8a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_richtextedit.png diff --git a/kdevdesigner/designer/pics/designer_right.png b/kdevdesigner/designer/pics/designer_right.png Binary files differnew file mode 100644 index 00000000..5f2f7036 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_right.png diff --git a/kdevdesigner/designer/pics/designer_s_down.png b/kdevdesigner/designer/pics/designer_s_down.png Binary files differnew file mode 100644 index 00000000..908e55e1 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_s_down.png diff --git a/kdevdesigner/designer/pics/designer_s_editcut.png b/kdevdesigner/designer/pics/designer_s_editcut.png Binary files differnew file mode 100644 index 00000000..7cf5a9eb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_s_editcut.png diff --git a/kdevdesigner/designer/pics/designer_s_left.png b/kdevdesigner/designer/pics/designer_s_left.png Binary files differnew file mode 100644 index 00000000..e6e19f8f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_s_left.png diff --git a/kdevdesigner/designer/pics/designer_s_right.png b/kdevdesigner/designer/pics/designer_s_right.png Binary files differnew file mode 100644 index 00000000..bfccda6b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_s_right.png diff --git a/kdevdesigner/designer/pics/designer_s_up.png b/kdevdesigner/designer/pics/designer_s_up.png Binary files differnew file mode 100644 index 00000000..97705d47 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_s_up.png diff --git a/kdevdesigner/designer/pics/designer_scrollbar.png b/kdevdesigner/designer/pics/designer_scrollbar.png Binary files differnew file mode 100644 index 00000000..466c58de --- /dev/null +++ b/kdevdesigner/designer/pics/designer_scrollbar.png diff --git a/kdevdesigner/designer/pics/designer_searchfind.png b/kdevdesigner/designer/pics/designer_searchfind.png Binary files differnew file mode 100644 index 00000000..3f369fdb --- /dev/null +++ b/kdevdesigner/designer/pics/designer_searchfind.png diff --git a/kdevdesigner/designer/pics/designer_setbuddy.png b/kdevdesigner/designer/pics/designer_setbuddy.png Binary files differnew file mode 100644 index 00000000..c1edb89b --- /dev/null +++ b/kdevdesigner/designer/pics/designer_setbuddy.png diff --git a/kdevdesigner/designer/pics/designer_sizeall.png b/kdevdesigner/designer/pics/designer_sizeall.png Binary files differnew file mode 100644 index 00000000..fa2a266a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_sizeall.png diff --git a/kdevdesigner/designer/pics/designer_sizeb.png b/kdevdesigner/designer/pics/designer_sizeb.png Binary files differnew file mode 100644 index 00000000..ac5235b0 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_sizeb.png diff --git a/kdevdesigner/designer/pics/designer_sizef.png b/kdevdesigner/designer/pics/designer_sizef.png Binary files differnew file mode 100644 index 00000000..28a30c29 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_sizef.png diff --git a/kdevdesigner/designer/pics/designer_sizeh.png b/kdevdesigner/designer/pics/designer_sizeh.png Binary files differnew file mode 100644 index 00000000..7b8abd3a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_sizeh.png diff --git a/kdevdesigner/designer/pics/designer_sizev.png b/kdevdesigner/designer/pics/designer_sizev.png Binary files differnew file mode 100644 index 00000000..80b3d8b2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_sizev.png diff --git a/kdevdesigner/designer/pics/designer_slider.png b/kdevdesigner/designer/pics/designer_slider.png Binary files differnew file mode 100644 index 00000000..525bd1ca --- /dev/null +++ b/kdevdesigner/designer/pics/designer_slider.png diff --git a/kdevdesigner/designer/pics/designer_spacer.png b/kdevdesigner/designer/pics/designer_spacer.png Binary files differnew file mode 100644 index 00000000..926e8afc --- /dev/null +++ b/kdevdesigner/designer/pics/designer_spacer.png diff --git a/kdevdesigner/designer/pics/designer_spinbox.png b/kdevdesigner/designer/pics/designer_spinbox.png Binary files differnew file mode 100644 index 00000000..7ae20630 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_spinbox.png diff --git a/kdevdesigner/designer/pics/designer_splash.png b/kdevdesigner/designer/pics/designer_splash.png Binary files differnew file mode 100644 index 00000000..d3b62a17 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_splash.png diff --git a/kdevdesigner/designer/pics/designer_table.png b/kdevdesigner/designer/pics/designer_table.png Binary files differnew file mode 100644 index 00000000..4bbd9c2d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_table.png diff --git a/kdevdesigner/designer/pics/designer_tabwidget.png b/kdevdesigner/designer/pics/designer_tabwidget.png Binary files differnew file mode 100644 index 00000000..1254bb63 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_tabwidget.png diff --git a/kdevdesigner/designer/pics/designer_textbold.png b/kdevdesigner/designer/pics/designer_textbold.png Binary files differnew file mode 100644 index 00000000..7f4f7344 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textbold.png diff --git a/kdevdesigner/designer/pics/designer_textbrowser.png b/kdevdesigner/designer/pics/designer_textbrowser.png Binary files differnew file mode 100644 index 00000000..090e2f84 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textbrowser.png diff --git a/kdevdesigner/designer/pics/designer_textcenter.png b/kdevdesigner/designer/pics/designer_textcenter.png Binary files differnew file mode 100644 index 00000000..5c68b09c --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textcenter.png diff --git a/kdevdesigner/designer/pics/designer_textedit.png b/kdevdesigner/designer/pics/designer_textedit.png Binary files differnew file mode 100644 index 00000000..823d0818 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textedit.png diff --git a/kdevdesigner/designer/pics/designer_textfont.png b/kdevdesigner/designer/pics/designer_textfont.png Binary files differnew file mode 100644 index 00000000..a4de87a4 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textfont.png diff --git a/kdevdesigner/designer/pics/designer_texth1.png b/kdevdesigner/designer/pics/designer_texth1.png Binary files differnew file mode 100644 index 00000000..1c3aa2fd --- /dev/null +++ b/kdevdesigner/designer/pics/designer_texth1.png diff --git a/kdevdesigner/designer/pics/designer_texth2.png b/kdevdesigner/designer/pics/designer_texth2.png Binary files differnew file mode 100644 index 00000000..ba73121d --- /dev/null +++ b/kdevdesigner/designer/pics/designer_texth2.png diff --git a/kdevdesigner/designer/pics/designer_texth3.png b/kdevdesigner/designer/pics/designer_texth3.png Binary files differnew file mode 100644 index 00000000..1d9f8732 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_texth3.png diff --git a/kdevdesigner/designer/pics/designer_textitalic.png b/kdevdesigner/designer/pics/designer_textitalic.png Binary files differnew file mode 100644 index 00000000..68e2b44c --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textitalic.png diff --git a/kdevdesigner/designer/pics/designer_textjustify.png b/kdevdesigner/designer/pics/designer_textjustify.png Binary files differnew file mode 100644 index 00000000..6e746c80 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textjustify.png diff --git a/kdevdesigner/designer/pics/designer_textlarger.png b/kdevdesigner/designer/pics/designer_textlarger.png Binary files differnew file mode 100644 index 00000000..89960939 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textlarger.png diff --git a/kdevdesigner/designer/pics/designer_textleft.png b/kdevdesigner/designer/pics/designer_textleft.png Binary files differnew file mode 100644 index 00000000..72b27652 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textleft.png diff --git a/kdevdesigner/designer/pics/designer_textlinebreak.png b/kdevdesigner/designer/pics/designer_textlinebreak.png Binary files differnew file mode 100644 index 00000000..081a49e0 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textlinebreak.png diff --git a/kdevdesigner/designer/pics/designer_textparagraph.png b/kdevdesigner/designer/pics/designer_textparagraph.png Binary files differnew file mode 100644 index 00000000..dcd0b3ea --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textparagraph.png diff --git a/kdevdesigner/designer/pics/designer_textright.png b/kdevdesigner/designer/pics/designer_textright.png Binary files differnew file mode 100644 index 00000000..d7186722 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textright.png diff --git a/kdevdesigner/designer/pics/designer_textsmaller.png b/kdevdesigner/designer/pics/designer_textsmaller.png Binary files differnew file mode 100644 index 00000000..10953d9a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textsmaller.png diff --git a/kdevdesigner/designer/pics/designer_textteletext.png b/kdevdesigner/designer/pics/designer_textteletext.png Binary files differnew file mode 100644 index 00000000..c0204636 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textteletext.png diff --git a/kdevdesigner/designer/pics/designer_textunderline.png b/kdevdesigner/designer/pics/designer_textunderline.png Binary files differnew file mode 100644 index 00000000..3477ccb3 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textunderline.png diff --git a/kdevdesigner/designer/pics/designer_textview.png b/kdevdesigner/designer/pics/designer_textview.png Binary files differnew file mode 100644 index 00000000..ec2270c3 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_textview.png diff --git a/kdevdesigner/designer/pics/designer_timeedit.png b/kdevdesigner/designer/pics/designer_timeedit.png Binary files differnew file mode 100644 index 00000000..01b37888 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_timeedit.png diff --git a/kdevdesigner/designer/pics/designer_toolbox.png b/kdevdesigner/designer/pics/designer_toolbox.png Binary files differnew file mode 100644 index 00000000..2ab71dc7 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_toolbox.png diff --git a/kdevdesigner/designer/pics/designer_toolbutton.png b/kdevdesigner/designer/pics/designer_toolbutton.png Binary files differnew file mode 100644 index 00000000..25d240a1 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_toolbutton.png diff --git a/kdevdesigner/designer/pics/designer_undo.png b/kdevdesigner/designer/pics/designer_undo.png Binary files differnew file mode 100644 index 00000000..839a823f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_undo.png diff --git a/kdevdesigner/designer/pics/designer_up.png b/kdevdesigner/designer/pics/designer_up.png Binary files differnew file mode 100644 index 00000000..e4373122 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_up.png diff --git a/kdevdesigner/designer/pics/designer_uparrow.png b/kdevdesigner/designer/pics/designer_uparrow.png Binary files differnew file mode 100644 index 00000000..eefe4a00 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_uparrow.png diff --git a/kdevdesigner/designer/pics/designer_vsplit.png b/kdevdesigner/designer/pics/designer_vsplit.png Binary files differnew file mode 100644 index 00000000..b820c19f --- /dev/null +++ b/kdevdesigner/designer/pics/designer_vsplit.png diff --git a/kdevdesigner/designer/pics/designer_wait.png b/kdevdesigner/designer/pics/designer_wait.png Binary files differnew file mode 100644 index 00000000..5d8cfed2 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_wait.png diff --git a/kdevdesigner/designer/pics/designer_widgetstack.png b/kdevdesigner/designer/pics/designer_widgetstack.png Binary files differnew file mode 100644 index 00000000..c326de81 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_widgetstack.png diff --git a/kdevdesigner/designer/pics/designer_wizarddata.png b/kdevdesigner/designer/pics/designer_wizarddata.png Binary files differnew file mode 100644 index 00000000..9493e3b1 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_wizarddata.png diff --git a/kdevdesigner/designer/pics/designer_wizarddialog.png b/kdevdesigner/designer/pics/designer_wizarddialog.png Binary files differnew file mode 100644 index 00000000..a22dc88a --- /dev/null +++ b/kdevdesigner/designer/pics/designer_wizarddialog.png diff --git a/kdevdesigner/designer/pics/designer_wordwrap.png b/kdevdesigner/designer/pics/designer_wordwrap.png Binary files differnew file mode 100644 index 00000000..29513c32 --- /dev/null +++ b/kdevdesigner/designer/pics/designer_wordwrap.png diff --git a/kdevdesigner/designer/pixmapchooser.cpp b/kdevdesigner/designer/pixmapchooser.cpp new file mode 100644 index 00000000..aaac22c0 --- /dev/null +++ b/kdevdesigner/designer/pixmapchooser.cpp @@ -0,0 +1,231 @@ +/********************************************************************** +** 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. +** +** 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 <qvariant.h> // HP-UX compiler needs this here + +#include <kiconloader.h> +#include <kimageio.h> +#include <kfiledialog.h> +#include <kimagefilepreview.h> +#include <klineedit.h> + +#include "kdevdesigner_part.h" + +#include "pixmapchooser.h" +#include "formwindow.h" +#if defined(DESIGNER) && !defined(RESOURCE) +#include "pixmapfunction.h" +#endif +#include "metadatabase.h" +#include "mainwindow.h" +#include "pixmapcollectioneditor.h" +#include "pixmapcollection.h" +#include "project.h" + +#include <qapplication.h> +#include <qimage.h> +#include <qpainter.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qiconview.h> + +#if defined(DESIGNER) +static ImageIconProvider *imageIconProvider = 0; +#endif + +PixmapView::PixmapView( QWidget *parent ) + : QScrollView( parent ) +{ + viewport()->setBackgroundMode( PaletteBase ); +} + +void PixmapView::setPixmap( const QPixmap &pix ) +{ + pixmap = pix; + resizeContents( pixmap.size().width(), pixmap.size().height() ); + viewport()->repaint( FALSE ); +} + +void PixmapView::drawContents( QPainter *p, int cx, int cy, int cw, int ch ) +{ + p->fillRect( cx, cy, cw, ch, colorGroup().brush( QColorGroup::Base ) ); + p->drawPixmap( 0, 0, pixmap ); +} + +void PixmapView::previewUrl( const QUrl &u ) +{ + if ( u.isLocalFile() ) { + QString path = u.path(); + QPixmap pix( path ); + if ( !pix.isNull() ) + setPixmap( pix ); + } else { + qWarning( "Previewing remote files not supported." ); + } +} + +static void buildImageFormatList( QString &filter, QString &all ) +{ + all = qApp->translate( "qChoosePixmap", "All Pixmaps (" ); + for ( uint i = 0; i < QImageIO::outputFormats().count(); i++ ) { + QString outputFormat = QImageIO::outputFormats().at( i ); + QString outputExtension; + if ( outputFormat != "JPEG" ) + outputExtension = outputFormat.lower(); + else + outputExtension = "jpg;*.jpeg"; + filter += qApp->translate( "qChoosePixmap", "%1-Pixmaps (%2)\n" ). + arg( outputFormat ).arg( "*." + outputExtension); + all += "*." + outputExtension + ";"; + } + filter.prepend( all + qApp->translate( "qChoosePixmap", ")\n" ) ); + filter += qApp->translate( "qChoosePixmap", "All Files (*)" ); + +} +QStringList qChoosePixmaps( QWidget *parent ) +{ +/* if ( !imageIconProvider && !QFileDialog::iconProvider() ) + QFileDialog::setIconProvider( ( imageIconProvider = new ImageIconProvider ) ); + + QString filter; + QString all; + buildImageFormatList( filter, all ); + + QFileDialog fd( QString::null, filter, parent, 0, TRUE ); + fd.setMode( QFileDialog::ExistingFiles ); + fd.setContentsPreviewEnabled( TRUE ); + PixmapView *pw = new PixmapView( &fd ); + fd.setContentsPreview( pw, pw ); + fd.setViewMode( QFileDialog::List ); + fd.setPreviewMode( QFileDialog::Contents ); + fd.setCaption( qApp->translate( "qChoosePixmap", "Choose Images..." ) ); + if ( fd.exec() == QDialog::Accepted ) + return fd.selectedFiles(); + return QStringList();*/ + QStringList mimetypes = KImageIO::mimeTypes( KImageIO::Reading ); + KFileDialog dlg(QString::null, mimetypes.join(" "), parent, "filedialog", true); + dlg.setOperationMode( KFileDialog::Opening ); + dlg.setCaption( qApp->translate( "qChoosePixmap", "Choose Images..." ) ); + dlg.setMode( KFile::Files ); + KImageFilePreview *ip = new KImageFilePreview( &dlg ); + dlg.setPreviewWidget( ip ); + if (dlg.exec()) + return dlg.selectedFiles(); + return QStringList(); +} + +QPixmap qChoosePixmap( QWidget *parent, FormWindow *fw, const QPixmap &old, QString *fn ) +{ +#if defined(DESIGNER) + if ( !fw || fw->savePixmapInline() ) { +/* if ( !imageIconProvider && !QFileDialog::iconProvider() ) + QFileDialog::setIconProvider( ( imageIconProvider = new ImageIconProvider ) ); + + QString filter; + QString all; + buildImageFormatList( filter, all ); + + QFileDialog fd( QString::null, filter, parent, 0, TRUE ); + fd.setContentsPreviewEnabled( TRUE ); + PixmapView *pw = new PixmapView( &fd ); + fd.setContentsPreview( pw, pw ); + fd.setViewMode( QFileDialog::List ); + fd.setPreviewMode( QFileDialog::Contents ); + fd.setCaption( qApp->translate( "qChoosePixmap", "Choose Pixmap" ) ); + if ( fd.exec() == QDialog::Accepted ) { + QPixmap pix( fd.selectedFile() ); + if ( fn ) + *fn = fd.selectedFile(); + MetaDataBase::setPixmapArgument( fw, pix.serialNumber(), fd.selectedFile() ); + return pix; + }*/ + QStringList mimetypes = KImageIO::mimeTypes( KImageIO::Reading ); + KFileDialog dlg(QString::null, mimetypes.join(" "), parent, "filedialog", true); + dlg.setOperationMode( KFileDialog::Opening ); + dlg.setCaption( qApp->translate( "qChoosePixmap", "Choose Pixmap" ) ); + dlg.setMode( KFile::File ); + KImageFilePreview *ip = new KImageFilePreview( &dlg ); + dlg.setPreviewWidget( ip ); + if (dlg.exec()) + { + QPixmap pix( dlg.selectedURL().path() ); + if ( fn ) + *fn = dlg.selectedURL().path(); + MetaDataBase::setPixmapArgument( fw, pix.serialNumber(), dlg.selectedURL().path() ); + return pix; + } + } else if ( fw && fw->savePixmapInProject() ) { + PixmapCollectionEditor dia( parent, 0, TRUE ); + dia.setProject( fw->project() ); + dia.setChooserMode( TRUE ); + dia.setCurrentItem( MetaDataBase::pixmapKey( fw, old.serialNumber() ) ); + if ( dia.exec() == QDialog::Accepted ) { + QPixmap pix( fw->project()->pixmapCollection()->pixmap( dia.viewPixmaps->currentItem()->text() ) ); + MetaDataBase::setPixmapKey( fw, pix.serialNumber(), dia.viewPixmaps->currentItem()->text() ); + return pix; + } + } else { + PixmapFunction dia( parent, 0, TRUE ); + QObject::connect( dia.helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + dia.labelFunction->setText( fw->pixmapLoaderFunction() + "(" ); + dia.editArguments->setText( MetaDataBase::pixmapArgument( fw, old.serialNumber() ) ); + dia.editArguments->setFocus(); + if ( dia.exec() == QDialog::Accepted ) { + QPixmap pix; + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( BarIcon( "designer_image.png", KDevDesignerPartFactory::instance() ).convertToImage() ); + + MetaDataBase::setPixmapArgument( fw, pix.serialNumber(), dia.editArguments->text() ); + return pix; + } + } +#else + Q_UNUSED( parent ); + Q_UNUSED( fw ); + Q_UNUSED( old ); +#endif + return QPixmap(); +} + +ImageIconProvider::ImageIconProvider( QWidget *parent, const char *name ) + : QFileIconProvider( parent, name ), imagepm( BarIcon( "designer_image.png", KDevDesignerPartFactory::instance() ) ) +{ + fmts = QImage::inputFormats(); +} + +ImageIconProvider::~ImageIconProvider() +{ +} + +const QPixmap * ImageIconProvider::pixmap( const QFileInfo &fi ) +{ + QString ext = fi.extension().upper(); + if ( fmts.contains( ext ) ) { + return &imagepm; + } else { + return QFileIconProvider::pixmap( fi ); + } +} diff --git a/kdevdesigner/designer/pixmapchooser.h b/kdevdesigner/designer/pixmapchooser.h new file mode 100644 index 00000000..cea45bfd --- /dev/null +++ b/kdevdesigner/designer/pixmapchooser.h @@ -0,0 +1,72 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PIXMAPCHOOSER_H +#define PIXMAPCHOOSER_H + +#include <qfiledialog.h> +#include <qscrollview.h> +#include <qpixmap.h> +#include <qurl.h> + +class FormWindow; + +class PixmapView : public QScrollView, + public QFilePreview +{ + Q_OBJECT + +public: + PixmapView( QWidget *parent ); + void setPixmap( const QPixmap &pix ); + void drawContents( QPainter *p, int, int, int, int ); + void previewUrl( const QUrl &u ); + +private: + QPixmap pixmap; + +}; + +class ImageIconProvider : public QFileIconProvider +{ + Q_OBJECT + +public: + ImageIconProvider( QWidget *parent = 0, const char *name = 0 ); + ~ImageIconProvider(); + + const QPixmap *pixmap( const QFileInfo &fi ); + +private: + QStrList fmts; + QPixmap imagepm; + +}; + +QPixmap qChoosePixmap( QWidget *parent, FormWindow *fw = 0, const QPixmap &old = QPixmap(), QString *fn = 0 ); +QStringList qChoosePixmaps( QWidget *parent ); + +#endif diff --git a/kdevdesigner/designer/pixmapcollection.cpp b/kdevdesigner/designer/pixmapcollection.cpp new file mode 100644 index 00000000..c8b14ffa --- /dev/null +++ b/kdevdesigner/designer/pixmapcollection.cpp @@ -0,0 +1,180 @@ +/********************************************************************** +** 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 "pixmapcollection.h" +#include "project.h" +#include "mainwindow.h" +#include <qmime.h> +#include <qdir.h> +#include <qfileinfo.h> +#include <qtextstream.h> +#include <qimage.h> + +PixmapCollection::PixmapCollection( Project *pro ) + : project( pro ) +{ + iface = new DesignerPixmapCollectionImpl( this ); + mimeSourceFactory = new QMimeSourceFactory(); +} + +PixmapCollection::~PixmapCollection() +{ + delete mimeSourceFactory; + delete iface; +} + +bool PixmapCollection::addPixmap( const Pixmap &pix, bool force ) +{ + Pixmap pixmap = pix; + savePixmap( pixmap ); + + if ( !force ) { + for ( QValueList<Pixmap>::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( (*it).name == pixmap.name ) + return FALSE; + } + } + + pixList.append( pixmap ); + mimeSourceFactory->setPixmap( pixmap.name, pixmap.pix ); + project->setModified( TRUE ); + return TRUE; +} + +void PixmapCollection::removePixmap( const QString &name ) +{ + for ( QValueList<Pixmap>::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( (*it).name == name ) { + pixList.remove( it ); + break; + } + } + project->setModified( TRUE ); +} + +QValueList<PixmapCollection::Pixmap> PixmapCollection::pixmaps() const +{ + return pixList; +} + +QString PixmapCollection::unifyName( const QString &n ) +{ + QString name = n; + bool restart = FALSE; + int added = 1; + + for ( QValueList<Pixmap>::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( restart ) + it = pixList.begin(); + restart = FALSE; + if ( name == (*it).name ) { + name = n; + name += "_" + QString::number( added ); + ++added; + restart = TRUE; + } + } + + return name; +} + +void PixmapCollection::setActive( bool b ) +{ + if ( b ) + QMimeSourceFactory::defaultFactory()->addFactory( mimeSourceFactory ); + else + QMimeSourceFactory::defaultFactory()->removeFactory( mimeSourceFactory ); +} + +QPixmap PixmapCollection::pixmap( const QString &name ) +{ + for ( QValueList<Pixmap>::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( (*it).name == name ) + return (*it).pix; + } + return QPixmap(); +} + +void PixmapCollection::savePixmap( Pixmap &pix ) +{ + if ( pix.absname == imageDir() + "/" + pix.name ) + return; // no need to save, it is already there + QString rel = project->makeRelative( pix.absname ); + if ( rel[0] == '/' || ( rel[1] == ':' && rel[2] == '/' ) ) { // only save if file is outside the project + mkdir(); + pix.name = unifyName( QFileInfo( pix.absname ).baseName() ) + ".png"; + pix.absname = imageDir() + "/" + pix.name; + pix.pix.save( pix.absname, "PNG" ); + } else if ( rel.isEmpty() ) { + mkdir(); + pix.name = unifyName( pix.name ); + pix.absname = imageDir() + "/" + pix.name; + pix.pix.save( pix.absname, "PNG" ); + } +} + +QString PixmapCollection::imageDir() const +{ + return QFileInfo( project->fileName() ).dirPath( TRUE ) + "/images"; +} + +void PixmapCollection::mkdir() +{ + QString f = project->fileName(); + QDir d( QFileInfo( f ).dirPath( TRUE ) ); + d.mkdir( "images" ); +} + +void PixmapCollection::load( const QString& filename ) +{ + if ( filename.isEmpty() ) + return; + QString absfile; + if ( filename[0] == '/' ) + absfile = filename; + else + absfile = QFileInfo( project->fileName() ).dirPath( TRUE ) + "/" + filename; + + QPixmap pm( absfile ); + if ( pm.isNull() ) + return; + + Pixmap pix; + pix.name = QFileInfo( absfile ).fileName(); + pix.absname = absfile; + pix.pix = pm; + addPixmap( pix, TRUE ); +} + +DesignerPixmapCollection *PixmapCollection::iFace() +{ + return iface; +} + +bool PixmapCollection::isEmpty() const +{ + return pixList.isEmpty(); +} diff --git a/kdevdesigner/designer/pixmapcollection.h b/kdevdesigner/designer/pixmapcollection.h new file mode 100644 index 00000000..ed36ecb8 --- /dev/null +++ b/kdevdesigner/designer/pixmapcollection.h @@ -0,0 +1,80 @@ +/********************************************************************** +** 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 PIXMAPCOLLECTION_H +#define PIXMAPCOLLECTION_H + +#include <qstring.h> +#include <qpixmap.h> +#include <qvaluelist.h> +#include "designerappiface.h" + +class QMimeSourceFactory; +class Project; + +class PixmapCollection +{ +public: + struct Pixmap + { + QPixmap pix; + QString name; + QString absname; + Q_DUMMY_COMPARISON_OPERATOR( Pixmap ) + }; + + PixmapCollection( Project *pro ); + ~PixmapCollection(); + + bool addPixmap( const Pixmap &pix, bool force = TRUE ); + void removePixmap( const QString &name ); + QPixmap pixmap( const QString &name ); + + QValueList<Pixmap> pixmaps() const; + bool isEmpty() const; + + void setActive( bool b ); + + void load( const QString& filename ); + + DesignerPixmapCollection *iFace(); + +private: + QString unifyName( const QString &n ); + void savePixmap( Pixmap &pix ); + + QString imageDir() const; + void mkdir(); + +private: + QValueList<Pixmap> pixList; + QMimeSourceFactory *mimeSourceFactory; + Project *project; + DesignerPixmapCollectionImpl *iface; + +}; + +#endif diff --git a/kdevdesigner/designer/pixmapcollectioneditor.ui b/kdevdesigner/designer/pixmapcollectioneditor.ui new file mode 100644 index 00000000..c4888193 --- /dev/null +++ b/kdevdesigner/designer/pixmapcollectioneditor.ui @@ -0,0 +1,218 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>PixmapCollectionEditor</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>PixmapCollectionEditor</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>455</width> + <height>260</height> + </rect> + </property> + <property name="caption"> + <string>Manage Image Collection</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QIconView"> + <property name="name"> + <cstring>viewPixmaps</cstring> + </property> + <property name="resizeMode"> + <enum>Adjust</enum> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Add...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton3</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonClose</cstring> + </property> + <property name="text"> + <string>C&lose</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>PixmapCollectionEditor</receiver> + <slot>addPixmap()</slot> + </connection> + <connection> + <sender>PushButton3</sender> + <signal>clicked()</signal> + <receiver>PixmapCollectionEditor</receiver> + <slot>removePixmap()</slot> + </connection> + <connection> + <sender>viewPixmaps</sender> + <signal>currentChanged(QIconViewItem*)</signal> + <receiver>PixmapCollectionEditor</receiver> + <slot>currentChanged(QIconViewItem*)</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>PixmapCollectionEditor</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>PixmapCollectionEditor</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonClose</sender> + <signal>clicked()</signal> + <receiver>PixmapCollectionEditor</receiver> + <slot>accept()</slot> + </connection> +</connections> +<tabstops> + <tabstop>PushButton2</tabstop> + <tabstop>PushButton3</tabstop> + <tabstop>viewPixmaps</tabstop> + <tabstop>buttonClose</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">pixmapcollection.h</include> + <include location="local" impldecl="in implementation">pixmapchooser.h</include> + <include location="local" impldecl="in implementation">project.h</include> + <include location="global" impldecl="in implementation">qfileinfo.h</include> + <include location="global" impldecl="in implementation">qimage.h</include> + <include location="global" impldecl="in declaration">qpixmap.h</include> + <include location="local" impldecl="in implementation">pixmapcollectioneditor.ui.h</include> +</includes> +<forwards> + <forward>class Project;</forward> +</forwards> +<variables> + <variable>Project *project;</variable> + <variable>bool chooser;</variable> +</variables> +<slots> + <slot>init()</slot> + <slot>destroy()</slot> + <slot>addPixmap()</slot> + <slot>removePixmap()</slot> + <slot>updateView()</slot> + <slot>currentChanged(QIconViewItem * i)</slot> + <slot>setChooserMode(bool c)</slot> + <slot>setCurrentItem(const QString & name)</slot> + <slot>setProject(Project * pro)</slot> + <slot returnType="QPixmap">scaledPixmap(const QPixmap & p)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/pixmapcollectioneditor.ui.h b/kdevdesigner/designer/pixmapcollectioneditor.ui.h new file mode 100644 index 00000000..4d82f3f3 --- /dev/null +++ b/kdevdesigner/designer/pixmapcollectioneditor.ui.h @@ -0,0 +1,150 @@ +#include <klocale.h> +/********************************************************************** +** Copyright (C) 2001-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. +** +**********************************************************************/ + +void PixmapCollectionEditor::init() +{ + project = 0; + setChooserMode( FALSE ); +} + +void PixmapCollectionEditor::destroy() +{ +} + +void PixmapCollectionEditor::addPixmap() +{ + if ( !project ) + return; + + QString f; + QStringList pixmaps = qChoosePixmaps( this ); + if ( pixmaps.isEmpty() ) + return; + + QString lastName; + for ( QStringList::ConstIterator it = pixmaps.begin(); it != pixmaps.end(); ++it ) { + QPixmap pm( *it ); + if ( pm.isNull() ) + continue; + PixmapCollection::Pixmap pixmap; + pixmap.pix = pm; + QFileInfo fi ( *it ); + pixmap.name = fi.fileName(); + pixmap.absname = fi.filePath(); + if ( !project->pixmapCollection()->addPixmap( pixmap, FALSE ) ) + continue; + lastName = pixmap.name; + } + + updateView(); + QIconViewItem *item = viewPixmaps->findItem( lastName ); + if ( item ) { + viewPixmaps->setCurrentItem( item ); + viewPixmaps->ensureItemVisible( item ); + } + +} + +void PixmapCollectionEditor::removePixmap() +{ + if ( !project || !viewPixmaps->currentItem() ) + return; + project->pixmapCollection()->removePixmap( viewPixmaps->currentItem()->text() ); + updateView(); +} + +void PixmapCollectionEditor::updateView() +{ + if ( !project ) + return; + + viewPixmaps->clear(); + + QValueList<PixmapCollection::Pixmap> pixmaps = project->pixmapCollection()->pixmaps(); + for ( QValueList<PixmapCollection::Pixmap>::Iterator it = pixmaps.begin(); it != pixmaps.end(); ++it ) { + // #### might need to scale down the pixmap + QIconViewItem *item = new QIconViewItem( viewPixmaps, (*it).name, scaledPixmap( (*it).pix ) ); + //item->setRenameEnabled( TRUE ); // this will be a bit harder to implement + item->setDragEnabled( FALSE ); + item->setDropEnabled( FALSE ); + } + viewPixmaps->setCurrentItem( viewPixmaps->firstItem() ); + currentChanged( viewPixmaps->firstItem() ); +} + +void PixmapCollectionEditor::currentChanged( QIconViewItem * i ) +{ + buttonOk->setEnabled( !!i ); +} + +void PixmapCollectionEditor::setChooserMode( bool c ) +{ + chooser = c; + if ( chooser ) { + buttonClose->hide(); + buttonOk->show(); + buttonCancel->show(); + buttonOk->setEnabled( FALSE ); + buttonOk->setDefault( TRUE ); + connect( viewPixmaps, SIGNAL( doubleClicked( QIconViewItem * ) ), buttonOk, SIGNAL( clicked() ) ); + connect( viewPixmaps, SIGNAL( returnPressed( QIconViewItem * ) ), buttonOk, SIGNAL( clicked() ) ); + setCaption( i18n( "Choose Image" ) ); + } else { + buttonClose->show(); + buttonOk->hide(); + buttonCancel->hide(); + buttonClose->setDefault( TRUE ); + } + updateView(); +} + +void PixmapCollectionEditor::setCurrentItem( const QString & name ) +{ + QIconViewItem *i = viewPixmaps->findItem( name ); + if ( i ) { + viewPixmaps->setCurrentItem( i ); + currentChanged( i ); + } +} + +void PixmapCollectionEditor::setProject( Project * pro ) +{ + project = pro; + updateView(); +} + +QPixmap PixmapCollectionEditor::scaledPixmap( const QPixmap & p ) +{ + QPixmap pix( p ); + if ( pix.width() < 50 && pix.height() < 50 ) + return pix; + QImage img; + img = pix; + img = img.smoothScale( 50, 50 ); + pix.convertFromImage( img ); + return pix; +} diff --git a/kdevdesigner/designer/pixmapfunction.ui b/kdevdesigner/designer/pixmapfunction.ui new file mode 100644 index 00000000..7eb5fb94 --- /dev/null +++ b/kdevdesigner/designer/pixmapfunction.ui @@ -0,0 +1,976 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>PixmapFunction</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>PixmapFunction</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>305</width> + <height>120</height> + </rect> + </property> + <property name="caption"> + <string>Choose Pixmap</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>&Enter arguments for loading the pixmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editArguments</cstring> + </property> + </widget> + <widget class="QFrame"> + <property name="name"> + <cstring>Frame9</cstring> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="lineWidth"> + <number>2</number> + </property> + <property name="layoutMargin" stdset="0"> + </property> + <property name="layoutSpacing" stdset="0"> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>2</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelFunction</cstring> + </property> + <property name="palette"> + <palette> + <active> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>233</red> + <green>233</green> + <blue>233</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </active> + <disabled> + <color> + <red>128</red> + <green>128</green> + <blue>128</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>242</red> + <green>242</green> + <blue>242</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>128</red> + <green>128</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </disabled> + <inactive> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>242</red> + <green>242</green> + <blue>242</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </inactive> + </palette> + </property> + <property name="text"> + <string>QPixmap(</string> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editArguments</cstring> + </property> + <property name="palette"> + <palette> + <active> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>233</red> + <green>233</green> + <blue>233</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </active> + <disabled> + <color> + <red>128</red> + <green>128</green> + <blue>128</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>242</red> + <green>242</green> + <blue>242</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>128</red> + <green>128</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </disabled> + <inactive> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>242</red> + <green>242</green> + <blue>242</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </inactive> + </palette> + </property> + <property name="frame"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel5</cstring> + </property> + <property name="palette"> + <palette> + <active> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>233</red> + <green>233</green> + <blue>233</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </active> + <disabled> + <color> + <red>128</red> + <green>128</green> + <blue>128</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>242</red> + <green>242</green> + <blue>242</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>128</red> + <green>128</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </disabled> + <inactive> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>211</red> + <green>211</green> + <blue>211</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>242</red> + <green>242</green> + <blue>242</blue> + </color> + <color> + <red>105</red> + <green>105</green> + <blue>105</blue> + </color> + <color> + <red>140</red> + <green>140</green> + <blue>140</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>128</blue> + </color> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </inactive> + </palette> + </property> + <property name="text"> + <string>)</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>PixmapFunction</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>PixmapFunction</receiver> + <slot>reject()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/kdevdesigner/designer/popupmenueditor.cpp b/kdevdesigner/designer/popupmenueditor.cpp new file mode 100644 index 00000000..198880f9 --- /dev/null +++ b/kdevdesigner/designer/popupmenueditor.cpp @@ -0,0 +1,1469 @@ +/********************************************************************** +** Copyright (C) 2003 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 <qapplication.h> +#include <qcstring.h> +#include <qdatastream.h> +#include <qdragobject.h> +#include <qlineedit.h> +#include <qobjectlist.h> +#include <qpainter.h> +#include <qpopupmenu.h> +#include <qrect.h> +#include <qsize.h> +#include <qstyle.h> +#include <qtimer.h> +#include "actiondnd.h" +#include "actioneditorimpl.h" +#include "command.h" +#include "formfile.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "pixmapchooser.h" +#include "popupmenueditor.h" +#include "menubareditor.h" + +#include <klocale.h> + +// Drag Object Declaration ------------------------------------------- + +class PopupMenuEditorItemPtrDrag : public QStoredDrag +{ +public: + PopupMenuEditorItemPtrDrag( PopupMenuEditorItem * item, QWidget * parent = 0, + const char * name = 0 ); + ~PopupMenuEditorItemPtrDrag() {}; + static bool canDecode( QDragMoveEvent * e ); + static bool decode( QDropEvent * e, PopupMenuEditorItem ** i ); +}; + +// Drag Object Implementation --------------------------------------- + +PopupMenuEditorItemPtrDrag::PopupMenuEditorItemPtrDrag( PopupMenuEditorItem * item, + QWidget * parent, const char * name ) + : QStoredDrag( "qt/popupmenueditoritemptr", parent, name ) +{ + QByteArray data( sizeof( Q_LONG ) ); + QDataStream stream( data, IO_WriteOnly ); + stream << ( Q_LONG ) item; + setEncodedData( data ); +} + +bool PopupMenuEditorItemPtrDrag::canDecode( QDragMoveEvent * e ) +{ + return e->provides( "qt/popupmenueditoritemptr" ); +} + +bool PopupMenuEditorItemPtrDrag::decode( QDropEvent * e, PopupMenuEditorItem ** i ) +{ + QByteArray data = e->encodedData( "qt/popupmenueditoritemptr" ); + QDataStream stream( data, IO_ReadOnly ); + + if ( !data.size() ) + return FALSE; + + Q_LONG p = 0; + stream >> p; + *i = ( PopupMenuEditorItem *) p; + + return TRUE; +} + +// PopupMenuEditorItem Implementation ----------------------------------- + +PopupMenuEditorItem::PopupMenuEditorItem( PopupMenuEditor * menu, QObject * parent, const char * name ) + : QObject( parent, name ), + a( 0 ), + s( 0 ), + m( menu ), + separator( FALSE ), + removable( FALSE ) +{ + init(); + a = new QAction( this ); + QObject::connect( a, SIGNAL( destroyed() ), this, SLOT( selfDestruct() ) ); +} + + +PopupMenuEditorItem::PopupMenuEditorItem( QAction * action, PopupMenuEditor * menu, + QObject * parent, const char * name ) + : QObject( parent, name ), + a( action ), + s( 0 ), + m( menu ), + separator( FALSE ), + removable( TRUE ) +{ + init(); + if ( /*a->name() == "qt_separator_action" ||*/ ::qt_cast<QSeparatorAction*>(a) ) + separator = TRUE; + if ( a && a->children() ) + a->installEventFilter( this ); +} + +PopupMenuEditorItem::PopupMenuEditorItem( PopupMenuEditorItem * item, PopupMenuEditor * menu, + QObject * parent, const char * name ) + : QObject( parent, name ), + a( item->a ), + s( 0 ), + m( menu ), + separator( item->separator ), + removable( item->removable ) +{ + init(); + if ( ::qt_cast<QActionGroup*>(a) ) + a->installEventFilter( this ); +} + +PopupMenuEditorItem::~PopupMenuEditorItem() +{ + +} + +void PopupMenuEditorItem::init() +{ + if ( a ) { + QObject::connect( a, SIGNAL( destroyed() ), this, SLOT( selfDestruct() ) ); + if ( m && !isSeparator() ) { + s = new PopupMenuEditor( m->formWindow(), m ); + QString n = "PopupMenuEditor"; + m->formWindow()->unify( s, n, TRUE ); + s->setName( n ); + MetaDataBase::addEntry( s ); + } + } +} + +PopupMenuEditorItem::ItemType PopupMenuEditorItem::type() const +{ + if ( separator ) + return Separator; + else if ( a ) + return Action; + return Unknown; +} + +void PopupMenuEditorItem::setVisible( bool enable ) +{ + if ( a ) + a->setVisible( enable ); +} + +bool PopupMenuEditorItem::isVisible() const +{ + QActionGroup *g = ::qt_cast<QActionGroup*>(a); + if ( g ) + return ( g->isVisible() && g->usesDropDown() ); + else if ( a ) + return a->isVisible(); + return FALSE; +} + +void PopupMenuEditorItem::showMenu( int x, int y ) +{ + if ( ( !separator ) && s ) { + s->move( x, y ); + s->show(); + s->raise(); + } +} + +void PopupMenuEditorItem::hideMenu() +{ + if ( s ) { + s->hideSubMenu(); + s->hide(); + } +} + +void PopupMenuEditorItem::focusOnMenu() +{ + if ( s ) { + s->showSubMenu(); + s->setFocus(); + } +} + +int PopupMenuEditorItem::count() const +{ + if ( s ) { + return s->count(); + } else if ( ::qt_cast<QActionGroup*>(a) ) { + const QObjectList * l = a->children(); + if ( l ) + return l->count(); + } + return 0; +} + +bool PopupMenuEditorItem::eventFilter( QObject * o, QEvent * event ) +{ + if ( ! ::qt_cast<QActionGroup*>( o ) ) + return FALSE; + if ( event->type() == QEvent::ChildInserted ) { + QChildEvent * ce = ( QChildEvent * ) event; + QObject * c = ce->child(); + QAction * action = ::qt_cast<QAction*>( c ); + if ( s->find( action ) != -1 ) // avoid duplicates + return FALSE; + QActionGroup * actionGroup = ::qt_cast<QActionGroup*>( c ); + if ( actionGroup ) + s->insert( actionGroup ); + else if ( action ) + s->insert( action ); + } + return FALSE; +} + +void PopupMenuEditorItem::selfDestruct() +{ + hideMenu(); + int i = m->find( s ); + if ( i != -1 && i < m->count() ) + m->remove( i ); // remove this item + a = 0; // the selfDestruct call was caused by the deletion of the action + delete this; +} + +// PopupMenuEditor Implementation ----------------------------------- + +PopupMenuEditorItem * PopupMenuEditor::draggedItem = 0; +int PopupMenuEditor::clipboardOperation = 0; +PopupMenuEditorItem * PopupMenuEditor::clipboardItem = 0; + +PopupMenuEditor::PopupMenuEditor( FormWindow * fw, QWidget * parent, const char * name ) + : QWidget( 0, name, WStyle_Customize | WStyle_NoBorder | WRepaintNoErase | WResizeNoErase ), + formWnd( fw ), + parentMenu( parent ), + iconWidth( 0 ), + textWidth( 0 ), + accelWidth( 0 ), + arrowWidth( 30 ), + borderSize( 2 ), + currentField( 1 ), + currentIndex( 0 ) +{ + init(); +} + +PopupMenuEditor::PopupMenuEditor( FormWindow * fw, PopupMenuEditor * menu, + QWidget * parent, const char * name ) + : QWidget( 0, name, WStyle_Customize | WStyle_NoBorder | WRepaintNoErase ), + formWnd( fw ), + parentMenu( parent ), + iconWidth( menu->iconWidth ), + textWidth( menu->textWidth ), + accelWidth( menu->accelWidth ), + arrowWidth( menu->arrowWidth ), + borderSize( menu->borderSize ), + currentField( menu->currentField ), + currentIndex( menu->currentIndex ) +{ + init(); + PopupMenuEditorItem * i; + for ( i = menu->itemList.first(); i; i = menu->itemList.next() ) { + PopupMenuEditorItem * n = new PopupMenuEditorItem( i, this ); + itemList.append( n ); + } +} + +PopupMenuEditor::~PopupMenuEditor() +{ + itemList.setAutoDelete( TRUE ); +} + +void PopupMenuEditor::init() +{ + reparent( ( QMainWindow * ) formWnd->mainContainer(), pos() ); + + addItem.action()->setMenuText( i18n("new item") ); + addSeparator.action()->setMenuText( i18n("new separator") ); + + setAcceptDrops( TRUE ); + setFocusPolicy( StrongFocus ); + + lineEdit = new QLineEdit( this ); + lineEdit->hide(); + lineEdit->setFrameStyle(QFrame::Plain | QFrame::NoFrame); + lineEdit->polish(); + lineEdit->setBackgroundOrigin(ParentOrigin); + lineEdit->setBackgroundMode(PaletteButton); + lineEdit->installEventFilter( this ); + + dropLine = new QWidget( this, 0, Qt::WStyle_NoBorder | WStyle_StaysOnTop ); + dropLine->setBackgroundColor( Qt::red ); + dropLine->hide(); + + hide(); +} + +void PopupMenuEditor::insert( PopupMenuEditorItem * item, int index ) +{ + if ( !item ) + return; + if ( index == -1 ) { + itemList.append( item ); + if ( isVisible() ) + currentIndex = itemList.count() - 1; + } else { + itemList.insert( index, item ); + if ( isVisible() ) + currentIndex = index; + } + item->m = this; + item->s->parentMenu = this; + resizeToContents(); + if ( isVisible() && parentMenu ) + parentMenu->update(); // draw arrow in parent menu + emit inserted( item->action() ); +} + +void PopupMenuEditor::insert( QAction * action, int index ) +{ + if ( !action ) + return; + insert( new PopupMenuEditorItem( action, this, 0, action->name() ), index ); +} + +void PopupMenuEditor::insert( QActionGroup * actionGroup, int index ) +{ + if ( !actionGroup ) + return; + bool dropdown = actionGroup->usesDropDown(); + PopupMenuEditorItem *i = new PopupMenuEditorItem( (QAction *)actionGroup, this, 0, + QString( actionGroup->name() ) + "Menu" ); + QActionGroup *g = 0; + QObjectList *l = actionGroup->queryList( "QAction", 0, FALSE, FALSE ); + QObjectListIterator it( *l ); + insert( i, index ); + for ( ; it.current(); ++it ) { + g = ::qt_cast<QActionGroup*>(it.current()); + if ( g ) { + if ( dropdown ) + i->s->insert( g ); + else + insert( g ); + } else { + i->s->insert( (QAction*)it.current() ); + } + } + delete l; +} + +int PopupMenuEditor::find( const QAction * action ) +{ + PopupMenuEditorItem * i = itemList.first(); + while ( i ) { + if ( i->action() == action ) + return itemList.at(); + i = itemList.next(); + } + return -1; +} + +int PopupMenuEditor::find( PopupMenuEditor * menu ) +{ + PopupMenuEditorItem * i = itemList.first(); + while ( i ) { + if ( i->subMenu() == menu ) + return itemList.at(); + i = itemList.next(); + } + return -1; +} + +int PopupMenuEditor::count() +{ + return itemList.count(); +} + +PopupMenuEditorItem * PopupMenuEditor::at( int index ) +{ + return itemList.at( index ); +} + +void PopupMenuEditor::exchange( int a, int b ) +{ + PopupMenuEditorItem * ia = itemList.at( a ); + PopupMenuEditorItem * ib = itemList.at( b ); + if ( !ia || !ib || + ia == &addItem || ia == &addSeparator || + ib == &addItem || ib == &addSeparator ) + return; // do nothing + itemList.replace( b, ia ); + itemList.replace( a, ib ); +} + +void PopupMenuEditor::cut( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + if ( clipboardItem && clipboardOperation == Cut ) + delete clipboardItem; + + clipboardOperation = Cut; + clipboardItem = itemList.at( idx ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + return; // do nothing + } + + RemoveActionFromPopupCommand * cmd = + new RemoveActionFromPopupCommand( i18n( "Cut Item" ), formWnd, this, idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void PopupMenuEditor::copy( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + if ( clipboardItem && clipboardOperation == Cut ) + delete clipboardItem; + + clipboardOperation = Copy; + clipboardItem = itemList.at( idx ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + } +} + +void PopupMenuEditor::paste( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + if ( clipboardItem && clipboardOperation ) { + PopupMenuEditorItem * n = new PopupMenuEditorItem( clipboardItem, this ); + AddActionToPopupCommand * cmd = + new AddActionToPopupCommand( i18n( "Paste Item" ), formWnd, this, n, idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void PopupMenuEditor::insertedActions( QPtrList<QAction> & list ) +{ + QAction * a = 0; + PopupMenuEditorItem * i = itemList.first(); + + while ( i ) { + a = i->action(); + if ( a ) + list.append( a ); + i = itemList.next(); + } +} + +void PopupMenuEditor::show() +{ + resizeToContents(); + QWidget::show(); +} + +void PopupMenuEditor::choosePixmap( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + PopupMenuEditorItem * i = 0; + QAction * a = 0; + + if ( idx < (int)itemList.count() ) { + i = itemList.at( idx ); + a = i->action(); + } else { + createItem(); + } + + hide(); // qChoosePixmap hides the menu + QIconSet icons( qChoosePixmap( 0, formWnd, 0, 0 ) ); + SetActionIconsCommand * cmd = + new SetActionIconsCommand( i18n( "Set Icon" ), formWnd, a, this, icons ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + show(); + setFocus(); +} + +void PopupMenuEditor::showLineEdit( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + PopupMenuEditorItem * i = 0; + + if ( idx >= (int)itemList.count() ) + i = &addItem; + else + i = itemList.at( idx ); + + // open edit currentField for item name + lineEdit->setText( i->action()->menuText() ); + lineEdit->selectAll(); + lineEdit->setGeometry( borderSize + iconWidth, borderSize + itemPos( i ), + textWidth, itemHeight( i ) ); + lineEdit->show(); + lineEdit->setFocus(); +} + +void PopupMenuEditor::setAccelerator( int key, Qt::ButtonState state, int index ) +{ + // FIXME: make this a command + + int idx = ( index == -1 ? currentIndex : index ); + + if ( key == Qt::Key_Shift || + key == Qt::Key_Control || + key == Qt::Key_Alt || + key == Qt::Key_Meta || + key == Qt::Key_unknown ) + return; // ignore these keys when they are pressed + + PopupMenuEditorItem * i = 0; + + if ( idx >= (int)itemList.count() ) + i = createItem(); + else + i = itemList.at( idx ); + + int shift = ( state & Qt::ShiftButton ? Qt::SHIFT : 0 ); + int ctrl = ( state & Qt::ControlButton ? Qt::CTRL : 0 ); + int alt = ( state & Qt::AltButton ? Qt::ALT : 0 ); + int meta = ( state & Qt::MetaButton ? Qt::META : 0 ); + + QAction * a = i->action(); + QKeySequence ks = a->accel(); + int keys[4] = { ks[0], ks[1], ks[2], ks[3] }; + int n = 0; + while ( n < 4 && ks[n++] ); + n--; + if ( n < 4 ) + keys[n] = key | shift | ctrl | alt | meta; + a->setAccel( QKeySequence( keys[0], keys[1], keys[2], keys[3] ) ); + MetaDataBase::setPropertyChanged( a, "accel", TRUE ); + resizeToContents(); +} + +void PopupMenuEditor::resizeToContents() +{ + QSize s = contentsSize(); + dropLine->resize( s.width(), 2 ); + s.rwidth() += borderSize * 2; + s.rheight() += borderSize * 2; + resize( s ); +} + +void PopupMenuEditor::showSubMenu() +{ + if ( currentIndex < (int)itemList.count() ) { + itemList.at( currentIndex )->showMenu( pos().x() + width() - borderSize * 3, + pos().y() + itemPos( at( currentIndex ) ) + + borderSize * 2 ); + setFocus(); // Keep focus in this widget + } +} + +void PopupMenuEditor::hideSubMenu() +{ + if ( currentIndex < (int)itemList.count() ) + itemList.at( currentIndex )->hideMenu(); +} + +void PopupMenuEditor::focusOnSubMenu() +{ + if ( currentIndex < (int)itemList.count() ) + itemList.at( currentIndex )->focusOnMenu(); +} + +// This function has no undo. It is only here to remove an item when its action was +// removed from the action editor. +// Use removeItem to put the command on the command stack. +void PopupMenuEditor::remove( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + PopupMenuEditorItem * i = itemList.at( idx ); + if ( i && i->isRemovable() ) { + itemList.remove( idx ); + int n = itemList.count() + 1; + if ( currentIndex >= n ) + currentIndex = itemList.count() + 1; + emit removed( i->action() ); + resizeToContents(); + } +} + +PopupMenuEditorItem * PopupMenuEditor::createItem( QAction * a ) +{ + ActionEditor * ae = (ActionEditor *) formWindow()->mainWindow()->child( 0, "ActionEditor" ); + if ( !a ) + a = ae->newActionEx(); + PopupMenuEditorItem * i = new PopupMenuEditorItem( a, this ); + QString n = QString( a->name() ) + "Item"; + formWindow()->unify( i, n, FALSE ); + i->setName( n ); + AddActionToPopupCommand * cmd = + new AddActionToPopupCommand( i18n( "Add Item" ), formWnd, this, i ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + return i; +} + +void PopupMenuEditor::removeItem( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + if ( idx < (int)itemList.count() ) { + RemoveActionFromPopupCommand * cmd = new RemoveActionFromPopupCommand( i18n( "Remove Item" ), + formWnd, + this, + idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + if ( itemList.count() == 0 && parentMenu ) + parentMenu->update(); + resizeToContents(); + } +} + +PopupMenuEditorItem * PopupMenuEditor::currentItem() +{ + int count = itemList.count(); + if ( currentIndex < count ) + return itemList.at( currentIndex ); + else if ( currentIndex == count ) + return &addItem; + return &addSeparator; +} + +PopupMenuEditorItem * PopupMenuEditor::itemAt( int y ) +{ + PopupMenuEditorItem * i = itemList.first(); + int iy = 0; + + while ( i ) { + iy += itemHeight( i ); + if ( iy > y ) + return i; + i = itemList.next(); + } + iy += itemHeight( &addItem ); + if ( iy > y ) + return &addItem; + return &addSeparator; +} + +void PopupMenuEditor::setFocusAt( const QPoint & pos ) +{ + hideSubMenu(); + lineEdit->hide(); + + currentIndex = 0; + int iy = 0; + PopupMenuEditorItem * i = itemList.first(); + + while ( i ) { + iy += itemHeight( i ); + if ( iy > pos.y() ) + break; + i = itemList.next(); + currentIndex++; + } + + iy += itemHeight( &addItem ); + if ( iy <= pos.y() ) + currentIndex++; + + if ( currentIndex < (int)itemList.count() ) { + if ( pos.x() < iconWidth ) + currentField = 0; + else if ( pos.x() < iconWidth + textWidth ) + currentField = 1; + else + currentField = 2; + } else { + currentField = 1; + } + + showSubMenu(); +} + +bool PopupMenuEditor::eventFilter( QObject * o, QEvent * e ) +{ + if ( o == lineEdit && e->type() == QEvent::FocusOut ) { + leaveEditMode( 0 ); + update(); + } + return QWidget::eventFilter( o, e ); +} + +void PopupMenuEditor::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.save(); + QRegion reg( rect() ); + QRegion mid( borderSize, borderSize, + rect().width() - borderSize * 2, rect().height() - borderSize * 2 ); + reg -= mid; + p.setClipRegion( reg ); + style().drawPrimitive( QStyle::PE_PanelPopup, &p, rect(), colorGroup() ); + p.restore(); + drawItems( &p ); +} + +void PopupMenuEditor::mousePressEvent( QMouseEvent * e ) +{ + mousePressPos = e->pos(); + setFocusAt( mousePressPos ); + e->accept(); + update(); +} + +void PopupMenuEditor::mouseDoubleClickEvent( QMouseEvent * ) +{ + setFocusAt( mousePressPos ); + if ( currentItem() == &addSeparator ) { + PopupMenuEditorItem * i = createItem( new QSeparatorAction( 0 ) ); + i->setSeparator( TRUE ); + return; + } + if ( currentField == 0 ) { + choosePixmap(); + resizeToContents(); + } else if ( currentField == 1 ) { + showLineEdit(); + } +} + +void PopupMenuEditor::mouseMoveEvent( QMouseEvent * e ) +{ + if ( e->state() & Qt::LeftButton ) { + if ( ( e->pos() - mousePressPos ).manhattanLength() > 3 ) { + draggedItem = itemAt( mousePressPos.y() ); + if ( draggedItem == &addItem ) { + draggedItem = createItem(); + RenameActionCommand cmd( i18n( "Rename Item" ), formWnd, draggedItem->action(), + this, "Unnamed" ); + cmd.execute(); + // FIXME: start rename after drop + } else if ( draggedItem == &addSeparator ) { + draggedItem = createItem( new QSeparatorAction( 0 ) ); + draggedItem->setSeparator( TRUE ); + } + + PopupMenuEditorItemPtrDrag * d = + new PopupMenuEditorItemPtrDrag( draggedItem, this ); + + hideSubMenu(); + + draggedItem->setVisible( FALSE ); + resizeToContents(); + + // If the item is dropped in the same list, + // we will have two instances of the same pointer + // in the list. We use node instead. + int idx = itemList.find( draggedItem ); + QLNode * node = itemList.currentNode(); + + d->dragCopy(); // dragevents and stuff happens + + if ( draggedItem ) { // item was not dropped + draggedItem->setVisible( TRUE ); + draggedItem = 0; + if ( hasFocus() ) { + hideSubMenu(); + resizeToContents(); + showSubMenu(); + } + } else { // item was dropped + itemList.takeNode( node )->setVisible( TRUE ); + if ( currentIndex > 0 && currentIndex > idx ) + --currentIndex; + // the drop might happen in another menu, so we'll resize + // and show the submenu there + } + } + } +} + +void PopupMenuEditor::dragEnterEvent( QDragEnterEvent * e ) +{ + if ( e->provides( "qt/popupmenueditoritemptr" ) || + e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-actiongroup" ) ) { + e->accept(); + dropLine->show(); + } +} + +void PopupMenuEditor::dragLeaveEvent( QDragLeaveEvent * ) +{ + dropLine->hide(); +} + +void PopupMenuEditor::dragMoveEvent( QDragMoveEvent * e ) +{ + QPoint pos = e->pos(); + dropLine->move( borderSize, snapToItem( pos.y() ) ); + + if ( currentItem() != itemAt( pos.y() ) ) { + hideSubMenu(); + setFocusAt( pos ); + showSubMenu(); + } +} + +void PopupMenuEditor::dropEvent( QDropEvent * e ) +{ + if ( !( e->provides( "qt/popupmenueditoritemptr" ) || + e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-actiongroup" ) ) ) + return; + + // Hide the sub menu of the current item, but do it later + if ( currentIndex < (int)itemList.count() ) { + PopupMenuEditor *s = itemList.at( currentIndex )->s; + QTimer::singleShot( 0, s, SLOT( hide() ) ); + } + + draggedItem = 0; + PopupMenuEditorItem * i = 0; + + if ( e->provides( "qt/popupmenueditoritemptr" ) ) { + PopupMenuEditorItemPtrDrag::decode( e, &i ); + } else { + if ( e->provides( "application/x-designer-actiongroup" ) ) { + QActionGroup * g = ::qt_cast<QDesignerActionGroup*>(ActionDrag::action()); + if ( g->usesDropDown() ) { + i = new PopupMenuEditorItem( g, this ); + QString n = QString( g->name() ) + "Item"; + formWindow()->unify( i, n, FALSE ); + i->setName( n ); + QObjectList *l = g->queryList( "QAction", 0, FALSE, FALSE ); + QObjectListIterator it( *l ); + for ( ; it.current(); ++it ) { + g = ::qt_cast<QActionGroup*>(it.current()); + if ( g ) + i->s->insert( g ); + else + i->s->insert( (QAction*)it.current() ); + } + delete l; + } else { + dropInPlace( g, e->pos().y() ); + } + } else if ( e->provides( "application/x-designer-actions" ) ) { + QAction *a = ::qt_cast<QDesignerAction*>(ActionDrag::action()); + i = new PopupMenuEditorItem( a, this ); + } + } + + if ( i ) { + dropInPlace( i, e->pos().y() ); + QTimer::singleShot( 0, this, SLOT( resizeToContents() ) ); + } + + QTimer::singleShot( 0, this, SLOT( showSubMenu() ) ); + QTimer::singleShot( 0, this, SLOT( setFocus() ) ); + dropLine->hide(); + e->accept(); +} + +void PopupMenuEditor::keyPressEvent( QKeyEvent * e ) +{ + if ( lineEdit->isHidden() ) { // In navigation mode + + switch ( e->key() ) { + + case Qt::Key_Delete: + hideSubMenu(); + removeItem(); + showSubMenu(); + break; + + case Qt::Key_Backspace: + clearCurrentField(); + break; + + case Qt::Key_Up: + navigateUp( e->state() & Qt::ControlButton ); + break; + + case Qt::Key_Down: + navigateDown( e->state() & Qt::ControlButton ); + break; + + case Qt::Key_Left: + navigateLeft(); + break; + + case Qt::Key_Right: + navigateRight(); + break; + + case Qt::Key_PageUp: + currentIndex = 0; + break; + + case Qt::Key_PageDown: + currentIndex = itemList.count(); + break; + + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_F2: + enterEditMode( e ); + // move on + case Qt::Key_Alt: + case Qt::Key_Shift: + case Qt::Key_Control: + // do nothing + return; + + case Qt::Key_Escape: + currentField = 0; + navigateLeft(); + break; + + case Qt::Key_C: + if ( e->state() & Qt::ControlButton && + currentIndex < (int)itemList.count() ) { + copy( currentIndex ); + break; + } + + case Qt::Key_X: + if ( e->state() & Qt::ControlButton && + currentIndex < (int)itemList.count() ) { + hideSubMenu(); + cut( currentIndex ); + showSubMenu(); + break; + } + + case Qt::Key_V: + if ( e->state() & Qt::ControlButton ) { + hideSubMenu(); + paste( currentIndex < (int)itemList.count() ? currentIndex + 1: itemList.count() ); + showSubMenu(); + break; + } + + default: + if ( currentItem()->isSeparator() ) + return; + if ( currentField == 1 ) { + showLineEdit(); + QApplication::sendEvent( lineEdit, e ); + e->accept(); + return; + } else if ( currentField == 2 ) { + setAccelerator( e->key(), e->state() ); + showSubMenu(); + } + break; + + } + + } else { // In edit mode + switch ( e->key() ) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + leaveEditMode( e ); + e->accept(); + return; + } + } + update(); +} + +void PopupMenuEditor::focusInEvent( QFocusEvent * ) +{ + showSubMenu(); + update(); + parentMenu->update(); +} + +void PopupMenuEditor::focusOutEvent( QFocusEvent * ) +{ + QWidget * fw = qApp->focusWidget(); + if ( !fw || ( !::qt_cast<PopupMenuEditor*>(fw) && fw != lineEdit ) ) { + hideSubMenu(); + if ( fw && ::qt_cast<MenuBarEditor*>(fw) ) + return; + QWidget * w = this; + while ( w && w != fw && ::qt_cast<PopupMenuEditor*>(w) ) { // hide all popups + w->hide(); + w = ((PopupMenuEditor *)w)->parentEditor(); + } + } +} + +void PopupMenuEditor::drawItem( QPainter * p, PopupMenuEditorItem * i, + const QRect & r, int f ) const +{ + int x = r.x(); + int y = r.y(); + int h = r.height(); + + p->fillRect( r, colorGroup().brush( QColorGroup::Background ) ); + + if ( i->isSeparator() ) { + style().drawPrimitive( QStyle::PE_Separator, p, + QRect( r.x(), r.y() + 2, r.width(), 1 ), + colorGroup(), QStyle::Style_Sunken | f ); + return; + } + + const QAction * a = i->action(); + if ( a->isToggleAction() && a->isOn() ) { + style().drawPrimitive( QStyle::PE_CheckMark, p, + QRect( x , y, iconWidth, h ), + colorGroup(), f ); + } else { + QPixmap icon = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ); + p->drawPixmap( x + ( iconWidth - icon.width() ) / 2, + y + ( h - icon.height() ) / 2, + icon ); + } + x += iconWidth; + p->drawText( x, y, textWidth, h, + QPainter::AlignLeft | + QPainter::AlignVCenter | + Qt::ShowPrefix | + Qt::SingleLine, + a->menuText() ); + + x += textWidth + borderSize * 3; + p->drawText( x, y, accelWidth, h, + QPainter::AlignLeft | QPainter::AlignVCenter, + a->accel() ); + if ( i->count() ) // Item has submenu + style().drawPrimitive( QStyle::PE_ArrowRight, p, + QRect( r.width() - arrowWidth, r.y(), arrowWidth, r.height() ), + colorGroup(), f ); +} + +void PopupMenuEditor::drawWinFocusRect( QPainter * p, const QRect & r ) const +{ + if ( currentIndex < (int)itemList.count() && + ((PopupMenuEditor*)this)->itemList.at( currentIndex )->isSeparator() ) { + p->drawWinFocusRect( borderSize, r.y(), width() - borderSize * 2, r.height() ); + return; + } + int y = r.y(); + int h = r.height(); + if ( currentField == 0 ) + p->drawWinFocusRect( borderSize + 1, y, iconWidth - 2, h ); + else if ( currentField == 1 ) + p->drawWinFocusRect( borderSize + iconWidth, y, textWidth, h ); + else if ( currentField == 2 ) + p->drawWinFocusRect( borderSize + iconWidth + textWidth + + borderSize * 3, y, accelWidth, h ); +} + +void PopupMenuEditor::drawItems( QPainter * p ) +{ + int flags = 0; + int idx = 0; + + QColorGroup enabled = colorGroup(); + QColorGroup disabled = palette().disabled(); + QRect focus; + QRect rect( borderSize, borderSize, width() - borderSize * 2, 0 ); + + PopupMenuEditorItem * i = itemList.first(); + while ( i ) { + if ( i->isVisible() ) { + rect.setHeight( itemHeight( i ) ); + if ( idx == currentIndex ) + focus = rect; + if ( i->action()->isEnabled() ) { + flags = QStyle::Style_Enabled; + p->setPen( enabled.buttonText() ); + } else { + flags = QStyle::Style_Default; + p->setPen( disabled.buttonText() ); + } + drawItem( p, i, rect, flags ); + rect.moveBy( 0, rect.height() ); + } + i = itemList.next(); + idx++; + } + + // Draw the "add item" and "add separator" items + p->setPen( darkBlue ); + rect.setHeight( itemHeight( &addItem ) ); + if ( idx == currentIndex ) + focus = rect; + drawItem( p, &addItem, rect, QStyle::Style_Default ); + rect.moveBy( 0, rect.height() ); + idx++; + rect.setHeight( itemHeight( &addSeparator ) ); + if ( idx == currentIndex ) + focus = rect; + drawItem( p, &addSeparator, rect, QStyle::Style_Default ); + idx++; + + if ( hasFocus() && !draggedItem ) + drawWinFocusRect( p, focus ); +} + +QSize PopupMenuEditor::contentsSize() +{ + QRect textRect = fontMetrics().boundingRect( addSeparator.action()->menuText() ); + textWidth = textRect.width(); + accelWidth = textRect.height(); // default size + iconWidth = textRect.height(); + + int w = 0; + int h = itemHeight( &addItem ) + itemHeight( &addSeparator ); + PopupMenuEditorItem * i = itemList.first(); + QAction * a = 0; + while ( i ) { + if ( i->isVisible() ) { + if ( !i->isSeparator() ) { + a = i->action(); + w = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ).rect().width() + + borderSize; // padding + iconWidth = QMAX( iconWidth, w ); + w = fontMetrics().boundingRect( a->menuText() ).width(); + textWidth = QMAX( textWidth, w ); + w = fontMetrics().boundingRect( a->accel() ).width() + 2; // added padding? + accelWidth = QMAX( accelWidth, w ); + } + h += itemHeight( i ); + } + i = itemList.next(); + } + + int width = iconWidth + textWidth + borderSize * 3 + accelWidth + arrowWidth; + return QSize( width, h ); +} + +int PopupMenuEditor::itemHeight( const PopupMenuEditorItem * item ) const +{ + if ( !item || ( item && !item->isVisible() ) ) + return 0; + if ( item->isSeparator() ) + return 4; // FIXME: hardcoded ( get from styles )r + int padding = + borderSize * 6; + QAction * a = item->action(); + int h = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ).rect().height(); + h = QMAX( h, fontMetrics().boundingRect( a->menuText() ).height() + padding ); + h = QMAX( h, fontMetrics().boundingRect( a->accel() ).height() + padding ); + return h; +} + +int PopupMenuEditor::itemPos( const PopupMenuEditorItem * item ) const +{ + PopupMenuEditor * that = ( PopupMenuEditor * ) this; + int y = 0; + PopupMenuEditorItem * i = that->itemList.first(); + while ( i ) { + if ( i == item ) + return y; + y += itemHeight( i ); + i = that->itemList.next(); + } + return y; +} + +int PopupMenuEditor::snapToItem( int y ) +{ + int iy = 0; + int dy = 0; + + PopupMenuEditorItem * i = itemList.first(); + + while ( i ) { + dy = itemHeight( i ); + if ( iy + dy / 2 > y ) + return iy; + iy += dy; + i = itemList.next(); + } + + return iy; +} + +void PopupMenuEditor::dropInPlace( PopupMenuEditorItem * i, int y ) +{ + int iy = 0; + int dy = 0; + int idx = 0; + + PopupMenuEditorItem * n = itemList.first(); + + while ( n ) { + dy = itemHeight( n ); + if ( iy + dy / 2 > y ) + break; + iy += dy; + idx++; + n = itemList.next(); + } + int same = itemList.findRef( i ); + AddActionToPopupCommand * cmd = new AddActionToPopupCommand( i18n( "Drop Item" ), formWnd, this, i, idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + currentIndex = ( same >= 0 && same < idx ) ? idx - 1 : idx; + currentField = 1; +} + +void PopupMenuEditor::dropInPlace( QActionGroup * g, int y ) +{ + if (!g->children()) + return; + QObjectList l = *g->children(); + for ( int i = 0; i < (int)l.count(); ++i ) { + QAction *a = ::qt_cast<QAction*>(l.at(i)); + QActionGroup *g = ::qt_cast<QActionGroup*>(l.at(i)); + if ( g ) + dropInPlace( g, y ); + else if ( a ) + dropInPlace( new PopupMenuEditorItem( a, this ), y ); + } +} + +void PopupMenuEditor::safeDec() +{ + do { + currentIndex--; + } while ( currentIndex > 0 && !currentItem()->isVisible() ); + if ( currentIndex == 0 && + !currentItem()->isVisible() && + parentMenu ) { + parentMenu->setFocus(); + } +} + +void PopupMenuEditor::safeInc() +{ + int max = itemList.count() + 1; + if ( currentIndex < max ) { + do { + currentIndex++; + } while ( currentIndex < max && !currentItem()->isVisible() ); // skip invisible items + } +} + +void PopupMenuEditor::clearCurrentField() +{ + if ( currentIndex >= (int)itemList.count() ) + return; // currentIndex is addItem or addSeparator + PopupMenuEditorItem * i = currentItem(); + hideSubMenu(); + if ( i->isSeparator() ) + return; + if ( currentField == 0 ) { + QIconSet icons( 0 ); + SetActionIconsCommand * cmd = new SetActionIconsCommand( i18n( "Remove Icon" ), + formWnd, + i->action(), + this, + icons ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( currentField == 2 ) { + i->action()->setAccel( 0 ); + } + resizeToContents(); + showSubMenu(); + return; +} + +void PopupMenuEditor::navigateUp( bool ctrl ) +{ + if ( currentIndex > 0 ) { + hideSubMenu(); + if ( ctrl ) { + ExchangeActionInPopupCommand * cmd = + new ExchangeActionInPopupCommand( i18n( "Move Item Up" ), + formWnd, + this, + currentIndex, + currentIndex - 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeDec(); + } else { + safeDec(); + } + showSubMenu(); + } else if ( parentMenu ) { + parentMenu->setFocus(); + parentMenu->update(); + } +} + +void PopupMenuEditor::navigateDown( bool ctrl ) +{ + hideSubMenu(); + if ( ctrl ) { + if ( currentIndex < ( (int)itemList.count() - 1 ) ) { // safe index + ExchangeActionInPopupCommand * cmd = + new ExchangeActionInPopupCommand( i18n( "Move Item Down" ), + formWnd, + this, + currentIndex, + currentIndex + 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeInc(); + } + } else { // ! Ctrl + safeInc(); + } + if ( currentIndex >= (int)itemList.count() ) + currentField = 1; + showSubMenu(); +} + +void PopupMenuEditor::navigateLeft() +{ + if ( currentItem()->isSeparator() || + currentIndex >= (int)itemList.count() || + currentField == 0 ) { + if ( parentMenu ) { + hideSubMenu(); + parentMenu->setFocus(); + } else if ( !currentItem()->isSeparator() ) { + currentField = 2; + } + } else { + currentField--; + } +} + +void PopupMenuEditor::navigateRight() +{ + if ( !currentItem()->isSeparator() && + currentIndex < (int)itemList.count() ) { + if ( currentField == 2 ) { + focusOnSubMenu(); + } else { + currentField++; + currentField %= 3; + } + } +} + +void PopupMenuEditor::enterEditMode( QKeyEvent * e ) +{ + PopupMenuEditorItem * i = currentItem(); + + if ( i == &addSeparator ) { + i = createItem( new QSeparatorAction( 0 ) ); + } else if ( i->isSeparator() ) { + return; + } else if ( currentField == 0 ) { + choosePixmap(); + } else if ( currentField == 1 ) { + showLineEdit(); + return; + } else {// currentField == 2 + setAccelerator( e->key(), e->state() ); + } + showSubMenu(); + return; +} + +void PopupMenuEditor::leaveEditMode( QKeyEvent * e ) +{ + setFocus(); + lineEdit->hide(); + + PopupMenuEditorItem * i = 0; + if ( e && e->key() == Qt::Key_Escape ) { + update(); + return; + } + + if ( currentIndex >= (int)itemList.count() ) { + // new item was created + QAction * a = formWnd->mainWindow()->actioneditor()->newActionEx(); + QString actionText = lineEdit->text(); + actionText.replace("&&", "&"); + QString menuText = lineEdit->text(); + a->setText( actionText ); + a->setMenuText( menuText ); + i = createItem( a ); + QString n = constructName( i ); + formWindow()->unify( a, n, TRUE ); + a->setName( n ); + MetaDataBase::addEntry( a ); + MetaDataBase::setPropertyChanged( a, "menuText", TRUE ); + ActionEditor *ae = (ActionEditor*)formWindow()->mainWindow()->child( 0, "ActionEditor" ); + if ( ae ) + ae->updateActionName( a ); + } else { + i = itemList.at( currentIndex ); + RenameActionCommand * cmd = new RenameActionCommand( i18n( "Rename Item" ), + formWnd, + i->action(), + this, + lineEdit->text() ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + resizeToContents(); + + if ( !i ) + return; + + if ( i->isSeparator() ) + hideSubMenu(); + else + showSubMenu(); +} + +QString PopupMenuEditor::constructName( PopupMenuEditorItem *item ) +{ + QString s; + QString name = item->action()->menuText(); + QWidget *e = parentEditor(); + PopupMenuEditor *p = ::qt_cast<PopupMenuEditor*>(e); + if ( p ) { + int idx = p->find( item->m ); + PopupMenuEditorItem * i = ( idx > -1 ? p->at( idx ) : 0 ); + s = ( i ? QString( i->action()->name() ).remove( "Action" ) : QString( "" ) ); + } else { + MenuBarEditor *b = ::qt_cast<MenuBarEditor*>(e); + if ( b ) { + int idx = b->findItem( item->m ); + MenuBarEditorItem * i = ( idx > -1 ? b->item( idx ) : 0 ); + s = ( i ? i->menuText().lower() : QString( "" ) ); + } + } + // replace illegal characters + + return ( RenameMenuCommand::makeLegal( s ) + + RenameMenuCommand::makeLegal( name ) + "Action" ); +} diff --git a/kdevdesigner/designer/popupmenueditor.h b/kdevdesigner/designer/popupmenueditor.h new file mode 100644 index 00000000..ca14205b --- /dev/null +++ b/kdevdesigner/designer/popupmenueditor.h @@ -0,0 +1,235 @@ +/********************************************************************** +** Copyright (C) 2003 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 POPUPMENUEDITOR_H +#define POPUPMENUEDITOR_H + +#include <qwidget.h> +#include <qptrlist.h> +#include <qaction.h> + +class PopupMenuEditor; +class QMenuItem; + +class PopupMenuEditorItem : public QObject +{ + Q_OBJECT + + friend class PopupMenuEditor; + + PopupMenuEditorItem( PopupMenuEditor * menu = 0, QObject * parent = 0, const char * name = 0 ); + +public: + enum ItemType { + Unknown = -1, + Separator = 0, + Action = 1 + }; + + PopupMenuEditorItem( QAction * action, PopupMenuEditor * menu, + QObject * parent = 0, const char * name = 0 ); + PopupMenuEditorItem( PopupMenuEditorItem * item, PopupMenuEditor * menu, + QObject * parent = 0, const char * name = 0 ); + ~PopupMenuEditorItem(); + + void init(); + + ItemType type() const; + QAction * action() const { return a; } + + void setVisible( bool enable ); + bool isVisible() const; + + void setSeparator( bool enable ) { separator = enable; } + bool isSeparator() const { return separator; } + + void setRemovable( bool enable ) { removable = enable; } + bool isRemovable() const { return removable; } + + void showMenu( int x, int y ); + void hideMenu(); + void focusOnMenu(); + PopupMenuEditor * subMenu() const { return s; } + + int count() const; + + bool eventFilter( QObject *, QEvent * event ); + +public slots: + void selfDestruct(); + +protected: + +private: + QAction * a; + PopupMenuEditor * s; + PopupMenuEditor * m; + uint separator : 1; + uint removable : 1; +}; + +class FormWindow; +class MainWindow; +class QLineEdit; + +#include <qpopupmenu.h> + +class PopupMenuEditor : public QWidget +{ + Q_OBJECT + + friend class PopupMenuEditorItem; + friend class MenuBarEditor; + friend class Resource; + +public: + PopupMenuEditor( FormWindow * fw, QWidget * parent = 0, const char * name = 0 ); + PopupMenuEditor( FormWindow * fw, PopupMenuEditor * menu, QWidget * parent, const char * name = 0 ); + ~PopupMenuEditor(); + + void init(); + + void insert( PopupMenuEditorItem * item, int index = -1 ); + void insert( QAction * action, int index = -1 ); + void insert( QActionGroup * actionGroup, int index = -1 ); + int find( const QAction * action ); + int find( PopupMenuEditor * menu ); + int count(); + PopupMenuEditorItem * at( int index ); + PopupMenuEditorItem * at( QPoint pos ) { return itemAt( pos.y() ); } + void exchange( int a, int b ); + + void cut( int index ); + void copy( int index ); + void paste( int index ); + + void insertedActions( QPtrList<QAction> & list ); + + void show(); + void choosePixmap( int index = -1 ); + void showLineEdit( int index = -1); + void setAccelerator( int key, Qt::ButtonState state, int index = -1 ); + + FormWindow * formWindow() { return formWnd; } + bool isCreatingAccelerator() { return ( currentField == 2 ); } + + QPtrList<PopupMenuEditorItem> * items() { return &itemList; } + + QWidget * parentEditor() { return parentMenu; } + +signals: + void inserted( QAction * ); + void removed( QAction * ); + +public slots: + + void cut() { cut( currentIndex ); } + void copy() { copy( currentIndex ); } + void paste() { paste( currentIndex ); } + + void remove( int index ); + void remove( QAction * a ) { remove( find( a ) ); } + + void resizeToContents(); + void showSubMenu(); + void hideSubMenu(); + void focusOnSubMenu(); + +protected: + PopupMenuEditorItem * createItem( QAction * a = 0 ); + void removeItem( int index = -1 ); + PopupMenuEditorItem * currentItem(); + PopupMenuEditorItem * itemAt( int y ); + void setFocusAt( const QPoint & pos ); + + bool eventFilter( QObject * o, QEvent * e ); + void paintEvent( QPaintEvent * e ); + void mousePressEvent( QMouseEvent * e ); + void mouseDoubleClickEvent( QMouseEvent * e ); + void mouseMoveEvent( QMouseEvent * e ); + void dragEnterEvent( QDragEnterEvent * e ); + void dragLeaveEvent( QDragLeaveEvent * e ); + void dragMoveEvent( QDragMoveEvent * e ); + void dropEvent( QDropEvent * e ); + void keyPressEvent( QKeyEvent * e ); + void focusInEvent( QFocusEvent * e ); + void focusOutEvent( QFocusEvent * e ); + + void drawItems( QPainter * p ); + void drawItem( QPainter * p, PopupMenuEditorItem * i, const QRect & r, int f ) const; + void drawWinFocusRect( QPainter * p, const QRect & r ) const; + + QSize contentsSize(); + int itemHeight( const PopupMenuEditorItem * item ) const; + int itemPos( const PopupMenuEditorItem * item ) const; + + int snapToItem( int y ); + void dropInPlace( PopupMenuEditorItem * i, int y ); + void dropInPlace( QActionGroup * g, int y ); + + void safeDec(); + void safeInc(); + + void clearCurrentField(); + void navigateUp( bool ctrl ); + void navigateDown( bool ctrl ); + void navigateLeft(); + void navigateRight(); + void enterEditMode( QKeyEvent * e ); + void leaveEditMode( QKeyEvent * e ); + + QString constructName( PopupMenuEditorItem *item ); + +private: + FormWindow * formWnd; + QLineEdit * lineEdit; + QWidget * dropLine; + QPtrList<PopupMenuEditorItem> itemList; + PopupMenuEditorItem addItem; + PopupMenuEditorItem addSeparator; + QWidget * parentMenu; + + int iconWidth; + int textWidth; + int accelWidth; + int arrowWidth; + int borderSize; + + int currentField; + int currentIndex; + QPoint mousePressPos; + static PopupMenuEditorItem * draggedItem; + + enum ClipboardOperation { + None = 0, + Cut = 1, + Copy = 2 + }; + static int clipboardOperation; + static PopupMenuEditorItem * clipboardItem; +}; + +#endif //POPUPMENUEDITOR_H diff --git a/kdevdesigner/designer/preferences.ui b/kdevdesigner/designer/preferences.ui new file mode 100644 index 00000000..58cc7def --- /dev/null +++ b/kdevdesigner/designer/preferences.ui @@ -0,0 +1,648 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>Preferences</class> +<comment>********************************************************************* +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>Preferences</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>482</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Preferences</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Preferences</b><p>Change the preferences of Qt Designer. There is always one tab with general preferences. There may be additional tabs, depending on which plugins are installed.</p></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>pageGeneral</cstring> + </property> + <attribute name="title"> + <string>General</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="1" column="1"> + <property name="name"> + <cstring>groupBox4</cstring> + </property> + <property name="title"> + <string>File Saving</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxAutoSave</cstring> + </property> + <property name="text"> + <string>Enable auto sa&ve</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabelAutoSave</cstring> + </property> + <property name="text"> + <string>Auto save &interval:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>timeEditAutoSave</cstring> + </property> + </widget> + <widget class="QTimeEdit"> + <property name="name"> + <cstring>timeEditAutoSave</cstring> + </property> + <property name="time"> + <time> + <hour>0</hour> + <minute>30</minute> + <second>0</second> + </time> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>buttonGroup2</cstring> + </property> + <property name="title"> + <string>Plu&gin Paths</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTextEdit"> + <property name="name"> + <cstring>textEditPluginPaths</cstring> + </property> + </widget> + </hbox> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + <property name="whatsThis" stdset="0"> + <string>A splash screen is displayed when starting Qt Designer if this option is checked.</string> + </property> + </spacer> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>GroupBox5</cstring> + </property> + <property name="title"> + <string>Ge&neral</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxWorkspace</cstring> + </property> + <property name="text"> + <string>Restore last &workspace on startup</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Restore last workspace</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The current workspace settings will be restored the next time you start Qt Designer if this option is checked.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxSplash</cstring> + </property> + <property name="text"> + <string>Show &splash screen on startup</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Show Splashscreen</string> + </property> + <property name="whatsThis" stdset="0"> + <string>A splash screen is displayed when starting Qt Designer if this option is checked.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxStartDialog</cstring> + </property> + <property name="text"> + <string>Show start &dialog</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkAutoEdit</cstring> + </property> + <property name="text"> + <string>Disable data&base auto-edit in preview</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxTextLabels</cstring> + </property> + <property name="text"> + <string>Show toolbutton lab&els</string> + </property> + <property name="toolTip" stdset="0"> + <string>Text Labels</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Text labels will be used in the toolbars if this is checked.</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QGroupBox" row="0" column="1"> + <property name="name"> + <cstring>groupBoxGrid</cstring> + </property> + <property name="title"> + <string>G&rid</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxSnapGrid</cstring> + </property> + <property name="text"> + <string>Sn&ap to grid</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Snap to the grid</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Customize the grid-settings for all forms.</b><p>When <b>Snap to Grid</b> is checked, the widgets snap to the grid using the the X/Y resolution.</p></string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QSpinBox" row="0" column="1"> + <property name="name"> + <cstring>spinGridX</cstring> + </property> + <property name="maxValue"> + <number>50</number> + </property> + <property name="minValue"> + <number>5</number> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="toolTip" stdset="0"> + <string>Grid resolution</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Customize the grid-settings for all forms.</b><p>When <b>Show Grid</b> is checked, a grid is shown on all forms using the X/Y resolution.</p></string> + </property> + </widget> + <widget class="QSpinBox" row="1" column="1"> + <property name="name"> + <cstring>spinGridY</cstring> + </property> + <property name="maxValue"> + <number>50</number> + </property> + <property name="minValue"> + <number>5</number> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="toolTip" stdset="0"> + <string>Grid resolution</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Customize the grid-settings for all forms.</b><p>When <b>Show Grid</b> is checked, a grid is shown on all forms using the X/Y resolution.</p></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>Label1</cstring> + </property> + <property name="text"> + <string>Grid-&X:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinGridX</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label1_2</cstring> + </property> + <property name="text"> + <string>Grid-&Y:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinGridY</cstring> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>Backgro&und</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="StyledButton" row="0" column="1"> + <property name="name"> + <cstring>buttonColor</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Choose a color</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Select a color in the color dialog.</string> + </property> + </widget> + <widget class="QRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioColor</cstring> + </property> + <property name="focusPolicy"> + <enum>NoFocus</enum> + </property> + <property name="text"> + <string>Co&lor</string> + </property> + <property name="toolTip" stdset="0"> + <string>Use a background color</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Use a background color.</string> + </property> + </widget> + <widget class="QRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioPixmap</cstring> + </property> + <property name="text"> + <string>&Pixmap</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Use a background pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Use a background pixmap.</string> + </property> + </widget> + <widget class="StyledButton" row="1" column="1"> + <property name="name"> + <cstring>buttonPixmap</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="scale" stdset="0"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Select a pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Choose a pixmap file.</string> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>helpButton</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>false</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>StyledButton</class> + <header location="local">styledbutton.h</header> + <sizehint> + <width>40</width> + <height>25</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>"image0"</pixmap> + <signal>clicked()</signal> + <signal>changed()</signal> + <property type="Color">color</property> + <property type="Pixmap">pixmap</property> + <property type="Bool">scale</property> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="1112">789c9dd2cb8e9b301406e07d9e0225bba89a09601350d505302c5b7559a9eac23e6672b363620c0ca9faeef53949da2e2a55eab123f9e38f2f217e5e475f3e7f8cd6cf8bde0b7f8008f6c2456b3518337ffdf6e1fb62992451e8691ac5cb778be55304d1277b6e71fc12c6ab0d157222e61bd8e4c812196f6216535a13f318624a6764b2495842e99558249014c81e99c6294b69d3376291424ae9806431638cd28628183081f4489e70ce13e4852878c129ad905992f18cd291283295517a466ed32ddfa64847945bb595c80e99a739cf29d54499ab9c528b2c58c10b86344428540148400a26b8a0541241b482d215523299494a0551c9562ae409091c32e0c82351410b942aa4e22a53941e882d36e41ed966d8903b2215f215f99a6143b6442afaafff5aff485658622584a091941256948443d1cabbdd6ebf3f28753c09a9e9cdc1fe703c9e4ea19f689a0430fa4c8908082be093d08d016bbb0bbd5e7ceafade5b30de19d083b3fa9e008cd39b9fafd69495b473af7fcfb15325c1d61eea0afaf005ddf97b5295c658a866338f97591babef7340fa396c6c5ca9e7fe650807d0bf566b4262299986ba335a3b4a2cc84b69ac85b1b673037d8fabf95b023a9c09cc7530e104dd5419ed6e27083fb09a7c752db5a9bd31cde4ec634ed8a39aebbe337618c3f6fdc5dee6d8b0bb0d6b5b8b1fad43d78fe4e14e3f6aace8e29d9d736777fea3c686eee0138c9726d4d00c548df7a315ff750f7ebc5ffc04a0e5308d</data> + </image> +</images> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>Preferences</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>Preferences</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>radioColor</sender> + <signal>toggled(bool)</signal> + <receiver>buttonColor</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>radioPixmap</sender> + <signal>toggled(bool)</signal> + <receiver>buttonPixmap</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>tabWidget</tabstop> + <tabstop>radioColor</tabstop> + <tabstop>radioPixmap</tabstop> + <tabstop>buttonColor</tabstop> + <tabstop>buttonPixmap</tabstop> + <tabstop>checkBoxSnapGrid</tabstop> + <tabstop>spinGridX</tabstop> + <tabstop>spinGridY</tabstop> + <tabstop>checkBoxWorkspace</tabstop> + <tabstop>checkBoxSplash</tabstop> + <tabstop>checkBoxStartDialog</tabstop> + <tabstop>checkAutoEdit</tabstop> + <tabstop>checkBoxTextLabels</tabstop> + <tabstop>helpButton</tabstop> +</tabstops> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>styledbutton.h</includehint> + <includehint>styledbutton.h</includehint> +</includehints> +</UI> diff --git a/kdevdesigner/designer/previewframe.cpp b/kdevdesigner/designer/previewframe.cpp new file mode 100644 index 00000000..2d14fb7b --- /dev/null +++ b/kdevdesigner/designer/previewframe.cpp @@ -0,0 +1,57 @@ +/********************************************************************** +** 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 <qvbox.h> +#include <qpainter.h> + +#include "previewframe.h" + +PreviewFrame::PreviewFrame( QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + setMinimumSize(200, 200); + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + setLineWidth(1); + + PreviewWorkspace * w = new PreviewWorkspace( this ); + w->setEraseColor(colorGroup().dark()); + previewWidget = new PreviewWidget( w ); + previewWidget->move( 10, 10 ); +} + +void PreviewFrame::setPreviewPalette(QPalette pal) +{ + previewWidget->setPalette(pal); +} + +void PreviewWorkspace::paintEvent( QPaintEvent* ) +{ + QPainter p ( this ); + p.setPen( QPen( white ) ); + p.drawText ( 0, height() / 2, width(), height(), AlignHCenter, + "The moose in the noose\nate the goose who was loose." ); +} + diff --git a/kdevdesigner/designer/previewframe.h b/kdevdesigner/designer/previewframe.h new file mode 100644 index 00000000..632e8b9a --- /dev/null +++ b/kdevdesigner/designer/previewframe.h @@ -0,0 +1,59 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PREVIEWFRAME_H +#define PREVIEWFRAME_H + +#include <qvbox.h> +#include <qworkspace.h> + +#include "previewwidgetimpl.h" + +class PreviewWorkspace : public QWorkspace +{ + Q_OBJECT +public: + PreviewWorkspace( QWidget* parent = 0, const char* name = 0 ) + : QWorkspace( parent, name ) {} + ~PreviewWorkspace() {} + +protected: + void paintEvent( QPaintEvent* ); +}; + +class PreviewFrame : public QVBox +{ + Q_OBJECT + +public: + PreviewFrame( QWidget *parent = 0, const char *name = 0 ); + void setPreviewPalette(QPalette); + +private: + PreviewWidget *previewWidget; +}; + +#endif diff --git a/kdevdesigner/designer/previewwidget.ui b/kdevdesigner/designer/previewwidget.ui new file mode 100644 index 00000000..f297d2d4 --- /dev/null +++ b/kdevdesigner/designer/previewwidget.ui @@ -0,0 +1,304 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>PreviewWidgetBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QWidget"> + <property name="name"> + <cstring>PreviewWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>378</width> + <height>236</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property name="caption"> + <string>Preview Window</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout17</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>ButtonGroup</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>RadioButton1</cstring> + </property> + <property name="text"> + <string>RadioButton1</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>RadioButton2</cstring> + </property> + <property name="text"> + <string>RadioButton2</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>RadioButton3</cstring> + </property> + <property name="text"> + <string>RadioButton3</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>ButtonGroup2</cstring> + </property> + <property name="title"> + <string>ButtonGroup2</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>CheckBox1</cstring> + </property> + <property name="text"> + <string>CheckBox1</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>CheckBox2</cstring> + </property> + <property name="text"> + <string>CheckBox2</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QProgressBar"> + <property name="name"> + <cstring>ProgressBar1</cstring> + </property> + <property name="progress"> + <number>50</number> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>LineEdit1</cstring> + </property> + <property name="text"> + <string>LineEdit</string> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>ComboBox</string> + </property> + </item> + <property name="name"> + <cstring>ComboBox1</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout13</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>SpinBox1</cstring> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QScrollBar"> + <property name="name"> + <cstring>ScrollBar1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QSlider"> + <property name="name"> + <cstring>Slider1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QTextView"> + <property name="name"> + <cstring>textView</cstring> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>50</height> + </size> + </property> + <property name="text"> + <string><p> +<a href="http://www.trolltech.com/">http://www.trolltech.com</a> +</p> +<p> +<a href="http://www.kde.org/">http://www.kde.org</a> +</p></string> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<connections> + <slot access="protected" language="C++" returnType="void">init()</slot> + <slot access="protected" language="C++" returnType="void">destroy()</slot> +</connections> +</UI> diff --git a/kdevdesigner/designer/previewwidgetimpl.cpp b/kdevdesigner/designer/previewwidgetimpl.cpp new file mode 100644 index 00000000..2c2c6528 --- /dev/null +++ b/kdevdesigner/designer/previewwidgetimpl.cpp @@ -0,0 +1,65 @@ +/********************************************************************** +** 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 "qobjectlist.h" +#include "previewwidgetimpl.h" + +PreviewWidget::PreviewWidget( QWidget *parent, const char *name ) + : PreviewWidgetBase( parent, name ) +{ + // install event filter on child widgets + QObjectList *l = queryList("QWidget"); + QObjectListIt it(*l); + QObject * obj; + while ((obj = it.current()) != 0) { + ++it; + obj->installEventFilter(this); + ((QWidget*)obj)->setFocusPolicy(NoFocus); + } +} + +void PreviewWidget::closeEvent(QCloseEvent *e) +{ + e->ignore(); +} + +bool PreviewWidget::eventFilter(QObject *, QEvent *e) +{ + switch ( e->type() ) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::Enter: + case QEvent::Leave: + return TRUE; // ignore; + default: + break; + } + return FALSE; +} diff --git a/kdevdesigner/designer/previewwidgetimpl.h b/kdevdesigner/designer/previewwidgetimpl.h new file mode 100644 index 00000000..63227cdd --- /dev/null +++ b/kdevdesigner/designer/previewwidgetimpl.h @@ -0,0 +1,43 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PREVIEWWIDGETIMPL_H +#define PREVIEWWIDGETIMPL_H + +#include "previewwidget.h" + +class PreviewWidget : public PreviewWidgetBase +{ + Q_OBJECT + +public: + PreviewWidget( QWidget *parent = 0, const char *name = 0 ); + + void closeEvent(QCloseEvent *); + bool eventFilter(QObject *, QEvent *); +}; + +#endif diff --git a/kdevdesigner/designer/project.cpp b/kdevdesigner/designer/project.cpp new file mode 100644 index 00000000..2a261d20 --- /dev/null +++ b/kdevdesigner/designer/project.cpp @@ -0,0 +1,1558 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +**1 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 "project.h" +#include "formwindow.h" +#include "designerappiface.h" +#include "../interfaces/languageinterface.h" +#include "pixmapcollection.h" +#ifndef QT_NO_SQL +#include "dbconnectionimpl.h" +#endif +#include "resource.h" +#include <qwidgetfactory.h> +#include "outputwindow.h" + +#include <qfile.h> +#include <qtextstream.h> +#include <qurl.h> +#include <qobjectlist.h> +#include <qfeatures.h> +#include <qtextcodec.h> +#include <qdom.h> +#include <qmessagebox.h> +#include <qapplication.h> +#include "mainwindow.h" +#include <qworkspace.h> + +#ifndef QT_NO_SQL +#include <qsqldatabase.h> +#include <qsqlrecord.h> +#include <qdatatable.h> +#endif + +#include <stdlib.h> +#ifdef Q_OS_UNIX +# include <unistd.h> +#endif + +#include <klocale.h> + +#ifndef QT_NO_SQL +DatabaseConnection::~DatabaseConnection() +{ + delete iface; +} + +bool DatabaseConnection::refreshCatalog() +{ +#ifndef QT_NO_SQL + if ( loaded ) + return TRUE; + if ( !open() ) + return FALSE; + tbls = conn->tables( QSql::TableType( QSql::Tables | QSql::Views ) ); + flds.clear(); + for ( QStringList::Iterator it = tbls.begin(); it != tbls.end(); ++it ) { + QSqlRecord fil = conn->record( *it ); + QStringList lst; + for ( uint j = 0; j < fil.count(); ++j ) + lst << fil.field( j )->name(); + flds.insert( *it, lst ); + } + loaded = TRUE; + conn->close(); + return loaded; +#else + return FALSE; +#endif +} + +#ifndef QT_NO_SQL +void DatabaseConnection::remove() +{ + if ( nm == "(default)" ) + QSqlDatabase::removeDatabase( QSqlDatabase::defaultConnection ); + else + QSqlDatabase::removeDatabase( nm ); + // the above will effectively delete the current connection + conn = 0; +} +#endif + +bool DatabaseConnection::open( bool suppressDialog ) +{ +#ifndef QT_NO_SQL + // register our name, if nec + if ( nm == "(default)" ) { + if ( !QSqlDatabase::contains() ) // default doesn't exists? + conn = QSqlDatabase::addDatabase( drv ); + else + conn = QSqlDatabase::database(); + } else { + if ( !QSqlDatabase::contains( nm ) ) + conn = QSqlDatabase::addDatabase( drv, nm ); + else + conn = QSqlDatabase::database( nm ); + } + conn->setDatabaseName( dbName ); + conn->setUserName( uname ); + conn->setPassword( pword ); + conn->setHostName( hname ); + conn->setPort( prt ); + bool success = conn->open(); + for( ; suppressDialog == FALSE ; ) { + bool done = FALSE; + if ( !success ) { + DatabaseConnectionEditor dia( this, 0 , 0 , TRUE ); + switch( dia.exec() ) { + case QDialog::Accepted: + done = FALSE; + break; + case QDialog::Rejected: + done = TRUE; + break; + } + } + if ( done ) + break; + conn->setUserName( uname ); + conn->setPassword( pword ); + conn->setHostName( hname ); + conn->setPort( prt ); + success = conn->open(); + if ( !success ) { + switch( QMessageBox::warning( project->messageBoxParent(), i18n( "Connection" ), + i18n( "Could not connect to the database.\n" + "Press 'OK' to continue or 'Cancel' to " + "specify different\nconnection information.\n" ) + + QString( "[" + conn->lastError().driverText() + "\n" + + conn->lastError().databaseText() + "]\n" ), + i18n( "&OK" ), + i18n( "&Cancel" ), QString::null, 0, 1 ) ) { + case 0: // OK or Enter + continue; + case 1: // Cancel or Escape + done = TRUE; + break; + } + } else + break; + if ( done ) + break; + } + if ( !success ) { + dbErr = conn->lastError().driverText() + "\n" + conn->lastError().databaseText(); + remove(); + } + return success; +#else + return FALSE; +#endif +} + +void DatabaseConnection::close() +{ + if ( !loaded ) + return; +#ifndef QT_NO_SQL + if ( conn ) { + conn->close(); + } +#endif +} + +DesignerDatabase *DatabaseConnection::iFace() +{ + if ( !iface ) + iface = new DesignerDatabaseImpl( this ); + return iface; +} + +#endif + +//////// + +bool Project::isDummy() const +{ + return isDummyProject; +} + +Project::Project( const QString &fn, const QString &pName, + QPluginManager<ProjectSettingsInterface> *pm, bool isDummy, + const QString &l ) + : proName( pName ), projectSettingsPluginManager( pm ), isDummyProject( isDummy ) +{ + modified = TRUE; + pixCollection = new PixmapCollection( this ); + iface = 0; + lang = l; + is_cpp = lang == "C++"; + cfg.insert( "(all)", "qt warn_on release" ); + templ = "app"; + setFileName( fn ); + if ( !pName.isEmpty() ) + proName = pName; + sourcefiles.setAutoDelete( TRUE ); + modified = FALSE; + objs.setAutoDelete( FALSE ); + fakeFormFiles.setAutoDelete( FALSE ); +} + +Project::~Project() +{ + if ( singleProjectMode() ) + removeTempProject(); + delete iface; + delete pixCollection; +} + +void Project::setModified( bool b ) +{ + modified = b; + emit projectModified(); +} + +#ifndef QT_NO_SQL +DatabaseConnection *Project::databaseConnection( const QString &name ) +{ + for ( DatabaseConnection *conn = dbConnections.first(); + conn; + conn = dbConnections.next() ) { + if ( conn->name() == name ) + return conn; + } + return 0; +} +#endif + +void Project::setFileName( const QString &fn, bool doClear ) +{ + if ( fn == filename ) + return; + + if ( singleProjectMode() ) { + QString qsa = QString( getenv( "HOME" ) ) + QString( "/.qsa" ); + if ( !QFile::exists( qsa ) ) { + QDir d; + d.mkdir( qsa ); + } + if ( fn == singleProFileName ) + return; + singleProFileName = fn; + static int counter = 0; + QString str_counter = QString::number( counter++ ); + str_counter = "/.qsa/" + str_counter; + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + filename = QString( getenv( "HOME" ) + str_counter + QString( "tmp_" ) + + QFileInfo( fn ).baseName() + "/" + QFileInfo( fn ).baseName() + ".pro" ); + removeTempProject(); + if ( iface && iface->supports( LanguageInterface::CompressProject ) ) { + filename = iface->uncompressProject( makeAbsolute( singleProFileName ), + QString( getenv( "HOME" ) + + str_counter + QString( "tmp_" ) + + QFileInfo( fn ).baseName() ) ); + proName = makeAbsolute( singleProFileName ); + } + } else { + filename = fn; + if ( !filename.endsWith( ".pro" ) ) + filename += ".pro"; + proName = filename; + } + + + if ( proName.contains( '.' ) ) + proName = proName.left( proName.find( '.' ) ); + + if ( !doClear ) + return; + clear(); + if ( QFile::exists( filename ) ) + parse(); +} + +QString Project::fileName( bool singlePro ) const +{ + if ( singlePro ) + return singleProFileName; + return filename; +} + +QString Project::databaseDescription() const +{ + return dbFile; +} + +QString Project::projectName() const +{ + return proName; +} + +static QString parse_part( const QString &part ) +{ + QString res; + bool inName = FALSE; + QString currName; + for ( int i = 0; i < (int)part.length(); ++i ) { + QChar c = part[ i ]; + if ( !inName ) { + if ( c != ' ' && c != '\t' && c != '\n' && c != '=' && c != '\\' && c != '+' ) + inName = TRUE; + else + continue; + } + if ( inName ) { + if ( c == '\n' ) + break; + res += c; + } + } + return res; +} + +QStringList parse_multiline_part( const QString &contents, const QString &key, int *start = 0 ) +{ + if ( start ) + *start = -1; + QString lastWord; + // Account for things like win32: SOURCES + int extraWhiteSpaceCount = 0; + int braceCount = 0; + for ( int i = 0; i < (int)contents.length(); ++i ) { + QChar c( contents[ i ] ); + switch ( c ) { + case '{': + braceCount++; + lastWord = ""; + break; + case '}': + braceCount--; + lastWord = ""; + break; + case ' ': case '\t': + if (!key.startsWith(lastWord)) { + lastWord = ""; + extraWhiteSpaceCount = 0; + } else { + extraWhiteSpaceCount++; + } + break; + case '\\': case '\n': + lastWord = ""; + break; + default: + lastWord += c; + } + + // ### we should read the 'bla { SOURCES= ... }' stuff as well (braceCount > 0) + if ( lastWord == key && braceCount == 0 ) { + if ( start ) + *start = i - lastWord.length() - extraWhiteSpaceCount + 1; + QStringList lst; + bool inName = FALSE; + QString currName; + bool hadEqual = FALSE; + for ( ; i < (int)contents.length(); ++i ) { + c = contents[ i ]; + if ( !hadEqual && c != '=' ) + continue; + if ( !hadEqual ) { + hadEqual = TRUE; + continue; + } + if ( ( c.isLetter() || c.isDigit() || c == '.' || c == '/' || c == '_' || c == '\\' || + c == '\"' || c == '\'' || c == '=' || + c == '$' || c == '-' || c == '(' || c == ')' || c == ':' || c == '+' || c == ',' || c == '~' ) && + c != ' ' && c != '\t' && c != '\n' ) { + if ( !inName ) + currName = QString::null; + if ( c != '\\' || contents[i+1] != '\n' ) { + currName += c; + inName = TRUE; + } + } else { + if ( inName ) { + inName = FALSE; + if ( currName.simplifyWhiteSpace() != "\\" ) + lst.append( currName ); + } + if ( c == '\n' && i > 0 && contents[ (int)i - 1 ] != '\\' ) + break; + } + } + return lst; + } + } + + return QStringList(); +} + +void Project::parse() +{ + QFile f( filename ); + if ( !f.exists() || !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + QString contents = ts.read(); + f.close(); + + proName = QFileInfo( filename ).baseName(); + + QStringList::ConstIterator it; + + int i = contents.find( "LANGUAGE" ); + if ( i != -1 ) { + lang = ""; + is_cpp = FALSE; + QString part = contents.mid( i + QString( "LANGUAGE" ).length() ); + lang = parse_part( part ); + is_cpp = lang == "C++"; + } + + i = contents.find( "DBFILE" ); + if ( i != -1 ) { + dbFile = ""; + QString part = contents.mid( i + QString( "DBFILE" ).length() ); + dbFile = parse_part( part ); + } + + QStringList uifiles = parse_multiline_part( contents, "FORMS" ); + uifiles += parse_multiline_part( contents, "INTERFACES" ); // compatibility + for ( it = uifiles.begin(); it != uifiles.end(); ++it ) { + if ( (*it).startsWith( "__APPOBJ" ) ) + continue; + (void) new FormFile( *it, FALSE, this ); + } + + + i = contents.find( "TEMPLATE" ); + if ( i != -1 ) { + templ = ""; + QString part = contents.mid( i + QString( "TEMPLATE" ).length() ); + templ = parse_part( part ); + } + + readPlatformSettings( contents, "CONFIG", cfg ); + readPlatformSettings( contents, "LIBS", lbs ); + readPlatformSettings( contents, "INCLUDEPATH", inclPath ); + readPlatformSettings( contents, "DEFINES", defs ); + readPlatformSettings( contents, "SOURCES", sources ); + readPlatformSettings( contents, "HEADERS", headers ); + + LanguageInterface *iface = MetaDataBase::languageInterface( lang ); + if ( iface ) { + QStringList sourceKeys; + iface->sourceProjectKeys( sourceKeys ); + for ( QStringList::Iterator it = sourceKeys.begin(); it != sourceKeys.end(); ++it ) { + QStringList lst = parse_multiline_part( contents, *it ); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) + (void) new SourceFile( *it, FALSE, this ); + } + } + + updateCustomSettings(); + + for ( it = csList.begin(); it != csList.end(); ++it ) { + i = contents.find( *it ); + if ( i != -1 ) { + QString val = ""; + QString part = contents.mid( i + QString( *it ).length() ); + val = parse_part( part ); + customSettings.replace( *it, val ); + } + } + + loadConnections(); + + QStringList images = parse_multiline_part( contents, "IMAGES" ); + + // ### remove that for the final - this is beta-compatibility + if ( images.isEmpty() && QDir( QFileInfo( filename ).dirPath( TRUE ) + "/images" ).exists() ) { + images = QDir( QFileInfo( filename ).dirPath( TRUE ) + "/images" ).entryList(); + for ( int i = 0; i < (int)images.count(); ++i ) + images[ i ].prepend( "images/" ); + modified = TRUE; + } + + for ( QStringList::ConstIterator pit = images.begin(); pit != images.end(); ++pit ) + pixCollection->load( *pit ); +} + +void Project::clear() +{ + dbFile = ""; + proName = "unnamed"; + desc = ""; +} + +bool Project::removeSourceFile( SourceFile *sf ) +{ + if ( !sourcefiles.containsRef( sf ) ) + return FALSE; + if ( !sf->close() ) + return FALSE; + sourcefiles.removeRef( sf ); + modified = TRUE; + emit sourceFileRemoved( sf ); + return TRUE; +} + +void Project::setDatabaseDescription( const QString &db ) +{ + dbFile = db; +} + +void Project::setDescription( const QString &s ) +{ + desc = s; +} + +QString Project::description() const +{ + return desc; +} + + +bool Project::isValid() const +{ + // #### do more checking here? + if ( filename.isEmpty() || proName.isEmpty() ) + return FALSE; + + return TRUE; +} + +QString Project::makeAbsolute( const QString &f ) +{ + if ( isDummy() ) + return f; + QString encodedUrl = QFileInfo( filename ).dirPath( TRUE ); + QUrl::encode( encodedUrl ); + QUrl u( encodedUrl, f ); + return u.path(); +} + +QString Project::makeRelative( const QString &f ) +{ + if ( isDummy() ) + return f; + QString p = QFileInfo( filename ).dirPath( TRUE ); + QString f2 = f; + if ( f2.left( p.length() ) == p ) + f2.remove( 0, p.length() + 1 ); + return f2; +} + +static void remove_contents( QString &contents, const QString &s ) +{ + int i = contents.find( s ); + if ( i != -1 ) { + int start = i; + int end = contents.find( '\n', i ); + if ( end == -1 ) + end = contents.length() - 1; + contents.remove( start, end - start + 1 ); + } +} + +static void remove_multiline_contents( QString &contents, const QString &s, int *strt = 0 ) +{ + int i = contents.find( s ); + if ( strt ) + *strt = i; + int start = i; + bool lastWasBackspash = FALSE; + if ( i != -1 && ( i == 0 || contents[ i - 1 ] != '{' || contents[ i - 1 ] != ':' ) ) { + for ( ; i < (int)contents.length(); ++i ) { + if ( contents[ i ] == '\n' && !lastWasBackspash ) + break; + lastWasBackspash = ( contents[ i ] == '\\' || + lastWasBackspash && ( contents[ i ] == ' ' || contents[ i ] == '\t' ) ); + } + contents.remove( start, i - start + 1 ); + } +} + +void Project::save( bool onlyProjectFile ) +{ + bool anythingModified = FALSE; + + // save sources and forms + if ( !onlyProjectFile ) { + + saveConnections(); + + for ( SourceFile *sf = sourcefiles.first(); sf; sf = sourcefiles.next() ) { + anythingModified = anythingModified || sf->isModified(); + if ( !sf->save() ) + return; + } + + for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { + anythingModified = anythingModified || ff->isModified(); + if ( !ff->save() ) + return; + } + } + + if ( isDummy() || filename.isEmpty() ) + return; + + if ( !modified ) { + if ( singleProjectMode() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + if ( iface && iface->supports( LanguageInterface::CompressProject ) ) + iface->compressProject( makeAbsolute( filename ), singleProFileName, anythingModified ); + } + return; + } + + QFile f( filename ); + QString original = ""; + + // read the existing file + bool hasPreviousContents = FALSE; + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + original = ts.read(); + f.close(); + hasPreviousContents = TRUE; + remove_contents( original, "{SOURCES+=" ); // ### compatibility with early 3.0 betas + remove_contents( original, "DBFILE" ); + remove_contents( original, "LANGUAGE" ); + remove_contents( original, "TEMPLATE" ); + removePlatformSettings( original, "CONFIG" ); + removePlatformSettings( original, "DEFINES" ); + removePlatformSettings( original, "LIBS" ); + removePlatformSettings( original, "INCLUDEPATH" ); + removePlatformSettings( original, "SOURCES" ); + removePlatformSettings( original, "HEADERS" ); + remove_multiline_contents( original, "FORMS" ); + remove_multiline_contents( original, "INTERFACES" ); // compatibility + remove_multiline_contents( original, "IMAGES" ); + for ( QStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) + remove_contents( original, *it ); + } + + // the contents of the saved file + QString contents; + + // template + contents += "TEMPLATE\t= " + templ + "\n"; + + // language + contents += "LANGUAGE\t= " + lang + "\n"; + contents += "\n"; + + // config + writePlatformSettings( contents, "CONFIG", cfg ); + LanguageInterface *iface = MetaDataBase::languageInterface( lang ); + if ( iface ) { + QStringList sourceKeys; + iface->sourceProjectKeys( sourceKeys ); + for ( QStringList::Iterator spit = sourceKeys.begin(); spit != sourceKeys.end(); ++spit ) + remove_multiline_contents( contents, *spit ); + } + contents += "\n"; + + // libs, defines, includes + writePlatformSettings( contents, "LIBS", lbs ); + writePlatformSettings( contents, "DEFINES", defs ); + writePlatformSettings( contents, "INCLUDEPATH", inclPath ); + writePlatformSettings( contents, "SOURCES", sources ); + writePlatformSettings( contents, "HEADERS", headers ); + + // unix + if ( !hasPreviousContents ) { + contents += + "unix {\n" + " UI_DIR = .ui\n" + " MOC_DIR = .moc\n" + " OBJECTS_DIR = .obj\n" + "}\n"; + } + contents += "\n"; + + // sources + if ( !sourcefiles.isEmpty() && iface ) { + QMap<QString, QStringList> sourceToKey; + for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) { + QString key = iface->projectKeyForExtension( QFileInfo( f->fileName() ).extension() ); + QStringList lst = sourceToKey[ key ]; + lst << makeRelative( f->fileName() ); + sourceToKey.replace( key, lst ); + } + + for ( QMap<QString, QStringList>::Iterator skit = sourceToKey.begin(); + skit != sourceToKey.end(); ++skit ) { + QString part = skit.key() + "\t+= "; + QStringList lst = *skit; + for ( QStringList::Iterator sit = lst.begin(); sit != lst.end(); ++sit ) { + part += *sit; + part += ++sit != lst.end() ? " \\\n\t" : ""; + --sit; + } + part += "\n"; + contents += part; + } + } + + // forms and interfaces + if ( !formfiles.isEmpty() ) { + contents += "FORMS\t= "; + for ( QPtrListIterator<FormFile> fit = formfiles; fit.current(); ++fit ) { + contents += fit.current()->fileName() + + (fit != formfiles.last() ? " \\\n\t" : ""); + } + contents += "\n"; + } + + // images + if ( !pixCollection->isEmpty() ) { + contents += "IMAGES\t= "; + QValueList<PixmapCollection::Pixmap> pixmaps = pixCollection->pixmaps(); + for ( QValueList<PixmapCollection::Pixmap>::Iterator it = pixmaps.begin(); + it != pixmaps.end(); ++it ) { + contents += makeRelative( (*it).absname ); + contents += ++it != pixmaps.end() ? " \\\n\t" : ""; + --it; + } + contents += "\n"; + } + + // database + if ( !dbFile.isEmpty() ) + contents += "DBFILE\t= " + dbFile + "\n"; + contents += "\n"; + + // custom settings + for ( QStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) { + QString val = *customSettings.find( *it ); + if ( !val.isEmpty() ) + contents += *it + "\t= " + val + "\n"; + } + + if ( !f.open( IO_WriteOnly | IO_Translate ) ) { + QMessageBox::warning( messageBoxParent(), + "Save Project Failed", "Couldn't write project file " + filename ); + return; + } + + QTextStream os( &f ); + os << contents; + if (hasPreviousContents) + os << original; + + f.close(); + + setModified( FALSE ); + + if ( singleProjectMode() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + if ( iface && iface->supports( LanguageInterface::CompressProject ) ) + iface->compressProject( makeAbsolute( filename ), singleProFileName, TRUE ); + } +} + +#ifndef QT_NO_SQL +QPtrList<DatabaseConnection> Project::databaseConnections() const +{ + return dbConnections; +} +#endif + +#ifndef QT_NO_SQL +void Project::setDatabaseConnections( const QPtrList<DatabaseConnection> &lst ) +{ + dbConnections = lst; +} +#endif + +#ifndef QT_NO_SQL +void Project::addDatabaseConnection( DatabaseConnection *conn ) +{ + dbConnections.append( conn ); + modified = TRUE; +} +#endif + +#ifndef QT_NO_SQL +void Project::removeDatabaseConnection( const QString &c ) +{ + for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { + if ( conn->name() == c ) { + conn->remove(); + dbConnections.removeRef( conn ); + delete conn; + return; + } + } +} +#endif + +#ifndef QT_NO_SQL +QStringList Project::databaseConnectionList() +{ + QStringList lst; + for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) + lst << conn->name(); + return lst; +} +#endif + +#ifndef QT_NO_SQL +QStringList Project::databaseTableList( const QString &connection ) +{ + DatabaseConnection *conn = databaseConnection( connection ); + if ( !conn ) { + return QStringList(); + } + return conn->tables(); +} +#endif + +#ifndef QT_NO_SQL +QStringList Project::databaseFieldList( const QString &connection, const QString &table ) +{ + DatabaseConnection *conn = databaseConnection( connection ); + if ( !conn ) + return QStringList(); + return conn->fields( table ); +} +#endif + +#ifndef QT_NO_SQL +static QString makeIndent( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} +#endif + +#ifndef QT_NO_SQL +static void saveSingleProperty( QTextStream &ts, const QString& name, const QString& value, int indent ) +{ + ts << makeIndent( indent ) << "<property name=\"" << name << "\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<string>" << value << "</string>" << endl; + --indent; + ts << makeIndent( indent ) << "</property>" << endl; +} +#endif + +void Project::saveConnections() +{ +#ifndef QT_NO_SQL + if ( dbFile.isEmpty() ) { + QFileInfo fi( fileName() ); + setDatabaseDescription( fi.baseName() + ".db" ); + } + + QFile f( makeAbsolute( dbFile ) ); + + if ( dbConnections.isEmpty() ) { + if ( f.exists() ) + f.remove(); + setDatabaseDescription( "" ); + modified = TRUE; + return; + } + + /* .db xml */ + if ( f.open( IO_WriteOnly | IO_Translate ) ) { + QTextStream ts( &f ); + ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); + ts << "<!DOCTYPE DB><DB version=\"1.0\">" << endl; + + /* db connections */ + int indent = 0; + for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { + ts << makeIndent( indent ) << "<connection>" << endl; + ++indent; + saveSingleProperty( ts, "name", conn->name(), indent ); + saveSingleProperty( ts, "driver", conn->driver(), indent ); + saveSingleProperty( ts, "database", conn->database(), indent ); + saveSingleProperty( ts, "username", conn->username(), indent ); + saveSingleProperty( ts, "hostname", conn->hostname(), indent ); + saveSingleProperty( ts, "port", QString::number( conn->port() ), indent ); + + /* connection tables */ + QStringList tables = conn->tables(); + for ( QStringList::Iterator it = tables.begin(); + it != tables.end(); ++it ) { + ts << makeIndent( indent ) << "<table>" << endl; + ++indent; + saveSingleProperty( ts, "name", (*it), indent ); + + /* tables fields */ + QStringList fields = conn->fields( *it ); + for ( QStringList::Iterator it2 = fields.begin(); + it2 != fields.end(); ++it2 ) { + ts << makeIndent( indent ) << "<field>" << endl; + ++indent; + saveSingleProperty( ts, "name", (*it2), indent ); + --indent; + ts << makeIndent( indent ) << "</field>" << endl; + } + + --indent; + ts << makeIndent( indent ) << "</table>" << endl; + } + + --indent; + ts << makeIndent( indent ) << "</connection>" << endl; + } + + ts << "</DB>" << endl; + f.close(); + } +#endif +} + +#ifndef QT_NO_SQL +static QDomElement loadSingleProperty( 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; +} +#endif + +void Project::loadConnections() +{ +#ifndef QT_NO_SQL + if ( dbFile.isEmpty() || !QFile::exists( makeAbsolute( dbFile ) ) ) + return; + + QFile f( makeAbsolute( dbFile ) ); + if ( f.open( IO_ReadOnly ) ) { + QDomDocument doc; + QString errMsg; + int errLine; + if ( doc.setContent( &f, &errMsg, &errLine ) ) { + QDomElement e; + e = doc.firstChild().toElement(); + + /* connections */ + QDomNodeList connections = e.toElement().elementsByTagName( "connection" ); + for ( uint i = 0; i < connections.length(); i++ ) { + QDomElement connection = connections.item(i).toElement(); + QDomElement connectionName = loadSingleProperty( connection, "name" ); + QDomElement connectionDriver = loadSingleProperty( connection, "driver" ); + QDomElement connectionDatabase = loadSingleProperty( connection, + "database" ); + QDomElement connectionUsername = loadSingleProperty( connection, + "username" ); + QDomElement connectionHostname = loadSingleProperty( connection, + "hostname" ); + QDomElement connectionPort = loadSingleProperty( connection, + "port" ); + + DatabaseConnection *conn = new DatabaseConnection( this ); + conn->setName( connectionName.firstChild().firstChild().toText().data() ); + conn->setDriver( connectionDriver.firstChild().firstChild().toText().data() ); + conn->setDatabase( connectionDatabase.firstChild().firstChild().toText().data() ); + conn->setUsername( connectionUsername.firstChild().firstChild().toText().data() ); + conn->setHostname( connectionHostname.firstChild().firstChild().toText().data() ); + conn->setPort( QString( connectionPort.firstChild().firstChild().toText().data() ).toInt() ); + + /* connection tables */ + QDomNodeList tables = connection.toElement().elementsByTagName( "table" ); + for ( uint j = 0; j < tables.length(); j++ ) { + QDomElement table = tables.item(j).toElement(); + QDomElement tableName = loadSingleProperty( table, "name" ); + conn->addTable( tableName.firstChild().firstChild().toText().data() ); + + /* table fields */ + QStringList fieldList; + QDomNodeList fields = table.toElement().elementsByTagName( "field" ); + for ( uint k = 0; k < fields.length(); k++ ) { + QDomElement field = fields.item(k).toElement(); + QDomElement fieldName = loadSingleProperty( field, "name" ); + fieldList.append( fieldName.firstChild().firstChild().toText().data() ); + } + conn->setFields( tableName.firstChild().firstChild().toText().data(), + fieldList ); + } + + dbConnections.append( conn ); + } + } else { + qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine ); + } + f.close(); + } +#endif +} + +/*! Opens the database \a connection. The connection remains open and +can be closed again with closeDatabase(). +*/ + +bool Project::openDatabase( const QString &connection, bool suppressDialog ) +{ +#ifndef QT_NO_SQL + DatabaseConnection *conn = databaseConnection( connection ); + if ( connection.isEmpty() && !conn ) + conn = databaseConnection( "(default)" ); + if ( !conn ) + return FALSE; + bool b = conn->open( suppressDialog ); + return b; +#else + Q_UNUSED( connection ); + Q_UNUSED( suppressDialog ); + return FALSE; +#endif +} + +/*! Closes the database \a connection. +*/ +void Project::closeDatabase( const QString &connection ) +{ +#ifndef QT_NO_SQL + DatabaseConnection *conn = databaseConnection( connection ); + if ( connection.isEmpty() && !conn ) + conn = databaseConnection( "(default)" ); + if ( !conn ) + return; + conn->close(); +#else + Q_UNUSED( connection ); +#endif +} + +// void Project::formClosed( FormWindow *fw ) +// { +// formWindows.remove( fw ); +// } + +QObjectList *Project::formList( bool resolveFakeObjects ) const +{ + QObjectList *l = new QObjectList; + for ( QPtrListIterator<FormFile> forms(formfiles); forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->formWindow() ) { + if ( resolveFakeObjects && f->formWindow()->isFake() ) + l->append( objectForFakeForm( f->formWindow() ) ); + else + l->append( f->formWindow()->child( 0, "QWidget" ) ); + } else if ( f->isFake() ) { + l->append( objectForFakeFormFile( f ) ); + } + } + return l; +} + +DesignerProject *Project::iFace() +{ + if ( !iface ) + iface = new DesignerProjectImpl( this ); + return iface; +} + +void Project::setLanguage( const QString &l ) +{ + if ( l == lang ) + return; + lang = l; + is_cpp = lang == "C++"; + updateCustomSettings(); + modified = TRUE; +} + +QString Project::language() const +{ + return lang; +} + +void Project::setCustomSetting( const QString &key, const QString &value ) +{ + customSettings.remove( key ); + customSettings.insert( key, value ); + modified = TRUE; +} + +QString Project::customSetting( const QString &key ) const +{ + return *customSettings.find( key ); +} + +void Project::updateCustomSettings() +{ + if ( !projectSettingsPluginManager ) + return; + +/* + ProjectSettingsInterface *iface = 0; + projectSettingsPluginManager->queryInterface( lang, (QUnknownInterface**)&iface ); + if ( !iface ) + return; + csList = iface->projectSettings(); + iface->release(); +*/ + + QInterfacePtr<ProjectSettingsInterface> iface; + projectSettingsPluginManager->queryInterface( lang, &iface ); + if ( !iface ) + return; + csList = iface->projectSettings(); + customSettings.clear(); + +} + +void Project::setActive( bool b ) +{ + pixCollection->setActive( b ); +} + +void Project::addSourceFile( SourceFile *sf ) +{ + sourcefiles.append( sf ); + modified = TRUE; + emit sourceFileAdded( sf ); +} + + +SourceFile* Project::findSourceFile( const QString& filename, SourceFile *ignore ) const +{ + QPtrListIterator<SourceFile> it(sourcefiles); + while ( it.current() ) { + if ( it.current() != ignore && it.current()->fileName() == filename ) + return it.current(); + ++it; + } + return 0; +} + +FormFile* Project::findFormFile( const QString& filename, FormFile *ignore ) const +{ + QPtrListIterator<FormFile> it(formfiles); + while ( it.current() ) { + if ( it.current() != ignore && it.current()->fileName() == filename ) + return it.current(); + ++it; + } + return 0; +} + +void Project::setIncludePath( const QString &platform, const QString &path ) +{ + if ( inclPath[platform] == path ) + return; + inclPath.replace( platform, path ); + modified = TRUE; +} + +void Project::setLibs( const QString &platform, const QString &path ) +{ + lbs.replace( platform, path ); +} + +void Project::setDefines( const QString &platform, const QString &path ) +{ + defs.replace( platform, path ); +} + +void Project::setConfig( const QString &platform, const QString &config ) +{ + cfg.replace( platform, config ); +} + +QString Project::config( const QString &platform ) const +{ + return cfg[ platform ]; +} + +QString Project::libs( const QString &platform ) const +{ + return lbs[ platform ]; +} + +QString Project::defines( const QString &platform ) const +{ + return defs[ platform ]; +} + +QString Project::includePath( const QString &platform ) const +{ + return inclPath[ platform ]; +} + +QString Project::templte() const +{ + return templ; +} + +void Project::setTemplate( const QString &t ) +{ + templ = t; +} + +void Project::readPlatformSettings( const QString &contents, + const QString &setting, + QMap<QString, QString> &res ) +{ + const QString platforms[] = { "", "win32", "unix", "mac", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + QString p = platforms[ i ]; + if ( !p.isEmpty() ) + p += ":"; + QStringList lst = parse_multiline_part( contents, p + setting ); + QString s = lst.join( " " ); + QString key = platforms[ i ]; + if ( key.isEmpty() ) + key = "(all)"; + res.replace( key, s ); + } +} + +void Project::removePlatformSettings( QString &contents, const QString &setting ) +{ + const QString platforms[] = { "win32", "unix", "mac", "", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + QString p = platforms[ i ]; + if ( !p.isEmpty() ) + p += ":"; + remove_multiline_contents( contents, p + setting ); + } +} + +void Project::writePlatformSettings( QString &contents, const QString &setting, + const QMap<QString, QString> &input ) +{ + const QString platforms[] = { "", "win32", "unix", "mac", QString::null }; + int i; + LanguageInterface *iface = MetaDataBase::languageInterface( lang ); + if (iface && (setting == "SOURCES" || setting == "HEADERS")) // The (all) part will be saved later on + i = 1; + else + i = 0; + for (; platforms[ i ] != QString::null; ++i ) { + QString p = platforms[ i ]; + if ( !p.isEmpty() ) + p += ":"; + QString key = platforms[ i ]; + if ( key.isEmpty() ) + key = "(all)"; + QMap<QString, QString>::ConstIterator it = input.find( key ); + if ( it == input.end() || (*it).isEmpty() ) + continue; + contents += p + setting + "\t+= " + *it + "\n"; + } +} + +void Project::addFormFile( FormFile *ff ) +{ + formfiles.append( ff ); + modified = TRUE; + emit formFileAdded( ff ); +} + +bool Project::removeFormFile( FormFile *ff ) +{ + if ( !formfiles.containsRef( ff ) ) + return FALSE; + if ( !ff->close() ) + return FALSE; + formfiles.removeRef( ff ); + modified = TRUE; + emit formFileRemoved( ff ); + return TRUE; +} + +void Project::addObject( QObject *o ) +{ + bool wasModified = modified; + objs.append( o ); + FormFile *ff = new FormFile( "", FALSE, this, "qt_fakewindow" ); + ff->setFileName( "__APPOBJ" + QString( o->name() ) + ".ui" ); + fakeFormFiles.insert( (void*)o, ff ); + MetaDataBase::addEntry( o ); + if ( hasGUI() ) { + QWidget *parent = MainWindow::self ? MainWindow::self->qWorkspace() : 0; + FormWindow *fw = new FormWindow( ff, MainWindow::self, parent, "qt_fakewindow" ); + fw->setProject( this ); + if ( QFile::exists( ff->absFileName() ) ) + Resource::loadExtraSource( ff, ff->absFileName(), + MetaDataBase::languageInterface( language() ), FALSE ); + if ( MainWindow::self ) + fw->setMainWindow( MainWindow::self ); + if ( MainWindow::self ) { + QApplication::sendPostedEvents( MainWindow::self->qWorkspace(), QEvent::ChildInserted ); + connect( fw, + SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ), + MainWindow::self, + SLOT( updateUndoRedo( bool, bool, const QString &, const QString & ) ) + ); + } + if ( fw->parentWidget() ) { + fw->parentWidget()->setFixedSize( 1, 1 ); + fw->show(); + } + } else { + if ( QFile::exists( ff->absFileName() ) ) + Resource::loadExtraSource( ff, ff->absFileName(), + MetaDataBase::languageInterface( language() ), FALSE ); + } + emit objectAdded( o ); + modified = wasModified; +} + +void Project::setObjects( const QObjectList &ol ) +{ + for ( QObjectListIt it( ol ); it.current(); ++it ) + addObject( it.current() ); +} + +void Project::removeObject( QObject *o ) +{ + bool wasModified = modified; + objs.removeRef( o ); + MetaDataBase::removeEntry( o ); + fakeFormFiles.remove( (void*)o ); + emit objectRemoved( o ); + modified = wasModified; +} + +QObjectList Project::objects() const +{ + return objs; +} + +FormFile *Project::fakeFormFileFor( QObject *o ) const +{ + return fakeFormFiles.find( (void*)o ); +} + +QObject *Project::objectForFakeForm( FormWindow *fw ) const +{ + for ( QPtrDictIterator<FormFile> it( fakeFormFiles ); it.current(); ++it ) { + if ( it.current()->formWindow() == fw || + it.current() == fw->formFile() ) + return (QObject*)it.currentKey(); + } + return 0; +} + +QObject *Project::objectForFakeFormFile( FormFile *ff ) const +{ + for ( QPtrDictIterator<FormFile> it( fakeFormFiles ); it.current(); ++it ) { + if ( it.current() == ff ) + return (QObject*)it.currentKey(); + } + return 0; +} + +void Project::removeTempProject() +{ + if ( !singleProjectMode() ) + return; + QDir d( QFileInfo( filename ).dirPath() ); + if ( !d.exists( QFileInfo( filename ).dirPath() ) ) + return; + QStringList files = d.entryList( QDir::Files ); + QStringList::Iterator it; + for ( it = files.begin(); it != files.end(); ++it ) { + d.remove( *it ); + } + if ( d.exists( QFileInfo( filename ).dirPath() + "/images" ) ) { + d = QDir( QFileInfo( filename ).dirPath() + "/images" ); + files = d.entryList( QDir::Files ); + for ( it = files.begin(); it != files.end(); ++it ) + d.remove( *it ); + d = QDir( QFileInfo( filename ).dirPath() ); + d.remove( "images" ); + } + d.remove( QFileInfo( filename ).dirPath() ); +#if defined(Q_OS_UNIX) + // ##### implement for all platforms, ideally should be in Qt + ::rmdir( QFile::encodeName( d.absPath() ) ); +#endif +} + +void Project::addAndEditFunction( const QString &function, const QString &functionBody, bool openDeveloper ) +{ + for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) { + if ( QFileInfo( f->fileName() ).baseName() == "main" ) { + QValueList<LanguageInterface::Function> funcs; + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + if ( !iface ) + return; + iface->functions( f->text(), &funcs ); + QString func = function; + int i = func.find( '(' ); + if ( i != -1 ) + func = func.left( i ); + + bool found = FALSE; + for ( QValueList<LanguageInterface::Function>::Iterator it = funcs.begin(); + it != funcs.end(); ++it ) { + if ( (*it).name.left( (*it).name.find( '(' ) ) == func ) { + found = TRUE; + break; + } + } + + if ( !found ) { + QString code = f->text(); + if ( functionBody.isEmpty() ) + code += "\n\n" + iface->createFunctionStart( "", func, "", "" ) + "()\n{\n\n}\n"; + else + code += "\n\n" + iface->createFunctionStart( "", func, "", "" ) + + "()\n" + functionBody + "\n"; + f->setText( code ); + if ( f->editor() ) + f->editor()->refresh( FALSE ); + } + + if ( openDeveloper ) { + if ( MainWindow::self ) + MainWindow::self->editSource( f ); + f->editor()->setFunction( func, "" ); + } + + break; + } + } +} + +bool Project::hasParentObject( QObject *o ) +{ + for ( QObject *p = objs.first(); p; p = objs.next() ) { + QObject *c = p->child( o->name(), o->className() ); + if ( c ) + return TRUE; + } + return FALSE; +} + +QString Project::qualifiedName( QObject *o ) +{ + QString name = o->name(); + QObject *p = o->parent(); + while ( p ) { + name.prepend( QString( p->name() ) + "." ); + if ( objs.findRef( p ) != -1 ) + break; + p = p->parent(); + } + return name; +} + +bool Project::singleProjectMode() const +{ + return !MainWindow::self || MainWindow::self->singleProjectMode(); +} + +QWidget *Project::messageBoxParent() const +{ + return MainWindow::self; +} + +void Project::designerCreated() +{ + for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { + FormWindow *fw = ff->formWindow(); + if ( !fw || fw->mainWindow() ) + continue; + fw->setMainWindow( MainWindow::self ); + connect( fw, SIGNAL( undoRedoChanged( bool, bool, const QString &, + const QString & ) ), + MainWindow::self, SLOT( updateUndoRedo( bool, bool, + const QString &, const QString & ) ) ); + fw->reparent( MainWindow::self->qWorkspace(), QPoint( 0, 0 ), FALSE ); + QApplication::sendPostedEvents( MainWindow::self->qWorkspace(), + QEvent::ChildInserted ); + fw->parentWidget()->setFixedSize( 1, 1 ); + fw->show(); + } +} + +void Project::formOpened( FormWindow *fw ) +{ + if ( fw->isFake() ) + return; + emit newFormOpened( fw ); +} + +QString Project::locationOfObject( QObject *o ) +{ + if ( !o ) + return QString::null; + + if ( MainWindow::self ) { + QWidgetList windows = MainWindow::self->qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + FormWindow *fw = ::qt_cast<FormWindow*>(w); + SourceEditor *se = ::qt_cast<SourceEditor*>(w); + if ( fw ) { + if ( fw->isFake() ) + return objectForFakeForm( fw )->name() + QString( " [Source]" ); + else + return fw->name() + QString( " [Source]" ); + } else if ( se ) { + if ( !se->object() ) + continue; + if ( se->formWindow() ) + return se->formWindow()->name() + QString( " [Source]" ); + else + return makeRelative( se->sourceFile()->fileName() ); + } + } + } + + if ( ::qt_cast<SourceFile*>(o) ) { + for ( QPtrListIterator<SourceFile> sources = sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + if ( f == o ) + return makeRelative( f->fileName() ); + } + } + + extern QMap<QWidget*, QString> *qwf_forms; + if ( !qwf_forms ) { + qWarning( "Project::locationOfObject: qwf_forms is NULL!" ); + return QString::null; + } + + QString s = makeRelative( *qwf_forms->find( (QWidget*)o ) ); + s += " [Source]"; + return s; +} + +bool Project::hasGUI() const +{ + return qApp->type() != QApplication::Tty; +} diff --git a/kdevdesigner/designer/project.h b/kdevdesigner/designer/project.h new file mode 100644 index 00000000..a2606ffa --- /dev/null +++ b/kdevdesigner/designer/project.h @@ -0,0 +1,273 @@ +/********************************************************************** +** 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 PROJECT_H +#define PROJECT_H + +#include <qfeatures.h> + +#include <qstring.h> +#include <qstringlist.h> +#include <qptrlist.h> +#include <qmap.h> +#include <private/qpluginmanager_p.h> +#include "../interfaces/projectsettingsiface.h" +#include "sourcefile.h" +#include "formfile.h" +#include <qobjectlist.h> +#include <qptrdict.h> +#include "formfile.h" + +class QObjectList; +struct DesignerProject; +struct DesignerDatabase; +class PixmapCollection; +class Project; + +#ifndef QT_NO_SQL +class QSqlDatabase; + +class DatabaseConnection +{ +public: + DatabaseConnection( Project *p ) : +#ifndef QT_NO_SQL + conn( 0 ), +#endif + project( p ), loaded( FALSE ), iface( 0 ) {} + ~DatabaseConnection(); + + bool refreshCatalog(); + bool open( bool suppressDialog = TRUE ); + void close(); + DesignerDatabase *iFace(); + + bool isLoaded() const { return loaded; } + void setName( const QString& n ) { nm = n; } + QString name() const { return nm; } + void setDriver( const QString& d ) { drv = d; } + QString driver() const { return drv; } + void setDatabase( const QString& db ) { dbName = db; } + QString database() const { return dbName; } + void setUsername( const QString& u ) { uname = u; } + QString username() const { return uname; } + void setPassword( const QString& p ) { pword = p; } + QString password() const { return pword; } + void setHostname( const QString& h ) { hname = h; } + QString hostname() const { return hname; } + void setPort( int p ) { prt = p; } + int port() const { return prt; } + QString lastError() const { return dbErr; } + void addTable( const QString& t ) { tbls.append(t); } + void setFields( const QString& t, const QStringList& f ) { flds[t] = f; } + QStringList tables() const { return tbls; } + QStringList fields( const QString& t ) { return flds[t]; } + QMap<QString, QStringList> fields() { return flds; } +#ifndef QT_NO_SQL + QSqlDatabase* connection() const { return conn; } + void remove(); +#endif + +private: + QString nm; + QString drv, dbName, uname, pword, hname; + QString dbErr; + int prt; + QStringList tbls; + QMap<QString, QStringList> flds; +#ifndef QT_NO_SQL + QSqlDatabase *conn; +#endif + Project *project; + bool loaded; + DesignerDatabase *iface; +}; + +#endif + +class Project : public QObject +{ + Q_OBJECT + friend class DatabaseConnection; + +public: + Project( const QString &fn, const QString &pName = QString::null, + QPluginManager<ProjectSettingsInterface> *pm = 0, bool isDummy = FALSE, + const QString &l = "C++" ); + ~Project(); + + void setFileName( const QString &fn, bool doClear = TRUE ); + QString fileName( bool singlePro = FALSE ) const; + QString projectName() const; + + void setDatabaseDescription( const QString &db ); + QString databaseDescription() const; + + void setDescription( const QString &s ); + QString description() const; + + void setLanguage( const QString &l ); + QString language() const; + + + bool isValid() const; + + // returns TRUE if this project is the <No Project> project + bool isDummy() const; + + QString makeAbsolute( const QString &f ); + QString makeRelative( const QString &f ); + + void save( bool onlyProjectFile = FALSE ); + +#ifndef QT_NO_SQL + QPtrList<DatabaseConnection> databaseConnections() const; + void setDatabaseConnections( const QPtrList<DatabaseConnection> &lst ); + void addDatabaseConnection( DatabaseConnection *conn ); + void removeDatabaseConnection( const QString &conn ); + DatabaseConnection *databaseConnection( const QString &name ); + QStringList databaseConnectionList(); + QStringList databaseTableList( const QString &connection ); + QStringList databaseFieldList( const QString &connection, const QString &table ); +#endif + void saveConnections(); + void loadConnections(); + + bool openDatabase( const QString &connection, bool suppressDialog = TRUE ); + void closeDatabase( const QString &connection ); + + QObjectList *formList( bool resolveFakeObjects = FALSE ) const; + + DesignerProject *iFace(); + + void setCustomSetting( const QString &key, const QString &value ); + QString customSetting( const QString &key ) const; + + PixmapCollection *pixmapCollection() const { return pixCollection; } + + void setActive( bool b ); + + QPtrListIterator<SourceFile> sourceFiles() const { return QPtrListIterator<SourceFile>(sourcefiles); } + void addSourceFile( SourceFile *sf ); + bool removeSourceFile( SourceFile *sf ); + SourceFile* findSourceFile( const QString& filename, SourceFile *ignore = 0 ) const; + + QPtrListIterator<FormFile> formFiles() const { return QPtrListIterator<FormFile>(formfiles); } + void addFormFile( FormFile *ff ); + bool removeFormFile( FormFile *ff ); + FormFile* findFormFile( const QString& filename, FormFile *ignore = 0 ) const; + + void setIncludePath( const QString &platform, const QString &path ); + void setLibs( const QString &platform, const QString &path ); + void setDefines( const QString &platform, const QString &path ); + void setConfig( const QString &platform, const QString &config ); + void setTemplate( const QString &t ); + + QString config( const QString &platform ) const; + QString libs( const QString &platform ) const; + QString defines( const QString &platform ) const; + QString includePath( const QString &platform ) const; + QString templte() const; + + bool isModified() const { return !isDummy() && modified; } + void setModified( bool b ); + + void addObject( QObject *o ); + void setObjects( const QObjectList &ol ); + void removeObject( QObject *o ); + QObjectList objects() const; + FormFile *fakeFormFileFor( QObject *o ) const; + QObject *objectForFakeForm( FormWindow *fw ) const; + QObject *objectForFakeFormFile( FormFile *ff ) const; + + void addAndEditFunction( const QString &functionName, const QString &functionBody, + bool openDeveloper ); + + void removeTempProject(); + bool hasParentObject( QObject *o ); + QString qualifiedName( QObject *o ); + + bool isCpp() const { return is_cpp; } + + void designerCreated(); + + void formOpened( FormWindow *fw ); + + QString locationOfObject( QObject *o ); + + bool hasGUI() const; + +signals: + void projectModified(); + void sourceFileAdded( SourceFile* ); + void sourceFileRemoved( SourceFile* ); + void formFileAdded( FormFile* ); + void formFileRemoved( FormFile* ); + void objectAdded( QObject * ); + void objectRemoved( QObject * ); + void newFormOpened( FormWindow *fw ); + +private: + void parse(); + void clear(); + void updateCustomSettings(); + void readPlatformSettings( const QString &contents, + const QString &setting, + QMap<QString, QString> &res ); + void removePlatformSettings( QString &contents, const QString &setting ); + void writePlatformSettings( QString &contents, const QString &setting, + const QMap<QString, QString> &input ); + bool singleProjectMode() const; + QWidget *messageBoxParent() const; + +private: + QString filename; + QString proName; + QString desc; + QString dbFile; +#ifndef QT_NO_SQL + QPtrList<DatabaseConnection> dbConnections; +#endif + QString lang; + DesignerProject *iface; + QMap<QString, QString> customSettings; + QStringList csList; + QPluginManager<ProjectSettingsInterface> *projectSettingsPluginManager; + PixmapCollection *pixCollection; + QPtrList<SourceFile> sourcefiles; + QPtrList<FormFile> formfiles; + QMap<QString, QString> inclPath, defs, lbs, cfg, sources, headers; + QString templ; + bool isDummyProject; + bool modified; + QObjectList objs; + QPtrDict<FormFile> fakeFormFiles; + QString singleProFileName; + bool is_cpp; + +}; + +#endif diff --git a/kdevdesigner/designer/projectsettings.ui b/kdevdesigner/designer/projectsettings.ui new file mode 100644 index 00000000..258b7739 --- /dev/null +++ b/kdevdesigner/designer/projectsettings.ui @@ -0,0 +1,301 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ProjectSettingsBase</class> +<comment>********************************************************************* +** Copyright (C) 2001-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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ProjectSettingsBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>375</width> + <height>224</height> + </rect> + </property> + <property name="caption"> + <string>Project Settings</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tabSettings</cstring> + </property> + <attribute name="title"> + <string>&Settings</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>&Project file:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editProjectFile</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel1_3</cstring> + </property> + <property name="text"> + <string>&Language:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboLanguage</cstring> + </property> + </widget> + <widget class="QToolButton" row="2" column="2"> + <property name="name"> + <cstring>buttonDatabaseFile_2</cstring> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>editDatabaseFile</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel1_2_2_2</cstring> + </property> + <property name="text"> + <string>&Database file:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editDatabaseFile</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>comboLanguage</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>editProjectFile</cstring> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>buttonProject</cstring> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </hbox> + </widget> + <spacer row="4" column="1"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>71</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonProject</sender> + <signal>clicked()</signal> + <receiver>ProjectSettingsBase</receiver> + <slot>chooseProjectFile()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ProjectSettingsBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>ProjectSettingsBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonHelp</sender> + <signal>clicked()</signal> + <receiver>ProjectSettingsBase</receiver> + <slot>helpClicked()</slot> + </connection> + <connection> + <sender>comboLanguage</sender> + <signal>activated(const QString&)</signal> + <receiver>ProjectSettingsBase</receiver> + <slot>languageChanged(const QString&)</slot> + </connection> +</connections> +<tabstops> + <tabstop>tabWidget</tabstop> + <tabstop>editProjectFile</tabstop> + <tabstop>comboLanguage</tabstop> + <tabstop>buttonHelp</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot access="protected">chooseDatabaseFile()</slot> + <slot access="protected">chooseProjectFile()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">helpClicked()</slot> + <slot access="protected">init()</slot> + <slot access="protected">languageChanged( const QString & )</slot> + <slot access="protected">okClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/projectsettingsimpl.cpp b/kdevdesigner/designer/projectsettingsimpl.cpp new file mode 100644 index 00000000..a1a2b6b1 --- /dev/null +++ b/kdevdesigner/designer/projectsettingsimpl.cpp @@ -0,0 +1,126 @@ +/********************************************************************** +** 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. +** +** 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 "projectsettingsimpl.h" +#include "project.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "mainwindow.h" +#include "asciivalidator.h" +#include "mainwindow.h" +#include "sourcefile.h" +#include "workspace.h" + +#include <kfiledialog.h> +#include <klocale.h> +#include <klineedit.h> + +#include <qtextedit.h> +#include <qcheckbox.h> +#include <qfiledialog.h> +#include <qcombobox.h> +#include <qobjectlist.h> +#include <qheader.h> +#include <qpushbutton.h> +#include <qlabel.h> + +/* + * Constructs a ProjectSettings which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +ProjectSettings::ProjectSettings( Project *pro, QWidget* parent, const char* name, bool modal, WFlags fl ) + : ProjectSettingsBase( parent, name, modal, fl ), project( pro ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + editProjectFile->setFocus(); + + if ( project->isDummy() ) { + editProjectFile->setEnabled( FALSE ); + editProjectFile->setText( project->projectName() ); + } else { + if ( project->fileName().isEmpty() || project->fileName() == ".pro" ) { + editProjectFile->setText( tr( "unnamed.pro" ) ); + editProjectFile->selectAll(); + } else { + editProjectFile->setText( project->fileName() ); + } + } + + editDatabaseFile->setText( project->databaseDescription() ); + + comboLanguage->insertStringList( MetaDataBase::languages() ); + for ( int j = 0; j < (int)comboLanguage->count(); ++j ) { + if ( project->language() == comboLanguage->text( j ) ) { + comboLanguage->setCurrentItem( j ); + break; + } + } +} + +/* + * Destroys the object and frees any allocated resources + */ +ProjectSettings::~ProjectSettings() +{ +} + +void ProjectSettings::chooseDatabaseFile() +{ + QString fn = KFileDialog::getSaveFileName( editDatabaseFile->text(), i18n( "*.db|Database Files\n*|All Files" ), this ); + if ( fn.isEmpty() ) + return; + editDatabaseFile->setText( fn ); +} + +void ProjectSettings::chooseProjectFile() +{ + QString fn = KFileDialog::getSaveFileName( editDatabaseFile->text(), i18n( "*.pro|Project Files\n*|All Files" ), this ); + if ( fn.isEmpty() ) + return; + editProjectFile->setText( fn ); +} + +void ProjectSettings::helpClicked() +{ +} + +void ProjectSettings::okClicked() +{ + // ### check for validity + project->setFileName( editProjectFile->text(), FALSE ); + project->setDatabaseDescription( editDatabaseFile->text() ); + project->setLanguage( comboLanguage->text( comboLanguage->currentItem() ) ); + project->setModified( TRUE ); + accept(); +} + +void ProjectSettings::languageChanged( const QString & ) +{ +} diff --git a/kdevdesigner/designer/projectsettingsimpl.h b/kdevdesigner/designer/projectsettingsimpl.h new file mode 100644 index 00000000..3833d813 --- /dev/null +++ b/kdevdesigner/designer/projectsettingsimpl.h @@ -0,0 +1,56 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PROJECTSETTINGSIMPL_H +#define PROJECTSETTINGSIMPL_H + +#include "projectsettings.h" + +class Project; +class QListViewItem; +class FormWindow; +class SourceFile; + +class ProjectSettings : public ProjectSettingsBase +{ + Q_OBJECT + +public: + ProjectSettings( Project *pro, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~ProjectSettings(); + +protected slots: + void chooseDatabaseFile(); + void chooseProjectFile(); + void helpClicked(); + void okClicked(); + void languageChanged( const QString &lang ); + +private: + Project *project; +}; + +#endif diff --git a/kdevdesigner/designer/propertyeditor.cpp b/kdevdesigner/designer/propertyeditor.cpp new file mode 100644 index 00000000..06b8f93b --- /dev/null +++ b/kdevdesigner/designer/propertyeditor.cpp @@ -0,0 +1,4332 @@ +/********************************************************************** +** 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 <qvariant.h> // HP-UX compiler needs this here + +#include "propertyeditor.h" +#include "formwindow.h" +#include "command.h" +#include "metadatabase.h" +#include "propertyobject.h" +#include <widgetdatabase.h> +#include "widgetfactory.h" +#include "globaldefs.h" +#include "defs.h" +#include "asciivalidator.h" +#include "paletteeditorimpl.h" +#include "multilineeditorimpl.h" +#include "mainwindow.h" +#include "project.h" +#include "hierarchyview.h" +#include "database.h" +#include "menubareditor.h" + +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include "kdevdesigner_part.h" + +#include <qpainter.h> +#include <qpalette.h> +#include <qapplication.h> +#include <qheader.h> +#include <qlineedit.h> +#include <qstrlist.h> +#include <qmetaobject.h> +#include <qcombobox.h> +#include <qpushbutton.h> +#include <qhbox.h> +#include <qfontdialog.h> +#include <qspinbox.h> +#include <qevent.h> +#include <qobjectlist.h> +#include <qlistbox.h> +#include <qfontdatabase.h> +#include <qcolor.h> +#include <qcolordialog.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qsizepolicy.h> +#include <qbitmap.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qaccel.h> +#include <qworkspace.h> +#include <qtimer.h> +#include <qdragobject.h> +#include <qdom.h> +#include <qprocess.h> +#include <qstyle.h> +#include <qdatetimeedit.h> +#include <qassistantclient.h> +#include <qdrawutil.h> +#include <qmultilineedit.h> // FIXME: obsolete +#include <qsplitter.h> +#include <qdatatable.h> +#include <qtextview.h> + +#include <limits.h> + + +static QFontDatabase *fontDataBase = 0; +QString assistantPath(); + +#ifdef Q_WS_MAC +#include <qwindowsstyle.h> +static void setupStyle(QWidget *w) +{ + static QStyle *windowsStyle = 0; + if(!windowsStyle) + windowsStyle = new QWindowsStyle; + w->setStyle(windowsStyle); +} +#else +#define setupStyle(x) +#endif + +static void cleanupFontDatabase() +{ + delete fontDataBase; + fontDataBase = 0; +} + +static QStringList getFontList() +{ + if ( !fontDataBase ) { + fontDataBase = new QFontDatabase; + qAddPostRoutine( cleanupFontDatabase ); + } + return fontDataBase->families(); +} + + +class PropertyWhatsThis : public QWhatsThis +{ +public: + PropertyWhatsThis( PropertyList *l ); + QString text( const QPoint &pos ); + bool clicked( const QString& href ); + +private: + PropertyList *propertyList; + +}; + +PropertyWhatsThis::PropertyWhatsThis( PropertyList *l ) + : QWhatsThis( l->viewport() ), propertyList( l ) +{ +} + +QString PropertyWhatsThis::text( const QPoint &pos ) +{ + return propertyList->whatsThisAt( pos ); +} + +bool PropertyWhatsThis::clicked( const QString& href ) +{ + if ( !href.isEmpty() ) { + QAssistantClient *ac = MainWindow::self->assistantClient(); + ac->showPage( QString( qInstallPathDocs() ) + "/html/" + href ); + } + return FALSE; // do not hide window +} + + +/*! + \class PropertyItem propertyeditor.h + \brief Base class for all property items + + This is the base class for each property item for the + PropertyList. A simple property item has just a name and a value to + provide an editor for a datatype. But more complex datatypes might + provide an expandable item for editing single parts of the + datatype. See hasSubItems(), initChildren() for that. +*/ + +/*! If this item should be a child of another property item, specify + \a prop as the parent item. +*/ + +PropertyItem::PropertyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : QListViewItem( l, after ), listview( l ), property( prop ), propertyName( propName ) +{ + setSelectable( FALSE ); + open = FALSE; + setText( 0, propertyName ); + changed = FALSE; + setText( 1, "" ); + resetButton = 0; +} + +PropertyItem::~PropertyItem() +{ + if ( resetButton ) + delete resetButton->parentWidget(); + resetButton = 0; +} + +void PropertyItem::toggle() +{ +} + +void PropertyItem::updateBackColor() +{ + if ( itemAbove() && this != listview->firstChild() ) { + if ( ( ( PropertyItem*)itemAbove() )->backColor == *backColor1 ) + backColor = *backColor2; + else + backColor = *backColor1; + } else { + backColor = *backColor1; + } + if ( listview->firstChild() == this ) + backColor = *backColor1; +} + +QColor PropertyItem::backgroundColor() +{ + updateBackColor(); + if ( (QListViewItem*)this == listview->currentItem() ) + return *selectedBack; + return backColor; +} + +/*! If a subclass is a expandable item, this is called when the child +items should be created. +*/ + +void PropertyItem::createChildren() +{ +} + +/*! If a subclass is a expandable item, this is called when the child +items should be initialized. +*/ + +void PropertyItem::initChildren() +{ +} + +void PropertyItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + g.setColor( QColorGroup::Foreground, Qt::black ); + g.setColor( QColorGroup::Text, Qt::black ); + int indent = 0; + if ( column == 0 ) { + indent = 20 + ( property ? 20 : 0 ); + p->fillRect( 0, 0, width, height(), backgroundColor() ); + p->save(); + p->translate( indent, 0 ); + } + + if ( isChanged() && column == 0 ) { + p->save(); + QFont f = p->font(); + f.setBold( TRUE ); + p->setFont( f ); + } + + if ( !hasCustomContents() || column != 1 ) { + QListViewItem::paintCell( p, g, column, width - indent, align ); + } else { + p->fillRect( 0, 0, width, height(), backgroundColor() ); + drawCustomContents( p, QRect( 0, 0, width, height() ) ); + } + + if ( isChanged() && column == 0 ) + p->restore(); + if ( column == 0 ) + p->restore(); + if ( hasSubItems() && column == 0 ) { + p->save(); + p->setPen( cg.foreground() ); + p->setBrush( cg.base() ); + p->drawRect( 5, height() / 2 - 4, 9, 9 ); + p->drawLine( 7, height() / 2, 11, height() / 2 ); + if ( !isOpen() ) + p->drawLine( 9, height() / 2 - 2, 9, height() / 2 + 2 ); + p->restore(); + } + p->save(); + p->setPen( QPen( cg.dark(), 1 ) ); + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); + + if ( listview->currentItem() == this && column == 0 && + !listview->hasFocus() && !listview->viewport()->hasFocus() ) + paintFocus( p, cg, QRect( 0, 0, width, height() ) ); +} + +void PropertyItem::paintBranches( QPainter * p, const QColorGroup & cg, + int w, int y, int h ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + QListViewItem::paintBranches( p, g, w, y, h ); +} + +void PropertyItem::paintFocus( QPainter *p, const QColorGroup &cg, const QRect &r ) +{ + p->save(); + QApplication::style().drawPrimitive(QStyle::PE_Panel, p, r, cg, + QStyle::Style_Sunken, QStyleOption(1,1) ); + p->restore(); +} + +/*! Subclasses which are expandable items have to return TRUE + here. Default is FALSE. +*/ + +bool PropertyItem::hasSubItems() const +{ + return FALSE; +} + +/*! Returns the parent property item here if this is a child or 0 + otherwise. + */ + +PropertyItem *PropertyItem::propertyParent() const +{ + return property; +} + +bool PropertyItem::isOpen() const +{ + return open; +} + +void PropertyItem::setOpen( bool b ) +{ + if ( b == open ) + return; + open = b; + + if ( !open ) { + children.setAutoDelete( TRUE ); + children.clear(); + children.setAutoDelete( FALSE ); + qApp->processEvents(); + listview->updateEditorSize(); + return; + } + + createChildren(); + initChildren(); + qApp->processEvents(); + listview->updateEditorSize(); +} + +/*! Subclasses have to show the editor of the item here +*/ + +void PropertyItem::showEditor() +{ + createResetButton(); + resetButton->parentWidget()->show(); +} + +/*! Subclasses have to hide the editor of the item here +*/ + +void PropertyItem::hideEditor() +{ + createResetButton(); + resetButton->parentWidget()->hide(); +} + +/*! This is called to init the value of the item. Reimplement in + subclasses to init the editor +*/ + +void PropertyItem::setValue( const QVariant &v ) +{ + val = v; +} + +QVariant PropertyItem::value() const +{ + return val; +} + +bool PropertyItem::isChanged() const +{ + return changed; +} + +void PropertyItem::setChanged( bool b, bool updateDb ) +{ + if ( propertyParent() ) + return; + if ( changed == b ) + return; + changed = b; + repaint(); + if ( updateDb ) { + MetaDataBase::setPropertyChanged( listview->propertyEditor()->widget(), name(), changed ); + } + updateResetButtonState(); +} + +QString PropertyItem::name() const +{ + return propertyName; +} + +void PropertyItem::createResetButton() +{ + if ( resetButton ) { + resetButton->parentWidget()->lower(); + return; + } + const QPixmap DesignerResetPix = SmallIcon( "designer_resetproperty.png" , KDevDesignerPartFactory::instance()); + + QHBox *hbox = new QHBox( listview->viewport() ); + hbox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + hbox->setLineWidth( 1 ); + resetButton = new QPushButton( hbox ); + setupStyle( resetButton ); + resetButton->setPixmap( DesignerResetPix ); + resetButton->setFixedWidth( resetButton->sizeHint().width() ); + hbox->layout()->setAlignment( Qt::AlignRight ); + listview->addChild( hbox ); + hbox->hide(); + QObject::connect( resetButton, SIGNAL( clicked() ), + listview, SLOT( resetProperty() ) ); + QToolTip::add( resetButton, i18n( "Reset the property to its default value" ) ); + QWhatsThis::add( resetButton, i18n( "Click this button to reset the property to its default value" ) ); + updateResetButtonState(); +} + +void PropertyItem::updateResetButtonState() +{ + if ( !resetButton ) + return; + if ( propertyParent() || !WidgetFactory::canResetProperty( listview->propertyEditor()->widget(), name() ) ) + resetButton->setEnabled( FALSE ); + else + resetButton->setEnabled( isChanged() ); +} + +/*! Call this to place/resize the item editor correctly (normally + call it from showEditor()) +*/ + +void PropertyItem::placeEditor( QWidget *w ) +{ + createResetButton(); + QRect r = listview->itemRect( this ); + if ( !r.size().isValid() ) { + listview->ensureItemVisible( this ); +#if defined(Q_WS_WIN) + listview->repaintContents( FALSE ); +#endif + r = listview->itemRect( this ); + } + r.setX( listview->header()->sectionPos( 1 ) ); + r.setWidth( listview->header()->sectionSize( 1 ) - 1 ); + r.setWidth( r.width() - resetButton->width() - 2 ); + r = QRect( listview->viewportToContents( r.topLeft() ), r.size() ); + w->resize( r.size() ); + listview->moveChild( w, r.x(), r.y() ); + resetButton->parentWidget()->resize( resetButton->sizeHint().width() + 10, r.height() ); + listview->moveChild( resetButton->parentWidget(), r.x() + r.width() - 8, r.y() ); + resetButton->setFixedHeight( QMAX( 0, r.height() - 3 ) ); +} + +/*! This should be called by subclasses if the user changed the value + of the property and this value should be applied to the widget property +*/ + +void PropertyItem::notifyValueChange() +{ + if ( !propertyParent() ) { + listview->valueChanged( this ); + setChanged( TRUE ); + if ( hasSubItems() ) + initChildren(); + } else { + propertyParent()->childValueChanged( this ); + setChanged( TRUE ); + } +} + +/*! If a subclass is a expandable item reimplement this as this is + always called if a child item changed its value. So update the + display of the item here then. +*/ + +void PropertyItem::childValueChanged( PropertyItem * ) +{ +} + +/*! When adding a child item, call this (normally from addChildren() +*/ + +void PropertyItem::addChild( PropertyItem *i ) +{ + children.append( i ); +} + +int PropertyItem::childCount() const +{ + return children.count(); +} + +PropertyItem *PropertyItem::child( int i ) const +{ + // ARRRRRRRRG + return ( (PropertyItem*)this )->children.at( i ); +} + +/*! If the contents of the item is not displayable with a text, but + you want to draw it yourself (using drawCustomContents()), return + TRUE here. +*/ + +bool PropertyItem::hasCustomContents() const +{ + return FALSE; +} + +/*! + \sa hasCustomContents() +*/ + +void PropertyItem::drawCustomContents( QPainter *, const QRect & ) +{ +} + +QString PropertyItem::currentItem() const +{ + return QString::null; +} + +int PropertyItem::currentIntItem() const +{ + return -1; +} + +void PropertyItem::setCurrentItem( const QString & ) +{ +} + +void PropertyItem::setCurrentItem( int ) +{ +} + +int PropertyItem::currentIntItemFromObject() const +{ + return -1; +} + +QString PropertyItem::currentItemFromObject() const +{ + return QString::null; +} + +void PropertyItem::setFocus( QWidget *w ) +{ + if ( !qApp->focusWidget() || + listview->propertyEditor()->formWindow() && + ( !MainWindow::self->isAFormWindowChild( qApp->focusWidget() ) && + !qApp->focusWidget()->inherits( "Editor" ) ) ) + w->setFocus(); +} + +void PropertyItem::setText( int col, const QString &t ) +{ + QString txt( t ); + if ( col == 1 ) + txt = txt.replace( "\n", " " ); + QListViewItem::setText( col, txt ); +} + +// -------------------------------------------------------------- + +PropertyTextItem::PropertyTextItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool comment, bool multiLine, bool ascii, bool a ) + : PropertyItem( l, after, prop, propName ), withComment( comment ), + hasMultiLines( multiLine ), asciiOnly( ascii ), accel( a ) +{ + lin = 0; + box = 0; +} + +QLineEdit *PropertyTextItem::lined() +{ + if ( lin ) + return lin; + if ( hasMultiLines ) { + box = new QHBox( listview->viewport() ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + box->hide(); + } + + lin = 0; + if ( hasMultiLines ) + lin = new QLineEdit( box ); + else + lin = new QLineEdit( listview->viewport() ); + + if ( asciiOnly ) { + if ( PropertyItem::name() == "name" ) { + lin->setValidator( new AsciiValidator( QString(":"), lin, "ascii_validator" ) ); + if ( listview->propertyEditor()->formWindow()->isFake() ) + lin->setEnabled( FALSE ); + } else { + lin->setValidator( new AsciiValidator( QString("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9" + "\xaa\xab\xac\xad\xae\xaf\xb1\xb2\xb3" + "\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc" + "\xbd\xbe\xbf"), lin, "ascii_validator" ) ); + } + } if ( !hasMultiLines ) { + lin->hide(); + } else { + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getText() ) ); + lin->setFrame( FALSE ); + } + connect( lin, SIGNAL( returnPressed() ), + this, SLOT( setValue() ) ); + connect( lin, SIGNAL( textChanged( const QString & ) ), + this, SLOT( setValue() ) ); + if ( PropertyItem::name() == "name" || PropertyItem::name() == "itemName" ) + connect( lin, SIGNAL( returnPressed() ), + listview->propertyEditor()->formWindow()->commandHistory(), + SLOT( checkCompressedCommand() ) ); + lin->installEventFilter( listview ); + return lin; +} + +PropertyTextItem::~PropertyTextItem() +{ + delete (QLineEdit*)lin; + lin = 0; + delete (QHBox*)box; + box = 0; +} + +void PropertyTextItem::setChanged( bool b, bool updateDb ) +{ + PropertyItem::setChanged( b, updateDb ); + if ( withComment && childCount() > 0 ) + ( (PropertyTextItem*)PropertyItem::child( 0 ) )->lined()->setEnabled( b ); +} + +bool PropertyTextItem::hasSubItems() const +{ + return withComment; +} + +void PropertyTextItem::childValueChanged( PropertyItem *child ) +{ + if ( PropertyItem::name() != "name" ) + MetaDataBase::setPropertyComment( listview->propertyEditor()->widget(), + PropertyItem::name(), child->value().toString() ); + else + MetaDataBase::setExportMacro( listview->propertyEditor()->widget(), child->value().toString() ); + listview->propertyEditor()->formWindow()->commandHistory()->setModified( TRUE ); +} + +void PropertyTextItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin || lin->text().length() == 0 ) { + lined()->blockSignals( TRUE ); + lined()->setText( value().toString() ); + lined()->blockSignals( FALSE ); + } + + QWidget* w; + if ( hasMultiLines ) + w = box; + else + w= lined(); + + placeEditor( w ); + if ( !w->isVisible() || !lined()->hasFocus() ) { + w->show(); + setFocus( lined() ); + } +} + +void PropertyTextItem::createChildren() +{ + PropertyTextItem *i = new PropertyTextItem( listview, this, this, + PropertyItem::name() == "name" ? + "export macro" : "comment", FALSE, FALSE, + PropertyItem::name() == "name" ); + i->lined()->setEnabled( isChanged() ); + addChild( i ); +} + +void PropertyTextItem::initChildren() +{ + if ( !childCount() ) + return; + PropertyItem *item = PropertyItem::child( 0 ); + if ( item ) { + if ( PropertyItem::name() != "name" ) + item->setValue( MetaDataBase::propertyComment( listview->propertyEditor()->widget(), + PropertyItem::name() ) ); + else + item->setValue( MetaDataBase::exportMacro( listview->propertyEditor()->widget() ) ); + } +} + +void PropertyTextItem::hideEditor() +{ + PropertyItem::hideEditor(); + QWidget* w; + if ( hasMultiLines ) + w = box; + else + w = lined(); + + w->hide(); +} + +void PropertyTextItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + if ( lin ) { + lined()->blockSignals( TRUE ); + int oldCursorPos; + oldCursorPos = lin->cursorPosition(); + lined()->setText( v.toString() ); + if ( oldCursorPos < (int)lin->text().length() ) + lin->setCursorPosition( oldCursorPos ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toString() ); + PropertyItem::setValue( v ); +} + +void PropertyTextItem::setValue() +{ + setText( 1, lined()->text() ); + QVariant v; + if ( accel ) { + v = QVariant( QKeySequence( lined()->text() ) ); + if ( v.toString().isNull() ) + return; // not yet valid input + } else { + v = lined()->text(); + } + PropertyItem::setValue( v ); + notifyValueChange(); +} + +void PropertyTextItem::getText() +{ + bool richText = !::qt_cast<QButton*>(listview->propertyEditor()->widget()) || + ( text( 0 ) == "whatsThis" ); + bool doWrap = FALSE; + QString txt = MultiLineEditor::getText( listview, value().toString(), richText, &doWrap ); + if ( !txt.isEmpty() ) { + setText( 1, txt ); + PropertyItem::setValue( txt ); + notifyValueChange(); + lined()->blockSignals( TRUE ); + lined()->setText( txt ); + lined()->blockSignals( FALSE ); + } +} + +// -------------------------------------------------------------- + +PropertyDoubleItem::PropertyDoubleItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QLineEdit *PropertyDoubleItem::lined() +{ + if ( lin ) + return lin; + lin = new QLineEdit( listview->viewport() ); + lin->setValidator( new QDoubleValidator( lin, "double_validator" ) ); + + connect( lin, SIGNAL( returnPressed() ), + this, SLOT( setValue() ) ); + connect( lin, SIGNAL( textChanged( const QString & ) ), + this, SLOT( setValue() ) ); + lin->installEventFilter( listview ); + return lin; +} + +PropertyDoubleItem::~PropertyDoubleItem() +{ + delete (QLineEdit*)lin; + lin = 0; +} + +void PropertyDoubleItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setText( QString::number( value().toDouble() ) ); + lined()->blockSignals( FALSE ); + } + QWidget* w = lined(); + + placeEditor( w ); + if ( !w->isVisible() || !lined()->hasFocus() ) { + w->show(); + setFocus( lined() ); + } +} + + +void PropertyDoubleItem::hideEditor() +{ + PropertyItem::hideEditor(); + QWidget* w = lined(); + w->hide(); +} + +void PropertyDoubleItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + if ( lin ) { + lined()->blockSignals( TRUE ); + int oldCursorPos; + oldCursorPos = lin->cursorPosition(); + lined()->setText( QString::number( v.toDouble() ) ); + if ( oldCursorPos < (int)lin->text().length() ) + lin->setCursorPosition( oldCursorPos ); + lined()->blockSignals( FALSE ); + } + setText( 1, QString::number( v.toDouble() ) ); + PropertyItem::setValue( v ); +} + +void PropertyDoubleItem::setValue() +{ + setText( 1, lined()->text() ); + QVariant v = lined()->text().toDouble(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + + +// -------------------------------------------------------------- + +PropertyDateItem::PropertyDateItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QDateEdit *PropertyDateItem::lined() +{ + if ( lin ) + return lin; + lin = new QDateEdit( listview->viewport() ); + QObjectList *l = lin->queryList( "QLineEdit" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( listview ); + delete l; + connect( lin, SIGNAL( valueChanged( const QDate & ) ), + this, SLOT( setValue() ) ); + return lin; +} + +PropertyDateItem::~PropertyDateItem() +{ + delete (QDateEdit*)lin; + lin = 0; +} + +void PropertyDateItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setDate( value().toDate() ); + lined()->blockSignals( FALSE ); + } + placeEditor( lin ); + if ( !lin->isVisible() ) { + lin->show(); + setFocus( lin ); + } +} + +void PropertyDateItem::hideEditor() +{ + PropertyItem::hideEditor(); + if ( lin ) + lin->hide(); +} + +void PropertyDateItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( lin ) { + lined()->blockSignals( TRUE ); + if ( lined()->date() != v.toDate() ) + lined()->setDate( v.toDate() ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toDate().toString( ::Qt::ISODate ) ); + PropertyItem::setValue( v ); +} + +void PropertyDateItem::setValue() +{ + setText( 1, lined()->date().toString( ::Qt::ISODate ) ); + QVariant v; + v = lined()->date(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyTimeItem::PropertyTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QTimeEdit *PropertyTimeItem::lined() +{ + if ( lin ) + return lin; + lin = new QTimeEdit( listview->viewport() ); + connect( lin, SIGNAL( valueChanged( const QTime & ) ), + this, SLOT( setValue() ) ); + QObjectList *l = lin->queryList( "QLineEdit" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( listview ); + delete l; + return lin; +} + +PropertyTimeItem::~PropertyTimeItem() +{ + delete (QTimeEdit*)lin; + lin = 0; +} + +void PropertyTimeItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setTime( value().toTime() ); + lined()->blockSignals( FALSE ); + } + placeEditor( lin ); + if ( !lin->isVisible() ) { + lin->show(); + setFocus( lin ); + } +} + +void PropertyTimeItem::hideEditor() +{ + PropertyItem::hideEditor(); + if ( lin ) + lin->hide(); +} + +void PropertyTimeItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( lin ) { + lined()->blockSignals( TRUE ); + if ( lined()->time() != v.toTime() ) + lined()->setTime( v.toTime() ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toTime().toString( ::Qt::ISODate ) ); + PropertyItem::setValue( v ); +} + +void PropertyTimeItem::setValue() +{ + setText( 1, lined()->time().toString( ::Qt::ISODate ) ); + QVariant v; + v = lined()->time(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyDateTimeItem::PropertyDateTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QDateTimeEdit *PropertyDateTimeItem::lined() +{ + if ( lin ) + return lin; + lin = new QDateTimeEdit( listview->viewport() ); + connect( lin, SIGNAL( valueChanged( const QDateTime & ) ), + this, SLOT( setValue() ) ); + QObjectList *l = lin->queryList( "QLineEdit" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( listview ); + delete l; + return lin; +} + +PropertyDateTimeItem::~PropertyDateTimeItem() +{ + delete (QDateTimeEdit*)lin; + lin = 0; +} + +void PropertyDateTimeItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setDateTime( value().toDateTime() ); + lined()->blockSignals( FALSE ); + } + placeEditor( lin ); + if ( !lin->isVisible() ) { + lin->show(); + setFocus( lin ); + } +} + +void PropertyDateTimeItem::hideEditor() +{ + PropertyItem::hideEditor(); + if ( lin ) + lin->hide(); +} + +void PropertyDateTimeItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( lin ) { + lined()->blockSignals( TRUE ); + if ( lined()->dateTime() != v.toDateTime() ) + lined()->setDateTime( v.toDateTime() ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toDateTime().toString( ::Qt::ISODate ) ); + PropertyItem::setValue( v ); +} + +void PropertyDateTimeItem::setValue() +{ + setText( 1, lined()->dateTime().toString( ::Qt::ISODate ) ); + QVariant v; + v = lined()->dateTime(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyBoolItem::PropertyBoolItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + comb = 0; +} + +QComboBox *PropertyBoolItem::combo() +{ + if ( comb ) + return comb; + comb = new QComboBox( FALSE, listview->viewport() ); + comb->hide(); + comb->insertItem( i18n( "False" ) ); + comb->insertItem( i18n( "True" ) ); + connect( comb, SIGNAL( activated( int ) ), + this, SLOT( setValue() ) ); + comb->installEventFilter( listview ); + return comb; +} + +PropertyBoolItem::~PropertyBoolItem() +{ + delete (QComboBox*)comb; + comb = 0; +} + +void PropertyBoolItem::toggle() +{ + bool b = value().toBool(); + setValue( QVariant( !b, 0 ) ); + setValue(); +} + +void PropertyBoolItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !comb ) { + combo()->blockSignals( TRUE ); + if ( value().toBool() ) + combo()->setCurrentItem( 1 ); + else + combo()->setCurrentItem( 0 ); + combo()->blockSignals( FALSE ); + } + placeEditor( combo() ); + if ( !combo()->isVisible() || !combo()->hasFocus() ) { + combo()->show(); + setFocus( combo() ); + } +} + +void PropertyBoolItem::hideEditor() +{ + PropertyItem::hideEditor(); + combo()->hide(); +} + +void PropertyBoolItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( comb ) { + combo()->blockSignals( TRUE ); + if ( v.toBool() ) + combo()->setCurrentItem( 1 ); + else + combo()->setCurrentItem( 0 ); + combo()->blockSignals( FALSE ); + } + QString tmp = i18n( "True" ); + if ( !v.toBool() ) + tmp = i18n( "False" ); + setText( 1, tmp ); + PropertyItem::setValue( v ); +} + +void PropertyBoolItem::setValue() +{ + if ( !comb ) + return; + setText( 1, combo()->currentText() ); + bool b = combo()->currentItem() == 0 ? (bool)FALSE : (bool)TRUE; + PropertyItem::setValue( QVariant( b, 0 ) ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyIntItem::PropertyIntItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool s ) + : PropertyItem( l, after, prop, propName ), signedValue( s ) +{ + spinBx = 0; +} + +QSpinBox *PropertyIntItem::spinBox() +{ + if ( spinBx ) + return spinBx; + if ( signedValue ) + spinBx = new QSpinBox( -INT_MAX, INT_MAX, 1, listview->viewport() ); + else + spinBx = new QSpinBox( 0, INT_MAX, 1, listview->viewport() ); + spinBx->hide(); + spinBx->installEventFilter( listview ); + QObjectList *ol = spinBx->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ol->first()->installEventFilter( listview ); + delete ol; + connect( spinBx, SIGNAL( valueChanged( int ) ), + this, SLOT( setValue() ) ); + return spinBx; +} + +PropertyIntItem::~PropertyIntItem() +{ + delete (QSpinBox*)spinBx; + spinBx = 0; +} + +void PropertyIntItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !spinBx ) { + spinBox()->blockSignals( TRUE ); + if ( signedValue ) + spinBox()->setValue( value().toInt() ); + else + spinBox()->setValue( value().toUInt() ); + spinBox()->blockSignals( FALSE ); + } + placeEditor( spinBox() ); + if ( !spinBox()->isVisible() || !spinBox()->hasFocus() ) { + spinBox()->show(); + setFocus( spinBox() ); + } +} + +void PropertyIntItem::hideEditor() +{ + PropertyItem::hideEditor(); + spinBox()->hide(); +} + +void PropertyIntItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( spinBx ) { + spinBox()->blockSignals( TRUE ); + if ( signedValue ) + spinBox()->setValue( v.toInt() ); + else + spinBox()->setValue( v.toUInt() ); + spinBox()->blockSignals( FALSE ); + } + + if ( signedValue ) + setText( 1, QString::number( v.toInt() ) ); + else + setText( 1, QString::number( v.toUInt() ) ); + PropertyItem::setValue( v ); +} + +void PropertyIntItem::setValue() +{ + if ( !spinBx ) + return; + setText( 1, QString::number( spinBox()->value() ) ); + if ( signedValue ) + PropertyItem::setValue( spinBox()->value() ); + else + PropertyItem::setValue( (uint)spinBox()->value() ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyLayoutItem::PropertyLayoutItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + spinBx = 0; +} + +PropertyLayoutItem::~PropertyLayoutItem() +{ + delete (QSpinBox*)spinBx; + spinBx = 0; +} + +QSpinBox* PropertyLayoutItem::spinBox() +{ + if ( spinBx ) + return spinBx; + spinBx = new QSpinBox( -1, INT_MAX, 1, listview->viewport() ); + spinBx->setSpecialValueText( i18n( "default" ) ); + spinBx->hide(); + spinBx->installEventFilter( listview ); + QObjectList *ol = spinBx->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ol->first()->installEventFilter( listview ); + delete ol; + connect( spinBx, SIGNAL( valueChanged( int ) ), + this, SLOT( setValue() ) ); + return spinBx; +} + +void PropertyLayoutItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !spinBx ) { + spinBox()->blockSignals( TRUE ); + spinBox()->setValue( value().toInt() ); + spinBox()->blockSignals( TRUE ); + } + placeEditor( spinBox() ); + if ( !spinBox()->isVisible() || !spinBox()->hasFocus() ) { + spinBox()->show(); + setFocus( spinBox() ); + } +} + +void PropertyLayoutItem::hideEditor() +{ + PropertyItem::hideEditor(); + spinBox()->hide(); +} + +void PropertyLayoutItem::setValue( const QVariant &v ) +{ + if ( spinBx ) { + spinBox()->blockSignals( TRUE ); + spinBox()->setValue( v.toInt() ); + spinBox()->blockSignals( FALSE ); + } + QString s = v.toString(); + if ( v.toInt() == -1 ) + s = spinBox()->specialValueText(); + setText( 1, s ); + PropertyItem::setValue( v ); +} + +void PropertyLayoutItem::setValue() +{ + if ( !spinBx ) + return; + PropertyItem::setValue( spinBox()->value() ); + notifyValueChange(); +} + + +// -------------------------------------------------------------- + +PropertyListItem::PropertyListItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool e ) + : PropertyItem( l, after, prop, propName ), editable( e ) +{ + comb = 0; + oldInt = -1; +} + +QComboBox *PropertyListItem::combo() +{ + if ( comb ) + return comb; + comb = new QComboBox( editable, listview->viewport() ); + comb->hide(); + connect( comb, SIGNAL( activated( int ) ), + this, SLOT( setValue() ) ); + comb->installEventFilter( listview ); + if ( editable ) { + QObjectList *ol = comb->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ol->first()->installEventFilter( listview ); + delete ol; + } + return comb; +} + +PropertyListItem::~PropertyListItem() +{ + delete (QComboBox*)comb; + comb = 0; +} + +void PropertyListItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( value().toStringList() ); + combo()->blockSignals( FALSE ); + } + placeEditor( combo() ); + if ( !combo()->isVisible() || !combo()->hasFocus() ) { + combo()->show(); + setFocus( combo() ); + } +} + +void PropertyListItem::hideEditor() +{ + PropertyItem::hideEditor(); + combo()->hide(); +} + +void PropertyListItem::setValue( const QVariant &v ) +{ + if ( comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( v.toStringList() ); + combo()->blockSignals( FALSE ); + } + setText( 1, v.toStringList().first() ); + PropertyItem::setValue( v ); +} + +void PropertyListItem::setValue() +{ + if ( !comb ) + return; + setText( 1, combo()->currentText() ); + QStringList lst; + for ( uint i = 0; i < combo()->listBox()->count(); ++i ) + lst << combo()->listBox()->item( i )->text(); + PropertyItem::setValue( lst ); + notifyValueChange(); + oldInt = currentIntItem(); + oldString = currentItem(); +} + +QString PropertyListItem::currentItem() const +{ + return ( (PropertyListItem*)this )->combo()->currentText(); +} + +void PropertyListItem::setCurrentItem( const QString &s ) +{ + if ( comb && currentItem().lower() == s.lower() ) + return; + + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( value().toStringList() ); + combo()->blockSignals( FALSE ); + } + for ( uint i = 0; i < combo()->listBox()->count(); ++i ) { + if ( combo()->listBox()->item( i )->text().lower() == s.lower() ) { + combo()->setCurrentItem( i ); + setText( 1, combo()->currentText() ); + break; + } + } + oldInt = currentIntItem(); + oldString = currentItem(); +} + +void PropertyListItem::addItem( const QString &s ) +{ + combo()->insertItem( s ); +} + +void PropertyListItem::setCurrentItem( int i ) +{ + if ( comb && i == combo()->currentItem() ) + return; + + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( value().toStringList() ); + combo()->blockSignals( FALSE ); + } + combo()->setCurrentItem( i ); + setText( 1, combo()->currentText() ); + oldInt = currentIntItem(); + oldString = currentItem(); +} + +int PropertyListItem::currentIntItem() const +{ + return ( (PropertyListItem*)this )->combo()->currentItem(); +} + +int PropertyListItem::currentIntItemFromObject() const +{ + return oldInt; +} + +QString PropertyListItem::currentItemFromObject() const +{ + return oldString; +} + +// -------------------------------------------------------------- + +PropertyCoordItem::PropertyCoordItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ) + : PropertyItem( l, after, prop, propName ), typ( t ) +{ + lin = 0; + +} + +QLineEdit *PropertyCoordItem::lined() +{ + if ( lin ) + return lin; + lin = new QLineEdit( listview->viewport() ); + lin->setReadOnly( TRUE ); + lin->installEventFilter( listview ); + lin->hide(); + return lin; +} + +void PropertyCoordItem::createChildren() +{ + PropertyItem *i = this; + if ( typ == Rect || typ == Point ) { + i = new PropertyIntItem( listview, i, this, i18n( "x" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "y" ), TRUE ); + addChild( i ); + } + if ( typ == Rect || typ == Size ) { + i = new PropertyIntItem( listview, i, this, i18n( "width" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "height" ), TRUE ); + addChild( i ); + } +} + +void PropertyCoordItem::initChildren() +{ + PropertyItem *item = 0; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == i18n( "x" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().x() ); + else if ( typ == Point ) + item->setValue( val.toPoint().x() ); + } else if ( item->name() == i18n( "y" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().y() ); + else if ( typ == Point ) + item->setValue( val.toPoint().y() ); + } else if ( item->name() == i18n( "width" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().width() ); + else if ( typ == Size ) + item->setValue( val.toSize().width() ); + } else if ( item->name() == i18n( "height" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().height() ); + else if ( typ == Size ) + item->setValue( val.toSize().height() ); + } + } +} + +PropertyCoordItem::~PropertyCoordItem() +{ + delete (QLineEdit*)lin; + lin = 0; +} + +void PropertyCoordItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) + lined()->setText( text( 1 ) ); + placeEditor( lined() ); + if ( !lined()->isVisible() || !lined()->hasFocus() ) { + lined()->show(); + setFocus( lined() ); + } +} + +void PropertyCoordItem::hideEditor() +{ + PropertyItem::hideEditor(); + lined()->hide(); +} + +void PropertyCoordItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + QString s; + if ( typ == Rect ) + s = "[ " + QString::number( v.toRect().x() ) + ", " + QString::number( v.toRect().y() ) + ", " + + QString::number( v.toRect().width() ) + ", " + QString::number( v.toRect().height() ) + " ]"; + else if ( typ == Point ) + s = "[ " + QString::number( v.toPoint().x() ) + ", " + + QString::number( v.toPoint().y() ) + " ]"; + else if ( typ == Size ) + s = "[ " + QString::number( v.toSize().width() ) + ", " + + QString::number( v.toSize().height() ) + " ]"; + setText( 1, s ); + if ( lin ) + lined()->setText( s ); + PropertyItem::setValue( v ); +} + +bool PropertyCoordItem::hasSubItems() const +{ + return TRUE; +} + +void PropertyCoordItem::childValueChanged( PropertyItem *child ) +{ + if ( typ == Rect ) { + QRect r = value().toRect(); + if ( child->name() == i18n( "x" ) ) + r.moveBy( -r.x() + child->value().toInt(), 0 ); + else if ( child->name() == i18n( "y" ) ) + r.moveBy( 0, -r.y() + child->value().toInt() ); + else if ( child->name() == i18n( "width" ) ) + r.setWidth( child->value().toInt() ); + else if ( child->name() == i18n( "height" ) ) + r.setHeight( child->value().toInt() ); + setValue( r ); + } else if ( typ == Point ) { + QPoint r = value().toPoint(); + if ( child->name() == i18n( "x" ) ) + r.setX( child->value().toInt() ); + else if ( child->name() == i18n( "y" ) ) + r.setY( child->value().toInt() ); + setValue( r ); + } else if ( typ == Size ) { + QSize r = value().toSize(); + if ( child->name() == i18n( "width" ) ) + r.setWidth( child->value().toInt() ); + else if ( child->name() == i18n( "height" ) ) + r.setHeight( child->value().toInt() ); + setValue( r ); + } + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyPixmapItem::PropertyPixmapItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ) + : PropertyItem( l, after, prop, propName ), type( t ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + pixPrev = new QLabel( box ); + pixPrev->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Minimum ) ); + pixPrev->setBackgroundColor( pixPrev->colorGroup().color( QColorGroup::Base ) ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + pixPrev->setFrameStyle( QFrame::NoFrame ); + box->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getPixmap() ) ); +} + +PropertyPixmapItem::~PropertyPixmapItem() +{ + delete (QHBox*)box; +} + +void PropertyPixmapItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertyPixmapItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyPixmapItem::setValue( const QVariant &v ) +{ + QString s; + if ( type == Pixmap ) + pixPrev->setPixmap( v.toPixmap() ); + else if ( type == IconSet ) + pixPrev->setPixmap( v.toIconSet().pixmap() ); + else + pixPrev->setPixmap( v.toImage() ); + PropertyItem::setValue( v ); + repaint(); +} + +void PropertyPixmapItem::getPixmap() +{ + QPixmap pix = qChoosePixmap( listview, listview->propertyEditor()->formWindow(), value().toPixmap() ); + if ( !pix.isNull() ) { + if ( type == Pixmap ) + setValue( pix ); + else if ( type == IconSet ) + setValue( QIconSet( pix ) ); + else + setValue( pix.convertToImage() ); + + notifyValueChange(); + } +} + +bool PropertyPixmapItem::hasCustomContents() const +{ + return TRUE; +} + +void PropertyPixmapItem::drawCustomContents( QPainter *p, const QRect &r ) +{ + QPixmap pix; + if ( type == Pixmap ) + pix = value().toPixmap(); + else if ( type == IconSet ) + pix = value().toIconSet().pixmap(); + else + pix = value().toImage(); + + if ( !pix.isNull() ) { + p->save(); + p->setClipRect( QRect( QPoint( (int)(p->worldMatrix().dx() + r.x()), + (int)(p->worldMatrix().dy() + r.y()) ), + r.size() ) ); + p->drawPixmap( r.x(), r.y() + ( r.height() - pix.height() ) / 2, pix ); + p->restore(); + } +} + + +// -------------------------------------------------------------- + +PropertyColorItem::PropertyColorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool children ) + : PropertyItem( l, after, prop, propName ), withChildren( children ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + colorPrev = new QFrame( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + colorPrev->setFrameStyle( QFrame::Plain | QFrame::Box ); + colorPrev->setLineWidth( 2 ); + QPalette pal = colorPrev->palette(); + QColorGroup cg = pal.active(); + cg.setColor( QColorGroup::Foreground, cg.color( QColorGroup::Base ) ); + pal.setActive( cg ); + pal.setInactive( cg ); + pal.setDisabled( cg ); + colorPrev->setPalette( pal ); + box->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getColor() ) ); +} + +void PropertyColorItem::createChildren() +{ + PropertyItem *i = this; + i = new PropertyIntItem( listview, i, this, i18n( "Red" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "Green" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "Blue" ), TRUE ); + addChild( i ); +} + +void PropertyColorItem::initChildren() +{ + PropertyItem *item = 0; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == i18n( "Red" ) ) + item->setValue( val.toColor().red() ); + else if ( item->name() == i18n( "Green" ) ) + item->setValue( val.toColor().green() ); + else if ( item->name() == i18n( "Blue" ) ) + item->setValue( val.toColor().blue() ); + } +} + +PropertyColorItem::~PropertyColorItem() +{ + delete (QHBox*)box; +} + +void PropertyColorItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertyColorItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyColorItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + QString s; + setText( 1, v.toColor().name() ); + colorPrev->setBackgroundColor( v.toColor() ); + PropertyItem::setValue( v ); +} + +bool PropertyColorItem::hasSubItems() const +{ + return withChildren; +} + +void PropertyColorItem::childValueChanged( PropertyItem *child ) +{ + QColor c( val.toColor() ); + if ( child->name() == i18n( "Red" ) ) + c.setRgb( child->value().toInt(), c.green(), c.blue() ); + else if ( child->name() == i18n( "Green" ) ) + c.setRgb( c.red(), child->value().toInt(), c.blue() ); + else if ( child->name() == i18n( "Blue" ) ) + c.setRgb( c.red(), c.green(), child->value().toInt() ); + setValue( c ); + notifyValueChange(); +} + +void PropertyColorItem::getColor() +{ + QColor c = QColorDialog::getColor( val.asColor(), listview ); + if ( c.isValid() ) { + setValue( c ); + notifyValueChange(); + } +} + +bool PropertyColorItem::hasCustomContents() const +{ + return TRUE; +} + +void PropertyColorItem::drawCustomContents( QPainter *p, const QRect &r ) +{ + p->save(); + p->setPen( QPen( black, 1 ) ); + p->setBrush( val.toColor() ); + p->drawRect( r.x() + 2, r.y() + 2, r.width() - 5, r.height() - 5 ); + p->restore(); +} + +// -------------------------------------------------------------- + +PropertyFontItem::PropertyFontItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + lined = new QLineEdit( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + lined->setFrame( FALSE ); + lined->setReadOnly( TRUE ); + box->setFocusProxy( lined ); + box->installEventFilter( listview ); + lined->installEventFilter( listview ); + button->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getFont() ) ); +} + +void PropertyFontItem::createChildren() +{ + PropertyItem *i = this; + i = new PropertyListItem( listview, i, this, i18n( "Family" ), FALSE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "Point Size" ), TRUE ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, i18n( "Bold" ) ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, i18n( "Italic" ) ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, i18n( "Underline" ) ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, i18n( "Strikeout" ) ); + addChild( i ); +} + +void PropertyFontItem::initChildren() +{ + PropertyItem *item = 0; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == i18n( "Family" ) ) { + ( (PropertyListItem*)item )->setValue( getFontList() ); + ( (PropertyListItem*)item )->setCurrentItem( val.toFont().family() ); + } else if ( item->name() == i18n( "Point Size" ) ) + item->setValue( val.toFont().pointSize() ); + else if ( item->name() == i18n( "Bold" ) ) + item->setValue( QVariant( val.toFont().bold(), 0 ) ); + else if ( item->name() == i18n( "Italic" ) ) + item->setValue( QVariant( val.toFont().italic(), 0 ) ); + else if ( item->name() == i18n( "Underline" ) ) + item->setValue( QVariant( val.toFont().underline(), 0 ) ); + else if ( item->name() == i18n( "Strikeout" ) ) + item->setValue( QVariant( val.toFont().strikeOut(), 0 ) ); + } +} + +PropertyFontItem::~PropertyFontItem() +{ + delete (QHBox*)box; +} + +void PropertyFontItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() || !lined->hasFocus() ) { + box->show(); + setFocus( lined ); + } +} + +void PropertyFontItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyFontItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + + setText( 1, v.toFont().family() + "-" + QString::number( v.toFont().pointSize() ) ); + lined->setText( v.toFont().family() + "-" + QString::number( v.toFont().pointSize() ) ); + PropertyItem::setValue( v ); +} + +void PropertyFontItem::getFont() +{ + bool ok = FALSE; + QFont f = QFontDialog::getFont( &ok, val.toFont(), listview ); + if ( ok && f != val.toFont() ) { + setValue( f ); + notifyValueChange(); + } +} + +bool PropertyFontItem::hasSubItems() const +{ + return TRUE; +} + +void PropertyFontItem::childValueChanged( PropertyItem *child ) +{ + QFont f = val.toFont(); + if ( child->name() == i18n( "Family" ) ) + f.setFamily( ( (PropertyListItem*)child )->currentItem() ); + else if ( child->name() == i18n( "Point Size" ) ) + f.setPointSize( child->value().toInt() ); + else if ( child->name() == i18n( "Bold" ) ) + f.setBold( child->value().toBool() ); + else if ( child->name() == i18n( "Italic" ) ) + f.setItalic( child->value().toBool() ); + else if ( child->name() == i18n( "Underline" ) ) + f.setUnderline( child->value().toBool() ); + else if ( child->name() == i18n( "Strikeout" ) ) + f.setStrikeOut( child->value().toBool() ); + setValue( f ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyDatabaseItem::PropertyDatabaseItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool wField ) + : PropertyItem( l, after, prop, propName ), withField( wField ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + lined = new QLineEdit( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + lined->setFrame( FALSE ); + lined->setReadOnly( TRUE ); + box->setFocusProxy( lined ); + box->installEventFilter( listview ); + lined->installEventFilter( listview ); + button->installEventFilter( listview ); +} + +void PropertyDatabaseItem::createChildren() +{ + PropertyItem *i = this; + i = new PropertyListItem( listview, i, this, i18n( "Connection" ), TRUE ); + addChild( i ); + i = new PropertyListItem( listview, i, this, i18n( "Table" ), TRUE ); + addChild( i ); + if ( withField ) { + i = new PropertyListItem( listview, i, this, i18n( "Field" ), TRUE ); + addChild( i ); + } +} + +void PropertyDatabaseItem::initChildren() +{ +#ifndef QT_NO_SQL + PropertyItem *item = 0; + QStringList lst = value().toStringList(); + QString conn, table; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == i18n( "Connection" ) ) { + QStringList cl = listview->propertyEditor()->formWindow()->project()->databaseConnectionList(); + if ( !cl.isEmpty() ) + item->setValue( cl ); + else if ( lst.count() > 0 ) + item->setValue( QStringList( lst[ 0 ] ) ); + else if ( withField ) + item->setValue( QStringList( MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), + "database" ).toStringList()[ 0 ] ) ); + + if ( lst.count() > 0 && !lst[ 0 ].isEmpty() ) + item->setCurrentItem( lst[ 0 ] ); + else if ( !isChanged() && withField ) + item->setCurrentItem( MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), + "database" ).toStringList()[ 0 ] ); + else + item->setCurrentItem( 0 ); + conn = item->currentItem(); + } else if ( item->name() == i18n( "Table" ) ) { + QStringList cl = listview->propertyEditor()->formWindow()->project()->databaseTableList( conn ); + if ( !cl.isEmpty() ) + item->setValue( cl ); + else if ( lst.count() > 1 ) + item->setValue( QStringList( lst[ 1 ] ) ); + else if ( withField ) { + QStringList fakeLst = MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), "database" ).toStringList(); + if ( fakeLst.count() > 1 ) + item->setValue( fakeLst[ 1 ] ); + } + + if ( lst.count() > 1 && !lst[ 1 ].isEmpty() ) + item->setCurrentItem( lst[ 1 ] ); + else if ( !isChanged() && withField ) { + QStringList fakeLst = MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), "database" ).toStringList(); + if ( fakeLst.count() > 1 ) + item->setCurrentItem( fakeLst[ 1 ] ); + else + item->setCurrentItem( 0 ); + } else + item->setCurrentItem( 0 ); + table = item->currentItem(); + } else if ( item->name() == i18n( "Field" ) ) { + QStringList cl = listview->propertyEditor()->formWindow()->project()->databaseFieldList( conn, table ); + if ( !cl.isEmpty() ) + item->setValue( cl ); + else if ( lst.count() > 2 ) + item->setValue( QStringList( lst[ 2 ] ) ); + if ( lst.count() > 2 && !lst[ 2 ].isEmpty() ) + item->setCurrentItem( lst[ 2 ] ); + else + item->setCurrentItem( 0 ); + } + } +#endif +} + +PropertyDatabaseItem::~PropertyDatabaseItem() +{ + delete (QHBox*)box; +} + +void PropertyDatabaseItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() || !lined->hasFocus() ) { + box->show(); + setFocus( lined ); + } +} + +void PropertyDatabaseItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyDatabaseItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + + QStringList lst = v.toStringList(); + QString s = lst.join( "." ); + setText( 1, s ); + lined->setText( s ); + PropertyItem::setValue( v ); +} + +bool PropertyDatabaseItem::hasSubItems() const +{ + return TRUE; +} + +void PropertyDatabaseItem::childValueChanged( PropertyItem *c ) +{ +#ifndef QT_NO_SQL + QStringList lst; + lst << ( (PropertyListItem*)PropertyItem::child( 0 ) )->currentItem() + << ( (PropertyListItem*)PropertyItem::child( 1 ) )->currentItem(); + if ( withField ) + lst << ( (PropertyListItem*)PropertyItem::child( 2 ) )->currentItem(); + if ( c == PropertyItem::child( 0 ) ) { // if the connection changed + lst[ 0 ] = ( (PropertyListItem*)c )->currentItem(); + PropertyItem::child( 1 )->setValue( listview->propertyEditor()->formWindow()->project()->databaseTableList( lst[ 0 ] ) ); + if ( withField ) + PropertyItem::child( 2 )->setValue( listview->propertyEditor()->formWindow()->project()->databaseFieldList( lst[ 0 ], lst[ 1 ] ) ); + } else if ( withField && c == PropertyItem::child( 1 ) ) { // if the table changed + lst[ 1 ] = ( (PropertyListItem*)c )->currentItem(); + if ( withField ) + PropertyItem::child( 2 )->setValue( listview->propertyEditor()->formWindow()->project()->databaseFieldList( lst[ 0 ], lst[ 1 ] ) ); + } + lst.clear(); + lst << ( (PropertyListItem*)PropertyItem::child( 0 ) )->currentItem() + << ( (PropertyListItem*)PropertyItem::child( 1 ) )->currentItem(); + if ( withField ) + lst << ( (PropertyListItem*)PropertyItem::child( 2 ) )->currentItem(); + setValue( lst ); + notifyValueChange(); +#else + Q_UNUSED( c ); +#endif +} + +// -------------------------------------------------------------- + +PropertySizePolicyItem::PropertySizePolicyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QLineEdit *PropertySizePolicyItem::lined() +{ + if ( lin ) + return lin; + lin = new QLineEdit( listview->viewport() ); + lin->hide(); + lin->setReadOnly( TRUE ); + return lin; +} + +void PropertySizePolicyItem::createChildren() +{ + QStringList lst; + lst << "Fixed" << "Minimum" << "Maximum" << "Preferred" << "MinimumExpanding" << "Expanding" << "Ignored"; + + PropertyItem *i = this; + i = new PropertyListItem( listview, i, this, i18n( "hSizeType" ), FALSE ); + i->setValue( lst ); + addChild( i ); + i = new PropertyListItem( listview, i, this, i18n( "vSizeType" ), FALSE ); + i->setValue( lst ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "horizontalStretch" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, i18n( "verticalStretch" ), TRUE ); + addChild( i ); +} + +void PropertySizePolicyItem::initChildren() +{ + PropertyItem *item = 0; + QSizePolicy sp = val.toSizePolicy(); + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == i18n( "hSizeType" ) ) + ( (PropertyListItem*)item )->setCurrentItem( size_type_to_int( sp.horData() ) ); + else if ( item->name() == i18n( "vSizeType" ) ) + ( (PropertyListItem*)item )->setCurrentItem( size_type_to_int( sp.verData() ) ); + else if ( item->name() == i18n( "horizontalStretch" ) ) + ( (PropertyIntItem*)item )->setValue( sp.horStretch() ); + else if ( item->name() == i18n( "verticalStretch" ) ) + ( (PropertyIntItem*)item )->setValue( sp.verStretch() ); + } +} + +PropertySizePolicyItem::~PropertySizePolicyItem() +{ + delete (QLineEdit*)lin; +} + +void PropertySizePolicyItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( lined() ); + if ( !lined()->isVisible() || !lined()->hasFocus() ) { + lined()->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertySizePolicyItem::hideEditor() +{ + PropertyItem::hideEditor(); + lined()->hide(); +} + +void PropertySizePolicyItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + + QString s = i18n( "%1/%2/%3/%4" ); + s = s.arg( size_type_to_string( v.toSizePolicy().horData() ) ). + arg( size_type_to_string( v.toSizePolicy().verData() ) ). + arg( v.toSizePolicy().horStretch() ). + arg( v.toSizePolicy().verStretch() ); + setText( 1, s ); + lined()->setText( s ); + PropertyItem::setValue( v ); +} + +void PropertySizePolicyItem::childValueChanged( PropertyItem *child ) +{ + QSizePolicy sp = val.toSizePolicy(); + if ( child->name() == i18n( "hSizeType" ) ) + sp.setHorData( int_to_size_type( ( ( PropertyListItem*)child )->currentIntItem() ) ); + else if ( child->name() == i18n( "vSizeType" ) ) + sp.setVerData( int_to_size_type( ( ( PropertyListItem*)child )->currentIntItem() ) ); + else if ( child->name() == i18n( "horizontalStretch" ) ) + sp.setHorStretch( ( ( PropertyIntItem*)child )->value().toInt() ); + else if ( child->name() == i18n( "verticalStretch" ) ) + sp.setVerStretch( ( ( PropertyIntItem*)child )->value().toInt() ); + setValue( sp ); + notifyValueChange(); +} + +bool PropertySizePolicyItem::hasSubItems() const +{ + return TRUE; +} + +// -------------------------------------------------------------- + +PropertyPaletteItem::PropertyPaletteItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + palettePrev = new QLabel( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + palettePrev->setFrameStyle( QFrame::NoFrame ); + box->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getPalette() ) ); +} +PropertyPaletteItem::~PropertyPaletteItem() +{ + delete (QHBox*)box; +} + +void PropertyPaletteItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertyPaletteItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyPaletteItem::setValue( const QVariant &v ) +{ + QString s; + palettePrev->setPalette( v.toPalette() ); + PropertyItem::setValue( v ); + repaint(); +} + +void PropertyPaletteItem::getPalette() +{ + if ( !listview->propertyEditor()->widget()->isWidgetType() ) + return; + bool ok = FALSE; + QWidget *w = (QWidget*)listview->propertyEditor()->widget(); + if ( ::qt_cast<QScrollView*>(w) ) + w = ( (QScrollView*)w )->viewport(); + QPalette pal = PaletteEditor::getPalette( &ok, val.toPalette(), +#if defined(QT_NON_COMMERCIAL) + w->backgroundMode(), listview->topLevelWidget(), +#else + w->backgroundMode(), listview, +#endif + "choose_palette", listview->propertyEditor()->formWindow() ); + if ( !ok ) + return; + setValue( pal ); + notifyValueChange(); +} + +bool PropertyPaletteItem::hasCustomContents() const +{ + return TRUE; +} + +void PropertyPaletteItem::drawCustomContents( QPainter *p, const QRect &r ) +{ + QPalette pal( value().toPalette() ); + p->save(); + p->setClipRect( QRect( QPoint( (int)(p->worldMatrix().dx() + r.x()), + (int)(p->worldMatrix().dy() + r.y()) ), + r.size() ) ); + QRect r2( r ); + r2.setX( r2.x() + 2 ); + r2.setY( r2.y() + 2 ); + r2.setWidth( r2.width() - 3 ); + r2.setHeight( r2.height() - 3 ); + p->setPen( QPen( black, 1 ) ); + p->setBrush( pal.active().background() ); + p->drawRect( r2 ); + p->restore(); +} + +// -------------------------------------------------------------- + +PropertyCursorItem::PropertyCursorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + comb = 0; +} + +QComboBox *PropertyCursorItem::combo() +{ + if ( comb ) + return comb; + comb = new QComboBox( FALSE, listview->viewport() ); + comb->hide(); + QBitmap cur; + + const QPixmap ArrowPix = SmallIcon( "designer_arrow.png" , KDevDesignerPartFactory::instance()); + const QPixmap UpArrowPix = SmallIcon( "designer_uparrow.png" , KDevDesignerPartFactory::instance()); + const QPixmap CrossPix = SmallIcon( "designer_cross.png" , KDevDesignerPartFactory::instance()); + const QPixmap WaitPix = SmallIcon( "designer_wait.png" , KDevDesignerPartFactory::instance()); + const QPixmap IBeamPix = SmallIcon( "designer_ibeam.png" , KDevDesignerPartFactory::instance()); + const QPixmap SizeVPix = SmallIcon( "designer_sizev.png" , KDevDesignerPartFactory::instance()); + const QPixmap SizeHPix = SmallIcon( "designer_sizeh.png" , KDevDesignerPartFactory::instance()); + const QPixmap SizeFPix = SmallIcon( "designer_sizef.png" , KDevDesignerPartFactory::instance()); + const QPixmap SizeBPix = SmallIcon( "designer_sizeb.png" , KDevDesignerPartFactory::instance()); + const QPixmap SizeAllPix = SmallIcon( "designer_sizeall.png" , KDevDesignerPartFactory::instance()); + const QPixmap VSplitPix = SmallIcon( "designer_vsplit.png" , KDevDesignerPartFactory::instance()); + const QPixmap HSplitPix = SmallIcon( "designer_hsplit.png" , KDevDesignerPartFactory::instance()); + const QPixmap HandPix = SmallIcon( "designer_hand.png" , KDevDesignerPartFactory::instance()); + const QPixmap NoPix = SmallIcon( "designer_no.png" , KDevDesignerPartFactory::instance()); + + comb->insertItem( ArrowPix, i18n("Arrow"), QObject::ArrowCursor); + comb->insertItem( UpArrowPix, i18n("Up-Arrow"), QObject::UpArrowCursor ); + comb->insertItem( CrossPix, i18n("Cross"), QObject::CrossCursor ); + comb->insertItem( WaitPix, i18n("Waiting"), QObject::WaitCursor ); + comb->insertItem( IBeamPix, i18n("iBeam"), QObject::IbeamCursor ); + comb->insertItem( SizeVPix, i18n("Size Vertical"), QObject::SizeVerCursor ); + comb->insertItem( SizeHPix, i18n("Size Horizontal"), QObject::SizeHorCursor ); + comb->insertItem( SizeFPix, i18n("Size Slash"), QObject::SizeBDiagCursor ); + comb->insertItem( SizeBPix, i18n("Size Backslash"), QObject::SizeFDiagCursor ); + comb->insertItem( SizeAllPix, i18n("Size All"), QObject::SizeAllCursor ); + cur = QBitmap( 25, 25, 1 ); + cur.setMask( cur ); + comb->insertItem( cur, i18n("Blank"), QObject::BlankCursor ); + comb->insertItem( VSplitPix, i18n("Split Vertical"), QObject::SplitVCursor ); + comb->insertItem( HSplitPix, i18n("Split Horizontal"), QObject::SplitHCursor ); + comb->insertItem( HandPix, i18n("Pointing Hand"), QObject::PointingHandCursor ); + comb->insertItem( NoPix, i18n("Forbidden"), QObject::ForbiddenCursor ); + + connect( comb, SIGNAL( activated( int ) ), + this, SLOT( setValue() ) ); + comb->installEventFilter( listview ); + return comb; +} + +PropertyCursorItem::~PropertyCursorItem() +{ + delete (QComboBox*)comb; +} + +void PropertyCursorItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->setCurrentItem( (int)value().toCursor().shape() ); + combo()->blockSignals( FALSE ); + } + placeEditor( combo() ); + if ( !combo()->isVisible() || !combo()->hasFocus() ) { + combo()->show(); + setFocus( combo() ); + } +} + +void PropertyCursorItem::hideEditor() +{ + PropertyItem::hideEditor(); + combo()->hide(); +} + +void PropertyCursorItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + combo()->blockSignals( TRUE ); + combo()->setCurrentItem( (int)v.toCursor().shape() ); + combo()->blockSignals( FALSE ); + setText( 1, combo()->currentText() ); + PropertyItem::setValue( v ); +} + +void PropertyCursorItem::setValue() +{ + if ( !comb ) + return; + if ( QVariant( QCursor( combo()->currentItem() ) ) == val ) + return; + setText( 1, combo()->currentText() ); + PropertyItem::setValue( QCursor( combo()->currentItem() ) ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyKeysequenceItem::PropertyKeysequenceItem( PropertyList *l, + PropertyItem *after, + PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ), + k1( 0 ), k2( 0 ), k3( 0 ), k4( 0 ), num( 0 ), mouseEnter( FALSE ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + sequence = new QLineEdit( box ); + connect( sequence, SIGNAL(textChanged( const QString & )), + this, SLOT(setValue()) ); + sequence->installEventFilter( this ); +} + +PropertyKeysequenceItem::~PropertyKeysequenceItem() +{ + delete (QHBox*)box; +} + +void PropertyKeysequenceItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + sequence->setFocus(); + } +} + +void PropertyKeysequenceItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +bool PropertyKeysequenceItem::eventFilter( QObject *o, QEvent *e ) +{ + Q_UNUSED( o ); + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *k = (QKeyEvent *)e; + if ( !mouseEnter && + (k->key() == QObject::Key_Up || + k->key() == QObject::Key_Down) ) + return FALSE; + handleKeyEvent( k ); + return TRUE; + } else if ( (e->type() == QEvent::FocusIn) || + (e->type() == QEvent::MouseButtonPress) ) { + mouseEnter = ( listview->lastEvent() == PropertyList::MouseEvent ) || + (e->type() == QEvent::MouseButtonPress); + return TRUE; + } + + // Lets eat accelerators now.. + if ( e->type() == QEvent::Accel || + e->type() == QEvent::AccelOverride || + e->type() == QEvent::KeyRelease ) + return TRUE; + return FALSE; +} + +void PropertyKeysequenceItem::handleKeyEvent( QKeyEvent *e ) +{ + int nextKey = e->key(); + + if ( num > 3 || + nextKey == QObject::Key_Control || + nextKey == QObject::Key_Shift || + nextKey == QObject::Key_Meta || + nextKey == QObject::Key_Alt ) + return; + + nextKey |= translateModifiers( e->state() ); + switch( num ) { + case 0: + k1 = nextKey; + break; + case 1: + k2 = nextKey; + break; + case 2: + k3 = nextKey; + break; + case 3: + k4 = nextKey; + break; + default: + break; + } + num++; + QKeySequence ks( k1, k2, k3, k4 ); + sequence->setText( ks ); +} + +int PropertyKeysequenceItem::translateModifiers( int state ) +{ + int result = 0; + if ( state & QObject::ShiftButton ) + result |= QObject::SHIFT; + if ( state & QObject::ControlButton ) + result |= QObject::CTRL; + if ( state & QObject::MetaButton ) + result |= QObject::META; + if ( state & QObject::AltButton ) + result |= QObject::ALT; + return result; +} + +void PropertyKeysequenceItem::setValue() +{ + QVariant v; + v = QVariant( QKeySequence(sequence->text()) ); + if ( v.toString().isNull() ) + return; + setText( 1, sequence->text() ); + PropertyItem::setValue( v ); + if ( sequence->hasFocus() ) + notifyValueChange(); + setChanged( TRUE ); +} + +void PropertyKeysequenceItem::setValue( const QVariant &v ) +{ + QKeySequence ks = v.toKeySequence(); + if ( sequence ) { + sequence->setText( ks ); + } + num = ks.count(); + k1 = ks[0]; + k2 = ks[1]; + k3 = ks[2]; + k4 = ks[3]; + setText( 1, ks ); + PropertyItem::setValue( v ); +} + +// -------------------------------------------------------------- + +EnumPopup::EnumPopup( QWidget *parent, const char *name, WFlags f ) + : QFrame( parent, name, f ) +{ + setLineWidth( 1 ); + setFrameStyle( Panel | Plain ); + setPaletteBackgroundColor( Qt::white ); + popLayout = new QVBoxLayout( this, 3 ); + checkBoxList.setAutoDelete( TRUE ); +} + +EnumPopup::~EnumPopup() +{ +} + +void EnumPopup::insertEnums( QValueList<EnumItem> lst ) +{ + while ( checkBoxList.count() ) + checkBoxList.removeFirst(); + + itemList = lst; + QCheckBox *cb; + QValueListConstIterator<EnumItem> it = itemList.begin(); + for ( ; it != itemList.end(); ++it ) { + cb = new QCheckBox( this ); + cb->setText( (*it).key ); + cb->setChecked( (*it).selected ); + if ( it == itemList.begin() ) + cb->setFocus(); + checkBoxList.append( cb ); + cb->resize( width(), cb->height() ); + popLayout->addWidget( cb ); + } +} + +void EnumPopup::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Escape ) { + hide(); + emit hidden(); + } else if ( e->key() == Key_Enter || e->key() == Key_Return ) { + closeWidget(); + } +} + +void EnumPopup::closeWidget() +{ + QPtrListIterator<QCheckBox> it( checkBoxList ); + int i = 0; + while ( it.current() != 0 ) { + itemList[i].selected = (*it)->isChecked(); + ++it; + ++i; + } + close(); + emit closed(); +} + +QValueList<EnumItem> EnumPopup::enumList() const +{ + return itemList; +} + +EnumBox::EnumBox( QWidget *parent, const char *name ) + : QComboBox( parent, name ) +{ + pop = new EnumPopup( this, "popup", QObject::WType_Popup ); + connect( pop, SIGNAL( hidden() ), this, SLOT( popupHidden() ) ); + connect( pop, SIGNAL( closed() ), this, SLOT( popupClosed() ) ); + popupShown = FALSE; + arrowDown = FALSE; +} + +void EnumBox::popupHidden() +{ + popupShown = FALSE; +} + +void EnumBox::popupClosed() +{ + popupShown = FALSE; + emit valueChanged(); +} + +void EnumBox::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + const QColorGroup & g = colorGroup(); + p.setPen(g.text()); + + QStyle::SFlags flags = QStyle::Style_Default; + if (isEnabled()) + flags |= QStyle::Style_Enabled; + if (hasFocus()) + flags |= QStyle::Style_HasFocus; + + if ( width() < 5 || height() < 5 ) { + qDrawShadePanel( &p, rect().x(), rect().y(), rect().width(), rect().height(), g, FALSE, 2, + &g.brush( QColorGroup::Button ) ); + return; + } + style().drawComplexControl( QStyle::CC_ComboBox, &p, this, rect(), g, + flags, QStyle::SC_All, + (arrowDown ? + QStyle::SC_ComboBoxArrow : + QStyle::SC_None )); + + QRect re = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxEditField ); + re = QStyle::visualRect(re, this); + p.setClipRect( re ); + + if ( !str.isNull() ) { + p.save(); + p.setFont(font()); + QFontMetrics fm(font()); + int x = re.x(), y = re.y() + fm.ascent(); + p.drawText( x, y, str ); + p.restore(); + } +} + +void EnumBox::insertEnums( QValueList<EnumItem> lst ) +{ + pop->insertEnums( lst ); +} + +QValueList<EnumItem> EnumBox::enumList() const +{ + return pop->enumList(); +} + +void EnumBox::popup() +{ + if ( popupShown ) { + pop->closeWidget(); + popupShown = FALSE; + return; + } + pop->move( ((QWidget*)parent())->mapToGlobal( geometry().bottomLeft() ) ); + pop->setMinimumWidth( width() ); + emit aboutToShowPopup(); + pop->show(); + popupShown = TRUE; +} + +void EnumBox::mousePressEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton ) + return; + + QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxArrow); + arrowRect = QStyle::visualRect(arrowRect, this); + + arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) ); + + if ( arrowRect.contains( e->pos() ) ) { + arrowDown = TRUE; + repaint( FALSE ); + } + + popup(); + QTimer::singleShot( 100, this, SLOT( restoreArrow() ) ); +} + +void EnumBox::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Space ) { + popup(); + QTimer::singleShot( 100, this, SLOT( restoreArrow() ) ); + } else if ( e->key() == Key_Enter || e->key() == Key_Return ) { + popup(); + } +} + +void EnumBox::restoreArrow() +{ + arrowDown = FALSE; + repaint( FALSE ); +} + +void EnumBox::setText( const QString &text ) +{ + str = text; + repaint( FALSE ); +} + + + +PropertyEnumItem::PropertyEnumItem( PropertyList *l, + PropertyItem *after, + PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + box = new EnumBox( listview->viewport() ); + box->hide(); + box->installEventFilter( listview ); + connect( box, SIGNAL( aboutToShowPopup() ), this, SLOT( insertEnums() ) ); + connect( box, SIGNAL( valueChanged() ), this, SLOT( setValue() ) ); +} + +PropertyEnumItem::~PropertyEnumItem() +{ + delete (EnumBox*)box; +} + +void PropertyEnumItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + box->setText( enumString ); + listView()->viewport()->setFocus(); + } + box->setFocus(); +} + +void PropertyEnumItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyEnumItem::setValue( const QVariant &v ) +{ + enumString = ""; + enumList.clear(); + QStringList lst = v.toStringList(); + QValueListConstIterator<QString> it = lst.begin(); + for ( ; it != lst.end(); ++it ) + enumList.append( EnumItem( *it, FALSE ) ); + enumList.first().selected = TRUE; + enumString = enumList.first().key; + box->setText( enumString ); + setText( 1, enumString ); + PropertyItem::setValue( v ); +} + +void PropertyEnumItem::insertEnums() +{ + box->insertEnums( enumList ); +} + +void PropertyEnumItem::setValue() +{ + enumList = box->enumList(); + enumString = ""; + QValueListConstIterator<EnumItem> it = enumList.begin(); + for ( ; it != enumList.end(); ++it ) { + if ( (*it).selected ) + enumString += "|" + (*it).key; + } + if ( !enumString.isEmpty() ) + enumString.replace( 0, 1, "" ); + + box->setText( enumString ); + setText( 1, enumString ); + notifyValueChange(); +} + +void PropertyEnumItem::setCurrentValues( QStrList lst ) +{ + enumString =""; + QStrList::ConstIterator it = lst.begin(); + QValueList<EnumItem>::Iterator eit = enumList.begin(); + for ( ; eit != enumList.end(); ++eit ) { + (*eit).selected = FALSE; + for ( it = lst.begin(); it != lst.end(); ++it ) { + if ( QString( *it ) == (*eit).key ) { + (*eit).selected = TRUE; + enumString += "|" + (*eit).key; + break; + } + } + } + if ( !enumString.isEmpty() ) + enumString.replace( 0, 1, "" ); + box->setText( enumString ); + setText( 1, enumString ); +} + +QString PropertyEnumItem::currentItem() const +{ + return enumString; +} + +QString PropertyEnumItem::currentItemFromObject() const +{ + return enumString; +} + +// -------------------------------------------------------------- + +/*! + \class PropertyList propertyeditor.h + \brief PropertyList is a QListView derived class which is used for editing widget properties + + This class is used for widget properties. It has to be child of a + PropertyEditor. + + To initialize it for editing a widget call setupProperties() which + iterates through the properties of the current widget (see + PropertyEditor::widget()) and builds the list. + + To update the item values, refetchData() can be called. + + If the value of an item has been changed by the user, and this + change should be applied to the widget's property, valueChanged() + has to be called. + + To set the value of an item, setPropertyValue() has to be called. +*/ + +PropertyList::PropertyList( PropertyEditor *e ) + : QListView( e ), editor( e ) +{ + init_colors(); + + whatsThis = new PropertyWhatsThis( this ); + showSorted = FALSE; + header()->setMovingEnabled( FALSE ); + header()->setStretchEnabled( TRUE ); + setResizePolicy( QScrollView::Manual ); + viewport()->setAcceptDrops( TRUE ); + viewport()->installEventFilter( this ); + addColumn( i18n( "Property" ) ); + addColumn( i18n( "Value" ) ); + connect( header(), SIGNAL( sizeChange( int, int, int ) ), + this, SLOT( updateEditorSize() ) ); + disconnect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( changeSortColumn( int ) ) ); + connect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( toggleSort() ) ); + connect( this, SIGNAL( pressed( QListViewItem *, const QPoint &, int ) ), + this, SLOT( itemPressed( QListViewItem *, const QPoint &, int ) ) ); + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( toggleOpen( QListViewItem * ) ) ); + setSorting( -1 ); + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + setColumnWidthMode( 1, Manual ); + mousePressed = FALSE; + pressItem = 0; + theLastEvent = MouseEvent; + header()->installEventFilter( this ); +} + +void PropertyList::toggleSort() +{ + showSorted = !showSorted; + editor->clear(); + editor->setup(); +} + +void PropertyList::resizeEvent( QResizeEvent *e ) +{ + QListView::resizeEvent( e ); + if ( currentItem() ) + ( ( PropertyItem* )currentItem() )->showEditor(); +} + +static QVariant::Type type_to_variant( const QString &s ) +{ + if ( s == "Invalid " ) + return QVariant::Invalid; + if ( s == "Map" ) + return QVariant::Map; + if ( s == "List" ) + return QVariant::List; + if ( s == "String" ) + return QVariant::String; + if ( s == "StringList" ) + return QVariant::StringList; + if ( s == "Font" ) + return QVariant::Font; + if ( s == "Pixmap" ) + return QVariant::Pixmap; + if ( s == "Brush" ) + return QVariant::Brush; + if ( s == "Rect" ) + return QVariant::Rect; + if ( s == "Size" ) + return QVariant::Size; + if ( s == "Color" ) + return QVariant::Color; + if ( s == "Palette" ) + return QVariant::Palette; + if ( s == "ColorGroup" ) + return QVariant::ColorGroup; + if ( s == "IconSet" ) + return QVariant::IconSet; + if ( s == "Point" ) + return QVariant::Point; + if ( s == "Image" ) + return QVariant::Image; + if ( s == "Int" ) + return QVariant::Int; + if ( s == "UInt" ) + return QVariant::UInt; + if ( s == "Bool" ) + return QVariant::Bool; + if ( s == "Double" ) + return QVariant::Double; + if ( s == "CString" ) + return QVariant::CString; + if ( s == "PointArray" ) + return QVariant::PointArray; + if ( s == "Region" ) + return QVariant::Region; + if ( s == "Bitmap" ) + return QVariant::Bitmap; + if ( s == "Cursor" ) + return QVariant::Cursor; + if ( s == "SizePolicy" ) + return QVariant::SizePolicy; + if ( s == "Date" ) + return QVariant::Date; + if ( s == "Time" ) + return QVariant::Time; + if ( s == "DateTime" ) + return QVariant::DateTime; + return QVariant::Invalid; +} + +#ifndef QT_NO_SQL +static bool parent_is_data_aware( QWidget *w ) +{ + QWidget *p = w ? w->parentWidget() : 0; + while ( p && !p->isTopLevel() ) { + if ( ::qt_cast<QDesignerDataBrowser*>(p) || ::qt_cast<QDesignerDataView*>(p) ) + return TRUE; + p = p->parentWidget(); + } + return FALSE; +} +#endif + +/*! Sets up the property list by adding an item for each designable +property of the widget which is just edited. +*/ + +void PropertyList::setupProperties() +{ + if ( !editor->widget() ) + return; + bool allProperties = !::qt_cast<Spacer*>(editor->widget()); + QStrList lst = editor->widget()->metaObject()->propertyNames( allProperties ); + PropertyItem *item = 0; + QMap<QString, bool> unique; + QObject *w = editor->widget(); + QStringList valueSet; + bool parentHasLayout = + w->isWidgetType() && + !editor->formWindow()->isMainContainer( (QWidget*)w ) && ( (QWidget*)w )->parentWidget() && + WidgetFactory::layoutType( ( (QWidget*)w )->parentWidget() ) != WidgetFactory::NoLayout; + for ( QPtrListIterator<char> it( lst ); it.current(); ++it ) { + const QMetaProperty* p = + editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( it.current(), allProperties), allProperties ); + if ( !p ) + continue; + if ( unique.contains( QString::fromLatin1( it.current() ) ) ) + continue; + if ( ::qt_cast<QDesignerToolBar*>(editor->widget()) || + ::qt_cast<MenuBarEditor*>(editor->widget()) ) { + if ( qstrcmp( p->name(), "minimumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "sizePolicy" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumSize" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumSize" ) == 0 ) + continue; + } + unique.insert( QString::fromLatin1( it.current() ), TRUE ); + if ( editor->widget()->isWidgetType() && + editor->formWindow()->isMainContainer( (QWidget*)editor->widget() ) ) { + if ( qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + } else { // hide some toplevel-only stuff + if ( qstrcmp( p->name(), "icon" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "iconText" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "caption" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "sizeIncrement" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "baseSize" ) == 0 ) + continue; + if ( parentHasLayout && qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + if ( ::qt_cast<QLayoutWidget*>(w) || ::qt_cast<Spacer*>(w) ) { + if ( qstrcmp( p->name(), "sizePolicy" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumSize" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumSize" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "enabled" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "paletteForegroundColor" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "paletteBackgroundColor" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "paletteBackgroundPixmap" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "palette" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "font" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "cursor" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "mouseTracking" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "focusPolicy" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "acceptDrops" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "autoMask" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "backgroundOrigin" ) == 0 ) + continue; + } + } + if ( ::qt_cast<QActionGroup*>(w) ) { + if ( qstrcmp( p->name(), "usesDropDown" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "toggleAction" ) == 0 ) + continue; + } + if ( qstrcmp( p->name(), "minimumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "buttonGroupId" ) == 0 ) { // #### remove this when designable in Q_PROPERTY can take a function (isInButtonGroup() in this case) + if ( !editor->widget()->isWidgetType() || + !editor->widget()->parent() || + !::qt_cast<QButtonGroup*>(editor->widget()->parent()) ) + continue; + } + + bool isPropertyObject = w->isA( "PropertyObject" ); + + if ( ( p->designable(w) || + isPropertyObject && p->designable( ( (PropertyObject*)w )->widgetList().first() ) ) && + ( !isPropertyObject || qstrcmp( p->name(), "name" ) != 0 ) ) { + if ( p->isSetType() ) { + if ( QString( p->name() ) == "alignment" ) { + QStringList lst; + lst << p->valueToKey( AlignAuto ) + << p->valueToKey( AlignLeft ) + << p->valueToKey( AlignHCenter ) + << p->valueToKey( AlignRight ) + << p->valueToKey( AlignJustify ); + item = new PropertyListItem( this, item, 0, "hAlign", FALSE ); + item->setValue( lst ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "hAlign" ) ) + item->setChanged( TRUE, FALSE ); + if ( !::qt_cast<QMultiLineEdit*>(editor->widget()) ) { + lst.clear(); + lst << p->valueToKey( AlignTop ) + << p->valueToKey( AlignVCenter ) + << p->valueToKey( AlignBottom ); + item = new PropertyListItem( this, item, 0, "vAlign", FALSE ); + item->setValue( lst ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "vAlign" ) ) + item->setChanged( TRUE, FALSE ); + item = new PropertyBoolItem( this, item, 0, "wordwrap" ); + if ( ::qt_cast<QGroupBox*>(w) ) + item->setVisible( FALSE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "wordwrap" ) ) + item->setChanged( TRUE, FALSE ); + } + } else { + QStrList lst( p->enumKeys() ); + QStringList l; + QPtrListIterator<char> it( lst ); + while ( it.current() != 0 ) { + l << QString(*it); + ++it; + } + item = new PropertyEnumItem( this, item, 0, p->name() ); + item->setValue( l ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), p->name() ) ) + item->setChanged( TRUE, FALSE ); + } + } else if ( p->isEnumType() ) { + QStrList l = p->enumKeys(); + QStringList lst; + for ( uint i = 0; i < l.count(); ++i ) { + QString k = l.at( i ); + // filter out enum-masks + if ( k[0] == 'M' && k[1].category() == QChar::Letter_Uppercase ) + continue; + lst << k; + } + item = new PropertyListItem( this, item, 0, p->name(), FALSE ); + item->setValue( lst ); + } else { + QVariant::Type t = QVariant::nameToType( p->type() ); + if ( !addPropertyItem( item, p->name(), t ) ) + continue; + } + } + if ( item && !p->isSetType() ) { + if ( valueSet.findIndex( item->name() ) == -1 ) { + setPropertyValue( item ); + valueSet << item->name(); + } + if ( MetaDataBase::isPropertyChanged( editor->widget(), p->name() ) ) + item->setChanged( TRUE, FALSE ); + } + } + + if ( !::qt_cast<QSplitter*>(w) && !::qt_cast<MenuBarEditor*>(w) && !::qt_cast<QDesignerToolBar*>(w) && + w->isWidgetType() && WidgetFactory::layoutType( (QWidget*)w ) != WidgetFactory::NoLayout ) { + item = new PropertyLayoutItem( this, item, 0, "layoutSpacing" ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "layoutSpacing" ) + || MetaDataBase::spacing( editor->widget() ) != -1 ) + layoutInitValue( item, TRUE ); + else + layoutInitValue( item ); + item = new PropertyLayoutItem( this, item, 0, "layoutMargin" ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "layoutMargin" ) + || MetaDataBase::margin( editor->widget() ) != -1 ) + layoutInitValue( item, TRUE ); + else + layoutInitValue( item ); + QWidget *widget = (QWidget*)w; + if ( ( !::qt_cast<QLayoutWidget*>(widget) && + widget->parentWidget() && ::qt_cast<FormWindow*>(widget->parentWidget()) ) ) { + item = new PropertyListItem( this, item, 0, "resizeMode", FALSE ); + QStringList lst; + lst << "Auto" << "FreeResize" << "Minimum" << "Fixed"; + item->setValue( lst ); + setPropertyValue( item ); + QString resizeMod = MetaDataBase::resizeMode( editor->widget() ); + if ( !resizeMod.isEmpty() && + resizeMod != WidgetFactory::defaultCurrentItem( editor->widget(), "resizeMode" ) ) { + item->setChanged( TRUE, FALSE ); + MetaDataBase::setPropertyChanged( editor->widget(), "resizeMode", TRUE ); + } + } + } + + if ( !::qt_cast<Spacer*>(w) && !::qt_cast<QLayoutWidget*>(w) && + !::qt_cast<MenuBarEditor*>(w) && !::qt_cast<QDesignerToolBar*>(w) ) { + item = new PropertyTextItem( this, item, 0, "toolTip", TRUE, FALSE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "toolTip" ) ) + item->setChanged( TRUE, FALSE ); + item = new PropertyTextItem( this, item, 0, "whatsThis", TRUE, TRUE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "whatsThis" ) ) + item->setChanged( TRUE, FALSE ); + } + +#ifndef QT_NO_SQL + if ( !::qt_cast<QDataTable*>(editor->widget()) && !::qt_cast<QDataBrowser*>(editor->widget()) && + !::qt_cast<QDataView*>(editor->widget()) && parent_is_data_aware( ::qt_cast<QWidget*>(editor->widget()) ) ) { + item = new PropertyDatabaseItem( this, item, 0, "database", editor->formWindow()->mainContainer() != w ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "database" ) ) + item->setChanged( TRUE, FALSE ); + } + + if ( ::qt_cast<QDataTable*>(editor->widget()) || ::qt_cast<QDataBrowser*>(editor->widget()) || + ::qt_cast<QDataView*>(editor->widget()) ) { + item = new PropertyDatabaseItem( this, item, 0, "database", FALSE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "database" ) ) + item->setChanged( TRUE, FALSE ); + item = new PropertyBoolItem( this, item, 0, "frameworkCode" ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "frameworkCode" ) ) + item->setChanged( TRUE, FALSE ); + } +#endif + + if ( w->isA("PropertyObject") ) { + const QWidgetList wl = ( (PropertyObject*)w )->widgetList(); + QPtrListIterator<QWidget> wIt( wl ); + while ( *wIt ) { + if ( (*wIt)->inherits("CustomWidget") ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)*wIt )->customWidget(); + setupCusWidgetProperties( cw, unique, item ); + } + ++wIt; + } + } else if ( w->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)w )->customWidget(); + setupCusWidgetProperties( cw, unique, item ); + } + + setCurrentItem( firstChild() ); + + if ( showSorted ) { + setSorting( 0 ); + sort(); + setSorting( -1 ); + setCurrentItem( firstChild() ); + qApp->processEvents(); + } + + updateEditorSize(); +} + +void PropertyList::setupCusWidgetProperties( MetaDataBase::CustomWidget *cw, + QMap<QString, bool> &unique, + PropertyItem *&item ) +{ + if ( !cw ) + return; + + for ( QValueList<MetaDataBase::Property>::Iterator it = + cw->lstProperties.begin(); it != cw->lstProperties.end(); ++it ) { + if ( unique.contains( QString( (*it).property ) ) ) + continue; + unique.insert( QString( (*it).property ), TRUE ); + addPropertyItem( item, (*it).property, type_to_variant( (*it).type ) ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), (*it).property ) ) + item->setChanged( TRUE, FALSE ); + } +} + +bool PropertyList::addPropertyItem( PropertyItem *&item, const QCString &name, QVariant::Type t ) +{ + if ( name == "buddy" ) { + PropertyListItem *itm = new PropertyListItem( this, item, 0, name, TRUE ); + QPtrDict<QWidget> *widgets = editor->formWindow()->widgets(); + QPtrDictIterator<QWidget> it( *widgets ); + QStringList l; + l << ""; + while ( it.current() ) { + if ( editor->formWindow()->canBeBuddy( it.current() ) ) { + if ( l.find( it.current()->name() ) == l.end() ) + l << it.current()->name(); + } + ++it; + } + l.sort(); + itm->setValue( l ); + item = itm; + return TRUE; + } + + switch ( t ) { + case QVariant::String: + item = new PropertyTextItem( this, item, 0, name, TRUE, + ::qt_cast<QLabel*>(editor->widget()) || + ::qt_cast<QTextView*>(editor->widget()) || + ::qt_cast<QButton*>(editor->widget()) ); + break; + case QVariant::CString: + item = new PropertyTextItem( this, item, 0, + name, name == "name" && + editor->widget() == editor->formWindow()->mainContainer(), + FALSE, TRUE ); + break; + case QVariant::Bool: + item = new PropertyBoolItem( this, item, 0, name ); + break; + case QVariant::Font: + item = new PropertyFontItem( this, item, 0, name ); + break; + case QVariant::Int: + if ( name == "accel" ) + item = new PropertyTextItem( this, item, 0, name, FALSE, FALSE, FALSE, TRUE ); + else if ( name == "layoutSpacing" || name == "layoutMargin" ) + item = new PropertyLayoutItem( this, item, 0, name ); + else if ( name == "resizeMode" ) + item = new PropertyListItem( this, item, 0, name, TRUE ); + else + item = new PropertyIntItem( this, item, 0, name, TRUE ); + break; + case QVariant::Double: + item = new PropertyDoubleItem( this, item, 0, name ); + break; + case QVariant::KeySequence: + item = new PropertyKeysequenceItem( this, item, 0, name ); + break; + case QVariant::UInt: + item = new PropertyIntItem( this, item, 0, name, FALSE ); + break; + case QVariant::StringList: + item = new PropertyListItem( this, item, 0, name, TRUE ); + break; + case QVariant::Rect: + item = new PropertyCoordItem( this, item, 0, name, PropertyCoordItem::Rect ); + break; + case QVariant::Point: + item = new PropertyCoordItem( this, item, 0, name, PropertyCoordItem::Point ); + break; + case QVariant::Size: + item = new PropertyCoordItem( this, item, 0, name, PropertyCoordItem::Size ); + break; + case QVariant::Color: + item = new PropertyColorItem( this, item, 0, name, TRUE ); + break; + case QVariant::Pixmap: + item = new PropertyPixmapItem( this, item, 0, name, PropertyPixmapItem::Pixmap ); + break; + case QVariant::IconSet: + item = new PropertyPixmapItem( this, item, 0, name, PropertyPixmapItem::IconSet ); + break; + case QVariant::Image: + item = new PropertyPixmapItem( this, item, 0, name, PropertyPixmapItem::Image ); + break; + case QVariant::SizePolicy: + item = new PropertySizePolicyItem( this, item, 0, name ); + break; + case QVariant::Palette: + item = new PropertyPaletteItem( this, item, 0, name ); + break; + case QVariant::Cursor: + item = new PropertyCursorItem( this, item, 0, name ); + break; + case QVariant::Date: + item = new PropertyDateItem( this, item, 0, name ); + break; + case QVariant::Time: + item = new PropertyTimeItem( this, item, 0, name ); + break; + case QVariant::DateTime: + item = new PropertyDateTimeItem( this, item, 0, name ); + break; + default: + return FALSE; + } + return TRUE; +} + +void PropertyList::paintEmptyArea( QPainter *p, const QRect &r ) +{ + p->fillRect( r, *backColor2 ); +} + +void PropertyList::setCurrentItem( QListViewItem *i ) +{ + if ( !i ) + return; + + if ( currentItem() ) + ( (PropertyItem*)currentItem() )->hideEditor(); + QListView::setCurrentItem( i ); + ( (PropertyItem*)currentItem() )->showEditor(); +} + +void PropertyList::updateEditorSize() +{ + if ( currentItem() ) + ( ( PropertyItem* )currentItem() )->showEditor(); +} + +/*! This has to be called if the value if \a i should be set as + property to the currently edited widget. +*/ + +void PropertyList::valueChanged( PropertyItem *i ) +{ + if ( !editor->widget() ) + return; + QString pn( i18n( "Set '%1' of '%2'" ).arg( i->name() ).arg( editor->widget()->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, editor->formWindow(), + editor->widget(), editor, + i->name(), WidgetFactory::property( editor->widget(), i->name() ), + i->value(), i->currentItem(), i->currentItemFromObject() ); + + cmd->execute(); + editor->formWindow()->commandHistory()->addCommand( cmd, TRUE ); +} + +void PropertyList::layoutInitValue( PropertyItem *i, bool changed ) +{ + if ( !editor->widget() ) + return; + QString pn( i18n( "Set '%1' of '%2'" ).arg( i->name() ).arg( editor->widget()->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, editor->formWindow(), + editor->widget(), editor, + i->name(), WidgetFactory::property( editor->widget(), i->name() ), + i->value(), i->currentItem(), i->currentItemFromObject() ); + cmd->execute(); + if ( i->value().toString() != "-1" ) + changed = TRUE; + i->setChanged( changed ); +} + +void PropertyList::itemPressed( QListViewItem *i, const QPoint &p, int c ) +{ + if ( !i ) + return; + PropertyItem *pi = (PropertyItem*)i; + if ( !pi->hasSubItems() ) + return; + + if ( c == 0 && viewport()->mapFromGlobal( p ).x() < 20 ) + toggleOpen( i ); +} + +void PropertyList::toggleOpen( QListViewItem *i ) +{ + if ( !i ) + return; + PropertyItem *pi = (PropertyItem*)i; + if ( pi->hasSubItems() ) { + pi->setOpen( !pi->isOpen() ); + } else { + pi->toggle(); + } +} + +bool PropertyList::eventFilter( QObject *o, QEvent *e ) +{ + if ( !o || !e ) + return TRUE; + + PropertyItem *i = (PropertyItem*)currentItem(); + if ( e->type() == QEvent::KeyPress ) + theLastEvent = KeyEvent; + else if ( e->type() == QEvent::MouseButtonPress ) + theLastEvent = MouseEvent; + + if ( o != this &&e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ( ke->key() == Key_Up || ke->key() == Key_Down ) && + ( o != this || o != viewport() ) && + !( ke->state() & ControlButton ) ) { + QApplication::sendEvent( this, (QKeyEvent*)e ); + return TRUE; + } else if ( ( !::qt_cast<QLineEdit*>(o) || + ( ::qt_cast<QLineEdit*>(o) && ( (QLineEdit*)o )->isReadOnly() ) ) && + i && i->hasSubItems() ) { + if ( !i->isOpen() && + ( ke->key() == Key_Plus || + ke->key() == Key_Right )) + i->setOpen( TRUE ); + else if ( i->isOpen() && + ( ke->key() == Key_Minus || + ke->key() == Key_Left ) ) + i->setOpen( FALSE ); + } else if ( ( ke->key() == Key_Return || ke->key() == Key_Enter ) && ::qt_cast<QComboBox*>(o) ) { + QKeyEvent ke2( QEvent::KeyPress, Key_Space, 0, 0 ); + QApplication::sendEvent( o, &ke2 ); + return TRUE; + } + } else if ( e->type() == QEvent::FocusOut && ::qt_cast<QLineEdit*>(o) && editor->formWindow() ) { + QTimer::singleShot( 100, editor->formWindow()->commandHistory(), SLOT( checkCompressedCommand() ) ); + } else if ( o == viewport() ) { + QMouseEvent *me; + PropertyListItem* i; + switch ( e->type() ) { + case QEvent::MouseButtonPress: + me = (QMouseEvent*)e; + i = (PropertyListItem*) itemAt( me->pos() ); + if ( i && ( ::qt_cast<PropertyColorItem*>(i) || ::qt_cast<PropertyPixmapItem*>(i) ) ) { + pressItem = i; + pressPos = me->pos(); + mousePressed = TRUE; + } + break; + case QEvent::MouseMove: + me = (QMouseEvent*)e; + if ( me && me->state() & LeftButton && mousePressed) { + + i = (PropertyListItem*) itemAt( me->pos() ); + if ( i && i == pressItem ) { + + if (( pressPos - me->pos() ).manhattanLength() > QApplication::startDragDistance() ){ + if ( ::qt_cast<PropertyColorItem*>(i) ) { + QColor col = i->value().asColor(); + QColorDrag *drg = new QColorDrag( col, this ); + QPixmap pix( 25, 25 ); + pix.fill( col ); + QPainter p( &pix ); + p.drawRect( 0, 0, pix.width(), pix.height() ); + p.end(); + drg->setPixmap( pix ); + mousePressed = FALSE; + drg->dragCopy(); + } + else if ( ::qt_cast<PropertyPixmapItem*>(i) ) { + QPixmap pix = i->value().asPixmap(); + if( !pix.isNull() ) { + QImage img = pix.convertToImage(); + QImageDrag *drg = new QImageDrag( img, this ); + drg->setPixmap( pix ); + mousePressed = FALSE; + drg->dragCopy(); + } + } + } + } + } + break; + default: + break; + } + } else if ( o == header() ) { + if ( e->type() == QEvent::ContextMenu ) { + ((QContextMenuEvent *)e)->accept(); + QPopupMenu menu( 0 ); + menu.setCheckable( TRUE ); + const int cat_id = 1; + const int alpha_id = 2; + menu.insertItem( i18n( "Sort &Categorized" ), cat_id ); + int alpha = menu.insertItem( i18n( "Sort &Alphabetically" ), alpha_id ); + if ( showSorted ) + menu.setItemChecked( alpha_id, TRUE ); + else + menu.setItemChecked( cat_id, TRUE ); + int res = menu.exec( ( (QContextMenuEvent*)e )->globalPos() ); + if ( res != -1 ) { + bool newShowSorted = ( res == alpha ); + if ( showSorted != newShowSorted ) { + showSorted = newShowSorted; + editor->clear(); + editor->setup(); + } + } + return TRUE; + } + } + + return QListView::eventFilter( o, e ); +} + +/*! This method re-initializes each item of the property list. +*/ + +void PropertyList::refetchData() +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + PropertyItem *i = (PropertyItem*)it.current(); + if ( !i->propertyParent() ) + setPropertyValue( i ); + if ( i->hasSubItems() ) + i->initChildren(); + bool changed = MetaDataBase::isPropertyChanged( editor->widget(), i->name() ); + if ( ( i->name() == "layoutSpacing" || i->name() == "layoutMargin" ) ) { + if ( i->value().toString() != "-1" ) + i->setChanged( TRUE, FALSE ); + else + i->setChanged( FALSE, FALSE ); + } + else if ( changed != i->isChanged() ) + i->setChanged( changed, FALSE ); + } + updateEditorSize(); +} + +static void clearAlignList( QStrList &l ) +{ + if ( l.count() == 1 ) + return; + if ( l.find( "AlignAuto" ) != -1 ) + l.remove( "AlignAuto" ); + if ( l.find( "WordBreak" ) != -1 ) + l.remove( "WordBreak" ); +} + +/*! This method initializes the value of the item \a i to the value + of the corresponding property. +*/ + +void PropertyList::setPropertyValue( PropertyItem *i ) +{ + const QMetaProperty *p = + editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( i->name(), TRUE), TRUE ); + if ( !p ) { + if ( i->name() == "hAlign" ) { + int align = editor->widget()->property( "alignment" ).toInt(); + p = editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + align &= ~AlignVertical_Mask; + QStrList l = p->valueToKeys( align ); + clearAlignList( l ); + ( (PropertyListItem*)i )->setCurrentItem( l.last() ); + } else if ( i->name() == "vAlign" ) { + int align = editor->widget()->property( "alignment" ).toInt(); + p = editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + align &= ~AlignHorizontal_Mask; + ( (PropertyListItem*)i )->setCurrentItem( p->valueToKeys( align ).last() ); + } else if ( i->name() == "wordwrap" ) { + int align = editor->widget()->property( "alignment" ).toInt(); + if ( align & WordBreak ) + i->setValue( QVariant( TRUE, 0 ) ); + else + i->setValue( QVariant( FALSE, 0 ) ); + } else if ( i->name() == "layoutSpacing" ) { + ( (PropertyLayoutItem*)i )->setValue( MetaDataBase::spacing( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ) ) ); + } else if ( i->name() == "layoutMargin" ) { + ( (PropertyLayoutItem*)i )->setValue( MetaDataBase::margin( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ) ) ); + } else if ( i->name() == "resizeMode" ) { + ( (PropertyListItem*)i )->setCurrentItem( MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ) ) ); + } else if ( i->name() == "toolTip" || i->name() == "whatsThis" || i->name() == "database" || i->name() == "frameworkCode" ) { + i->setValue( MetaDataBase::fakeProperty( editor->widget(), i->name() ) ); + } else if ( editor->widget()->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)editor->widget() )->customWidget(); + if ( !cw ) + return; + i->setValue( MetaDataBase::fakeProperty( editor->widget(), i->name() ) ); + } + return; + } + if ( p->isSetType() ) + ( (PropertyEnumItem*)i )->setCurrentValues( p->valueToKeys( editor->widget()->property( i->name() ).toInt() ) ); + else if ( p->isEnumType() ) + ( (PropertyListItem*)i )->setCurrentItem( p->valueToKey( editor->widget()->property( i->name() ).toInt() ) ); + else if ( qstrcmp( p->name(), "buddy" ) == 0 ) + ( (PropertyListItem*)i )->setCurrentItem( editor->widget()->property( i->name() ).toString() ); + else + i->setValue( editor->widget()->property( i->name() ) ); +} + +void PropertyList::setCurrentProperty( const QString &n ) +{ + if ( currentItem() && currentItem()->text( 0 ) == n || + currentItem() && ( (PropertyItem*)currentItem() )->propertyParent() && + ( (PropertyItem*)currentItem() )->propertyParent()->text( 0 ) == n ) + return; + + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( it.current()->text( 0 ) == n ) { + setCurrentItem( it.current() ); + break; + } + } +} + +PropertyEditor *PropertyList::propertyEditor() const +{ + return editor; +} + +void PropertyList::resetProperty() +{ + if ( !currentItem() ) + return; + PropertyItem *i = (PropertyItem*)currentItem(); + if ( !MetaDataBase::isPropertyChanged( editor->widget(), i->PropertyItem::name() ) ) + return; + QString pn( i18n( "Reset '%1' of '%2'" ).arg( i->name() ).arg( editor->widget()->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, editor->formWindow(), + editor->widget(), editor, + i->name(), i->value(), + WidgetFactory::defaultValue( editor->widget(), i->name() ), + WidgetFactory::defaultCurrentItem( editor->widget(), i->name() ), + i->currentItem(), TRUE ); + cmd->execute(); + editor->formWindow()->commandHistory()->addCommand( cmd, FALSE ); + if ( i->hasSubItems() ) + i->initChildren(); +} + +void PropertyList::viewportDragEnterEvent( QDragEnterEvent *e ) +{ + PropertyListItem *i = (PropertyListItem*) itemAt( e->pos() ); + if( !i ) { + e->ignore(); + return; + } + + if ( ::qt_cast<PropertyColorItem*>(i) && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( ::qt_cast<PropertyPixmapItem*>(i) && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void PropertyList::viewportDragMoveEvent ( QDragMoveEvent *e ) +{ + PropertyListItem *i = (PropertyListItem*) itemAt( e->pos() ); + if( !i ) { + e->ignore(); + return; + } + + if ( ::qt_cast<PropertyColorItem*>(i) && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( ::qt_cast<PropertyPixmapItem*>(i) && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void PropertyList::viewportDropEvent ( QDropEvent *e ) +{ + PropertyListItem *i = (PropertyListItem*) itemAt( e->pos() ); + if( !i ) { + e->ignore(); + return; + } + + if ( ::qt_cast<PropertyColorItem*>(i) && QColorDrag::canDecode( e ) ) { + QColor color; + QColorDrag::decode( e, color ); + i->setValue( QVariant( color ) ); + valueChanged( i ); + e->accept(); + } + else if ( ::qt_cast<PropertyPixmapItem*>(i) && QImageDrag::canDecode( e ) ) { + QImage img; + QImageDrag::decode( e, img ); + QPixmap pm; + pm.convertFromImage( img ); + i->setValue( QVariant( pm ) ); + valueChanged( i ); + e->accept(); + } + else + e->ignore(); +} + +QString PropertyList::whatsThisAt( const QPoint &p ) +{ + return whatsThisText( itemAt( p ) ); +} + +void PropertyList::showCurrentWhatsThis() +{ + if ( !currentItem() ) + return; + QPoint p( 0, currentItem()->itemPos() ); + p = viewport()->mapToGlobal( contentsToViewport( p ) ); + QWhatsThis::display( whatsThisText( currentItem() ), p, viewport() ); +} + +QString PropertyList::whatsThisText( QListViewItem *i ) +{ + if ( !i || !editor->widget() ) + return QString::null; + readPropertyDocs(); + if ( ( (PropertyItem*)i )->propertyParent() ) + i = ( (PropertyItem*)i )->propertyParent(); + + const QMetaObject *mo = editor->widget()->metaObject(); + QString prop = ( (PropertyItem*)i )->name(); + while ( mo ) { + QString s; + s = QString( mo->className() ) + "::" + prop; + QMap<QString, QString>::Iterator it; + if ( ( it = propertyDocs.find( s ) ) != propertyDocs.end() ) { + return *it; + } + mo = mo->superClass(); + } + + return i18n( "<p><b>QWidget::%1</b></p><p>There is no documentation available for this property.</p>" ).arg( prop ); +} + +void PropertyList::readPropertyDocs() +{ + if ( !propertyDocs.isEmpty() ) + return; + + QString docFile = MainWindow::self->documentationPath() + "/propertydocs"; + QFile f( docFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &f, &errMsg, &errLine ) ) + return; + QDomElement e = doc.firstChild().toElement().firstChild().toElement(); + + for ( ; !e.isNull(); e = e.nextSibling().toElement() ) { + QDomElement n = e.firstChild().toElement(); + QString name; + QString doc; + for ( ; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "name" ) + name = n.firstChild().toText().data(); + else if ( n.tagName() == "doc" ) + doc = n.firstChild().toText().data(); + } + doc.insert( 0, "<p><b>" + name + "</b></p>" ); + propertyDocs.insert( name, doc ); + } +} + +PropertyList::LastEventType PropertyList::lastEvent() +{ + return theLastEvent; +} +// ------------------------------------------------------------ + +EventList::EventList( QWidget *parent, FormWindow *fw, PropertyEditor *e ) + : HierarchyList( parent, fw, TRUE ), editor( e ) +{ + header()->hide(); + removeColumn( 1 ); + setRootIsDecorated( TRUE ); + connect( this, SIGNAL( itemRenamed( QListViewItem *, int, const QString & ) ), + this, SLOT( renamed( QListViewItem * ) ) ); +} + +QString clean_arguments( const QString &s ) +{ + QString slot = s; + QString arg = slot.mid( slot.find( '(' ) + 1 ); + arg = arg.left( arg.findRev( ')' ) ); + QStringList args = QStringList::split( ',', arg ); + slot = slot.left( slot.find( '(' ) + 1 ); + int num = 0; + for ( QStringList::Iterator it = args.begin(); it != args.end(); ++it, ++num ) { + QString a = *it; + int i; + if ( ( i =a.find( ':' ) ) == -1 ) + slot += a.simplifyWhiteSpace(); + else + slot += a.mid( i + 1 ).simplifyWhiteSpace(); + if ( num < (int)args.count() - 1 ) + slot += ","; + } + + slot += ")"; + + return slot; +} + + +void EventList::setup() +{ + clear(); + + if ( !formWindow ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( formWindow->project()->language() ); + const QPixmap DesignerEditSlotsPix = SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()); + QStrList sigs; + if ( iface ) + { + sigs = iface->signalNames( editor->widget() ); + } + QStrListIterator it( sigs ); + while ( it.current() ) { + HierarchyItem *eventItem = new HierarchyItem( HierarchyItem::Event, this, (HierarchyItem*)0, + it.current(), QString::null, QString::null ); + eventItem->setOpen( TRUE ); + QValueList<MetaDataBase::Connection> conns = + MetaDataBase::connections( formWindow, editor->widget(), formWindow->mainContainer() ); + HierarchyItem *item = 0; + for ( QValueList<MetaDataBase::Connection>::Iterator cit = conns.begin(); + cit != conns.end(); ++cit ) { + QString s = it.current(); + if ( MetaDataBase::normalizeFunction( clean_arguments( QString( (*cit).signal ) ) ) != + MetaDataBase::normalizeFunction( clean_arguments( s ) ) ) + continue; + item = new HierarchyItem( HierarchyItem::EventFunction, eventItem, item, + (*cit).slot, QString::null, QString::null ); + item->setPixmap( 0, DesignerEditSlotsPix ); + } + ++it; + } +} + +extern QListViewItem *newItem; + +void EventList::contentsMouseDoubleClickEvent( QMouseEvent *e ) +{ + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if ( !i || i->parent() ) + return; + QString s; + if ( !formWindow->project()->isCpp() ) { + QString s1 = i->text( 0 ); + int pt = s1.find( "(" ); + if ( pt != -1 ) + s1 = s1.left( pt ); + s = QString( editor->widget()->name() ) + "_" + s1; + } else { + s = QString( editor->widget()->name() ) + "_" + i->text( 0 ); + } + + const QPixmap DesignerEditSlotsPix = SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()); + insertEntry( i, DesignerEditSlotsPix , s ); +} + +void EventList::setCurrent( QWidget * ) +{ +} + +void EventList::objectClicked( QListViewItem *i ) +{ + if ( !i || !i->parent() ) + return; +// formWindow->clearSelection(false); + formWindow->mainWindow()->part()->emitEditFunction(formWindow->fileName(), i->text( 0 )); +// formWindow->mainWindow()->editFunction( i->text( 0 ) ); +} + +void EventList::showRMBMenu( QListViewItem *i, const QPoint &pos ) +{ + if ( !i ) + return; + QPopupMenu menu; + const int NEW_ITEM = 1; + const int DEL_ITEM = 2; + menu.insertItem( SmallIcon( "designer_filenew.png" , KDevDesignerPartFactory::instance()), i18n( "New Signal Handler" ), NEW_ITEM ); + menu.insertItem( SmallIcon( "designer_editcut.png" , KDevDesignerPartFactory::instance()), i18n( "Delete Signal Handler" ), DEL_ITEM ); + int res = menu.exec( pos ); + if ( res == NEW_ITEM ) { + QString s; + if ( !formWindow->project()->isCpp() ) { + QString s1 = ( i->parent() ? i->parent() : i )->text( 0 ); + int pt = s1.find( "(" ); + if ( pt != -1 ) + s1 = s1.left( pt ); + s = QString( editor->widget()->name() ) + "_" + s1; + } else { + s = QString( editor->widget()->name() ) + "_" + ( i->parent() ? i->parent() : i )->text( 0 ); + } + insertEntry( i->parent() ? i->parent() : i, SmallIcon( "designer_editslots.png" , KDevDesignerPartFactory::instance()), s ); + } else if ( res == DEL_ITEM && i->parent() ) { + MetaDataBase::Connection conn; + conn.sender = editor->widget(); + conn.receiver = formWindow->mainContainer(); + conn.signal = i->parent()->text( 0 ); + conn.slot = i->text( 0 ); + delete i; + RemoveConnectionCommand *cmd = new RemoveConnectionCommand( i18n( "Remove Connection" ), + formWindow, + conn ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + editor->formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + } +} + +void EventList::renamed( QListViewItem *i ) +{ + if ( newItem == i ) + newItem = 0; + if ( !i->parent() ) + return; + QListViewItem *itm = i->parent()->firstChild(); + bool del = FALSE; + while ( itm ) { + if ( itm != i && itm->text( 0 ) == i->text( 0 ) ) { + del = TRUE; + break; + } + itm = itm->nextSibling(); + } + i->setRenameEnabled( 0, FALSE ); + if ( del ) { + delete i; + } else { + MetaDataBase::Connection conn; + conn.sender = editor->widget(); + conn.receiver = formWindow->mainContainer(); + conn.signal = i->parent()->text( 0 ); + conn.slot = i->text( 0 ); + AddConnectionCommand *cmd = new AddConnectionCommand( i18n( "Add Connection" ), + formWindow, + conn ); + formWindow->commandHistory()->addCommand( cmd ); + // #### we should look if the specified slot already + // exists and if we can connect to this one + QString funcname = i->text( 0 ).latin1(); + if ( funcname.find( '(' ) == -1 ) { // try to create a signature + QString sig = i->parent()->text( 0 ); + sig = sig.mid( sig.find( '(' ) + 1 ); + sig.remove( (int)sig.length() - 1, 1 ); + LanguageInterface *iface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( iface ) + sig = iface->createArguments( sig.simplifyWhiteSpace() ); + funcname += "(" + sig + ")"; + } + + //normally add a function in kdevdesigner + AddFunctionCommand *cmd2 = new AddFunctionCommand( i18n( "Add Function" ), + formWindow, funcname.latin1(), "virtual", + "public", + "slot", formWindow->project()->language(), + "void" ); + +/* MetaDataBase::addFunction( formWindow, funcname.latin1(), "virtual", "public", + "slot", formWindow->project()->language(), "void" ); + editor->formWindow()->mainWindow()-> + editFunction( i->text( 0 ).left( i->text( 0 ).find( "(" ) ), TRUE );*/ + cmd->execute(); + cmd2->execute(); + editor->formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + editor->formWindow()->formFile()->setModified( TRUE ); + } +} + +void EventList::save( QListViewItem *p ) +{ + QStringList lst; + QListViewItem *i = p->firstChild(); + while ( i ) { + lst << i->text( 0 ); + i = i->nextSibling(); + } +} + +// -------------------------------------------------------------- + +/*! + \class PropertyEditor propertyeditor.h + \brief PropertyEdior toplevel window + + This is the toplevel window of the property editor which contains a + listview for editing properties. +*/ + +PropertyEditor::PropertyEditor( QWidget *parent ) + : QTabWidget( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_StaysOnTop | WStyle_Tool |WStyle_MinMax | WStyle_SysMenu ) +{ + setCaption( i18n( "Property Editor" ) ); + wid = 0; + formwindow = 0; + listview = new PropertyList( this ); + addTab( listview, i18n( "P&roperties" ) ); + eList = new EventList( this, formWindow(), this ); + addTab( eList, i18n( "Signa&l Handlers" ) ); +} + +QObject *PropertyEditor::widget() const +{ + return wid; +} + +void PropertyEditor::setWidget( QObject *w, FormWindow *fw ) +{ + if ( fw && fw->isFake() ) + w = fw->project()->objectForFakeForm( fw ); + eList->setFormWindow( fw ); + if ( w && w == wid ) { + // if there is no properties displayed then we really should show them. + // to do this check the number of properties in the list. + bool ret = (listview->childCount() > 0) ? TRUE : FALSE; + if ( wid->isWidgetType() && WidgetFactory::layoutType( (QWidget*)wid ) != WidgetFactory::NoLayout ) { + QListViewItemIterator it( listview ); + ret = FALSE; + while ( it.current() ) { + if ( it.current()->text( 0 ) == "layoutSpacing" || it.current()->text( 0 ) == "layoutMargin" ) { + ret = TRUE; + break; + } + ++it; + } + } + if ( ret ) + return; + } + + if ( !w || !fw ) { + setCaption( i18n( "Property Editor" ) ); + clear(); + wid = 0; + formwindow = 0; + return; + } + + wid = w; + formwindow = fw; + setCaption( i18n( "Property Editor (%1)" ).arg( formwindow->name() ) ); + listview->viewport()->setUpdatesEnabled( FALSE ); + listview->setUpdatesEnabled( FALSE ); + clear(); + listview->viewport()->setUpdatesEnabled( TRUE ); + listview->setUpdatesEnabled( TRUE ); + setup(); +} + +void PropertyEditor::clear() +{ + listview->setContentsPos( 0, 0 ); + listview->clear(); + eList->setContentsPos( 0, 0 ); + eList->clear(); +} + +void PropertyEditor::setup() +{ + if ( !formwindow || !wid ) + return; + listview->viewport()->setUpdatesEnabled( FALSE ); + listview->setupProperties(); + listview->viewport()->setUpdatesEnabled( TRUE ); + listview->updateEditorSize(); + + if ( !wid->isA( "PropertyObject" ) ) { + eList->viewport()->setUpdatesEnabled( FALSE ); + eList->setup(); + eList->viewport()->setUpdatesEnabled( TRUE ); + } +} + +void PropertyEditor::refetchData() +{ + listview->refetchData(); +} + +void PropertyEditor::emitWidgetChanged() +{ + if ( formwindow && wid ) + formwindow->widgetChanged( wid ); +} + +void PropertyEditor::closed( FormWindow *w ) +{ + if ( w == formwindow ) { + formwindow = 0; + wid = 0; + clear(); + } +} + +void PropertyEditor::closeEvent( QCloseEvent *e ) +{ + emit hidden(); + e->accept(); +} + +PropertyList *PropertyEditor::propertyList() const +{ + return listview; +} + +FormWindow *PropertyEditor::formWindow() const +{ + return formwindow; +} + +QString PropertyEditor::currentProperty() const +{ + if ( !wid ) + return QString::null; + if ( ( (PropertyItem*)listview->currentItem() )->propertyParent() ) + return ( (PropertyItem*)listview->currentItem() )->propertyParent()->name(); + return ( (PropertyItem*)listview->currentItem() )->name(); +} + +QString PropertyEditor::classOfCurrentProperty() const +{ + if ( !wid ) + return QString::null; + QObject *o = wid; + QString curr = currentProperty(); + QMetaObject *mo = o->metaObject(); + while ( mo ) { + QStrList props = mo->propertyNames( FALSE ); + if ( props.find( curr.latin1() ) != -1 ) + return mo->className(); + mo = mo->superClass(); + } + return QString::null; +} + +QMetaObject* PropertyEditor::metaObjectOfCurrentProperty() const +{ + if ( !wid ) + return 0; + return wid->metaObject(); +} + +void PropertyEditor::resetFocus() +{ + if ( listview->currentItem() ) + ( (PropertyItem*)listview->currentItem() )->showEditor(); +} + +EventList *PropertyEditor::eventList() const +{ + return eList; +} + +void PropertyEditor::setPropertyEditorEnabled( bool b ) +{ + if ( !b ) + removePage( listview ); + else + insertTab( listview, i18n( "Property Editor" ), 0 ); + updateWindow(); +} + +void PropertyEditor::setSignalHandlersEnabled( bool b ) +{ + if ( !b ) + removePage( eList ); + else + insertTab( eList, i18n( "Signal Handlers" ), 0 ); + updateWindow(); +} + +void PropertyEditor::updateWindow() +{ + if ( isHidden() && count() ) { + parentWidget()->show(); + MainWindow::self->setAppropriate( (QDockWindow*)parentWidget(), TRUE ); + } else if ( isShown() && !count() ) { + parentWidget()->hide(); + MainWindow::self->setAppropriate( (QDockWindow*)parentWidget(), FALSE ); + } +} diff --git a/kdevdesigner/designer/propertyeditor.h b/kdevdesigner/designer/propertyeditor.h new file mode 100644 index 00000000..3bdc19e3 --- /dev/null +++ b/kdevdesigner/designer/propertyeditor.h @@ -0,0 +1,867 @@ +/********************************************************************** +** 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 PROPERTYEDITOR_H +#define PROPERTYEDITOR_H + +#include <qfeatures.h> +#include <qvariant.h> +#include <qlistview.h> +#include <qptrlist.h> +#include <qguardedptr.h> +#include <qtabwidget.h> +#include <qmodules.h> +#include <qptrlist.h> +#include <qlayout.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include "hierarchyview.h" +#include "metadatabase.h" + +class PropertyList; +class PropertyEditor; +class QPainter; +class QColorGroup; +class QLineEdit; +class QPushButton; +class QHBox; +class QSpinBox; +class QLabel; +class QFrame; +class FormWindow; +class QCloseEvent; +class QResizeEvent; +class PropertyWhatsThis; +class QDateEdit; +class QTimeEdit; +class QDateTimeEdit; + +class PropertyItem : public QListViewItem +{ +public: + PropertyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyItem(); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ); + void paintBranches( QPainter * p, const QColorGroup & cg, + int w, int y, int h ); + void paintFocus( QPainter *p, const QColorGroup &cg, const QRect &r ); + + virtual bool hasSubItems() const; + virtual void createChildren(); + virtual void initChildren(); + + bool isOpen() const; + void setOpen( bool b ); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + QVariant value() const; + QString name() const; + virtual void notifyValueChange(); + + virtual void setChanged( bool b, bool updateDb = TRUE ); + bool isChanged() const; + + virtual void placeEditor( QWidget *w ); + + virtual PropertyItem *propertyParent() const; + virtual void childValueChanged( PropertyItem *child ); + + void addChild( PropertyItem *i ); + int childCount() const; + PropertyItem *child( int i ) const; + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + + void updateBackColor(); + + void setup() { QListViewItem::setup(); setHeight( QListViewItem::height() + 2 ); } + + virtual QString currentItem() const; + virtual int currentIntItem() const; + virtual void setCurrentItem( const QString &s ); + virtual void setCurrentItem( int i ); + virtual int currentIntItemFromObject() const; + virtual QString currentItemFromObject() const; + + void setFocus( QWidget *w ); + + virtual void toggle(); + void setText( int col, const QString &txt ); + +protected: + PropertyList *listview; + QVariant val; + +private: + QColor backgroundColor(); + void createResetButton(); + void updateResetButtonState(); + +private: + bool open, changed; + PropertyItem *property; + QString propertyName; + QPtrList<PropertyItem> children; + QColor backColor; + QPushButton *resetButton; + +}; + +class PropertyTextItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyTextItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool comment, bool multiLine, bool ascii = FALSE, bool a = FALSE ); + ~PropertyTextItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + + virtual void setChanged( bool b, bool updateDb = TRUE ); + +private slots: + void setValue(); + void getText(); + +private: + QLineEdit *lined(); + QGuardedPtr<QLineEdit> lin; + QGuardedPtr<QHBox> box; + QPushButton *button; + bool withComment, hasMultiLines, asciiOnly, accel; + +}; + + +class PropertyBoolItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyBoolItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyBoolItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual void toggle(); + +private slots: + void setValue(); + +private: + QComboBox *combo(); + QGuardedPtr<QComboBox> comb; + +}; + +class PropertyIntItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyIntItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool s ); + ~PropertyIntItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QSpinBox *spinBox(); + QGuardedPtr<QSpinBox> spinBx; + bool signedValue; + +}; + +class PropertyLayoutItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyLayoutItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyLayoutItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QSpinBox *spinBox(); + QGuardedPtr<QSpinBox> spinBx; + +}; + +class PropertyDoubleItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDoubleItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyDoubleItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QLineEdit *lined(); + QGuardedPtr<QLineEdit> lin; +}; + +class PropertyListItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyListItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool editable ); + ~PropertyListItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + + QString currentItem() const; + int currentIntItem() const; + void setCurrentItem( const QString &s ); + void setCurrentItem( int i ); + int currentIntItemFromObject() const; + QString currentItemFromObject() const; + void addItem( const QString &s ); + +private slots: + void setValue(); + +private: + QComboBox *combo(); + QGuardedPtr<QComboBox> comb; + int oldInt; + bool editable; + QString oldString; + +}; + +class PropertyFontItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyFontItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyFontItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private slots: + void getFont(); + +private: + QGuardedPtr<QLineEdit> lined; + QGuardedPtr<QPushButton> button; + QGuardedPtr<QHBox> box; + +}; + +class PropertyCoordItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + enum Type { Rect, Size, Point }; + + PropertyCoordItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ); + ~PropertyCoordItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private: + QLineEdit *lined(); + QGuardedPtr<QLineEdit> lin; + Type typ; + +}; + +class PropertyColorItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyColorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool children ); + ~PropertyColorItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + +private slots: + void getColor(); + +private: + QGuardedPtr<QHBox> box; + QGuardedPtr<QFrame> colorPrev; + QGuardedPtr<QPushButton> button; + bool withChildren; + +}; + +class PropertyPixmapItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + enum Type { Pixmap, IconSet, Image }; + + PropertyPixmapItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ); + ~PropertyPixmapItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + +private slots: + void getPixmap(); + +private: + QGuardedPtr<QHBox> box; + QGuardedPtr<QLabel> pixPrev; + QPushButton *button; + Type type; + +}; + + +class PropertySizePolicyItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertySizePolicyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertySizePolicyItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private: + QLineEdit *lined(); + QGuardedPtr<QLineEdit> lin; + +}; + +class PropertyPaletteItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyPaletteItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyPaletteItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + +private slots: + void getPalette(); + +private: + QGuardedPtr<QHBox> box; + QGuardedPtr<QLabel> palettePrev; + QGuardedPtr<QPushButton> button; + +}; + +class PropertyCursorItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyCursorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyCursorItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QComboBox *combo(); + QGuardedPtr<QComboBox> comb; + +}; + +class PropertyKeysequenceItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyKeysequenceItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyKeysequenceItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + bool eventFilter( QObject *o, QEvent *e ); + void handleKeyEvent( QKeyEvent *e ); + int translateModifiers( int state ); + + QGuardedPtr<QLineEdit> sequence; + QGuardedPtr<QHBox> box; + int k1,k2,k3,k4; + int num; + bool mouseEnter; +}; + +class PropertyDatabaseItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDatabaseItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName, bool wField ); + ~PropertyDatabaseItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private: + QGuardedPtr<QLineEdit> lined; + QGuardedPtr<QPushButton> button; + QGuardedPtr<QHBox> box; + bool withField; + +}; + +struct EnumItem { + EnumItem( const QString &k, bool s ) + : key( k ), selected( s ) {} + EnumItem() : key( QString::null ), selected( FALSE ) {} + bool operator==( const EnumItem &item ) const { + return key == item.key; + } + QString key; + bool selected; +}; + +class EnumPopup : public QFrame +{ + Q_OBJECT + +public: + EnumPopup( QWidget *parent, const char *name, WFlags f=0 ); + ~EnumPopup(); + void insertEnums( QValueList<EnumItem> lst ); + QValueList<EnumItem> enumList() const; + void closeWidget(); + +signals: + void closed(); + void hidden(); + +protected: + void keyPressEvent( QKeyEvent *e ); + +private: + QValueList<EnumItem> itemList; + QPtrList<QCheckBox> checkBoxList; + QVBoxLayout *popLayout; +}; + +class EnumBox : public QComboBox +{ + Q_OBJECT + +public: + EnumBox( QWidget *parent, const char *name = 0 ); + ~EnumBox() {} + void setText( const QString &text ); + void insertEnums( QValueList<EnumItem> lst ); + QValueList<EnumItem> enumList() const; + +signals: + void aboutToShowPopup(); + void valueChanged(); + +protected: + void paintEvent( QPaintEvent * ); + void mousePressEvent( QMouseEvent *e ); + void keyPressEvent( QKeyEvent *e ); + +protected slots: + void restoreArrow(); + void popupHidden(); + void popupClosed(); + +private: + void popup(); + bool arrowDown; + QString str; + bool popupShown; + EnumPopup *pop; + +}; +class PropertyEnumItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyEnumItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyEnumItem(); + + void showEditor(); + void hideEditor(); + void setValue( const QVariant &v ); + QString currentItem() const; + QString currentItemFromObject() const; + void setCurrentValues( QStrList lst ); + +private slots: + void setValue(); + void insertEnums(); + +private: + QGuardedPtr<EnumBox> box; + QValueList<EnumItem> enumList; + QString enumString; +}; + +class PropertyList : public QListView +{ + Q_OBJECT + +public: + PropertyList( PropertyEditor *e ); + + virtual void setupProperties(); + + virtual void setCurrentItem( QListViewItem *i ); + virtual void valueChanged( PropertyItem *i ); + virtual void refetchData(); + virtual void setPropertyValue( PropertyItem *i ); + virtual void setCurrentProperty( const QString &n ); + + void layoutInitValue( PropertyItem *i, bool changed = FALSE ); + PropertyEditor *propertyEditor() const; + QString whatsThisAt( const QPoint &p ); + void showCurrentWhatsThis(); + + enum LastEventType { KeyEvent, MouseEvent }; + LastEventType lastEvent(); + +public slots: + void updateEditorSize(); + void resetProperty(); + void toggleSort(); + +private slots: + void itemPressed( QListViewItem *i, const QPoint &p, int c ); + void toggleOpen( QListViewItem *i ); + bool eventFilter( QObject *o, QEvent *e ); + +protected: + void resizeEvent( QResizeEvent *e ); + void paintEmptyArea( QPainter *p, const QRect &r ); + bool addPropertyItem( PropertyItem *&item, const QCString &name, QVariant::Type t ); + + void viewportDragEnterEvent( QDragEnterEvent * ); + void viewportDragMoveEvent ( QDragMoveEvent * ); + void viewportDropEvent ( QDropEvent * ); + +protected: + PropertyEditor *editor; + +private: + void readPropertyDocs(); + void setupCusWidgetProperties( MetaDataBase::CustomWidget *cw, + QMap<QString, bool> &unique, + PropertyItem *&item ); + QString whatsThisText( QListViewItem *i ); + +private: + PropertyListItem* pressItem; + QPoint pressPos; + bool mousePressed; + bool showSorted; + QMap<QString, QString> propertyDocs; + PropertyWhatsThis *whatsThis; + LastEventType theLastEvent; +}; + +class EventList : public HierarchyList +{ + Q_OBJECT + +public: + EventList( QWidget *parent, FormWindow *fw, PropertyEditor *e ); + + void setup(); + void setCurrent( QWidget *w ); + +protected: + void contentsMouseDoubleClickEvent( QMouseEvent *e ); + +private: + void save( QListViewItem *p ); + +private slots: + void objectClicked( QListViewItem *i ); + void showRMBMenu( QListViewItem *, const QPoint & ); + void renamed( QListViewItem *i ); + +private: + PropertyEditor *editor; + +}; + + +class PropertyEditor : public QTabWidget +{ + Q_OBJECT + +public: + PropertyEditor( QWidget *parent ); + + QObject *widget() const; + + void clear(); + void setup(); + + void emitWidgetChanged(); + void refetchData(); + + void closed( FormWindow *w ); + + PropertyList *propertyList() const; + FormWindow *formWindow() const; + EventList *eventList() const; + + QString currentProperty() const; + QString classOfCurrentProperty() const; + QMetaObject* metaObjectOfCurrentProperty() const; + + void resetFocus(); + + void setPropertyEditorEnabled( bool b ); + void setSignalHandlersEnabled( bool b ); + +signals: + void hidden(); + +public slots: + void setWidget( QObject *w, FormWindow *fw ); + +protected: + void closeEvent( QCloseEvent *e ); + +private: + void updateWindow(); + +private: + QObject *wid; + PropertyList *listview; + EventList *eList; + FormWindow *formwindow; + +}; + +class PropertyDateItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDateItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyDateItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QDateEdit *lined(); + QGuardedPtr<QDateEdit> lin; + +}; + +class PropertyTimeItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyTimeItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QTimeEdit *lined(); + QGuardedPtr<QTimeEdit> lin; + +}; + +class PropertyDateTimeItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDateTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyDateTimeItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QDateTimeEdit *lined(); + QGuardedPtr<QDateTimeEdit> lin; + +}; + +#endif diff --git a/kdevdesigner/designer/propertyobject.cpp b/kdevdesigner/designer/propertyobject.cpp new file mode 100644 index 00000000..8687033e --- /dev/null +++ b/kdevdesigner/designer/propertyobject.cpp @@ -0,0 +1,158 @@ +/********************************************************************** +** Copyright (C) 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 "propertyobject.h" +#include "metadatabase.h" +#include <qptrvector.h> +#include <qptrlist.h> +#include <qmetaobject.h> +#include <qvariant.h> + +PropertyObject::PropertyObject( const QWidgetList &objs ) + : QObject(), objects( objs ), mobj( 0 ) +{ + QPtrVector<QPtrList<QMetaObject> > v; + v.resize( objects.count() ); + v.setAutoDelete( TRUE ); + + for ( QObject *o = objects.first(); o; o = objects.next() ) { + const QMetaObject *m = o->metaObject(); + QPtrList<QMetaObject> *mol = new QPtrList<QMetaObject>; + while ( m ) { + mol->insert( 0, m ); + m = m->superClass(); + } + v.insert( v.count(), mol ); + } + + int numObjects = objects.count(); + int minDepth = v[0]->count(); + int depth = minDepth; + + for ( int i = 0; i < numObjects; ++i ) { + depth = (int)v[i]->count(); + if ( depth < minDepth ) + minDepth = depth; + } + + const QMetaObject *m = v[0]->at( --minDepth ); + + for ( int j = 0; j < numObjects; ++j ) { + if ( v[j]->at( minDepth ) != m ) { + m = v[0]->at( --minDepth ); + j = 0; + } + } + + mobj = m; + + Q_ASSERT( mobj ); +} + +bool PropertyObject::setProperty( const char *name, const QVariant& value ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + o->setProperty( name, value ); + + return TRUE; +} + +QVariant PropertyObject::property( const char *name ) const +{ + return ( (PropertyObject*)this )->objects.first()->property( name ); +} + +void PropertyObject::mdPropertyChanged( const QString &property, bool changed ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setPropertyChanged( o, property, changed ); +} + +bool PropertyObject::mdIsPropertyChanged( const QString &property ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) { + if ( MetaDataBase::isPropertyChanged( o, property ) ) + return TRUE; + } + return FALSE; +} + +void PropertyObject::mdSetPropertyComment( const QString &property, const QString &comment ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setPropertyComment( o, property, comment ); +} + +QString PropertyObject::mdPropertyComment( const QString &property ) +{ + return MetaDataBase::propertyComment( objects.first(), property ); +} + +void PropertyObject::mdSetFakeProperty( const QString &property, const QVariant &value ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setFakeProperty( o, property, value ); +} + +QVariant PropertyObject::mdFakeProperty( const QString &property ) +{ + return MetaDataBase::fakeProperty( objects.first(), property ); +} + +void PropertyObject::mdSetCursor( const QCursor &c ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) { + if ( o->isWidgetType() ) + MetaDataBase::setCursor( (QWidget*)o, c ); + } +} + +QCursor PropertyObject::mdCursor() +{ + return MetaDataBase::cursor( objects.first() ); +} + +void PropertyObject::mdSetPixmapKey( int pixmap, const QString &arg ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setPixmapKey( o, pixmap, arg ); +} + +QString PropertyObject::mdPixmapKey( int pixmap ) +{ + return MetaDataBase::pixmapKey( objects.first(), pixmap ); +} + +void PropertyObject::mdSetExportMacro( const QString ¯o ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setExportMacro( o, macro ); +} + +QString PropertyObject::mdExportMacro() +{ + return MetaDataBase::exportMacro( objects.first() ); +} diff --git a/kdevdesigner/designer/propertyobject.h b/kdevdesigner/designer/propertyobject.h new file mode 100644 index 00000000..c8445239 --- /dev/null +++ b/kdevdesigner/designer/propertyobject.h @@ -0,0 +1,43 @@ +#ifndef PROPERTYOBJECT_H +#define PROPERTYOBJECT_H + +#include <qobject.h> +#include <qwidgetlist.h> +#include <qcursor.h> + +class PropertyObject : public QObject +{ +public: + QMetaObject *metaObject() const { return (QMetaObject*)mobj; } + const char *className() const { return "PropertyObject"; } + QObject* qObject() { return (QObject*)this; } +private: + static QMetaObject *metaObj; + +public: + PropertyObject( const QWidgetList &objs ); + + bool setProperty( const char *name, const QVariant& value ); + QVariant property( const char *name ) const; + + void mdPropertyChanged( const QString &property, bool changed ); + bool mdIsPropertyChanged( const QString &property ); + void mdSetPropertyComment( const QString &property, const QString &comment ); + QString mdPropertyComment( const QString &property ); + void mdSetFakeProperty( const QString &property, const QVariant &value ); + QVariant mdFakeProperty( const QString &property ); + void mdSetCursor( const QCursor &c ); + QCursor mdCursor(); + void mdSetPixmapKey( int pixmap, const QString &arg ); + QString mdPixmapKey( int pixmap ); + void mdSetExportMacro( const QString ¯o ); + QString mdExportMacro(); + QWidgetList widgetList() const { return objects; } + +private: + QWidgetList objects; + const QMetaObject *mobj; + +}; + +#endif diff --git a/kdevdesigner/designer/qcompletionedit.cpp b/kdevdesigner/designer/qcompletionedit.cpp new file mode 100644 index 00000000..9c735577 --- /dev/null +++ b/kdevdesigner/designer/qcompletionedit.cpp @@ -0,0 +1,210 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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 "qcompletionedit.h" +#include <qlistbox.h> +#include <qsizegrip.h> +#include <qapplication.h> +#include <qvbox.h> + +QCompletionEdit::QCompletionEdit( QWidget *parent, const char *name ) + : QLineEdit( parent, name ), aAdd( FALSE ), caseSensitive( FALSE ) +{ + popup = new QVBox( 0, 0, WType_Popup ); + popup->setFrameStyle( QFrame::Box | QFrame::Plain ); + popup->setLineWidth( 1 ); + popup->hide(); + + listbox = new QListBox( popup ); + listbox->setFrameStyle( QFrame::NoFrame ); + listbox->setLineWidth( 1 ); + listbox->installEventFilter( this ); + listbox->setHScrollBarMode( QScrollView::AlwaysOn ); + listbox->setVScrollBarMode( QScrollView::AlwaysOn ); + listbox->setCornerWidget( new QSizeGrip( listbox, "completion sizegrip" ) ); + connect( this, SIGNAL( textChanged( const QString & ) ), + this, SLOT( textDidChange( const QString & ) ) ); + popup->setFocusProxy( listbox ); + installEventFilter( this ); +} + +bool QCompletionEdit::autoAdd() const +{ + return aAdd; +} + +QStringList QCompletionEdit::completionList() const +{ + return compList; +} + +void QCompletionEdit::setCompletionList( const QStringList &l ) +{ + compList = l; +} + +void QCompletionEdit::setAutoAdd( bool add ) +{ + aAdd = add; +} + +void QCompletionEdit::textDidChange( const QString &text ) +{ + if ( text.isEmpty() ) { + popup->close(); + return; + } + updateListBox(); + placeListBox(); +} + +void QCompletionEdit::placeListBox() +{ + if ( listbox->count() == 0 ) { + popup->close(); + return; + } + + popup->resize( QMAX( listbox->sizeHint().width() + listbox->verticalScrollBar()->width() + 4, width() ), + listbox->sizeHint().height() + listbox->horizontalScrollBar()->height() + 4 ); + + QPoint p( mapToGlobal( QPoint( 0, 0 ) ) ); + if ( p.y() + height() + popup->height() <= QApplication::desktop()->height() ) + popup->move( p.x(), p.y() + height() ); + else + popup->move( p.x(), p.y() - listbox->height() ); + popup->show(); + listbox->setCurrentItem( 0 ); + listbox->setSelected( 0, TRUE ); + setFocus(); +} + +void QCompletionEdit::updateListBox() +{ + listbox->clear(); + if ( compList.isEmpty() ) + return; + for ( QStringList::Iterator it = compList.begin(); it != compList.end(); ++it ) { + if ( caseSensitive && (*it).left( text().length() ) == text() || + !caseSensitive && (*it).left( text().length() ).lower() == text().lower() ) + listbox->insertItem( *it ); + } +} + +bool QCompletionEdit::eventFilter( QObject *o, QEvent *e ) +{ + if ( o == popup || o == listbox || o == listbox->viewport() ) { + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Enter || ke->key() == Key_Return || ke->key() == Key_Tab ) { + if ( ke->key() == Key_Tab && listbox->count() > 1 && + listbox->currentItem() < (int)listbox->count() - 1 ) { + listbox->setCurrentItem( listbox->currentItem() + 1 ); + return TRUE; + } + popup->close(); + setFocus(); + blockSignals( TRUE ); + setText( listbox->currentText() ); + blockSignals( FALSE ); + emit chosen( text() ); + return TRUE; + } else if ( ke->key() == Key_Left || ke->key() == Key_Right || + ke->key() == Key_Up || ke->key() == Key_Down || + ke->key() == Key_Home || ke->key() == Key_End || + ke->key() == Key_Prior || ke->key() == Key_Next ) { + return FALSE; + } else if ( ke->key() == Key_Escape ) { + popup->close(); + setFocus(); + } else if ( ke->key() != Key_Shift && ke->key() != Key_Control && + ke->key() != Key_Alt ) { + updateListBox(); + if ( listbox->count() == 0 || text().length() == 0 ) { + popup->close(); + setFocus(); + } + QApplication::sendEvent( this, e ); + return TRUE; + } + } else if ( e->type() == QEvent::MouseButtonDblClick ) { + popup->close(); + setFocus(); + blockSignals( TRUE ); + setText( listbox->currentText() ); + blockSignals( FALSE ); + emit chosen( text() ); + return TRUE; + } + } else if ( o == this ) { + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Up || + ke->key() == Key_Down || + ke->key() == Key_Prior || + ke->key() == Key_Next || + ke->key() == Key_Return || + ke->key() == Key_Enter || + ke->key() == Key_Tab || + ke->key() == Key_Escape ) { + QApplication::sendEvent( listbox, e ); + return TRUE; + } + } + } + return QLineEdit::eventFilter( o, e ); +} + +void QCompletionEdit::addCompletionEntry( const QString &entry ) +{ + if ( compList.find( entry ) == compList.end() ) { + compList << entry; + compList.sort(); + } +} + +void QCompletionEdit::removeCompletionEntry( const QString &entry ) +{ + QStringList::Iterator it = compList.find( entry ); + if ( it != compList.end() ) + compList.remove( it ); +} + +void QCompletionEdit::setCaseSensitive( bool b ) +{ + caseSensitive = b; +} + +bool QCompletionEdit::isCaseSensitive() const +{ + return caseSensitive; +} + +void QCompletionEdit::clear() +{ + QLineEdit::clear(); + compList.clear(); +} diff --git a/kdevdesigner/designer/qcompletionedit.h b/kdevdesigner/designer/qcompletionedit.h new file mode 100644 index 00000000..426e7202 --- /dev/null +++ b/kdevdesigner/designer/qcompletionedit.h @@ -0,0 +1,79 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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 QCOMPLETIONEDIT_H +#define QCOMPLETIONEDIT_H + +#include <qlineedit.h> +#include <qstringlist.h> + +class QListBox; +class QVBox; + +class QCompletionEdit : public QLineEdit +{ + Q_OBJECT + Q_PROPERTY( bool autoAdd READ autoAdd WRITE setAutoAdd ) + Q_PROPERTY( bool caseSensitive READ isCaseSensitive WRITE setCaseSensitive ) + +public: + QCompletionEdit( QWidget *parent = 0, const char *name = 0 ); + + bool autoAdd() const; + QStringList completionList() const; + bool eventFilter( QObject *o, QEvent *e ); + bool isCaseSensitive() const; + +public slots: + void setCompletionList( const QStringList &l ); + void setAutoAdd( bool add ); + void clear(); + void addCompletionEntry( const QString &entry ); + void removeCompletionEntry( const QString &entry ); + void setCaseSensitive( bool b ); + +signals: + void chosen( const QString &text ); + +private slots: + void textDidChange( const QString &text ); + +private: + void placeListBox(); + void updateListBox(); + +private: + bool aAdd; + QStringList compList; + QListBox *listbox; + QVBox *popup; + bool caseSensitive; + +}; + + + +#endif diff --git a/kdevdesigner/designer/replacedialog.ui b/kdevdesigner/designer/replacedialog.ui new file mode 100644 index 00000000..41a211ea --- /dev/null +++ b/kdevdesigner/designer/replacedialog.ui @@ -0,0 +1,318 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ReplaceDialog</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>ReplaceDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>286</width> + <height>217</height> + </rect> + </property> + <property name="caption"> + <string>Replace Text</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>R&eplace:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboReplace</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Find:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboFind</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>comboFind</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>comboReplace</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonReplace</cstring> + </property> + <property name="text"> + <string>&Replace</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonReplaceAll</cstring> + </property> + <property name="text"> + <string>Replace &All</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QButtonGroup" row="1" column="0"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkWords</cstring> + </property> + <property name="text"> + <string>&Whole words only</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkCase</cstring> + </property> + <property name="text"> + <string>Case &sensitive</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBegin</cstring> + </property> + <property name="text"> + <string>Start at &beginning</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup" row="1" column="1"> + <property name="name"> + <cstring>ButtonGroup2</cstring> + </property> + <property name="title"> + <string>Direction</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioForward</cstring> + </property> + <property name="text"> + <string>Forwar&d</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioBackward</cstring> + </property> + <property name="text"> + <string>Bac&kward</string> + </property> + </widget> + </vbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonReplace</sender> + <signal>clicked()</signal> + <receiver>ReplaceDialog</receiver> + <slot>doReplace()</slot> + </connection> + <connection> + <sender>buttonReplaceAll</sender> + <signal>clicked()</signal> + <receiver>ReplaceDialog</receiver> + <slot>doReplaceAll()</slot> + </connection> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>ReplaceDialog</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>comboFind</tabstop> + <tabstop>comboReplace</tabstop> + <tabstop>checkWords</tabstop> + <tabstop>checkCase</tabstop> + <tabstop>checkBegin</tabstop> + <tabstop>radioForward</tabstop> + <tabstop>radioBackward</tabstop> + <tabstop>buttonReplace</tabstop> + <tabstop>buttonReplaceAll</tabstop> + <tabstop>PushButton2</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">../interfaces/editorinterface.h</include> + <include location="global" impldecl="in implementation">qlineedit.h</include> + <include location="local" impldecl="in implementation">replacedialog.ui.h</include> +</includes> +<forwards> + <forward>struct EditorInterface;</forward> +</forwards> +<variables> + <variable>EditorInterface *editor;</variable> + <variable>QObject *formWindow;</variable> +</variables> +<slots> + <slot>init()</slot> + <slot>destroy()</slot> + <slot>doReplace()</slot> + <slot>doReplaceAll()</slot> + <slot>setEditor( EditorInterface * e, QObject * fw )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/replacedialog.ui.h b/kdevdesigner/designer/replacedialog.ui.h new file mode 100644 index 00000000..9fa0f546 --- /dev/null +++ b/kdevdesigner/designer/replacedialog.ui.h @@ -0,0 +1,75 @@ +/********************************************************************** +** Copyright (C) 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. +** +** 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. +** +**********************************************************************/ + + +void ReplaceDialog::init() +{ + editor = 0; + formWindow = 0; +} + +void ReplaceDialog::destroy() +{ + if ( editor ) + editor->release(); + editor = 0; + formWindow = 0; +} + +void ReplaceDialog::doReplace() +{ + if ( !editor ) + return; + + if ( !editor->replace( comboFind->currentText(), comboReplace->currentText(), checkCase->isChecked(), + checkWords->isChecked(), radioForward->isChecked(), !checkBegin->isChecked(), FALSE ) ) + checkBegin->setChecked( TRUE ); + else + checkBegin->setChecked( FALSE ); +} + +void ReplaceDialog::doReplaceAll() +{ + if ( !editor ) + return; + + if ( !editor->replace( comboFind->currentText(), comboReplace->currentText(), checkCase->isChecked(), + checkWords->isChecked(), radioForward->isChecked(), !checkBegin->isChecked(), TRUE ) ) + checkBegin->setChecked( TRUE ); + else + checkBegin->setChecked( FALSE ); +} + +void ReplaceDialog::setEditor( EditorInterface * e, QObject * fw ) +{ + if ( fw != formWindow ) + checkBegin->setChecked( TRUE ); + formWindow = fw; + if ( editor ) + editor->release(); + editor = e; + editor->addRef(); +} diff --git a/kdevdesigner/designer/resource.cpp b/kdevdesigner/designer/resource.cpp new file mode 100644 index 00000000..ca983a42 --- /dev/null +++ b/kdevdesigner/designer/resource.cpp @@ -0,0 +1,3327 @@ +/********************************************************************** +** 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 "actiondnd.h" +#include "command.h" +#ifndef QT_NO_SQL +#include "database.h" +#endif +#include "formfile.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "menubareditor.h" +#include "metadatabase.h" +#include "pixmapcollection.h" +#include "popupmenueditor.h" +#include "project.h" +#include "resource.h" +#include "widgetfactory.h" + +#include <domtool.h> +#include <widgetdatabase.h> + +#include <qaccel.h> +#include <qapplication.h> +#include <qbuffer.h> +#include <qcombobox.h> +#include <qdatetime.h> +#include <qdom.h> +#include <qfeatures.h> +#include <qfile.h> +#include <qheader.h> +#include <qiconview.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlistbox.h> +#include <qlistview.h> +#include <qmenudata.h> +#include <qmessagebox.h> +#include <qmetaobject.h> +#include <qobject.h> +#include <qobjectlist.h> +#include <qtabbar.h> +#ifndef QT_NO_TABLE +#include <qtable.h> +#include <qdatatable.h> +#endif +#include <qtabwidget.h> +#include <qtabwidget.h> +#include <qtextcodec.h> +#include <qtextstream.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qwidget.h> +#include <qwidgetstack.h> +#include <qwizard.h> +#include <qworkspace.h> +#include <qworkspace.h> +#include <qsplitter.h> +#include <private/qucom_p.h> + +#include <kiconloader.h> +#include <kfiledialog.h> +#include <klocale.h> + +#include "kdevdesigner_part.h" + +static QString makeIndent( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} + +static QString entitize( const QString &s, bool attribute = FALSE ) +{ + QString s2 = s; + s2 = s2.replace( "&", "&" ); + s2 = s2.replace( ">", ">" ); + s2 = s2.replace( "<", "<" ); + if ( attribute ) { + s2 = s2.replace( "\"", """ ); + s2 = s2.replace( "'", "'" ); + } + return s2; +} + +#ifdef Q_WS_MACX +static struct { + int key; + const char* name; +} keyname[] = { + { Qt::Key_Space, QT_TRANSLATE_NOOP( "QAccel", "Space" ) }, + { Qt::Key_Escape, QT_TRANSLATE_NOOP( "QAccel", "Esc" ) }, + { Qt::Key_Tab, QT_TRANSLATE_NOOP( "QAccel", "Tab" ) }, + { Qt::Key_Backtab, QT_TRANSLATE_NOOP( "QAccel", "Backtab" ) }, + { Qt::Key_Backspace, QT_TRANSLATE_NOOP( "QAccel", "Backspace" ) }, + { Qt::Key_Return, QT_TRANSLATE_NOOP( "QAccel", "Return" ) }, + { Qt::Key_Enter, QT_TRANSLATE_NOOP( "QAccel", "Enter" ) }, + { Qt::Key_Insert, QT_TRANSLATE_NOOP( "QAccel", "Ins" ) }, + { Qt::Key_Delete, QT_TRANSLATE_NOOP( "QAccel", "Del" ) }, + { Qt::Key_Pause, QT_TRANSLATE_NOOP( "QAccel", "Pause" ) }, + { Qt::Key_Print, QT_TRANSLATE_NOOP( "QAccel", "Print" ) }, + { Qt::Key_SysReq, QT_TRANSLATE_NOOP( "QAccel", "SysReq" ) }, + { Qt::Key_Home, QT_TRANSLATE_NOOP( "QAccel", "Home" ) }, + { Qt::Key_End, QT_TRANSLATE_NOOP( "QAccel", "End" ) }, + { Qt::Key_Left, QT_TRANSLATE_NOOP( "QAccel", "Left" ) }, + { Qt::Key_Up, QT_TRANSLATE_NOOP( "QAccel", "Up" ) }, + { Qt::Key_Right, QT_TRANSLATE_NOOP( "QAccel", "Right" ) }, + { Qt::Key_Down, QT_TRANSLATE_NOOP( "QAccel", "Down" ) }, + { Qt::Key_Prior, QT_TRANSLATE_NOOP( "QAccel", "PgUp" ) }, + { Qt::Key_Next, QT_TRANSLATE_NOOP( "QAccel", "PgDown" ) }, + { Qt::Key_CapsLock, QT_TRANSLATE_NOOP( "QAccel", "CapsLock" ) }, + { Qt::Key_NumLock, QT_TRANSLATE_NOOP( "QAccel", "NumLock" ) }, + { Qt::Key_ScrollLock, QT_TRANSLATE_NOOP( "QAccel", "ScrollLock" ) }, + { Qt::Key_Menu, QT_TRANSLATE_NOOP( "QAccel", "Menu" ) }, + { Qt::Key_Help, QT_TRANSLATE_NOOP( "QAccel", "Help" ) }, + + // Multimedia keys + { Qt::Key_Back, QT_TRANSLATE_NOOP( "QAccel", "Back" ) }, + { Qt::Key_Forward, QT_TRANSLATE_NOOP( "QAccel", "Forward" ) }, + { Qt::Key_Stop, QT_TRANSLATE_NOOP( "QAccel", "Stop" ) }, + { Qt::Key_Refresh, QT_TRANSLATE_NOOP( "QAccel", "Refresh" ) }, + { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP( "QAccel", "Volume Down" ) }, + { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP( "QAccel", "Volume Mute" ) }, + { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP( "QAccel", "Volume Up" ) }, + { Qt::Key_BassBoost, QT_TRANSLATE_NOOP( "QAccel", "Bass Boost" ) }, + { Qt::Key_BassUp, QT_TRANSLATE_NOOP( "QAccel", "Bass Up" ) }, + { Qt::Key_BassDown, QT_TRANSLATE_NOOP( "QAccel", "Bass Down" ) }, + { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP( "QAccel", "Treble Up" ) }, + { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP( "QAccel", "Treble Down" ) }, + { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP( "QAccel", "Media Play" ) }, + { Qt::Key_MediaStop, QT_TRANSLATE_NOOP( "QAccel", "Media Stop" ) }, + { Qt::Key_MediaPrev, QT_TRANSLATE_NOOP( "QAccel", "Media Previous" ) }, + { Qt::Key_MediaNext, QT_TRANSLATE_NOOP( "QAccel", "Media Next" ) }, + { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP( "QAccel", "Media Record" ) }, + { Qt::Key_HomePage, QT_TRANSLATE_NOOP( "QAccel", "Home" ) }, + { Qt::Key_Favorites, QT_TRANSLATE_NOOP( "QAccel", "Favorites" ) }, + { Qt::Key_Search, QT_TRANSLATE_NOOP( "QAccel", "Search" ) }, + { Qt::Key_Standby, QT_TRANSLATE_NOOP( "QAccel", "Standby" ) }, + { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP( "QAccel", "Open URL" ) }, + { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP( "QAccel", "Launch Mail" ) }, + { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP( "QAccel", "Launch Media" ) }, + { Qt::Key_Launch0, QT_TRANSLATE_NOOP( "QAccel", "Launch (0)" ) }, + { Qt::Key_Launch1, QT_TRANSLATE_NOOP( "QAccel", "Launch (1)" ) }, + { Qt::Key_Launch2, QT_TRANSLATE_NOOP( "QAccel", "Launch (2)" ) }, + { Qt::Key_Launch3, QT_TRANSLATE_NOOP( "QAccel", "Launch (3)" ) }, + { Qt::Key_Launch4, QT_TRANSLATE_NOOP( "QAccel", "Launch (4)" ) }, + { Qt::Key_Launch5, QT_TRANSLATE_NOOP( "QAccel", "Launch (5)" ) }, + { Qt::Key_Launch6, QT_TRANSLATE_NOOP( "QAccel", "Launch (6)" ) }, + { Qt::Key_Launch7, QT_TRANSLATE_NOOP( "QAccel", "Launch (7)" ) }, + { Qt::Key_Launch8, QT_TRANSLATE_NOOP( "QAccel", "Launch (8)" ) }, + { Qt::Key_Launch9, QT_TRANSLATE_NOOP( "QAccel", "Launch (9)" ) }, + { Qt::Key_LaunchA, QT_TRANSLATE_NOOP( "QAccel", "Launch (A)" ) }, + { Qt::Key_LaunchB, QT_TRANSLATE_NOOP( "QAccel", "Launch (B)" ) }, + { Qt::Key_LaunchC, QT_TRANSLATE_NOOP( "QAccel", "Launch (C)" ) }, + { Qt::Key_LaunchD, QT_TRANSLATE_NOOP( "QAccel", "Launch (D)" ) }, + { Qt::Key_LaunchE, QT_TRANSLATE_NOOP( "QAccel", "Launch (E)" ) }, + { Qt::Key_LaunchF, QT_TRANSLATE_NOOP( "QAccel", "Launch (F)" ) }, + + // -------------------------------------------------------------- + // More consistent namings + { Qt::Key_Print, QT_TRANSLATE_NOOP( "QAccel", "Print Screen" ) }, + { Qt::Key_Prior, QT_TRANSLATE_NOOP( "QAccel", "Page Up" ) }, + { Qt::Key_Next, QT_TRANSLATE_NOOP( "QAccel", "Page Down" ) }, + { Qt::Key_CapsLock, QT_TRANSLATE_NOOP( "QAccel", "Caps Lock" ) }, + { Qt::Key_NumLock, QT_TRANSLATE_NOOP( "QAccel", "Num Lock" ) }, + { Qt::Key_NumLock, QT_TRANSLATE_NOOP( "QAccel", "Number Lock" ) }, + { Qt::Key_ScrollLock, QT_TRANSLATE_NOOP( "QAccel", "Scroll Lock" ) }, + { Qt::Key_Insert, QT_TRANSLATE_NOOP( "QAccel", "Insert" ) }, + { Qt::Key_Delete, QT_TRANSLATE_NOOP( "QAccel", "Delete" ) }, + { Qt::Key_Escape, QT_TRANSLATE_NOOP( "QAccel", "Escape" ) }, + { Qt::Key_SysReq, QT_TRANSLATE_NOOP( "QAccel", "System Request" ) }, + + { 0, 0 } +}; +#endif +static QString platformNeutralKeySequence(const QKeySequence &ks) +{ +#ifndef Q_WS_MACX + return QString(ks); +#else + uint k; + QString str; + QString p; + for (k = 0; k < ks.count(); ++k) { + int keycombo = ks[k]; + int basekey = keycombo & ~(Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); + if (keycombo & Qt::CTRL) + str += "Ctrl+"; + if (keycombo & Qt::ALT) + str += "Alt+"; + if (keycombo & Qt::META) + str += "Meta+"; + if (keycombo & Qt::SHIFT) + str += "Shift+"; + + // begin copy and paste from QKeySequence :( + if (basekey & Qt::UNICODE_ACCEL) { + // Note: This character should NOT be upper()'ed, since + // the encoded string should indicate EXACTLY what the + // key represents! Hence a 'Ctrl+Shift+c' is posible to + // represent, but is clearly impossible to trigger... + p = QChar(basekey & 0xffff); + } else if ( basekey >= Qt::Key_F1 && basekey <= Qt::Key_F35 ) { + p = QAccel::tr( "F%1" ).arg(basekey - Qt::Key_F1 + 1); + } else if ( basekey > Qt::Key_Space && basekey <= Qt::Key_AsciiTilde ) { + p.sprintf( "%c", basekey ); + } else { + int i = 0; + while (keyname[i].name) { + if (basekey == keyname[i].key) { + p = QAccel::tr(keyname[i].name); + break; + } + ++i; + } + // If we can't find the actual translatable keyname, + // fall back on the unicode representation of it... + // Or else characters like Key_aring may not get displayed + // ( Really depends on you locale ) + if ( !keyname[i].name ) + // Note: This character should NOT be upper()'ed, see above! + p = QChar(basekey & 0xffff); + } + // end copy... + str += p + ", "; + } + str.truncate(str.length() - 2); + return str; +#endif +} + +static QString mkBool( bool b ) +{ + return b? "true" : "false"; +} + +/*! + \class Resource resource.h + \brief Class for saving/loading, etc. forms + + This class is used for saving and loading forms, code generation, + transferring data of widgets over the clipboard, etc.. + +*/ + + +Resource::Resource() +{ + mainwindow = 0; + formwindow = 0; + toplevel = 0; + copying = FALSE; + pasting = FALSE; + hadGeometry = FALSE; + langIface = 0; + hasFunctions = FALSE; +} + +Resource::Resource( MainWindow* mw ) + : mainwindow( mw ) +{ + formwindow = 0; + toplevel = 0; + copying = FALSE; + pasting = FALSE; + hadGeometry = FALSE; + langIface = 0; + hasFunctions = FALSE; +} + +Resource::~Resource() +{ + if ( langIface ) + langIface->release(); +} + +void Resource::setWidget( FormWindow *w ) +{ + formwindow = w; + toplevel = w; +} + +QWidget *Resource::widget() const +{ + return toplevel; +} + +bool Resource::load( FormFile *ff, Project *defProject ) +{ + if ( !ff || ff->absFileName().isEmpty() ) + return FALSE; + currFileName = ff->absFileName(); + mainContainerSet = FALSE; + + QFile f( ff->absFileName() ); + f.open( IO_ReadOnly | IO_Translate ); + + bool b = load( ff, &f, defProject ); + f.close(); + + return b; +} + +#undef signals +#undef slots + +bool Resource::load( FormFile *ff, QIODevice* dev, Project *defProject ) +{ + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( dev, &errMsg, &errLine ) ) { + return FALSE; + } + + DomTool::fixDocument( doc ); + + QWidget *p = mainwindow ? mainwindow->qWorkspace() : 0; + toplevel = formwindow = new FormWindow( ff, p, 0 ); + if ( defProject ) + formwindow->setProject( defProject ); + else if ( MainWindow::self ) + formwindow->setProject( MainWindow::self->currProject() ); + if ( mainwindow ) + formwindow->setMainWindow( mainwindow ); + MetaDataBase::addEntry( formwindow ); + + if ( !langIface ) { + QString lang = "Qt Script"; + if ( mainwindow ) + lang = mainwindow->currProject()->language(); + langIface = MetaDataBase::languageInterface( lang ); + if ( langIface ) + langIface->addRef(); + } + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + QDomElement e = doc.firstChild().toElement().firstChild().toElement(); + + QDomElement forwards = e; + while ( forwards.tagName() != "forwards" && !forwards.isNull() ) + forwards = forwards.nextSibling().toElement(); + + QDomElement includes = e; + while ( includes.tagName() != "includes" && !includes.isNull() ) + includes = includes.nextSibling().toElement(); + + QDomElement variables = e; + while ( variables.tagName() != "variables" && !variables.isNull() ) + variables = variables.nextSibling().toElement(); + + QDomElement signals = e; + while ( signals.tagName() != "signals" && !signals.isNull() ) + signals = signals.nextSibling().toElement(); + + QDomElement slots = e; + while ( slots.tagName() != "slots" && !slots.isNull() ) + slots = slots.nextSibling().toElement(); + + QDomElement functions = e; + while ( functions.tagName() != "functions" && !functions.isNull() ) + functions = functions.nextSibling().toElement(); + + QDomElement connections = e; + while ( connections.tagName() != "connections" && !connections.isNull() ) + connections = connections.nextSibling().toElement(); + + QDomElement imageCollection = e; + images.clear(); + while ( imageCollection.tagName() != "images" && !imageCollection.isNull() ) + imageCollection = imageCollection.nextSibling().toElement(); + + QDomElement customWidgets = e; + while ( customWidgets.tagName() != "customwidgets" && !customWidgets.isNull() ) + customWidgets = customWidgets.nextSibling().toElement(); + + QDomElement tabOrder = e; + while ( tabOrder.tagName() != "tabstops" && !tabOrder.isNull() ) + tabOrder = tabOrder.nextSibling().toElement(); + + QDomElement actions = e; + while ( actions.tagName() != "actions" && !actions.isNull() ) + actions = actions.nextSibling().toElement(); + + QDomElement toolbars = e; + while ( toolbars.tagName() != "toolbars" && !toolbars.isNull() ) + toolbars = toolbars.nextSibling().toElement(); + + QDomElement menubar = e; + while ( menubar.tagName() != "menubar" && !menubar.isNull() ) + menubar = menubar.nextSibling().toElement(); + + QDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "widget" ) { + widgets.clear(); + widget = e; + } else if ( e.tagName() == "include" ) { // compatibility with 2.x + MetaDataBase::Include inc; + inc.location = "global"; + if ( e.attribute( "location" ) == "local" ) + inc.location = "local"; + inc.implDecl = "in declaration"; + if ( e.attribute( "impldecl" ) == "in implementation" ) + inc.implDecl = "in implementation"; + inc.header = e.firstChild().toText().data(); + if ( inc.header.right( 5 ) != ".ui.h" ) { + metaIncludes.append( inc ); + } else { + if ( formwindow->formFile() ) + formwindow->formFile()->setCodeFileState( FormFile::Ok ); + } + } else if ( e.tagName() == "comment" ) { + metaInfo.comment = e.firstChild().toText().data(); + } else if ( e.tagName() == "forward" ) { // compatibility with old betas + metaForwards << e.firstChild().toText().data(); + } else if ( e.tagName() == "variable" ) { // compatibility with old betas + MetaDataBase::Variable v; + v.varName = e.firstChild().toText().data(); + v.varAccess = "protected"; + metaVariables << v; + } else if ( e.tagName() == "author" ) { + metaInfo.author = e.firstChild().toText().data(); + } else if ( e.tagName() == "class" ) { + metaInfo.className = e.firstChild().toText().data(); + } else if ( e.tagName() == "pixmapfunction" ) { + if ( formwindow ) { + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( FALSE ); + formwindow->setPixmapLoaderFunction( e.firstChild().toText().data() ); + } + } else if ( e.tagName() == "pixmapinproject" ) { + if ( formwindow ) { + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( TRUE ); + } + } else if ( e.tagName() == "exportmacro" ) { + exportMacro = e.firstChild().toText().data(); + } else if ( e.tagName() == "layoutdefaults" ) { + formwindow->setLayoutDefaultSpacing( e.attribute( "spacing", QString::number( formwindow->layoutDefaultSpacing() ) ).toInt() ); + formwindow->setLayoutDefaultMargin( e.attribute( "margin", QString::number( formwindow->layoutDefaultMargin() ) ).toInt() ); + } else if ( e.tagName() == "layoutfunctions" ) { + formwindow->setSpacingFunction( e.attribute( "spacing" ) ); + formwindow->setMarginFunction( e.attribute( "margin" ) ); + if ( !formwindow->marginFunction().isEmpty() || !formwindow->spacingFunction().isEmpty() ) + formwindow->hasLayoutFunctions( TRUE ); + } + + e = e.nextSibling().toElement(); + } + + if ( !imageCollection.isNull() ) + loadImageCollection( imageCollection ); + if ( !customWidgets.isNull() ) + loadCustomWidgets( customWidgets, this ); + +#if defined (QT_NON_COMMERCIAL) + bool previewMode = MainWindow::self ? MainWindow::self->isPreviewing() : FALSE; + QWidget *w = (QWidget*)createObject( widget, !previewMode ? (QWidget*)formwindow : MainWindow::self ); + if ( !w ) + return FALSE; + if ( previewMode ) + w->reparent( MainWindow::self, Qt::WType_TopLevel, w->pos(), TRUE ); +#else + if ( !createObject( widget, formwindow) ) + return FALSE; +#endif + + if ( !forwards.isNull() ) { + for ( QDomElement n = forwards.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "forward" ) + metaForwards << n.firstChild().toText().data(); + } + + if ( !includes.isNull() ) { + for ( QDomElement n = includes.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "include" ) { + if ( n.tagName() == "include" ) { + MetaDataBase::Include inc; + inc.location = "global"; + if ( n.attribute( "location" ) == "local" ) + inc.location = "local"; + inc.implDecl = "in declaration"; + if ( n.attribute( "impldecl" ) == "in implementation" ) + inc.implDecl = "in implementation"; + inc.header = n.firstChild().toText().data(); + if ( inc.header.right( 5 ) != ".ui.h" ) { + metaIncludes.append( inc ); + } else { + if ( formwindow->formFile() ) + formwindow->formFile()->setCodeFileState( FormFile::Ok ); + } + } + } + } + + if ( !variables.isNull() ) { + for ( QDomElement n = variables.firstChild().toElement(); !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "variable" ) { + MetaDataBase::Variable v; + v.varName = n.firstChild().toText().data(); + v.varAccess = n.attribute( "access", "protected" ); + if ( v.varAccess.isEmpty() ) + v.varAccess = "protected"; + metaVariables << v; + } + } + } + if ( !signals.isNull() ) { + for ( QDomElement n = signals.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "signal" ) + metaSignals << n.firstChild().toText().data(); + } + if ( !slots.isNull() ) { + for ( QDomElement n = slots.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "slot" ) { + MetaDataBase::Function function; + function.specifier = n.attribute( "specifier", "virtual" ); + if ( function.specifier.isEmpty() ) + function.specifier = "virtual"; + function.access = n.attribute( "access", "public" ); + if ( function.access.isEmpty() ) + function.access = "public"; + function.language = n.attribute( "language", "C++" ); + function.returnType = n.attribute( "returnType", "void" ); + if ( function.returnType.isEmpty() ) + function.returnType = "void"; + function.type = "slot"; + function.function = n.firstChild().toText().data(); + if ( !MetaDataBase::hasFunction( formwindow, function.function, TRUE ) ) + MetaDataBase::addFunction( formwindow, function.function, function.specifier, + function.access, "slot", function.language, function.returnType ); + else + MetaDataBase::changeFunctionAttributes( formwindow, function.function, function.function, + function.specifier, function.access, + "slot", function.language, + function.returnType ); + } + } + + if ( !functions.isNull() ) { + for ( QDomElement n = functions.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "function" ) { + MetaDataBase::Function function; + function.specifier = n.attribute( "specifier", "virtual" ); + if ( function.specifier.isEmpty() ) + function.specifier = "virtual"; + function.access = n.attribute( "access", "public" ); + if ( function.access.isEmpty() ) + function.access = "public"; + function.type = n.attribute( "type", "function" ); + function.type = "function"; + function.language = n.attribute( "language", "C++" ); + function.returnType = n.attribute( "returnType", "void" ); + if ( function.returnType.isEmpty() ) + function.returnType = "void"; + function.function = n.firstChild().toText().data(); + if ( !MetaDataBase::hasFunction( formwindow, function.function, TRUE ) ) + MetaDataBase::addFunction( formwindow, function.function, function.specifier, + function.access, function.type, function.language, + function.returnType ); + else + MetaDataBase::changeFunctionAttributes( formwindow, function.function, function.function, + function.specifier, function.access, + function.type, function.language, function.returnType ); + } + } + } + + if ( !actions.isNull() ) + loadActions( actions ); + if ( !toolbars.isNull() ) + loadToolBars( toolbars ); + if ( !menubar.isNull() ) + loadMenuBar( menubar ); + + if ( !connections.isNull() ) + loadConnections( connections ); + + if ( !tabOrder.isNull() ) + loadTabOrder( tabOrder ); + + if ( formwindow ) { + MetaDataBase::setIncludes( formwindow, metaIncludes ); + MetaDataBase::setForwards( formwindow, metaForwards ); + MetaDataBase::setVariables( formwindow, metaVariables ); + MetaDataBase::setSignalList( formwindow, metaSignals ); + metaInfo.classNameChanged = metaInfo.className != QString( formwindow->name() ); + MetaDataBase::setMetaInfo( formwindow, metaInfo ); + MetaDataBase::setExportMacro( formwindow->mainContainer(), exportMacro ); + } + + loadExtraSource( formwindow->formFile(), currFileName, langIface, hasFunctions ); + + if ( mainwindow && formwindow ) + mainwindow->insertFormWindow( formwindow ); + + if ( formwindow ) { + formwindow->killAccels( formwindow ); + if ( formwindow->layout() ) + formwindow->layout()->activate(); + if ( hadGeometry ) + formwindow->resize( formwindow->size().expandedTo( formwindow->minimumSize(). + expandedTo( formwindow->minimumSizeHint() ) ) ); + else + formwindow->resize( formwindow->size().expandedTo( formwindow->sizeHint() ) ); + } + + return TRUE; +} + +static bool saveCode( const QString &filename, const QString &code ) +{ + QFile f( filename ); + if ( f.open(IO_WriteOnly | IO_Translate) ) { + QTextStream ts( &f ); + ts << code; + return TRUE; + } + return FALSE; +} + +bool Resource::save( const QString& filename, bool formCodeOnly ) +{ + if ( !formwindow || filename.isEmpty() ) + return FALSE; + if (!langIface) { + QString lang = "Qt Script"; + if ( mainwindow ) + lang = mainwindow->currProject()->language(); + langIface = MetaDataBase::languageInterface( lang ); + if ( langIface ) + langIface->addRef(); + } + if ( formCodeOnly && langIface ) { + if ( saveFormCode(formwindow->formFile(), langIface) ) + return TRUE; + bool breakout = FALSE; + FormFile *ff = formwindow->formFile(); + QString codeFile = ff->project()->makeAbsolute( ff->codeFile() ); + QString filter = langIface->fileFilterList().join("\n"); + while ( !breakout ) { + QString fn = KFileDialog::getSaveFileName( codeFile, filter ); + breakout = fn.isEmpty(); + if ( !breakout ) { + if ( saveCode(fn, ff->code()) ) + return TRUE; + } + } + } + currFileName = filename; + + QFile f( filename ); + if ( !f.open( IO_WriteOnly | IO_Translate ) ) + return FALSE; + bool b = save( &f ); + f.close(); + return b; +} + +bool Resource::save( QIODevice* dev ) +{ + if ( !formwindow ) + return FALSE; + + if ( !langIface ) { + QString lang = "C++"; + if ( mainwindow ) + lang = mainwindow->currProject()->language(); + langIface = MetaDataBase::languageInterface( lang ); + if ( langIface ) + langIface->addRef(); + } + + QTextStream ts( dev ); + ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); + + ts << "<!DOCTYPE UI><UI version=\"3.3\" stdsetdef=\"1\">" << endl; + saveMetaInfoBefore( ts, 0 ); + saveObject( formwindow->mainContainer(), 0, ts, 0 ); + if ( ::qt_cast<QMainWindow*>(formwindow->mainContainer()) ) { + saveMenuBar( (QMainWindow*)formwindow->mainContainer(), ts, 0 ); + saveToolBars( (QMainWindow*)formwindow->mainContainer(), ts, 0 ); + } + if ( !MetaDataBase::customWidgets()->isEmpty() && !usedCustomWidgets.isEmpty() ) + saveCustomWidgets( ts, 0 ); + if ( ::qt_cast<QMainWindow*>(formwindow->mainContainer()) ) + saveActions( formwindow->actionList(), ts, 0 ); + if ( !images.isEmpty() ) + saveImageCollection( ts, 0 ); + if ( !MetaDataBase::connections( formwindow ).isEmpty() || + !MetaDataBase::slotList( formwindow ).isEmpty() ) + saveConnections( ts, 0 ); + saveTabOrder( ts, 0 ); + saveMetaInfoAfter( ts, 0 ); + saveIncludeHints( ts, 0 ); + ts << "</UI>" << endl; + bool ok = saveFormCode( formwindow->formFile(), langIface ); + images.clear(); + + return ok; +} + +QString Resource::copy() +{ + if ( !formwindow ) + return QString::null; + + copying = TRUE; + QString s; + QTextOStream ts( &s ); + + ts << "<!DOCTYPE UI-SELECTION><UI-SELECTION>" << endl; + QWidgetList widgets = formwindow->selectedWidgets(); + QWidgetList tmp( widgets ); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + QWidget *p = w->parentWidget(); + bool save = TRUE; + while ( p ) { + if ( tmp.findRef( p ) != -1 ) { + save = FALSE; + break; + } + p = p->parentWidget(); + } + if ( save ) + saveObject( w, 0, ts, 0 ); + } + if ( !MetaDataBase::customWidgets()->isEmpty() && !usedCustomWidgets.isEmpty() ) + saveCustomWidgets( ts, 0 ); + if ( !images.isEmpty() ) + saveImageCollection( ts, 0 ); + ts << "</UI-SELECTION>" << endl; + + return s; +} + + +void Resource::paste( const QString &cb, QWidget *parent ) +{ + if ( !formwindow ) + return; + mainContainerSet = TRUE; + + pasting = TRUE; + QDomDocument doc; + QString errMsg; + int errLine; + doc.setContent( cb, &errMsg, &errLine ); + + QDomElement firstWidget = doc.firstChild().toElement().firstChild().toElement(); + + QDomElement imageCollection = firstWidget; + images.clear(); + while ( imageCollection.tagName() != "images" && !imageCollection.isNull() ) + imageCollection = imageCollection.nextSibling().toElement(); + + QDomElement customWidgets = firstWidget; + while ( customWidgets.tagName() != "customwidgets" && !customWidgets.isNull() ) + customWidgets = customWidgets.nextSibling().toElement(); + + if ( !imageCollection.isNull() ) + loadImageCollection( imageCollection ); + if ( !customWidgets.isNull() ) + loadCustomWidgets( customWidgets, this ); + + QWidgetList widgets; + formwindow->clearSelection( FALSE ); + formwindow->setPropertyShowingBlocked( TRUE ); + formwindow->clearSelection( FALSE ); + while ( !firstWidget.isNull() ) { + if ( firstWidget.tagName() == "widget" ) { + QWidget *w = (QWidget*)createObject( firstWidget, parent, 0 ); + if ( !w ) + continue; + widgets.append( w ); + int x = w->x() + formwindow->grid().x(); + int y = w->y() + formwindow->grid().y(); + if ( w->x() + w->width() > parent->width() ) + x = QMAX( 0, parent->width() - w->width() ); + if ( w->y() + w->height() > parent->height() ) + y = QMAX( 0, parent->height() - w->height() ); + if ( x != w->x() || y != w->y() ) + w->move( x, y ); + formwindow->selectWidget( w ); + } else if ( firstWidget.tagName() == "spacer" ) { + QWidget *w = createSpacer( firstWidget, parent, 0, firstWidget.tagName() == "vspacer" ? Qt::Vertical : Qt::Horizontal ); + if ( !w ) + continue; + widgets.append( w ); + int x = w->x() + formwindow->grid().x(); + int y = w->y() + formwindow->grid().y(); + if ( w->x() + w->width() > parent->width() ) + x = QMAX( 0, parent->width() - w->width() ); + if ( w->y() + w->height() > parent->height() ) + y = QMAX( 0, parent->height() - w->height() ); + if ( x != w->x() || y != w->y() ) + w->move( x, y ); + formwindow->selectWidget( w ); + } + firstWidget = firstWidget.nextSibling().toElement(); + } + formwindow->setPropertyShowingBlocked( FALSE ); + formwindow->emitShowProperties(); + + PasteCommand *cmd = new PasteCommand( i18n( "Paste" ), formwindow, widgets ); + formwindow->commandHistory()->addCommand( cmd ); +} + +void Resource::saveObject( QObject *obj, QDesignerGridLayout* grid, QTextStream &ts, int indent ) +{ + if ( obj && obj->isWidgetType() && ( (QWidget*)obj )->isHidden() ) + return; + QString closeTag; + const char* className = WidgetFactory::classNameOf( obj ); + int classID = WidgetDatabase::idFromClassName( className ); + bool isPlugin = WidgetDatabase::isCustomPluginWidget( classID ); + if ( obj->isWidgetType() ) { + if ( obj->isA("CustomWidget") || isPlugin ) { + usedCustomWidgets << QString( className ); + includeHints << WidgetDatabase::includeFile( classID ); + } + + if ( obj != formwindow && !formwindow->widgets()->find( (QWidget*)obj ) ) + return; // we don't know anything about this thing + + QString attributes; + if ( grid ) { + QDesignerGridLayout::Item item = grid->items[ (QWidget*)obj ]; + attributes += QString(" row=\"") + QString::number(item.row) + "\""; + attributes += QString(" column=\"") + QString::number(item.column) + "\""; + if ( item.rowspan * item.colspan != 1 ) { + attributes += QString(" rowspan=\"") + QString::number(item.rowspan) + "\""; + attributes += QString(" colspan=\"") + QString::number(item.colspan) + "\""; + } + } + + if ( qstrcmp( className, "Spacer" ) == 0 ) { + closeTag = makeIndent( indent ) + "</spacer>\n"; + ts << makeIndent( indent ) << "<spacer" << attributes << ">" << endl; + ++indent; + } else { + closeTag = makeIndent( indent ) + "</widget>\n"; + ts << makeIndent( indent ) << "<widget class=\"" << className << "\"" << attributes << ">" << endl; + ++indent; + } + if ( WidgetFactory::hasItems(classID, obj) ) + saveItems( obj, ts, indent ); + saveObjectProperties( obj, ts, indent ); + } else { + // test for other objects we created. Nothing so far. + return; + } + + QDesignerWidgetStack* ws = 0; + + if ( ::qt_cast<QTabWidget*>(obj) ) { + QTabWidget* tw = (QTabWidget*) obj; + QObjectList* tmpl = tw->queryList( "QWidgetStack" ); + QWidgetStack *ws = (QWidgetStack*)tmpl->first(); + QTabBar *tb = ( (QDesignerTabWidget*)obj )->tabBar(); + for ( int i = 0; i < tb->count(); ++i ) { + QTab *t = tb->tabAt( i ); + if ( !t ) + continue; + QWidget *w = ws->widget( t->identifier() ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "<widget class=\"QWidget\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<property name=\"name\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" << entitize( w->name() ) << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + + ts << makeIndent( indent ) << "<attribute name=\"title\">" << endl; + indent++; + ts << makeIndent( indent ) << "<string>" << entitize( t->text() ) << "</string>" << endl; + indent--; + ts << makeIndent( indent ) << "</attribute>" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "</widget>" << endl; + } + delete tmpl; + } else if ( (ws = ::qt_cast<QDesignerWidgetStack*>(obj)) != 0 ) { + for ( int i = 0; i < ws->count(); ++i ) { + QWidget *w = ws->page( i ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(w)) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "<widget class=\"QWidget\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<property name=\"name\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" << entitize( w->name() ) << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + ts << makeIndent( indent ) << "<attribute name=\"id\">" << endl; + indent++; + ts << makeIndent( indent ) << "<number>" << QString::number(i) << "</number>" << endl; + indent--; + ts << makeIndent( indent ) << "</attribute>" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "</widget>" << endl; + } + } else if ( ::qt_cast<QToolBox*>(obj) ) { + QToolBox* tb = (QToolBox*)obj; + for ( int i = 0; i < tb->count(); ++i ) { + QWidget *w = tb->item( i ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(w)) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "<widget class=\"QWidget\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<property name=\"name\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" << entitize( w->name() ) << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + ts << makeIndent( indent ) << "<property name=\"backgroundMode\">" << endl; + indent++; + saveEnumProperty( w, "backgroundMode", QVariant::Invalid, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + ts << makeIndent( indent ) << "<attribute name=\"label\">" << endl; + indent++; + ts << makeIndent( indent ) << "<string>" << entitize( tb->itemLabel( tb->indexOf(w) ) ) << "</string>" << endl; + indent--; + ts << makeIndent( indent ) << "</attribute>" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "</widget>" << endl; + } + } else if ( ::qt_cast<QWizard*>(obj) ) { + QWizard* wiz = (QWizard*)obj; + for ( int i = 0; i < wiz->pageCount(); ++i ) { + QWidget *w = wiz->page( i ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(w)) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "<widget class=\"QWidget\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<property name=\"name\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" << entitize( w->name() ) << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + + ts << makeIndent( indent ) << "<attribute name=\"title\">" << endl; + indent++; + ts << makeIndent( indent ) << "<string>" << entitize( wiz->title( w ) ) << "</string>" << endl; + indent--; + ts << makeIndent( indent ) << "</attribute>" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "</widget>" << endl; + } + } else if ( ::qt_cast<QMainWindow*>(obj) ) { + saveChildrenOf( ( (QMainWindow*)obj )->centralWidget(), ts, indent ); + } else { + bool saved = FALSE; +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( isPlugin ) { + WidgetInterface *iface = 0; + widgetManager()->queryInterface( className, &iface ); + if ( iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + if ( iface2->supportsPages( className ) ) { + QWidgetList containers = iface2->pages( className, (QWidget*)obj ); + if ( !containers.isEmpty() ) { + saved = TRUE; + int i = 0; + for ( QWidget *w = containers.first(); w; w = containers.next(), ++i ) { + if ( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "<widget class=\"" + << WidgetFactory::classNameOf( w ) + << "\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<property name=\"name\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" << entitize( w->name() ) + << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + ts << makeIndent( indent ) << "<attribute name=\"label\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" + << entitize( iface2->pageLabel( className, (QWidget*)obj, i ) ) + << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</attribute>" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "</widget>" << endl; + } + } + } else { + saved = TRUE; + QWidget *w = iface2->containerOfWidget( className, (QWidget*)obj ); + if ( obj != w ) { + ts << makeIndent( indent ) << "<widget class=\"" + << WidgetFactory::classNameOf( w ) + << "\">" << endl; + ++indent; + ts << makeIndent( indent ) << "<property name=\"name\">" << endl; + indent++; + ts << makeIndent( indent ) << "<cstring>" << entitize( w->name() ) + << "</cstring>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "</widget>" << endl; + } + // Create a custom widget and then store it in the database + // so we can save the custom widgets. + MetaDataBase::CustomWidget *cw = new MetaDataBase::CustomWidget; + cw->className = className; + cw->includeFile = WidgetDatabase::includeFile( classID ); + QStrList lst = w->metaObject()->signalNames( TRUE ); + for ( QPtrListIterator<char> it(lst); it.current(); ++it ) + cw->lstSignals.append(it.current()); + + int i; + int total = w->metaObject()->numProperties( TRUE ); + for ( i = 0; i < total; i++ ) { + const QMetaProperty *p = w->metaObject()->property( i, TRUE ); + if ( p->designable(w) ) { + MetaDataBase::Property prop; + prop.property = p->name(); + QString pType = p->type(); + // *sigh* designer types are not normal types + // Handle most cases, the ones it misses are + // probably too difficult to deal with anyway... + if ( pType.startsWith("Q") ) { + pType = pType.right( pType.length() - 1 ); + } else { + pType[0] = pType[0].upper(); + } + prop.type = pType; + cw->lstProperties.append( prop ); + } + } + + total = w->metaObject()->numSlots( TRUE ); + for ( i = 0; i < total; i++ ) { + const QMetaData *md = w->metaObject()->slot( i, TRUE ); + MetaDataBase::Function funky; + // Find out if we have a return type. + if ( md->method->count > 0 ) { + const QUParameter p = md->method->parameters[0]; + if ( p.inOut == QUParameter::InOut ) + funky.returnType = p.type->desc(); + } + + funky.function = md->name; + funky.language = "C++"; + switch ( md->access ) { + case QMetaData::Public: + funky.access = "public"; + break; + case QMetaData::Protected: + funky.access = "protected"; + break; + case QMetaData::Private: + funky.access = "private"; + break; + } + cw->lstSlots.append( funky ); + } + MetaDataBase::addCustomWidget( cw ); + } + iface2->release(); + } + iface->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + if ( !saved ) + saveChildrenOf( obj, ts, indent ); + } + + indent--; + ts << closeTag; +} + +void Resource::saveItems( QObject *obj, QTextStream &ts, int indent ) +{ + if ( ::qt_cast<QListBox*>(obj) || ::qt_cast<QComboBox*>(obj) ) { + QListBox *lb = 0; + if ( ::qt_cast<QListBox*>(obj) ) + lb = (QListBox*)obj; + else + lb = ( (QComboBox*)obj )->listBox(); + + QListBoxItem *i = lb->firstItem(); + for ( ; i; i = i->next() ) { + ts << makeIndent( indent ) << "<item>" << endl; + indent++; + QStringList text; + text << i->text(); + QPtrList<QPixmap> pixmaps; + if ( i->pixmap() ) + pixmaps.append( i->pixmap() ); + saveItem( text, pixmaps, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</item>" << endl; + } + } else if ( ::qt_cast<QIconView*>(obj) ) { + QIconView *iv = (QIconView*)obj; + + QIconViewItem *i = iv->firstItem(); + for ( ; i; i = i->nextItem() ) { + ts << makeIndent( indent ) << "<item>" << endl; + indent++; + QStringList text; + text << i->text(); + QPtrList<QPixmap> pixmaps; + if ( i->pixmap() ) + pixmaps.append( i->pixmap() ); + saveItem( text, pixmaps, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</item>" << endl; + } + } else if ( ::qt_cast<QListView*>(obj) ) { + QListView *lv = (QListView*)obj; + int i; + for ( i = 0; i < lv->header()->count(); ++i ) { + ts << makeIndent( indent ) << "<column>" << endl; + indent++; + QStringList l; + l << lv->header()->label( i ); + QPtrList<QPixmap> pix; + pix.setAutoDelete( TRUE ); + if ( lv->header()->iconSet( i ) ) + pix.append( new QPixmap( lv->header()->iconSet( i )->pixmap() ) ); + saveItem( l, pix, ts, indent ); + ts << makeIndent( indent ) << "<property name=\"clickable\">" << endl; + indent++; + ts << makeIndent( indent ) << "<bool>" << mkBool( lv->header()->isClickEnabled( i ) )<< "</bool>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + ts << makeIndent( indent ) << "<property name=\"resizable\">" << endl; + indent++; + ts << makeIndent( indent ) << "<bool>" << mkBool( lv->header()->isResizeEnabled( i ) ) << "</bool>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + indent--; + ts << makeIndent( indent ) << "</column>" << endl; + } + saveItem( lv->firstChild(), ts, indent - 1 ); + } +#if !defined (QT_NO_TABLE) + else if ( ::qt_cast<QTable*>(obj) ) { + QTable *table = (QTable*)obj; + int i; + QMap<QString, QString> columnFields = MetaDataBase::columnFields( table ); +# ifndef QT_NO_SQL + bool isDataTable = ::qt_cast<QDataTable*>(table); +# else + bool isDataTable = false; +# endif + for ( i = 0; i < table->horizontalHeader()->count(); ++i ) { + if ( !table->horizontalHeader()->label( i ).isNull() && + table->horizontalHeader()->label( i ).toInt() != i + 1 || + table->horizontalHeader()->iconSet( i ) || + isDataTable ) { + ts << makeIndent( indent ) << "<column>" << endl; + indent++; + QStringList l; + l << table->horizontalHeader()->label( i ); + QPtrList<QPixmap> pix; + pix.setAutoDelete( TRUE ); + if ( table->horizontalHeader()->iconSet( i ) ) + pix.append( new QPixmap( table->horizontalHeader()->iconSet( i )->pixmap() ) ); + saveItem( l, pix, ts, indent ); + if ( isDataTable && !columnFields.isEmpty() ) { + ts << makeIndent( indent ) << "<property name=\"field\">" << endl; + indent++; + ts << makeIndent( indent ) << "<string>" << entitize( *columnFields.find( l[ 0 ] ) ) << "</string>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + } + indent--; + ts << makeIndent( indent ) << "</column>" << endl; + } + } + for ( i = 0; i < table->verticalHeader()->count(); ++i ) { + if ( !table->verticalHeader()->label( i ).isNull() && + table->verticalHeader()->label( i ).toInt() != i + 1 || + table->verticalHeader()->iconSet( i ) ) { + ts << makeIndent( indent ) << "<row>" << endl; + indent++; + QStringList l; + l << table->verticalHeader()->label( i ); + QPtrList<QPixmap> pix; + pix.setAutoDelete( TRUE ); + if ( table->verticalHeader()->iconSet( i ) ) + pix.append( new QPixmap( table->verticalHeader()->iconSet( i )->pixmap() ) ); + saveItem( l, pix, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</row>" << endl; + } + } + } +#endif +} + +void Resource::saveItem( QListViewItem *i, QTextStream &ts, int indent ) +{ + QListView *lv = i->listView(); + while ( i ) { + ts << makeIndent( indent ) << "<item>" << endl; + indent++; + + QPtrList<QPixmap> pixmaps; + QStringList textes; + for ( int c = 0; c < lv->columns(); ++c ) { + pixmaps.append( i->pixmap( c ) ); + textes << i->text( c ); + } + saveItem( textes, pixmaps, ts, indent ); + + if ( i->firstChild() ) + saveItem( i->firstChild(), ts, indent ); + + indent--; + ts << makeIndent( indent ) << "</item>" << endl; + i = i->nextSibling(); + } +} + +void Resource::savePixmap( const QPixmap &p, QTextStream &ts, int indent, const QString &tagname ) +{ + if ( p.isNull() ) { + ts << makeIndent( indent ) << "<" << tagname << "></" << tagname << ">" << endl; + return; + } + + if ( formwindow && formwindow->savePixmapInline() ) + ts << makeIndent( indent ) << "<" << tagname << ">" << saveInCollection( p ) << "</" << tagname << ">" << endl; + else if ( formwindow && formwindow->savePixmapInProject() ) + ts << makeIndent( indent ) << "<" << tagname << ">" << MetaDataBase::pixmapKey( formwindow, p.serialNumber() ) + << "</" << tagname << ">" << endl; + else + ts << makeIndent( indent ) << "<" << tagname << ">" << MetaDataBase::pixmapArgument( formwindow, p.serialNumber() ) + << "</" << tagname << ">" << endl; +} + +QPixmap Resource::loadPixmap( const QDomElement &e, const QString &/*tagname*/ ) +{ + QString arg = e.firstChild().toText().data(); + + if ( formwindow && formwindow->savePixmapInline() ) { + QImage img = loadFromCollection( arg ); + QPixmap pix; + pix.convertFromImage( img ); + MetaDataBase::setPixmapArgument( formwindow, pix.serialNumber(), arg ); + return pix; + } else if ( formwindow && formwindow->savePixmapInProject() ) { + QPixmap pix; + if ( mainwindow && mainwindow->currProject() ) { + pix = mainwindow->currProject()->pixmapCollection()->pixmap( arg ); + } else { + pix = BarIcon( "designer_image.png", KDevDesignerPartFactory::instance() ); + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( pix.convertToImage() ); + } + + MetaDataBase::setPixmapKey( formwindow, pix.serialNumber(), arg ); + return pix; + } + QPixmap pix = BarIcon( "designer_image.png", KDevDesignerPartFactory::instance() ); + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( pix.convertToImage() ); + MetaDataBase::setPixmapArgument( formwindow, pix.serialNumber(), arg ); + return pix; +} + +void Resource::saveItem( const QStringList &text, + const QPtrList<QPixmap> &pixmaps, QTextStream &ts, + int indent ) +{ + QStringList::ConstIterator it = text.begin(); + for ( ; it != text.end(); ++it ) { + ts << makeIndent( indent ) << "<property name=\"text\">" << endl; + indent++; + ts << makeIndent( indent ) << "<string>" << entitize( *it ) << "</string>" << endl; + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + } + + for ( int i = 0; i < (int)pixmaps.count(); ++i ) { + QPixmap *p = ( (QPtrList<QPixmap>)pixmaps ).at( i ); + ts << makeIndent( indent ) << "<property name=\"pixmap\">" << endl; + indent++; + if ( p ) + savePixmap( *p, ts, indent ); + else + savePixmap( QPixmap(), ts, indent ); + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + } +} + +void Resource::saveChildrenOf( QObject* obj, QTextStream &ts, int indent ) +{ + const QObjectList *l = obj->children(); + if ( !l ) + return; // no children to save + + QString closeTag; + // if the widget has a layout we pretend that all widget's childs are childs of the layout - makes the structure nicer + QLayout *layout = 0; + QDesignerGridLayout* grid = 0; + if ( !::qt_cast<QSplitter*>(obj) && + WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( obj ) ) ) && + obj->isWidgetType() && + WidgetFactory::layoutType( (QWidget*)obj, layout ) != WidgetFactory::NoLayout ) { + WidgetFactory::LayoutType lay = WidgetFactory::layoutType( (QWidget*)obj, layout ); + switch ( lay ) { + case WidgetFactory::HBox: + closeTag = makeIndent( indent ) + "</hbox>"; + ts << makeIndent( indent ) << "<hbox>" << endl; + ++indent; + break; + case WidgetFactory::VBox: + closeTag = makeIndent( indent ) + "</vbox>"; + ts << makeIndent( indent ) << "<vbox>" << endl; + ++indent; + break; + case WidgetFactory::Grid: + closeTag = makeIndent( indent ) + "</grid>"; + ts << makeIndent( indent ) << "<grid>" << endl; + ++indent; + grid = (QDesignerGridLayout*) layout; + break; + default: + break; + } + + // save properties of layout + if ( lay != WidgetFactory::NoLayout ) + saveObjectProperties( layout, ts, indent ); + + } + + QObject *o = 0; + for ( QPtrListIterator<QObject> it ( *l ); ( o = it.current() ); ++it ) + if ( !QString( o->name() ).startsWith( "qt_dead_widget_" ) ) + saveObject( o, grid, ts, indent ); + if ( !closeTag.isEmpty() ) { + indent--; + ts << closeTag << endl; + } +} + +void Resource::saveObjectProperties( QObject *w, QTextStream &ts, int indent ) +{ + QStringList saved; + QStringList changed; + changed = MetaDataBase::changedProperties( w ); + if ( w->isWidgetType() ) { + if ( ::qt_cast<Spacer*>(w) ) { + if ( !changed.contains( "sizeHint" ) ) + changed << "sizeHint"; + if ( !changed.contains( "geometry" ) ) + changed << "geometry"; + } else { + QToolButton *tb = ::qt_cast<QToolButton*>(w); + if ( tb && !tb->iconSet().isNull() ) { + changed << "iconSet"; + } + } + } else if ( ::qt_cast<QLayout*>(w) ) { + if ( MetaDataBase::spacing( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ) > -1 ) + changed << "spacing"; + if ( MetaDataBase::margin( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ) > -1 ) + changed << "margin"; + if ( MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ) != "Auto" + && !MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ).isEmpty() ) + changed << "resizeMode"; + } + + if ( w == formwindow->mainContainer() ) { + if ( changed.findIndex( "geometry" ) == -1 ) + changed << "geometry"; + if ( changed.findIndex( "caption" ) == -1 ) + changed << "caption"; + } + + if ( changed.isEmpty() ) + return; + + bool inLayout = w != formwindow->mainContainer() && !copying && w->isWidgetType() && ( (QWidget*)w )->parentWidget() && + WidgetFactory::layoutType( ( (QWidget*)w )->parentWidget() ) != WidgetFactory::NoLayout; + + QStrList lst = w->metaObject()->propertyNames( !::qt_cast<Spacer*>(w) ); + for ( QPtrListIterator<char> it( lst ); it.current(); ++it ) { + if ( changed.find( QString::fromLatin1( it.current() ) ) == changed.end() ) + continue; + if ( saved.find( QString::fromLatin1( it.current() ) ) != saved.end() ) + continue; + saved << QString::fromLatin1( it.current() ); + const QMetaProperty* p = w->metaObject()-> + property( w->metaObject()->findProperty( it.current(), TRUE ), TRUE ); + if ( !p || !p->stored( w ) || ( inLayout && qstrcmp( p->name(), "geometry" ) == 0 ) ) + continue; + if ( ::qt_cast<QLabel*>(w) && qstrcmp( p->name(), "pixmap" ) == 0 && + ( !( (QLabel*)w )->pixmap() || ( (QLabel*)w )->pixmap()->isNull() ) ) + continue; + if ( ::qt_cast<MenuBarEditor*>(w) && + ( qstrcmp( p->name(), "itemName" ) == 0 || qstrcmp( p->name(), "itemNumber" ) == 0 || + qstrcmp( p->name(), "itemText" ) == 0 ) ) + continue; + if ( qstrcmp( p->name(), "name" ) == 0 ) + knownNames << w->property( "name" ).toString(); + if ( !p->isSetType() && !p->isEnumType() && !w->property( p->name() ).isValid() ) + continue; + ts << makeIndent( indent ) << "<property"; + ts << " name=\"" << it.current() << "\""; + if ( !p->stdSet() ) + ts << " stdset=\"0\""; + ts << ">" << endl; + indent++; + if ( strcmp( it.current(), "resizeMode" ) == 0 && ::qt_cast<QLayout*>(w) ) { + saveProperty( w, it.current(), "", QVariant::String, ts, indent ); + } else if ( p->isSetType() ) { + saveSetProperty( w, it.current(), QVariant::nameToType( p->type() ), ts, indent ); + } else if ( p->isEnumType() ) { + saveEnumProperty( w, it.current(), QVariant::nameToType( p->type() ), ts, indent ); + } else { + saveProperty( w, it.current(), w->property( p->name() ), QVariant::nameToType( p->type() ), ts, indent ); + } + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + } + + if ( w->isWidgetType() && MetaDataBase::fakeProperties( w ) ) { + QMap<QString, QVariant>* fakeProperties = MetaDataBase::fakeProperties( w ); + for ( QMap<QString, QVariant>::Iterator fake = fakeProperties->begin(); + fake != fakeProperties->end(); ++fake ) { + if ( MetaDataBase::isPropertyChanged( w, fake.key() ) ) { + if ( w->inherits("CustomWidget") ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)w )->customWidget(); + if ( cw && !cw->hasProperty( fake.key().latin1() ) && fake.key() != "toolTip" && fake.key() != "whatsThis" ) + continue; + } + + ts << makeIndent( indent ) << "<property name=\"" << fake.key() << "\" stdset=\"0\">" << endl; + indent++; + saveProperty( w, fake.key(), *fake, (*fake).type(), ts, indent ); + indent--; + ts << makeIndent( indent ) << "</property>" << endl; + } + } + } +} + +void Resource::saveSetProperty( QObject *w, const QString &name, QVariant::Type, QTextStream &ts, int indent ) +{ + const QMetaProperty *p = w->metaObject()->property( w->metaObject()->findProperty( name, TRUE ), TRUE ); + QStrList l( p->valueToKeys( w->property( name ).toInt() ) ); + QString v; + for ( uint i = 0; i < l.count(); ++i ) { + v += l.at( i ); + if ( i < l.count() - 1 ) + v += "|"; + } + ts << makeIndent( indent ) << "<set>" << v << "</set>" << endl; +} + +void Resource::saveEnumProperty( QObject *w, const QString &name, QVariant::Type, QTextStream &ts, int indent ) +{ + const QMetaProperty *p = w->metaObject()->property( w->metaObject()->findProperty( name, TRUE ), TRUE ); + ts << makeIndent( indent ) << "<enum>" << p->valueToKey( w->property( name ).toInt() ) << "</enum>" << endl; +} + +void Resource::saveProperty( QObject *w, const QString &name, const QVariant &value, QVariant::Type t, QTextStream &ts, int indent ) +{ + if ( name == "hAlign" || name =="vAlign" || name == "wordwrap" || + name == "layoutMargin" || name =="layoutSpacing" ) + return; + int num; + uint unum; + double dob; + QString comment; + if ( w && formwindow->widgets()->find( (QWidget*)w ) || formwindow->actionList().find( (QAction*)w ) ) + comment = MetaDataBase::propertyComment( w, name ); + switch ( t ) { + case QVariant::String: + if ( name == "resizeMode" ) { + QString resmod = MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ); + if ( !resmod.isNull() && resmod != "Auto" ) { + ts << makeIndent( indent ) << "<enum>"; + ts << resmod; + ts << "</enum>" << endl; + } + + } else { + ts << makeIndent( indent ) << "<string>" << entitize( value.toString() ) << "</string>" << endl; + if ( !comment.isEmpty() ) + ts << makeIndent( indent ) << "<comment>" << entitize( comment ) << "</comment>" << endl; + } + break; + case QVariant::CString: + ts << makeIndent( indent ) << "<cstring>" << entitize( value.toCString() ).latin1() << "</cstring>" << endl; + break; + case QVariant::Bool: + ts << makeIndent( indent ) << "<bool>" << mkBool( value.toBool() ) << "</bool>" << endl; + break; + case QVariant::Int: + if ( ::qt_cast<QLayout*>(w) ) { + num = -1; + if ( name == "spacing" ) + num = MetaDataBase::spacing( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ); + else if ( name == "margin" ) + num = MetaDataBase::margin( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ); + if ( num != -1 ) + ts << makeIndent( indent ) << "<number>" << QString::number( num ) << "</number>" << endl; + } else { + num = value.toInt(); + ts << makeIndent( indent ) << "<number>" << QString::number( num ) << "</number>" << endl; + } + break; + case QVariant::Double: + dob = value.toDouble(); + ts << makeIndent( indent ) << "<number>" << QString::number( dob ) << "</number>" << endl; + break; + case QVariant::KeySequence: + ts << makeIndent( indent ) << "<string>" + << entitize(platformNeutralKeySequence(value.toKeySequence())) << "</string>" << endl; + break; + case QVariant::UInt: + unum = value.toUInt(); + ts << makeIndent( indent ) << "<number>" << QString::number( unum ) << "</number>" << endl; + break; + case QVariant::Rect: { + QVariant v( value ); + ts << makeIndent( indent ) << "<rect>" << endl; + indent++; + ts << makeIndent( indent ) << "<x>" << QString::number( v.toRect().x() ) << "</x>" << endl; + ts << makeIndent( indent ) << "<y>" << QString::number( v.toRect().y() ) << "</y>" << endl; + ts << makeIndent( indent ) << "<width>" << QString::number( v.toRect().width() ) << "</width>" << endl; + ts << makeIndent( indent ) << "<height>" << QString::number( v.toRect().height() ) << "</height>" << endl; + indent--; + ts << makeIndent( indent ) << "</rect>" << endl; + } break; + case QVariant::Point: { + QVariant v( value ); + ts << makeIndent( indent ) << "<point>" << endl; + indent++; + ts << makeIndent( indent ) << "<x>" << QString::number( v.toPoint().x() ) << "</x>" << endl; + ts << makeIndent( indent ) << "<y>" << QString::number( v.toPoint().y() ) << "</y>" << endl; + indent--; + ts << makeIndent( indent ) << "</point>" << endl; + } break; + case QVariant::Size: { + QVariant v( value ); + ts << makeIndent( indent ) << "<size>" << endl; + indent++; + ts << makeIndent( indent ) << "<width>" << QString::number( v.toSize().width() ) << "</width>" << endl; + ts << makeIndent( indent ) << "<height>" << QString::number( v.toSize().height() ) << "</height>" << endl; + indent--; + ts << makeIndent( indent ) << "</size>" << endl; + } break; + case QVariant::Color: { + QVariant v( value ); + ts << makeIndent( indent ) << "<color>" << endl; + indent++; + saveColor( ts, indent, v.toColor() ); + indent--; + ts << makeIndent( indent ) << "</color>" << endl; + } break; + case QVariant::Font: { + QVariant v( value ); + ts << makeIndent( indent ) << "<font>" << endl; + QFont f( qApp->font() ); + if ( w && w->isWidgetType() && ((QWidget*)w)->parentWidget() ) + f = ((QWidget*)w)->parentWidget()->font(); + QFont f2( v.toFont() ); + indent++; + if ( f.family() != f2.family() ) + ts << makeIndent( indent ) << "<family>" << f2.family() << "</family>" << endl; + if ( f.pointSize() != f2.pointSize() ) + ts << makeIndent( indent ) << "<pointsize>" << QString::number( f2.pointSize() ) << "</pointsize>" << endl; + if ( f.bold() != f2.bold() ) + ts << makeIndent( indent ) << "<bold>" << QString::number( (int)f2.bold() ) << "</bold>" << endl; + if ( f.italic() != f2.italic() ) + ts << makeIndent( indent ) << "<italic>" << QString::number( (int)f2.italic() ) << "</italic>" << endl; + if ( f.underline() != f2.underline() ) + ts << makeIndent( indent ) << "<underline>" << QString::number( (int)f2.underline() ) << "</underline>" << endl; + if ( f.strikeOut() != f2.strikeOut() ) + ts << makeIndent( indent ) << "<strikeout>" << QString::number( (int)f2.strikeOut() ) << "</strikeout>" << endl; + indent--; + ts << makeIndent( indent ) << "</font>" << endl; + } break; + case QVariant::SizePolicy: { + QSizePolicy sp( value.toSizePolicy() ); + ts << makeIndent( indent ) << "<sizepolicy>" << endl; + indent++; + ts << makeIndent( indent ) << "<hsizetype>" << (int)sp.horData() << "</hsizetype>" << endl; + ts << makeIndent( indent ) << "<vsizetype>" << (int)sp.verData() << "</vsizetype>" << endl; + ts << makeIndent( indent ) << "<horstretch>" << (int)sp.horStretch() << "</horstretch>" << endl; + ts << makeIndent( indent ) << "<verstretch>" << (int)sp.verStretch() << "</verstretch>" << endl; + indent--; + ts << makeIndent( indent ) << "</sizepolicy>" << endl; + break; + } + case QVariant::Pixmap: + savePixmap( value.toPixmap(), ts, indent ); + break; + case QVariant::IconSet: + savePixmap( value.toIconSet().pixmap(), ts, indent, "iconset" ); + break; + case QVariant::Image: + ts << makeIndent( indent ) << "<image>" << saveInCollection( value.toImage() ) << "</image>" << endl; + break; + case QVariant::Palette: { + QPalette p( value.toPalette() ); + ts << makeIndent( indent ) << "<palette>" << endl; + indent++; + + ts << makeIndent( indent ) << "<active>" << endl; + indent++; + saveColorGroup( ts, indent, p.active() ); + indent--; + ts << makeIndent( indent ) << "</active>" << endl; + + ts << makeIndent( indent ) << "<disabled>" << endl; + indent++; + saveColorGroup( ts, indent, p.disabled() ); + indent--; + ts << makeIndent( indent ) << "</disabled>" << endl; + + ts << makeIndent( indent ) << "<inactive>" << endl; + indent++; + saveColorGroup( ts, indent, p.inactive() ); + indent--; + ts << makeIndent( indent ) << "</inactive>" << endl; + + indent--; + ts << makeIndent( indent ) << "</palette>" << endl; + } break; + case QVariant::Cursor: + ts << makeIndent( indent ) << "<cursor>" << value.toCursor().shape() << "</cursor>" << endl; + break; + case QVariant::StringList: { + QStringList lst = value.toStringList(); + uint i = 0; + ts << makeIndent( indent ) << "<stringlist>" << endl; + indent++; + if ( !lst.isEmpty() ) { + for ( i = 0; i < lst.count(); ++i ) + ts << makeIndent( indent ) << "<string>" << entitize( lst[ i ] ) << "</string>" << endl; + } + indent--; + ts << makeIndent( indent ) << "</stringlist>" << endl; + } break; + case QVariant::Date: { + QDate d = value.toDate(); + ts << makeIndent( indent ) << "<date>" << endl; + indent++; + ts << makeIndent( indent ) << "<year>" << d.year() << "</year>" << endl; + ts << makeIndent( indent ) << "<month>" << d.month() << "</month>" << endl; + ts << makeIndent( indent ) << "<day>" << d.day() << "</day>" << endl; + indent--; + ts << makeIndent( indent ) << "</date>" << endl; + break; + } + case QVariant::Time: { + QTime t = value.toTime(); + ts << makeIndent( indent ) << "<time>" << endl; + indent++; + ts << makeIndent( indent ) << "<hour>" << t.hour() << "</hour>" << endl; + ts << makeIndent( indent ) << "<minute>" << t.minute() << "</minute>" << endl; + ts << makeIndent( indent ) << "<second>" << t.second() << "</second>" << endl; + indent--; + ts << makeIndent( indent ) << "</time>" << endl; + break; + } + case QVariant::DateTime: { + QDateTime dt = value.toDateTime(); + ts << makeIndent( indent ) << "<datetime>" << endl; + indent++; + ts << makeIndent( indent ) << "<year>" << dt.date().year() << "</year>" << endl; + ts << makeIndent( indent ) << "<month>" << dt.date().month() << "</month>" << endl; + ts << makeIndent( indent ) << "<day>" << dt.date().day() << "</day>" << endl; + ts << makeIndent( indent ) << "<hour>" << dt.time().hour() << "</hour>" << endl; + ts << makeIndent( indent ) << "<minute>" << dt.time().minute() << "</minute>" << endl; + ts << makeIndent( indent ) << "<second>" << dt.time().second() << "</second>" << endl; + indent--; + ts << makeIndent( indent ) << "</datetime>" << endl; + break; + } + default: + qWarning( "saving the property %s of type %d not supported yet", name.latin1(), (int)t ); + } +} + +void Resource::saveColorGroup( QTextStream &ts, int indent, const QColorGroup &cg ) +{ + for( int r = 0 ; r < QColorGroup::NColorRoles ; r++ ) { + ts << makeIndent( indent ) << "<color>" << endl; + indent++; + saveColor( ts, indent, cg.color( (QColorGroup::ColorRole)r ) ); + indent--; + ts << makeIndent( indent ) << "</color>" << endl; + QPixmap* pm = cg.brush( (QColorGroup::ColorRole)r ).pixmap(); + if ( pm && !pm->isNull() ) + savePixmap( *pm, ts, indent ); + } +} + +void Resource::saveColor( QTextStream &ts, int indent, const QColor &c ) +{ + ts << makeIndent( indent ) << "<red>" << QString::number( c.red() ) << "</red>" << endl; + ts << makeIndent( indent ) << "<green>" << QString::number( c.green() ) << "</green>" << endl; + ts << makeIndent( indent ) << "<blue>" << QString::number( c.blue() ) << "</blue>" << endl; +} + +QObject *Resource::createObject( const QDomElement &e, QWidget *parent, QLayout* layout ) +{ + lastItem = 0; + QDomElement n = e.firstChild().toElement(); + QWidget *w = 0; // the widget that got created + QObject *obj = 0; // gets the properties + + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + + QString className = e.attribute( "class", "QWidget" ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + QString parentClassName = WidgetFactory::classNameOf( parent ); + bool isPlugin = + WidgetDatabase::isCustomPluginWidget( WidgetDatabase::idFromClassName( parentClassName ) ); + if ( isPlugin ) + qWarning( "####### loading custom container widgets without page support not implemented!" ); + // ### TODO loading for custom container widgets without pages +#endif + if ( !className.isNull() ) { + obj = WidgetFactory::create( WidgetDatabase::idFromClassName( className ), parent, 0, FALSE ); + if ( !obj ) { + QMessageBox::critical( MainWindow::self, i18n( "Loading File" ), + i18n( "Error loading %1.\n" + "The widget %2 could not be created." ). + arg( currFileName ).arg( className ) ); + return 0; + } + if ( !mainContainerSet ) { + if ( formwindow ) + formwindow->setMainContainer( (QWidget*)obj ); + mainContainerSet = TRUE; + } + w = (QWidget*)obj; + if ( ::qt_cast<QMainWindow*>(w) ) + w = ( (QMainWindow*)w )->centralWidget(); + if ( layout ) { + switch ( WidgetFactory::layoutType( layout ) ) { + case WidgetFactory::HBox: + ( (QHBoxLayout*)layout )->addWidget( w ); + break; + case WidgetFactory::VBox: + ( (QVBoxLayout*)layout )->addWidget( w ); + break; + case WidgetFactory::Grid: + ( (QDesignerGridLayout*)layout )->addMultiCellWidget( w, row, row + rowspan - 1, + col, col + colspan - 1 ); + break; + default: + break; + } + } + + if ( !toplevel ) + toplevel = w; + layout = 0; + + if ( w && formwindow ) { + if ( !parent || + ( !::qt_cast<QTabWidget*>(parent) && + !::qt_cast<QWidgetStack*>(parent) && + !::qt_cast<QToolBox*>(parent) && + !::qt_cast<QWizard*>(parent) +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + && !isPlugin +#endif + ) ) + formwindow->insertWidget( w, pasting ); + else if ( parent && + ( ::qt_cast<QTabWidget*>(parent) || + ::qt_cast<QWidgetStack*>(parent) || + ::qt_cast<QToolBox*>(parent) || + ::qt_cast<QWizard*>(parent) +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + || isPlugin +#endif + ) ) + MetaDataBase::addEntry( w ); + } + } + + QDomElement sizePolicyElement; + QObject *sizePolicyObject = 0; + + while ( !n.isNull() ) { + if ( n.tagName() == "spacer" ) { + createSpacer( n, w, layout, Qt::Horizontal ); + } else if ( n.tagName() == "widget" ) { + createObject( n, w, layout ); + } else if ( n.tagName() == "hbox" ) { + layout = WidgetFactory::createLayout( w, layout, WidgetFactory::HBox ); + obj = layout; + n = n.firstChild().toElement(); + continue; + } else if ( n.tagName() == "grid" ) { + layout = WidgetFactory::createLayout( w, layout, WidgetFactory::Grid ); + obj = layout; + n = n.firstChild().toElement(); + continue; + } else if ( n.tagName() == "vbox" ) { + layout = WidgetFactory::createLayout( w, layout, WidgetFactory::VBox ); + obj = layout; + n = n.firstChild().toElement(); + continue; + } else if ( n.tagName() == "property" && obj ) { + if ( n.attribute( "name" ) == "sizePolicy" ) { + // ### Evil hack ### Delay setting sizePolicy so it won't be overridden by other properties. + sizePolicyElement = n; + sizePolicyObject = obj; + } else { + setObjectProperty( obj, n.attribute( "name" ), n.firstChild().toElement() ); + } + } else if ( n.tagName() == "attribute" && w ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( ::qt_cast<QTabWidget*>(parent) ) { + if ( attrib == "title" ) + ( (QTabWidget*)parent )->insertTab( w, v.toString() ); + } else if ( ::qt_cast<QWidgetStack*>(parent) ) { + if ( attrib == "id" ) + ( (QDesignerWidgetStack*)parent )->insertPage( w, v.toInt() ); + } else if ( ::qt_cast<QToolBox*>(parent) ) { + if ( attrib == "label" ) + ( (QToolBox*)parent )->addItem( w, v.toString() ); + } else if ( ::qt_cast<QWizard*>(parent) ) { + if ( attrib == "title" ) + ( (QWizard*)parent )->addPage( w, v.toString() ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( isPlugin ) { + if ( attrib == "label" ) { + WidgetInterface *iface = 0; + widgetManager()->queryInterface( parentClassName, &iface ); + if ( iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + iface2->insertPage( parentClassName, + (QWidget*)parent, v.toString(), -1, w ); + iface2->release(); + } + iface->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + } + } else if ( n.tagName() == "item" ) { + createItem( n, w ); + } else if ( n.tagName() == "column" || n.tagName() =="row" ) { + createColumn( n, w ); + } + + n = n.nextSibling().toElement(); + } + + // ### Evil hack ### See description above. + if ( !sizePolicyElement.isNull() ) { + setObjectProperty( sizePolicyObject, + sizePolicyElement.attribute( "name" ), + sizePolicyElement.firstChild().toElement() ); + } + + if ( w->isWidgetType() ) + widgets.insert( w->name(), w ); + + return w; +} + +void Resource::createColumn( const QDomElement &e, QWidget *widget ) +{ + if ( !widget ) + return; + + if ( ::qt_cast<QListView*>(widget) && e.tagName() == "column" ) { + QListView *lv = (QListView*)widget; + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + bool clickable = TRUE, resizable = TRUE; + 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(); + else if ( attrib == "pixmap" ) { + pix = loadPixmap( n.firstChild().toElement().toElement() ); + hasPixmap = !pix.isNull(); + } else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + lv->addColumn( txt ); + int i = lv->header()->count() - 1; + if ( hasPixmap ) { + lv->header()->setLabel( i, pix, txt ); + } + if ( !clickable ) + lv->header()->setClickEnabled( clickable, i ); + if ( !resizable ) + lv->header()->setResizeEnabled( resizable, i ); + } +#ifndef QT_NO_TABLE + else if ( ::qt_cast<QTable*>(widget) ) { + QTable *table = (QTable*)widget; + bool isRow; + if ( ( isRow = e.tagName() == "row" ) ) + table->setNumRows( table->numRows() + 1 ); + else + table->setNumCols( table->numCols() + 1 ); + + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + QString field; + QMap<QString, QString> fieldMap = MetaDataBase::columnFields( table ); + 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(); + else if ( attrib == "pixmap" ) { + hasPixmap = !n.firstChild().firstChild().toText().data().isEmpty(); + if ( hasPixmap ) + pix = loadPixmap( n.firstChild().toElement() ); + } else if ( attrib == "field" ) + field = v.toString(); + } + n = n.nextSibling().toElement(); + } + + int i = isRow ? table->numRows() - 1 : table->numCols() - 1; + QHeader *h = !isRow ? table->horizontalHeader() : table->verticalHeader(); + if ( hasPixmap ) + h->setLabel( i, pix, txt ); + else + h->setLabel( i, txt ); + if ( !isRow && !field.isEmpty() ) + fieldMap.insert( txt, field ); + MetaDataBase::setColumnFields( table, fieldMap ); + } +#endif +} + +void Resource::loadItem( const QDomElement &e, QPixmap &pix, QString &txt, bool &hasPixmap ) +{ + QDomElement n = e; + hasPixmap = 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(); + else if ( attrib == "pixmap" ) { + pix = loadPixmap( n.firstChild().toElement() ); + hasPixmap = !pix.isNull(); + } + } + n = n.nextSibling().toElement(); + } +} + +void Resource::createItem( const QDomElement &e, QWidget *widget, QListViewItem *i ) +{ + if ( !widget || !WidgetFactory::hasItems( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( widget ) ), widget ) ) + return; + + if ( ::qt_cast<QListBox*>(widget) || ::qt_cast<QComboBox*>(widget) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + QListBox *lb = 0; + if ( ::qt_cast<QListBox*>(widget) ) + lb = (QListBox*)widget; + else + lb = ( (QComboBox*)widget)->listBox(); + if ( hasPixmap ) { + new QListBoxPixmap( lb, pix, txt ); + } else { + new QListBoxText( lb, txt ); + } + } else if ( ::qt_cast<QIconView*>(widget) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + QIconView *iv = (QIconView*)widget; + if ( hasPixmap ) + new QIconViewItem( iv, txt, pix ); + else + new QIconViewItem( iv, txt ); + } else if ( ::qt_cast<QListView*>(widget) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QValueList<QPixmap> pixmaps; + QStringList textes; + QListViewItem *item = 0; + QListView *lv = (QListView*)widget; + if ( i ) + item = new QListViewItem( i, lastItem ); + else + item = new QListViewItem( lv, lastItem ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + textes << v.toString(); + else if ( attrib == "pixmap" ) { + QString s = v.toString(); + if ( s.isEmpty() ) { + pixmaps << QPixmap(); + } else { + pix = loadPixmap( n.firstChild().toElement() ); + pixmaps << pix; + } + } + } else if ( n.tagName() == "item" ) { + item->setOpen( TRUE ); + createItem( n, widget, item ); + } + + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < lv->columns(); ++i ) { + item->setText( i, textes[ i ] ); + item->setPixmap( i, pixmaps[ i ] ); + } + lastItem = item; + } +} + +QWidget *Resource::createSpacer( const QDomElement &e, QWidget *parent, QLayout *layout, Qt::Orientation o ) +{ + QDomElement n = e.firstChild().toElement(); + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + + Spacer *spacer = (Spacer*) WidgetFactory::create( WidgetDatabase::idFromClassName("Spacer"), + parent, "spacer", FALSE); + spacer->setOrientation( o ); + spacer->setInteraciveMode( FALSE ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) + setObjectProperty( spacer, n.attribute( "name" ), n.firstChild().toElement() ); + n = n.nextSibling().toElement(); + } + spacer->setInteraciveMode( TRUE ); + if ( formwindow ) + formwindow->insertWidget( spacer, pasting ); + if ( layout ) { + if ( ::qt_cast<QBoxLayout*>(layout) ) + ( (QBoxLayout*)layout )->addWidget( spacer, 0, spacer->alignment() ); + else + ( (QDesignerGridLayout*)layout )->addMultiCellWidget( spacer, row, row + rowspan - 1, col, col + colspan - 1, + spacer->alignment() ); + } + return spacer; +} + +/*! + Attention: this function has to be in sync with Uic::setObjectProperty(). If you change one, change both. +*/ +void Resource::setObjectProperty( QObject* obj, const QString &prop, const QDomElement &e ) +{ + const QMetaProperty *p = obj->metaObject()->property( obj->metaObject()->findProperty( prop, TRUE ), TRUE ); + + if ( !::qt_cast<QLayout*>(obj) ) {// no layouts in metadatabase... (RS) + if ( obj->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)obj )->customWidget(); + if ( cw && !cw->hasProperty( prop.latin1() ) && !p && prop != "toolTip" && prop != "whatsThis" ) + return; + } + MetaDataBase::setPropertyChanged( obj, prop, TRUE ); + } + + QVariant defVarient; + if ( e.tagName() == "font" ) { + QFont f( qApp->font() ); + if ( obj->isWidgetType() && ( (QWidget*)obj )->parentWidget() ) + f = ( (QWidget*)obj )->parentWidget()->font(); + defVarient = QVariant( f ); + } + + QString comment; + QVariant v( DomTool::elementToVariant( e, defVarient, comment ) ); + + if ( !comment.isEmpty() ) { + MetaDataBase::addEntry( obj ); + MetaDataBase::setPropertyComment( obj, prop, comment ); + } + + if ( e.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( e ); + if ( pix.isNull() ) + return; + v = QVariant( pix ); + } else if ( e.tagName() == "iconset" ) { + QPixmap pix = loadPixmap( e, "iconset" ); + if ( pix.isNull() ) + return; + v = QVariant( QIconSet( pix ) ); + } else if ( e.tagName() == "image" ) { + v = QVariant( loadFromCollection( v.toString() ) ); + } + + if ( !p ) { + MetaDataBase::setFakeProperty( obj, prop, v ); + if ( obj->isWidgetType() ) { + if ( prop == "database" && obj != toplevel ) { + QStringList lst = MetaDataBase::fakeProperty( obj, "database" ).toStringList(); + if ( lst.count() > 2 ) + dbControls.insert( obj->name(), lst[ 2 ] ); + else if ( lst.count() == 2 ) + dbTables.insert( obj->name(), lst ); + } + return; + } + } + + if ( e.tagName() == "palette" ) { + QDomElement n = e.firstChild().toElement(); + QPalette p; + while ( !n.isNull() ) { + QColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + p.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + p.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + p.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + v = QPalette( p ); + } else if ( e.tagName() == "enum" && p && p->isEnumType() && prop != "resizeMode" ) { + QString key( v.toString() ); + int vi = p->keyToValue( key ); + if ( p->valueToKey( vi ) != key ) + return; // ignore invalid properties + v = QVariant( vi ); + } else if ( e.tagName() == "set" && p && p->isSetType() ) { + QString keys( v.toString() ); + QStringList lst = QStringList::split( '|', keys ); + QStrList l; + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) + l.append( *it ); + v = QVariant( p->keysToValue( l ) ); + } + + if ( prop == "caption" ) { + QCString s1 = v.toCString(); + QString s2 = v.toString(); + if ( !s2.isEmpty() ) + formwindow->setCaption( s2 ); + else if ( !s1.isEmpty() ) + formwindow->setCaption( s1 ); + } + if ( prop == "icon" ) { + formwindow->setIcon( v.toPixmap() ); + QString pmk = MetaDataBase::pixmapKey( formwindow, v.toPixmap().serialNumber() ); + MetaDataBase::setPixmapKey( formwindow, + formwindow->icon()->serialNumber(), pmk ); + } + + if ( prop == "geometry" ) { + if ( obj == toplevel ) { + hadGeometry = TRUE; + toplevel->resize( v.toRect().size() ); + return; + } else if ( obj == formwindow->mainContainer() ) { + hadGeometry = TRUE; + formwindow->resize( v.toRect().size() ); + return; + } + } + + if ( ::qt_cast<QLayout*>(obj) ) { + if ( prop == "spacing" ) { + MetaDataBase::setSpacing( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)obj ) ), v.toInt() ); + return; + } else if ( prop == "margin" ) { + MetaDataBase::setMargin( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)obj ) ), v.toInt() ); + return; + } else if ( e.tagName() == "enum" && prop == "resizeMode" ) { + MetaDataBase::setResizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)obj ) ), v.toString() ); + return; + } + } + + if ( prop == "name" ) { + if ( pasting ) { + QString s = v.toString(); + formwindow->unify( (QWidget*)obj, s, TRUE ); + obj->setName( s ); + return; + } else if ( formwindow && obj == formwindow->mainContainer() ) { + formwindow->setName( v.toCString() ); + } + } + + if ( prop == "sizePolicy" ) { + QSizePolicy sp = v.toSizePolicy(); + sp.setHeightForWidth( ( (QWidget*)obj )->sizePolicy().hasHeightForWidth() ); + } + + if ( prop == "cursor" ) + MetaDataBase::setCursor( (QWidget*)obj, v.toCursor() ); + + obj->setProperty( prop, v ); +} + + +QString Resource::saveInCollection( const QImage &img ) +{ + QString imgName = "none"; + QValueList<Image>::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + if ( img == ( *it ).img ) { + imgName = ( *it ).name; + break; + } + } + + if ( imgName == "none" ) { + Image i; + imgName = "image" + QString::number( images.count() ); + i.name = imgName; + i.img = img; + images.append( i ); + } + return imgName; +} + +void Resource::saveImageData( const QImage &img, QTextStream &ts, int indent ) +{ + QByteArray ba; + QBuffer buf( ba ); + buf.open( IO_WriteOnly | IO_Translate ); + QString format; + bool compress = FALSE; + if (img.hasAlphaBuffer()) { + format = "PNG"; + } else { + format = img.depth() > 1 ? "XPM" : "XBM"; + compress = TRUE; + } + QImageIO iio( &buf, format ); + iio.setImage( img ); + iio.write(); + buf.close(); + QByteArray bazip = ba; + int i = 0; + if (compress) { + bazip = qCompress( ba ); + format += ".GZ"; + // The first 4 bytes in qCompress() are the length of the unzipped + // format. The XPM.GZ format does not use these. + i = 4; + } + ulong len = bazip.size(); + ts << makeIndent( indent ) << "<data format=\"" + format + "\" length=\"" << ba.size() << "\">"; + static const char hexchars[] = "0123456789abcdef"; + for (; i < (int)len; ++i ) { + uchar s = (uchar) bazip[i]; + ts << hexchars[s >> 4]; + ts << hexchars[s & 0x0f]; + } + ts << "</data>" << endl; +} + +void Resource::saveImageCollection( QTextStream &ts, int indent ) +{ + ts << makeIndent( indent ) << "<images>" << endl; + indent++; + + QValueList<Image>::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + ts << makeIndent( indent ) << "<image name=\"" << (*it).name << "\">" << endl; + indent++; + saveImageData( (*it).img, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</image>" << endl; + } + + indent--; + ts << makeIndent( indent ) << "</images>" << endl; +} + +static QImage loadImageData( QDomElement &n2 ) +{ + QImage img; + QString data = n2.firstChild().toText().data(); + 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; + } + QString format = n2.attribute( "format", "PNG" ); + if ( format == "XPM.GZ" || format == "XBM.GZ" ) { + ulong len = n2.attribute( "length" ).toULong(); + if ( len < data.length() * 5 ) + len = data.length() * 5; + // qUncompress() expects the first 4 bytes to be the expected length of + // the uncompressed data + ba[0] = ( len & 0xff000000 ) >> 24; + ba[1] = ( len & 0x00ff0000 ) >> 16; + ba[2] = ( len & 0x0000ff00 ) >> 8; + ba[3] = ( len & 0x000000ff ); + QByteArray baunzip = qUncompress( ba, baSize ); + img.loadFromData( (const uchar*)baunzip.data(), baunzip.size(), format.left(format.find('.')) ); + } else { + img.loadFromData( (const uchar*)ba+lengthOffset, baSize-lengthOffset, format ); + } + delete [] ba; + return img; +} + +void Resource::loadImageCollection( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "image" ) { + Image img; + img.name = n.attribute( "name" ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "data" ) + img.img = loadImageData( n2 ); + n2 = n2.nextSibling().toElement(); + } + images.append( img ); + n = n.nextSibling().toElement(); + } + } +} + +QImage Resource::loadFromCollection( const QString &name ) +{ + QValueList<Image>::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + if ( ( *it ).name == name ) + return ( *it ).img; + } + return QImage(); +} + +void Resource::saveConnections( QTextStream &ts, int indent ) +{ + QValueList<MetaDataBase::Connection> connections = MetaDataBase::connections( formwindow ); + if ( connections.isEmpty() ) + return; + ts << makeIndent( indent ) << "<connections>" << endl; + indent++; + QValueList<MetaDataBase::Connection>::Iterator it = connections.begin(); + for ( ; it != connections.end(); ++it ) { + MetaDataBase::Connection conn = *it; + if ( ( knownNames.findIndex( QString( conn.sender->name() ) ) == -1 && + qstrcmp( conn.sender->name(), "this" ) != 0 ) || + ( knownNames.findIndex( QString( conn.receiver->name() ) ) == -1 && + qstrcmp( conn.receiver->name(), "this" ) != 0 ) ) + continue; + if ( formwindow->isMainContainer( (QWidget*)(*it).receiver ) && + !MetaDataBase::hasSlot( formwindow, MetaDataBase::normalizeFunction( (*it).slot ).latin1() ) ) + continue; + + if ( conn.sender->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)conn.sender )->customWidget(); + if ( cw && !cw->hasSignal( conn.signal ) ) + continue; + } + + if ( conn.receiver->inherits( "CustomWidget" ) && !formwindow->isMainContainer( conn.receiver ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)conn.receiver )->customWidget(); + if ( cw && !cw->hasSlot( MetaDataBase::normalizeFunction( conn.slot ).latin1() ) ) + continue; + } + + ts << makeIndent( indent ) << "<connection>" << endl; + indent++; + ts << makeIndent( indent ) << "<sender>" << entitize( conn.sender->name() ) << "</sender>" << endl; + ts << makeIndent( indent ) << "<signal>" << entitize( conn.signal ) << "</signal>" << endl; + ts << makeIndent( indent ) << "<receiver>" << entitize( conn.receiver->name() ) << "</receiver>" << endl; + ts << makeIndent( indent ) << "<slot>" << entitize( MetaDataBase::normalizeFunction( conn.slot ) ) << "</slot>" << endl; + indent--; + ts << makeIndent( indent ) << "</connection>" << endl; + } + + QString lang = formwindow->project()->language(); + indent--; + ts << makeIndent( indent ) << "</connections>" << endl; +} + +void Resource::loadConnections( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "connection" ) { + QString lang = n.attribute( "language", "C++" ); + QDomElement n2 = n.firstChild().toElement(); + MetaDataBase::Connection conn; + while ( !n2.isNull() ) { + if ( n2.tagName() == "sender" ) { + conn.sender = 0; + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.sender = toplevel; + } else { + if ( name == "this" ) + name = toplevel->name(); + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.sender = l->first(); + delete l; + l = 0; + } + if ( !conn.sender ) + conn.sender = formwindow->findAction( name ); + } + } else if ( n2.tagName() == "signal" ) { + conn.signal = n2.firstChild().toText().data(); + } else if ( n2.tagName() == "receiver" ) { + conn.receiver = 0; + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.receiver = toplevel; + } else { + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.receiver = l->first(); + delete l; + l = 0; + } + if ( !conn.receiver ) + conn.receiver = formwindow->findAction( name ); + } + } else if ( n2.tagName() == "slot" ) { + conn.slot = n2.firstChild().toText().data(); + } + n2 = n2.nextSibling().toElement(); + } + if ( formwindow ) { + if ( conn.sender == formwindow ) + conn.sender = formwindow->mainContainer(); + if ( conn.receiver == formwindow ) + conn.receiver = formwindow->mainContainer(); + } + if ( conn.sender && conn.receiver ) { + if ( lang == "C++" ) { + MetaDataBase::addConnection( formwindow ? formwindow : toplevel, + conn.sender, conn.signal, conn.receiver, conn.slot ); + } + } + } else if ( n.tagName() == "slot" ) { // compatibility with 2.x + MetaDataBase::Function slot; + slot.specifier = n.attribute( "specifier", "virtual" ); + if ( slot.specifier.isEmpty() ) + slot.specifier = "virtual"; + slot.access = n.attribute( "access", "public" ); + if ( slot.access.isEmpty() ) + slot.access = "public"; + slot.language = n.attribute( "language", "C++" ); + slot.returnType = n.attribute( "returnType", "void" ); + if ( slot.returnType.isEmpty() ) + slot.returnType = "void"; + slot.function = n.firstChild().toText().data(); + if ( !MetaDataBase::hasFunction( formwindow, slot.function, TRUE ) ) + MetaDataBase::addFunction( formwindow, slot.function, slot.specifier, + slot.access, "slot", slot.language, slot.returnType ); + else + MetaDataBase::changeFunctionAttributes( formwindow, slot.function, slot.function, + slot.specifier, slot.access, + "slot", slot.language, slot.returnType ); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::saveCustomWidgets( QTextStream &ts, int indent ) +{ + ts << makeIndent( indent ) << "<customwidgets>" << endl; + indent++; + + QPtrList<MetaDataBase::CustomWidget> *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + if ( usedCustomWidgets.findIndex( w->className ) == -1 ) + continue; + ts << makeIndent( indent ) << "<customwidget>" << endl; + indent++; + ts << makeIndent( indent ) << "<class>" << w->className << "</class>" << endl; + ts << makeIndent( indent ) << "<header location=\"" + << ( w->includePolicy == MetaDataBase::CustomWidget::Local ? "local" : "global" ) + << "\">" << w->includeFile << "</header>" << endl; + ts << makeIndent( indent ) << "<sizehint>" << endl; + indent++; + ts << makeIndent( indent ) << "<width>" << w->sizeHint.width() << "</width>" << endl; + ts << makeIndent( indent ) << "<height>" << w->sizeHint.height() << "</height>" << endl; + indent--; + ts << makeIndent( indent ) << "</sizehint>" << endl; + ts << makeIndent( indent ) << "<container>" << (int)w->isContainer << "</container>" << endl; + ts << makeIndent( indent ) << "<sizepolicy>" << endl; + indent++; + ts << makeIndent( indent ) << "<hordata>" << (int)w->sizePolicy.horData() << "</hordata>" << endl; + ts << makeIndent( indent ) << "<verdata>" << (int)w->sizePolicy.verData() << "</verdata>" << endl; + ts << makeIndent( indent ) << "<horstretch>" << (int)w->sizePolicy.horStretch() << "</horstretch>" << endl; + ts << makeIndent( indent ) << "<verstretch>" << (int)w->sizePolicy.verStretch() << "</verstretch>" << endl; + indent--; + ts << makeIndent( indent ) << "</sizepolicy>" << endl; + ts << makeIndent( indent ) << "<pixmap>" << saveInCollection( w->pixmap->convertToImage() ) << "</pixmap>" << endl; + if ( !w->lstSignals.isEmpty() ) { + for ( QValueList<QCString>::Iterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + ts << makeIndent( indent ) << "<signal>" << entitize( *it ) << "</signal>" << endl; + } + if ( !w->lstSlots.isEmpty() ) { + for ( QValueList<MetaDataBase::Function>::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) + ts << makeIndent( indent ) << "<slot access=\"" << (*it).access << "\" specifier=\"" + << (*it).specifier << "\">" << entitize( (*it).function ) << "</slot>" << endl; + } + if ( !w->lstProperties.isEmpty() ) { + for ( QValueList<MetaDataBase::Property>::Iterator it = w->lstProperties.begin(); it != w->lstProperties.end(); ++it ) + ts << makeIndent( indent ) << "<property type=\"" << (*it).type << "\">" << entitize( (*it).property ) << "</property>" << endl; + } + indent--; + ts << makeIndent( indent ) << "</customwidget>" << endl; + } + + + indent--; + ts << makeIndent( indent ) << "</customwidgets>" << endl; +} + +void Resource::loadCustomWidgets( const QDomElement &e, Resource *r ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "customwidget" ) { + QDomElement n2 = n.firstChild().toElement(); + MetaDataBase::CustomWidget *w = new MetaDataBase::CustomWidget; + while ( !n2.isNull() ) { + if ( n2.tagName() == "class" ) { + w->className = n2.firstChild().toText().data(); + } else if ( n2.tagName() == "header" ) { + w->includeFile = n2.firstChild().toText().data(); + QString s = n2.attribute( "location" ); + if ( s != "local" ) + w->includePolicy = MetaDataBase::CustomWidget::Global; + else + w->includePolicy = MetaDataBase::CustomWidget::Local; + } else if ( n2.tagName() == "sizehint" ) { + QDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w->sizeHint.setWidth( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "height" ) + w->sizeHint.setHeight( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else if ( n2.tagName() == "sizepolicy" ) { + QDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "hordata" ) + w->sizePolicy.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verdata" ) + w->sizePolicy.setVerData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + w->sizePolicy.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + w->sizePolicy.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else if ( n2.tagName() == "pixmap" ) { + QPixmap pix; + if ( r ) { + pix = r->loadPixmap( n2 ); + } else { + QDomElement n3 = n2.firstChild().toElement(); + QImage img; + while ( !n3.isNull() ) { + if ( n3.tagName() == "data" ) { + img = loadImageData( n3 ); + } + n3 = n3.nextSibling().toElement(); + } + pix.convertFromImage( img ); + } + w->pixmap = new QPixmap( pix ); + } else if ( n2.tagName() == "signal" ) { + w->lstSignals.append( n2.firstChild().toText().data().latin1() ); + } else if ( n2.tagName() == "container" ) { + w->isContainer = (bool)n2.firstChild().toText().data().toInt(); + } else if ( n2.tagName() == "slot" ) { + MetaDataBase::Function function; + function.function = n2.firstChild().toText().data().latin1(); + function.access = n2.attribute( "access" ); + function.type = "slot"; + w->lstSlots.append( function ); + } else if ( n2.tagName() == "property" ) { + MetaDataBase::Property property; + property.property = n2.firstChild().toText().data().latin1(); + property.type = n2.attribute( "type" ); + w->lstProperties.append( property ); + } + n2 = n2.nextSibling().toElement(); + } + MetaDataBase::addCustomWidget( w ); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::saveTabOrder( QTextStream &ts, int indent ) +{ + QWidgetList l = MetaDataBase::tabOrder( toplevel ); + if ( l.isEmpty() ) + return; + + ts << makeIndent( indent ) << "<tabstops>" << endl; + indent++; + + for ( QWidget *w = l.first(); w; w = l.next() ) { + if ( w->testWState( Qt::WState_ForceHide ) || knownNames.findIndex( w->name() ) == -1 ) + continue; + ts << makeIndent( indent ) << "<tabstop>" << w->name() << "</tabstop>" << endl; + } + + indent--; + ts << makeIndent( indent ) << "</tabstops>" << endl; +} + +void Resource::loadTabOrder( const QDomElement &e ) +{ + QWidget *last = 0; + QDomElement n = e.firstChild().toElement(); + QWidgetList widgets; + while ( !n.isNull() ) { + if ( n.tagName() == "tabstop" ) { + QString name = n.firstChild().toText().data(); + if ( name.isEmpty() ) + continue; + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) { + QWidget *w = (QWidget*)l->first(); + widgets.append( w ); + if ( last ) + toplevel->setTabOrder( last, w ); + last = w; + } + delete l; + } + } + n = n.nextSibling().toElement(); + } + + if ( !widgets.isEmpty() ) + MetaDataBase::setTabOrder( toplevel, widgets ); +} + +void Resource::saveMetaInfoBefore( QTextStream &ts, int indent ) +{ + MetaDataBase::MetaInfo info = MetaDataBase::metaInfo( formwindow ); + QString cn; + if ( info.classNameChanged && !info.className.isEmpty() ) + cn = info.className; + else + cn = formwindow->name(); + ts << makeIndent( indent ) << "<class>" << entitize( cn ) << "</class>" << endl; + if ( !info.comment.isEmpty() ) + ts << makeIndent( indent ) << "<comment>" << entitize( info.comment ) << "</comment>" << endl; + if ( !info.author.isEmpty() ) + ts << makeIndent( indent ) << "<author>" << entitize( info.author ) << "</author>" << endl; +} + +void Resource::saveMetaInfoAfter( QTextStream &ts, int indent ) +{ + MetaDataBase::MetaInfo info = MetaDataBase::metaInfo( formwindow ); + if ( !langIface || formwindow->project()->isCpp() ) { + QValueList<MetaDataBase::Include> includes = MetaDataBase::includes( formwindow ); + QString extensionInclude; + bool needExtensionInclude = FALSE; + if ( langIface && + formwindow->formFile()->hasFormCode() && + formwindow->formFile()->codeFileState() != FormFile::Deleted ) { + extensionInclude = QFileInfo( currFileName ).fileName() + langIface->formCodeExtension(); + needExtensionInclude = TRUE; + } + if ( !includes.isEmpty() || needExtensionInclude ) { + ts << makeIndent( indent ) << "<includes>" << endl; + indent++; + + for ( QValueList<MetaDataBase::Include>::Iterator it = includes.begin(); it != includes.end(); ++it ) { + ts << makeIndent( indent ) << "<include location=\"" << (*it).location + << "\" impldecl=\"" << (*it).implDecl << "\">" << (*it).header << "</include>" << endl; + if ( needExtensionInclude ) + needExtensionInclude = (*it).header != extensionInclude; + } + + if ( needExtensionInclude ) + ts << makeIndent( indent ) << "<include location=\"local\" impldecl=\"in implementation\">" + << extensionInclude << "</include>" << endl; + indent--; + ts << makeIndent( indent ) << "</includes>" << endl; + } + + QStringList forwards = MetaDataBase::forwards( formwindow ); + if ( !forwards.isEmpty() ) { + ts << makeIndent( indent ) << "<forwards>" << endl; + indent++; + for ( QStringList::Iterator it2 = forwards.begin(); it2 != forwards.end(); ++it2 ) + ts << makeIndent( indent ) << "<forward>" << entitize( *it2 ) << "</forward>" << endl; + indent--; + ts << makeIndent( indent ) << "</forwards>" << endl; + } + QValueList<MetaDataBase::Variable> varLst = MetaDataBase::variables( formwindow ); + if ( !varLst.isEmpty() ) { + ts << makeIndent( indent ) << "<variables>" << endl; + indent++; + + QValueList<MetaDataBase::Variable>::Iterator it = varLst.begin(); + for ( ; it != varLst.end(); ++it ) { + ts << makeIndent( indent ) << "<variable"; + if ( (*it).varAccess != "protected" ) + ts << " access=\"" << (*it).varAccess << "\""; + + ts << ">" << entitize( (*it).varName ) << "</variable>" << endl; + } + indent--; + ts << makeIndent( indent ) << "</variables>" << endl; + } + QStringList sigs = MetaDataBase::signalList( formwindow ); + if ( !sigs.isEmpty() ) { + ts << makeIndent( indent ) << "<signals>" << endl; + indent++; + for ( QStringList::Iterator it3 = sigs.begin(); it3 != sigs.end(); ++it3 ) + ts << makeIndent( indent ) << "<signal>" << entitize( *it3 ) << "</signal>" << endl; + indent--; + ts << makeIndent( indent ) << "</signals>" << endl; + } + + QValueList<MetaDataBase::Function> slotList = MetaDataBase::slotList( formwindow ); + if ( !slotList.isEmpty() ) { + ts << makeIndent( indent ) << "<slots>" << endl; + indent++; + QString lang = formwindow->project()->language(); + QValueList<MetaDataBase::Function>::Iterator it = slotList.begin(); + for ( ; it != slotList.end(); ++it ) { + MetaDataBase::Function function = *it; + ts << makeIndent( indent ) << "<slot"; + if ( function.access != "public" ) + ts << " access=\"" << function.access << "\""; + if ( function.specifier != "virtual" ) + ts << " specifier=\"" << function.specifier << "\""; + if ( function.language != "C++" ) + ts << " language=\"" << function.language<< "\""; + if ( function.returnType != "void" ) + ts << " returnType=\"" << entitize( function.returnType ) << "\""; + ts << ">" << entitize( function.function ) << "</slot>" << endl; + } + indent--; + ts << makeIndent( indent ) << "</slots>" << endl; + } + + QValueList<MetaDataBase::Function> functionList = MetaDataBase::functionList( formwindow, TRUE ); + if ( !functionList.isEmpty() ) { + ts << makeIndent( indent ) << "<functions>" << endl; + indent++; + QString lang = formwindow->project()->language(); + QValueList<MetaDataBase::Function>::Iterator it = functionList.begin(); + for ( ; it != functionList.end(); ++it ) { + MetaDataBase::Function function = *it; + ts << makeIndent( indent ) << "<function"; + if ( function.access != "public" ) + ts << " access=\"" << function.access << "\""; + if ( function.specifier != "virtual" ) + ts << " specifier=\"" << function.specifier << "\""; + if ( function.language != "C++" ) + ts << " language=\"" << function.language<< "\""; + if ( function.returnType != "void" ) + ts << " returnType=\"" << entitize( function.returnType ) << "\""; + ts << ">" << entitize( function.function ) << "</function>" << endl; + } + indent--; + ts << makeIndent( indent ) << "</functions>" << endl; + } + } + + if ( formwindow && formwindow->savePixmapInline() ) + ; + else if ( formwindow && formwindow->savePixmapInProject() ) + ts << makeIndent( indent ) << "<pixmapinproject/>" << endl; + else + ts << makeIndent( indent ) << "<pixmapfunction>" << formwindow->pixmapLoaderFunction() << "</pixmapfunction>" << endl; + if ( !( exportMacro = MetaDataBase::exportMacro( formwindow->mainContainer() ) ).isEmpty() ) + ts << makeIndent( indent ) << "<exportmacro>" << exportMacro << "</exportmacro>" << endl; + if ( formwindow ) { + ts << makeIndent( indent ) << "<layoutdefaults spacing=\"" << formwindow->layoutDefaultSpacing() + << "\" margin=\"" << formwindow->layoutDefaultMargin() << "\"/>" << endl; + if ( formwindow->hasLayoutFunctions() ) { + QString s = ""; + QString m = ""; + if ( !formwindow->spacingFunction().isEmpty() ) + s = QString( " spacing=\"%1\"" ).arg( formwindow->spacingFunction() ); + if ( !formwindow->marginFunction().isEmpty() ) + m = QString( " margin=\"%1\"" ).arg( formwindow->marginFunction() ); + ts << makeIndent( indent ) << "<layoutfunctions" << s << m << "/>" << endl; + } + } +} + +void Resource::saveIncludeHints( QTextStream &ts, int indent ) +{ + if ( includeHints.isEmpty() ) + return; + ts << makeIndent( indent ) << "<includehints>" << endl; + indent++; + for ( QStringList::Iterator it = includeHints.begin(); it != includeHints.end(); ++it ) + ts << makeIndent( indent ) << "<includehint>" << *it << "</includehint>" << endl; + indent--; + ts << makeIndent( indent ) << "</includehints>" << endl; +} + +QColorGroup Resource::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 ) ) ); + } else if ( n.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( n ); + cg.setBrush( (QColorGroup::ColorRole)r, QBrush( col, pix ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +void Resource::saveChildActions( QAction *a, QTextStream &ts, int indent ) +{ + if ( !a->children() ) + return; + QObjectListIt it( *a->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast<QAction*>(o) ) + continue; + QAction *ac = (QAction*)o; + bool isGroup = ::qt_cast<QActionGroup*>(ac); + if ( isGroup ) + ts << makeIndent( indent ) << "<actiongroup>" << endl; + else + ts << makeIndent( indent ) << "<action>" << endl; + indent++; + saveObjectProperties( ac, ts, indent ); + indent--; + if ( isGroup ) { + indent++; + saveChildActions( ac, ts, indent ); + indent--; + } + if ( isGroup ) + ts << makeIndent( indent ) << "</actiongroup>" << endl; + else + ts << makeIndent( indent ) << "</action>" << endl; + } +} + +void Resource::saveActions( const QPtrList<QAction> &actions, QTextStream &ts, int indent ) +{ + if ( actions.isEmpty() ) + return; + ts << makeIndent( indent ) << "<actions>" << endl; + indent++; + QPtrListIterator<QAction> it( actions ); + while ( it.current() ) { + QAction *a = it.current(); + bool isGroup = ::qt_cast<QActionGroup*>(a); + if ( isGroup ) + ts << makeIndent( indent ) << "<actiongroup>" << endl; + else + ts << makeIndent( indent ) << "<action>" << endl; + indent++; + saveObjectProperties( a, ts, indent ); + indent--; + if ( isGroup ) { + indent++; + saveChildActions( a, ts, indent ); + indent--; + } + if ( isGroup ) + ts << makeIndent( indent ) << "</actiongroup>" << endl; + else + ts << makeIndent( indent ) << "</action>" << endl; + ++it; + } + indent--; + ts << makeIndent( indent ) << "</actions>" << endl; +} + +void Resource::loadChildAction( QObject *parent, const QDomElement &e ) +{ + QDomElement n = e; + QAction *a = 0; + if ( n.tagName() == "action" ) { + a = new QDesignerAction( parent ); + MetaDataBase::addEntry( a ); + QDomElement n2 = n.firstChild().toElement(); + bool hasMenuText = FALSE; + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QDomElement n3(n2); // don't modify n2 + QString prop = n3.attribute( "name" ); + if (prop == "menuText") + hasMenuText = TRUE; + QDomElement value(n3.firstChild().toElement()); + setObjectProperty( a, prop, value ); + if (!hasMenuText && uiFileVersion < "3.3" && prop == "text") + setObjectProperty( a, "menuText", value ); + } + n2 = n2.nextSibling().toElement(); + } + if ( !::qt_cast<QAction*>(parent) ) + formwindow->actionList().append( a ); + } else if ( n.tagName() == "actiongroup" ) { + a = new QDesignerActionGroup( parent ); + MetaDataBase::addEntry( a ); + QDomElement n2 = n.firstChild().toElement(); + bool hasMenuText = FALSE; + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QDomElement n3(n2); // don't modify n2 + QString prop = n3.attribute( "name" ); + if (prop == "menuText") + hasMenuText = TRUE; + QDomElement value = n3.firstChild().toElement(); + setObjectProperty( a, prop, value ); + if (!hasMenuText && uiFileVersion < "3.3" && prop == "text") + setObjectProperty( a, "menuText", value ); + } else if ( n2.tagName() == "action" || + n2.tagName() == "actiongroup" ) { + loadChildAction( a, n2 ); + } + n2 = n2.nextSibling().toElement(); + } + if ( !::qt_cast<QAction*>(parent) ) + formwindow->actionList().append( a ); + } +} + +void Resource::loadActions( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "action" ) { + loadChildAction( formwindow, n ); + } else if ( n.tagName() == "actiongroup" ) { + loadChildAction( formwindow, n ); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::saveToolBars( QMainWindow *mw, QTextStream &ts, int indent ) +{ + ts << makeIndent( indent ) << "<toolbars>" << endl; + indent++; + + QPtrList<QToolBar> tbList; + for ( int i = 0; i <= (int)Qt::DockMinimized; ++i ) { + tbList = mw->toolBars( (Qt::Dock)i ); + if ( tbList.isEmpty() ) + continue; + for ( QToolBar *tb = tbList.first(); tb; tb = tbList.next() ) { + if ( tb->isHidden() ) + continue; + ts << makeIndent( indent ) << "<toolbar dock=\"" << i << "\">" << endl; + indent++; + saveObjectProperties( tb, ts, indent ); + QPtrList<QAction> actionList = ( (QDesignerToolBar*)tb )->insertedActions(); + for ( QAction *a = actionList.first(); a; a = actionList.next() ) { + if ( ::qt_cast<QSeparatorAction*>(a) ) { + ts << makeIndent( indent ) << "<separator/>" << endl; + } else { + if ( ::qt_cast<QDesignerAction*>(a) && !( (QDesignerAction*)a )->supportsMenu() ) { + QWidget *w = ( (QDesignerAction*)a )->widget(); + ts << makeIndent( indent ) << "<widget class=\"" + << WidgetFactory::classNameOf( w ) << "\">" << endl; + indent++; + const char *className = WidgetFactory::classNameOf( w ); + if ( w->isA( "CustomWidget" ) ) + usedCustomWidgets << QString( className ); + if ( WidgetFactory::hasItems( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) + saveItems( w, ts, indent ); + saveObjectProperties( w, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</widget>" << endl; + } else { + ts << makeIndent( indent ) << "<action name=\"" << a->name() << "\"/>" << endl; + } + } + } + indent--; + ts << makeIndent( indent ) << "</toolbar>" << endl; + } + } + indent--; + ts << makeIndent( indent ) << "</toolbars>" << endl; +} + +void Resource::saveMenuBar( QMainWindow *mw, QTextStream &ts, int indent ) +{ + MenuBarEditor *mb = (MenuBarEditor *)mw->child( 0, "MenuBarEditor" ); + if ( !mb ) + return; + ts << makeIndent( indent ) << "<menubar>" << endl; + indent++; + MetaDataBase::setPropertyChanged( mb, "name", TRUE ); // FIXME: remove + saveObjectProperties( mb, ts, indent ); + + for ( int i = 0; i < (int)mb->count(); ++i ) { + MenuBarEditorItem *m = mb->item( i ); + if ( !m ) + continue; + if ( m->isSeparator() ) { + ts << makeIndent( indent ) << "<separator/>" << endl; + } else { + ts << makeIndent( indent ) << "<item text=\"" << entitize( m->menuText() ) + << "\" name=\"" << entitize( m->menu()->name() ) << "\">" << endl; + indent++; + savePopupMenu( m->menu(), mw, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</item>" << endl; + } + } + indent--; + ts << makeIndent( indent ) << "</menubar>" << endl; +} + +void Resource::savePopupMenu( PopupMenuEditor *pm, QMainWindow *mw, QTextStream &ts, int indent ) +{ + for ( PopupMenuEditorItem *i = pm->items()->first(); i; i = pm->items()->next() ) { + QAction *a = i->action(); + if ( ::qt_cast<QSeparatorAction*>(a) ) + ts << makeIndent( indent ) << "<separator/>" << endl; + else if ( ::qt_cast<QDesignerAction*>(a) ) + ts << makeIndent( indent ) << "<action name=\"" << a->name() << "\"/>" << endl; + else if ( ::qt_cast<QDesignerActionGroup*>(a) ) + ts << makeIndent( indent ) << "<actiongroup name=\"" << a->name() << "\"/>" << endl; + PopupMenuEditor *s = i->subMenu(); + if ( s && s->count() ) { + QString n = s->name(); + ts << makeIndent( indent ) << "<item text=\"" << entitize( a->menuText() ) + << "\" name=\"" << entitize( n ) + << "\" accel=\"" << entitize( a->accel() ) + << "\">" << endl; + indent++; + savePopupMenu( s, mw, ts, indent ); + indent--; + ts << makeIndent( indent ) << "</item>" << endl; + } + } +} + +void Resource::loadToolBars( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = ( (QMainWindow*)formwindow->mainContainer() ); + QDesignerToolBar *tb = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "toolbar" ) { + Qt::Dock dock = (Qt::Dock)n.attribute( "dock" ).toInt(); + tb = new QDesignerToolBar( mw, dock ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "action" ) { + QAction *a = formwindow->findAction( n2.attribute( "name" ) ); + if ( a ) { + a->addTo( tb ); + tb->addAction( a ); + } + } else if ( n2.tagName() == "separator" ) { + QAction *a = new QSeparatorAction( 0 ); + a->addTo( tb ); + tb->addAction( a ); + } else if ( n2.tagName() == "widget" ) { + QWidget *w = (QWidget*)createObject( n2, tb ); + QDesignerAction *a = new QDesignerAction( w, tb ); + a->addTo( tb ); + tb->addAction( a ); + tb->installEventFilters( w ); + } else if ( n2.tagName() == "property" ) { + setObjectProperty( tb, n2.attribute( "name" ), n2.firstChild().toElement() ); + } + n2 = n2.nextSibling().toElement(); + } + } + n = n.nextSibling().toElement(); + } +} + +void Resource::loadMenuBar( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = (QMainWindow*)formwindow->mainContainer(); + MenuBarEditor *mb = new MenuBarEditor( formwindow, mw ); + MetaDataBase::addEntry( mb ); + while ( !n.isNull() ) { + if ( n.tagName() == "item" ) { + PopupMenuEditor * popup = new PopupMenuEditor( formwindow, mw ); + loadPopupMenu( popup, n ); + popup->setName( n.attribute( "name" ) ); + mb->insertItem( n.attribute( "text" ), popup ); + MetaDataBase::addEntry( popup ); + } else if ( n.tagName() == "property" ) { + setObjectProperty( mb, n.attribute( "name" ), n.firstChild().toElement() ); + } else if ( n.tagName() == "separator" ) { + mb->insertSeparator(); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::loadPopupMenu( PopupMenuEditor *p, const QDomElement &e ) +{ + MetaDataBase::addEntry( p ); + QDomElement n = e.firstChild().toElement(); + QAction *a = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup") { + a = formwindow->findAction( n.attribute( "name" ) ); + if ( a ) + p->insert( a ); + } + if ( n.tagName() == "item" ) { + PopupMenuEditorItem *i = p->at( p->find( a ) ); + if ( i ) { + QString name = n.attribute( "name" ); + formwindow->unify( i, name, TRUE ); + i->setName( name ); + MetaDataBase::addEntry( i ); + loadPopupMenu( i->subMenu(), n ); + } + } else if ( n.tagName() == "separator" ) { + a = new QSeparatorAction( 0 ); + p->insert( a ); + } + n = n.nextSibling().toElement(); + } +} + +bool Resource::saveFormCode( FormFile *formfile, LanguageInterface * /*langIface*/ ) +{ + QString lang = formfile->project()->language(); + if ( formfile->hasTempFileName() || + formfile->code().isEmpty() || + !formfile->hasFormCode() || + !formfile->isModified(FormFile::WFormCode) ) + return TRUE; // There is no code to be saved. + return saveCode( formfile->project()->makeAbsolute(formfile->codeFile()), + formfile->code() ); +} + +void Resource::loadExtraSource( FormFile *formfile, const QString &currFileName, + LanguageInterface *langIface, bool hasFunctions ) +{ + QString lang = "Qt Script"; + if ( MainWindow::self ) + lang = MainWindow::self->currProject()->language(); + LanguageInterface *iface = langIface; + if ( hasFunctions || !iface ) + return; + QValueList<LanguageInterface::Function> functions; + QStringList forwards; + QStringList includesImpl; + QStringList includesDecl; + QStringList vars; + QValueList<LanguageInterface::Connection> connections; + + iface->loadFormCode( formfile->formName(), + currFileName + iface->formCodeExtension(), + functions, + vars, + connections ); + + QFile f( formfile->project()->makeAbsolute( formfile->codeFile() ) ); + QString code; + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + code = ts.read(); + } + formfile->setCode( code ); + + if ( !MainWindow::self || !MainWindow::self->currProject()->isCpp() ) + MetaDataBase::setupConnections( formfile, connections ); + + for ( QValueList<LanguageInterface::Function>::Iterator fit = functions.begin(); + fit != functions.end(); ++fit ) { + + if ( MetaDataBase::hasFunction( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + (*fit).name.latin1() ) ) { + QString access = (*fit).access; + if ( !MainWindow::self || !MainWindow::self->currProject()->isCpp() ) + MetaDataBase::changeFunction( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + (*fit).name, + (*fit).name, + QString::null ); + } else { + QString access = (*fit).access; + if ( access.isEmpty() ) + access = "protected"; + QString type = "function"; + if ( (*fit).returnType == "void" ) + type = "slot"; + MetaDataBase::addFunction( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + (*fit).name.latin1(), "virtual", (*fit).access, + type, lang, (*fit).returnType ); + } + } +} diff --git a/kdevdesigner/designer/resource.h b/kdevdesigner/designer/resource.h new file mode 100644 index 00000000..abf21cc2 --- /dev/null +++ b/kdevdesigner/designer/resource.h @@ -0,0 +1,165 @@ +/********************************************************************** +** 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 RESOURCE_H +#define RESOURCE_H + +#include <qstring.h> +#include <qtextstream.h> +#include <qvariant.h> +#include <qvaluelist.h> +#include <qimage.h> +#include "actiondnd.h" + +#include "metadatabase.h" + +class QWidget; +class QObject; +class QLayout; +class QStyle; +class QPalette; +class FormWindow; +class MainWindow; +class QDomElement; +class QDesignerGridLayout; +class QListViewItem; +class QMainWindow; +struct LanguageInterface; +class FormFile; +class Project; +class PopupMenuEditor; + +class Resource +{ +public: + struct Image { + QImage img; + QString name; + bool operator==( const Image &i ) const { + return ( i.name == name && + i.img == img ); + } + }; + + Resource(); + Resource( MainWindow* mw ); + ~Resource(); + + void setWidget( FormWindow *w ); + QWidget *widget() const; + + bool load( FormFile *ff, Project *defProject = 0 ); + bool load( FormFile *ff, QIODevice*, Project *defProject = 0 ); + QString copy(); + + bool save( const QString& filename, bool formCodeOnly = FALSE); + bool save( QIODevice* ); + void paste( const QString &cb, QWidget *parent ); + + static void saveImageData( const QImage &img, QTextStream &ts, int indent ); + static void loadCustomWidgets( const QDomElement &e, Resource *r ); + static void loadExtraSource( FormFile *formfile, const QString &currFileName, + LanguageInterface *langIface, bool hasFunctions ); + static bool saveFormCode( FormFile *formfile, LanguageInterface *langIface ); + +private: + void saveObject( QObject *obj, QDesignerGridLayout* grid, QTextStream &ts, int indent ); + void saveChildrenOf( QObject* obj, QTextStream &ts, int indent ); + void saveObjectProperties( QObject *w, QTextStream &ts, int indent ); + void saveSetProperty( QObject *w, const QString &name, QVariant::Type t, QTextStream &ts, int indent ); + void saveEnumProperty( QObject *w, const QString &name, QVariant::Type t, QTextStream &ts, int indent ); + void saveProperty( QObject *w, const QString &name, const QVariant &value, QVariant::Type t, QTextStream &ts, int indent ); + void saveProperty( const QVariant &value, QTextStream &ts, int indent ); + void saveItems( QObject *obj, QTextStream &ts, int indent ); + void saveItem( const QStringList &text, const QPtrList<QPixmap> &pixmaps, QTextStream &ts, int indent ); + void saveItem( QListViewItem *i, QTextStream &ts, int indent ); + void saveConnections( QTextStream &ts, int indent ); + void saveCustomWidgets( QTextStream &ts, int indent ); + void saveTabOrder( QTextStream &ts, int indent ); + void saveColorGroup( QTextStream &ts, int indent, const QColorGroup &cg ); + void saveColor( QTextStream &ts, int indent, const QColor &c ); + void saveMetaInfoBefore( QTextStream &ts, int indent ); + void saveMetaInfoAfter( QTextStream &ts, int indent ); + void saveIncludeHints( QTextStream &ts, int indent ); + void savePixmap( const QPixmap &p, QTextStream &ts, int indent, const QString &tagname = "pixmap" ); + void saveActions( const QPtrList<QAction> &actions, QTextStream &ts, int indent ); + void saveChildActions( QAction *a, QTextStream &ts, int indent ); + void saveToolBars( QMainWindow *mw, QTextStream &ts, int indent ); + void saveMenuBar( QMainWindow *mw, QTextStream &ts, int indent ); + void savePopupMenu( PopupMenuEditor *pm, QMainWindow *mw, QTextStream &ts, int indent ); + + QObject *createObject( const QDomElement &e, QWidget *parent, QLayout* layout = 0 ); + QWidget *createSpacer( const QDomElement &e, QWidget *parent, QLayout *layout, Qt::Orientation o ); + void createItem( const QDomElement &e, QWidget *widget, QListViewItem *i = 0 ); + void createColumn( const QDomElement &e, QWidget *widget ); + void setObjectProperty( QObject* widget, const QString &prop, const QDomElement &e); + QString saveInCollection( const QImage &img ); + QString saveInCollection( const QPixmap &pix ) { return saveInCollection( pix.convertToImage() ); } + QImage loadFromCollection( const QString &name ); + void saveImageCollection( QTextStream &ts, int indent ); + void loadImageCollection( const QDomElement &e ); + void loadConnections( const QDomElement &e ); + void loadTabOrder( const QDomElement &e ); + void loadItem( const QDomElement &n, QPixmap &pix, QString &txt, bool &hasPixmap ); + void loadActions( const QDomElement &n ); + void loadChildAction( QObject *parent, const QDomElement &e ); + void loadToolBars( const QDomElement &n ); + void loadMenuBar( const QDomElement &n ); + void loadPopupMenu( PopupMenuEditor *pm, const QDomElement &e ); + QColorGroup loadColorGroup( const QDomElement &e ); + QPixmap loadPixmap( const QDomElement &e, const QString &tagname = "pixmap" ); + +private: + MainWindow *mainwindow; + FormWindow *formwindow; + QWidget* toplevel; + QValueList<Image> images; + bool copying, pasting; + bool mainContainerSet; + QStringList knownNames; + QStringList usedCustomWidgets; + QListViewItem *lastItem; + + QValueList<MetaDataBase::Include> metaIncludes; + QValueList<MetaDataBase::Variable> metaVariables; + QStringList metaForwards; + QStringList metaSignals; + MetaDataBase::MetaInfo metaInfo; + QMap<QString, QString> dbControls; + QMap<QString, QStringList> dbTables; + QMap<QString, QWidget*> widgets; + QString exportMacro; + bool hadGeometry; + QMap<QString, QValueList<MetaDataBase::Connection> > langConnections; + QString currFileName; + LanguageInterface *langIface; + bool hasFunctions; + QStringList includeHints; + + QString uiFileVersion; +}; + +#endif diff --git a/kdevdesigner/designer/richtextfontdialog.ui b/kdevdesigner/designer/richtextfontdialog.ui new file mode 100644 index 00000000..c55343ad --- /dev/null +++ b/kdevdesigner/designer/richtextfontdialog.ui @@ -0,0 +1,347 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>RichTextFontDialog</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>RichTextFontDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>255</width> + <height>158</height> + </rect> + </property> + <property name="caption"> + <string>Font Properties</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QComboBox" row="0" column="1" rowspan="1" colspan="2"> + <item> + <property name="text"> + <string>default</string> + </property> + </item> + <property name="name"> + <cstring>fontCombo</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>&Font:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>fontCombo</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Rel. &size:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>fontSizeCombo</cstring> + </property> + </widget> + <spacer row="2" column="2"> + <property name="name"> + <cstring>Spacer13</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>C&olor:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>colorButton</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1" rowspan="1" colspan="2"> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>-4</string> + </property> + </item> + <item> + <property name="text"> + <string>-3</string> + </property> + </item> + <item> + <property name="text"> + <string>-2</string> + </property> + </item> + <item> + <property name="text"> + <string>-1</string> + </property> + </item> + <item> + <property name="text"> + <string>+1</string> + </property> + </item> + <item> + <property name="text"> + <string>+2</string> + </property> + </item> + <item> + <property name="text"> + <string>+3</string> + </property> + </item> + <item> + <property name="text"> + <string>+4</string> + </property> + </item> + <property name="name"> + <cstring>fontSizeCombo</cstring> + </property> + <property name="editable"> + <bool>true</bool> + </property> + <property name="insertionPolicy"> + <enum>AtTop</enum> + </property> + </widget> + <widget class="QToolButton" row="2" column="1"> + <property name="name"> + <cstring>colorButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </grid> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer14</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="Line" row="2" column="0"> + <property name="name"> + <cstring>Line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>Layout15</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer12</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>colorButton</sender> + <signal>clicked()</signal> + <receiver>RichTextFontDialog</receiver> + <slot>selectColor()</slot> + </connection> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>RichTextFontDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>RichTextFontDialog</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>fontCombo</tabstop> + <tabstop>fontSizeCombo</tabstop> + <tabstop>colorButton</tabstop> + <tabstop>okButton</tabstop> + <tabstop>cancelButton</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">richtextfontdialog.ui.h</include> +</includes> +<variables> + <variable>QString font</variable> + <variable>QColor color</variable> + <variable>QString size</variable> +</variables> +<slots> + <slot>init()</slot> + <slot>selectColor()</slot> + <slot>accept()</slot> + <slot>reject()</slot> + <slot returnType="QString">getSize()</slot> + <slot returnType="QString">getColor()</slot> + <slot returnType="QString">getFont()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/richtextfontdialog.ui.h b/kdevdesigner/designer/richtextfontdialog.ui.h new file mode 100644 index 00000000..8a3dd4c8 --- /dev/null +++ b/kdevdesigner/designer/richtextfontdialog.ui.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ +#include <qcolordialog.h> +#include <qfontdatabase.h> + +void RichTextFontDialog::init() +{ + QFontDatabase *db = new QFontDatabase(); + fontCombo->insertStringList( db->families() ); +} + +void RichTextFontDialog::selectColor() +{ + color = QColorDialog::getColor( "", this ); + if( color.isValid() ) + colorButton->setPaletteBackgroundColor( color ); +} + +void RichTextFontDialog::accept() +{ + size = fontSizeCombo->currentText(); + font = fontCombo->currentText(); + done( Accepted ); +} + +void RichTextFontDialog::reject() +{ + done( Rejected ); +} + +QString RichTextFontDialog::getSize() +{ + return size; +} + +QString RichTextFontDialog::getColor() +{ + return color.name(); +} + +QString RichTextFontDialog::getFont() +{ + return font; +} diff --git a/kdevdesigner/designer/sizehandle.cpp b/kdevdesigner/designer/sizehandle.cpp new file mode 100644 index 00000000..a63a3404 --- /dev/null +++ b/kdevdesigner/designer/sizehandle.cpp @@ -0,0 +1,388 @@ +/********************************************************************** +** 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 <qvariant.h> // HP-UX compiler needs this here + +#include "sizehandle.h" +#include "formwindow.h" +#include "widgetfactory.h" + +#include <qwidget.h> +#include <qapplication.h> +#include <qlabel.h> +#include <klocale.h> + +SizeHandle::SizeHandle( FormWindow *parent, Direction d, WidgetSelection *s ) + : QWidget( parent ) +{ + active = TRUE; + setBackgroundMode( active ? PaletteText : PaletteDark ); + setFixedSize( 6, 6 ); + widget = 0; + dir =d ; + setMouseTracking( FALSE ); + formWindow = parent; + sel = s; + updateCursor(); +} + +void SizeHandle::updateCursor() +{ + if ( !active ) { + setCursor( arrowCursor ); + return; + } + + switch ( dir ) { + case LeftTop: + setCursor( sizeFDiagCursor ); + break; + case Top: + setCursor( sizeVerCursor ); + break; + case RightTop: + setCursor( sizeBDiagCursor ); + break; + case Right: + setCursor( sizeHorCursor ); + break; + case RightBottom: + setCursor( sizeFDiagCursor ); + break; + case Bottom: + setCursor( sizeVerCursor ); + break; + case LeftBottom: + setCursor( sizeBDiagCursor ); + break; + case Left: + setCursor( sizeHorCursor ); + break; + } +} + +void SizeHandle::setActive( bool a ) +{ + active = a; + setBackgroundMode( active ? PaletteText : PaletteDark ); + updateCursor(); +} + +void SizeHandle::setWidget( QWidget *w ) +{ + widget = w; +} + +void SizeHandle::paintEvent( QPaintEvent * ) +{ + if ( ( (FormWindow*)parentWidget() )->currentWidget() != widget ) + return; + QPainter p( this ); + p.setPen( blue ); + p.drawRect( 0, 0, width(), height() ); +} + +void SizeHandle::mousePressEvent( QMouseEvent *e ) +{ + if ( !widget || e->button() != LeftButton || !active ) + return; + oldPressPos = e->pos(); + geom = origGeom = QRect( widget->pos(), widget->size() ); +} + +void SizeHandle::mouseMoveEvent( QMouseEvent *e ) +{ + if ( !widget || ( e->state() & LeftButton ) != LeftButton || !active ) + return; + QPoint rp = mapFromGlobal( e->globalPos() ); + QPoint d = oldPressPos - rp; + oldPressPos = rp; + QPoint checkPos = widget->parentWidget()->mapFromGlobal( e->globalPos() ); + QRect pr = widget->parentWidget()->rect(); + + // ##### move code around a bit to reduce duplicated code here + switch ( dir ) { + case LeftTop: { + if ( checkPos.x() > pr.width() - 2 * width() || checkPos.y() > pr.height() - 2 * height() ) + return; + int w = geom.width() + d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int h = geom.height() + d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + int dx = widget->width() - w; + int dy = widget->height() - h; + trySetGeometry( widget, widget->x() + dx, widget->y() + dy, w, h ); + } break; + case Top: { + if ( checkPos.y() > pr.height() - 2 * height() ) + return; + int h = geom.height() + d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + int dy = widget->height() - h; + trySetGeometry( widget, widget->x(), widget->y() + dy, widget->width(), h ); + } break; + case RightTop: { + if ( checkPos.x() < 2 * width() || checkPos.y() > pr.height() - 2 * height() ) + return; + int h = geom.height() + d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + int dy = widget->height() - h; + int w = geom.width() - d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + trySetGeometry( widget, widget->x(), widget->y() + dy, w, h ); + } break; + case Right: { + if ( checkPos.x() < 2 * width() ) + return; + int w = geom.width() - d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + tryResize( widget, w, widget->height() ); + } break; + case RightBottom: { + if ( checkPos.x() < 2 * width() || checkPos.y() < 2 * height() ) + return; + int w = geom.width() - d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int h = geom.height() - d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + tryResize( widget, w, h ); + } break; + case Bottom: { + if ( checkPos.y() < 2 * height() ) + return; + int h = geom.height() - d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + tryResize( widget, widget->width(), h ); + } break; + case LeftBottom: { + if ( checkPos.x() > pr.width() - 2 * width() || checkPos.y() < 2 * height() ) + return; + int w = geom.width() + d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int dx = widget->width() - w; + int h = geom.height() - d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + trySetGeometry( widget, widget->x() + dx, widget->y(), w, h ); + } break; + case Left: { + if ( checkPos.x() > pr.width() - 2 * width() ) + return; + int w = geom.width() + d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int dx = widget->width() - w; + trySetGeometry( widget, widget->x() + dx, widget->y(), w, widget->height() ); + } break; + } + + QPoint p = pos(); + sel->updateGeometry(); + oldPressPos += ( p - pos() ); + + formWindow->sizePreview()->setText( i18n( "%1/%2" ).arg( widget->width() ).arg( widget->height() ) ); + formWindow->sizePreview()->adjustSize(); + QRect lg( formWindow->mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), + formWindow->sizePreview()->size() ); + formWindow->checkPreviewGeometry( lg ); + formWindow->sizePreview()->setGeometry( lg ); + formWindow->sizePreview()->show(); + formWindow->sizePreview()->raise(); + if ( WidgetFactory::layoutType( widget ) != WidgetFactory::NoLayout ) + formWindow->updateChildSelections( widget ); +} + +void SizeHandle::mouseReleaseEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton || !active ) + return; + + formWindow->sizePreview()->hide(); + if ( geom != widget->geometry() ) + formWindow->commandHistory()->addCommand( new ResizeCommand( i18n( "Resize" ), + formWindow, + widget, origGeom, + widget->geometry() ) ); + formWindow->emitUpdateProperties( widget ); +} + +void SizeHandle::trySetGeometry( QWidget *w, int x, int y, int width, int height ) +{ + int minw = QMAX( w->minimumSizeHint().width(), w->minimumSize().width() ); + minw = QMAX( minw, 2 * formWindow->grid().x() ); + int minh = QMAX( w->minimumSizeHint().height(), w->minimumSize().height() ); + minh = QMAX( minh, 2 * formWindow->grid().y() ); + if ( QMAX( minw, width ) > w->maximumWidth() || + QMAX( minh, height ) > w->maximumHeight() ) + return; + if ( width < minw && x != w->x() ) + x -= minw - width; + if ( height < minh && y != w->y() ) + y -= minh - height; + w->setGeometry( x, y, QMAX( minw, width ), QMAX( minh, height ) ); +} + +void SizeHandle::tryResize( QWidget *w, int width, int height ) +{ + int minw = QMAX( w->minimumSizeHint().width(), w->minimumSize().width() ); + minw = QMAX( minw, 16 ); + int minh = QMAX( w->minimumSizeHint().height(), w->minimumSize().height() ); + minh = QMAX( minh, 16 ); + w->resize( QMAX( minw, width ), QMAX( minh, height ) ); +} + +// ------------------------------------------------------------------------ + +WidgetSelection::WidgetSelection( FormWindow *parent, QPtrDict<WidgetSelection> *selDict ) + : selectionDict( selDict ) +{ + formWindow = parent; + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + handles.insert( i, new SizeHandle( formWindow, (SizeHandle::Direction)i, this ) ); + } + hide(); +} + +void WidgetSelection::setWidget( QWidget *w, bool updateDict ) +{ + if ( !w ) { + hide(); + if ( updateDict ) + selectionDict->remove( wid ); + wid = 0; + return; + } + + wid = w; + bool active = !wid->parentWidget() || WidgetFactory::layoutType( wid->parentWidget() ) == WidgetFactory::NoLayout; + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) { + h->setWidget( wid ); + h->setActive( active ); + } + } + updateGeometry(); + show(); + if ( updateDict ) + selectionDict->insert( w, this ); +} + +bool WidgetSelection::isUsed() const +{ + return wid != 0; +} + +void WidgetSelection::updateGeometry() +{ + if ( !wid || !wid->parentWidget() ) + return; + + QPoint p = wid->parentWidget()->mapToGlobal( wid->pos() ); + p = formWindow->mapFromGlobal( p ); + QRect r( p, wid->size() ); + + int w = 6; + int h = 6; + + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *hndl = handles[ i ]; + if ( !hndl ) + continue; + switch ( i ) { + case SizeHandle::LeftTop: + hndl->move( r.x() - w / 2, r.y() - h / 2 ); + break; + case SizeHandle::Top: + hndl->move( r.x() + r.width() / 2 - w / 2, r.y() - h / 2 ); + break; + case SizeHandle::RightTop: + hndl->move( r.x() + r.width() - w / 2, r.y() - h / 2 ); + break; + case SizeHandle::Right: + hndl->move( r.x() + r.width() - w / 2, r.y() + r.height() / 2 - h / 2 ); + break; + case SizeHandle::RightBottom: + hndl->move( r.x() + r.width() - w / 2, r.y() + r.height() - h / 2 ); + break; + case SizeHandle::Bottom: + hndl->move( r.x() + r.width() / 2 - w / 2, r.y() + r.height() - h / 2 ); + break; + case SizeHandle::LeftBottom: + hndl->move( r.x() - w / 2, r.y() + r.height() - h / 2 ); + break; + case SizeHandle::Left: + hndl->move( r.x() - w / 2, r.y() + r.height() / 2 - h / 2 ); + break; + default: + break; + } + } +} + +void WidgetSelection::hide() +{ + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) + h->hide(); + } +} + +void WidgetSelection::show() +{ + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) { + h->show(); + h->raise(); + } + } +} + +void WidgetSelection::update() +{ + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) + h->update(); + } +} + +QWidget *WidgetSelection::widget() const +{ + return wid; +} diff --git a/kdevdesigner/designer/sizehandle.h b/kdevdesigner/designer/sizehandle.h new file mode 100644 index 00000000..8d53977c --- /dev/null +++ b/kdevdesigner/designer/sizehandle.h @@ -0,0 +1,97 @@ +/********************************************************************** +** 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 SIZEHANDLE_H +#define SIZEHANDLE_H + +#include <qwidget.h> +#include <qintdict.h> +#include <qptrdict.h> + +class QMouseEvent; +class FormWindow; +class WidgetSelection; +class QPaintEvent; + +class SizeHandle : public QWidget +{ + Q_OBJECT + +public: + enum Direction { LeftTop, Top, RightTop, Right, RightBottom, Bottom, LeftBottom, Left }; + + SizeHandle( FormWindow *parent, Direction d, WidgetSelection *s ); + void setWidget( QWidget *w ); + void setActive( bool a ); + void updateCursor(); + + void setEnabled( bool ) {} + +protected: + void paintEvent( QPaintEvent *e ); + void mousePressEvent( QMouseEvent *e ); + void mouseMoveEvent( QMouseEvent *e ); + void mouseReleaseEvent( QMouseEvent *e ); + +private: + void trySetGeometry( QWidget *w, int x, int y, int width, int height ); + void tryResize( QWidget *w, int width, int height ); + +private: + QWidget *widget; + Direction dir; + QPoint oldPressPos; + FormWindow *formWindow; + WidgetSelection *sel; + QRect geom, origGeom; + bool active; + +}; + +class WidgetSelection +{ +public: + WidgetSelection( FormWindow *parent, QPtrDict<WidgetSelection> *selDict ); + + void setWidget( QWidget *w, bool updateDict = TRUE ); + bool isUsed() const; + + void updateGeometry(); + void hide(); + void show(); + void update(); + + QWidget *widget() const; + +protected: + QIntDict<SizeHandle> handles; + QWidget *wid; + FormWindow *formWindow; + QPtrDict<WidgetSelection> *selectionDict; + +}; + +#endif diff --git a/kdevdesigner/designer/sourceeditor.cpp b/kdevdesigner/designer/sourceeditor.cpp new file mode 100644 index 00000000..f3a035b5 --- /dev/null +++ b/kdevdesigner/designer/sourceeditor.cpp @@ -0,0 +1,320 @@ +/********************************************************************** +** 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 <kiconloader.h> + +#include "sourceeditor.h" + +#include "formwindow.h" +#include "metadatabase.h" +#include "project.h" +#include "mainwindow.h" +#include "../interfaces/languageinterface.h" +#include <qregexp.h> +#include "project.h" +#include "sourcefile.h" +#include "hierarchyview.h" +#include <qmessagebox.h> +#include <qtextstream.h> +#include "kdevdesigner_part.h" + +SourceEditor::SourceEditor( QWidget *parent, EditorInterface *iface, LanguageInterface *liface ) + : QVBox( parent, 0, WDestructiveClose ), iFace( iface ), lIface( liface ), obj( 0 ), pro( 0 ) +{ + iFace->addRef(); + lIface->addRef(); + editor = iFace->editor( MainWindow::self->areEditorsReadOnly(), + this, MainWindow::self->designerInterface() ); + iFace->onBreakPointChange( MainWindow::self, SLOT( breakPointsChanged() ) ); + resize( 600, 400 ); + setIcon( SmallIcon( "designer_filenew.png" , KDevDesignerPartFactory::instance()) ); +} + +SourceEditor::~SourceEditor() +{ + saveBreakPoints(); + editor = 0; + if ( formWindow() ) { + formWindow()->formFile()->setCodeEdited( FALSE ); + formWindow()->formFile()->setEditor( 0 ); + } else if ( sourceFile() ) { + sourceFile()->setEditor( 0 ); + if ( MainWindow::self->objectHierarchy()->sourceEditor() == this ) + MainWindow::self->objectHierarchy()->setFormWindow( 0, 0 ); + } + iFace->release(); + lIface->release(); + MainWindow::self->editorClosed( this ); +} + +void SourceEditor::setObject( QObject *o, Project *p ) +{ + if ( sourceFile() ) + sourceFile()->setEditor( 0 ); + if ( formWindow() ) { + formWindow()->formFile()->setCodeEdited( FALSE ); + formWindow()->formFile()->setEditor( 0 ); + } + if ( ::qt_cast<FormWindow*>(o) ) + ( (FormWindow*)o )->formFile()->setCodeEdited( TRUE ); + save(); + bool changed = FALSE; + if ( &(*obj) != o ) { + saveBreakPoints(); + changed = TRUE; + } + obj = o; + pro = p; + if ( formWindow() ) { + if ( formWindow()->isFake() ) + setCaption( formWindow()->project()->objectForFakeForm( formWindow() )->name() ); + else + setCaption( obj->name() ); + } else { + setCaption( sourceFile()->fileName() ); + } + if ( sourceFile() ) + sourceFile()->setEditor( this ); + else if ( formWindow() ) + formWindow()->formFile()->setEditor( this ); + iFace->setText( sourceOfObject( obj, lang, iFace, lIface ) ); + if ( pro && formWindow() ) { + if ( formWindow()->isFake() ) + iFace->setContext( pro->objectForFakeFormFile( formWindow()->formFile() ) ); + else + iFace->setContext( formWindow()->mainContainer() ); + } else { + iFace->setContext( 0 ); + } + if ( changed || sourceFile() ) + iFace->setBreakPoints( MetaDataBase::breakPoints( o ) ); + MainWindow::self->objectHierarchy()->showClasses( this ); +} + +QString SourceEditor::sourceOfObject( QObject *o, const QString &, + EditorInterface *, LanguageInterface * ) +{ + QString txt; + if ( !o ) + return txt; + if ( ::qt_cast<FormWindow*>(o) ) + txt = ( (FormWindow*)o )->formFile()->code(); + else if ( ::qt_cast<SourceFile*>(o) ) + txt = ( (SourceFile*)o )->text(); + return txt; +} + +void SourceEditor::setFunction( const QString &func, const QString &clss ) +{ + iFace->scrollTo( lIface->createFunctionStart( obj->name(), func, "", "" ), clss ); +} + +void SourceEditor::setClass( const QString &clss ) +{ + iFace->scrollTo( clss, QString::null ); +} + +void SourceEditor::closeEvent( QCloseEvent *e ) +{ + e->accept(); + if ( !obj ) + return; + if ( formWindow() ) { + save(); + formWindow()->formFile()->cm = formWindow()->formFile()->isModified(); + } else { + if ( !sourceFile()->closeEvent() ) + e->ignore(); + } +} + +void SourceEditor::save() +{ + if ( !obj ) + return; + if ( formWindow() ) + formWindow()->formFile()->syncCode(); + else if ( sourceFile() && sourceFile()->editor() ) + sourceFile()->setText( iFace->text() ); +} + +QString SourceEditor::language() const +{ + return lang; +} + +void SourceEditor::setLanguage( const QString &l ) +{ + lang = l; +} + +void SourceEditor::editCut() +{ + iFace->cut(); +} + +void SourceEditor::editCopy() +{ + iFace->copy(); +} + +void SourceEditor::editPaste() +{ + iFace->paste(); +} + +bool SourceEditor::editIsUndoAvailable() +{ + return iFace->isUndoAvailable(); +} + +bool SourceEditor::editIsRedoAvailable() +{ + return iFace->isRedoAvailable(); +} + +void SourceEditor::editUndo() +{ + iFace->undo(); +} + +void SourceEditor::editRedo() +{ + iFace->redo(); +} + +void SourceEditor::editSelectAll() +{ + iFace->selectAll(); +} + +void SourceEditor::configChanged() +{ + iFace->readSettings(); +} + +void SourceEditor::setModified( bool b ) +{ + iFace->setModified( b ); +} + +void SourceEditor::refresh( bool allowSave ) +{ + if ( allowSave ) + save(); + bool oldMod = iFace->isModified(); + iFace->setText( sourceOfObject( obj, lang, iFace, lIface ) ); + iFace->setModified( oldMod ); +} + +void SourceEditor::resetContext() +{ + if ( pro && formWindow() ) { + if ( formWindow()->isFake() ) + iFace->setContext( pro->objectForFakeFormFile( formWindow()->formFile() ) ); + else + iFace->setContext( formWindow()->mainContainer() ); + } else { + iFace->setContext( 0 ); + } +} + +void SourceEditor::setFocus() +{ + if ( formWindow() ) + formWindow()->formFile()->setCodeEdited( TRUE ); + if ( editor ) + editor->setFocus(); +} + +int SourceEditor::numLines() const +{ + return iFace->numLines(); +} + +void SourceEditor::saveBreakPoints() +{ + if ( !obj ) + return; + QValueList<uint> l; + iFace->breakPoints( l ); + MetaDataBase::setBreakPoints( obj, l ); +} + +void SourceEditor::clearStep() +{ + iFace->clearStep(); +} + +void SourceEditor::clearStackFrame() +{ + iFace->clearStackFrame(); +} + +void SourceEditor::resetBreakPoints() +{ + iFace->setBreakPoints( MetaDataBase::breakPoints( obj ) ); +} + +QString SourceEditor::text() const +{ + return iFace->text(); +} + +bool SourceEditor::isModified() const +{ + return iFace->isModified(); +} + +void SourceEditor::checkTimeStamp() +{ + if ( formWindow() ) + formWindow()->formFile()->checkTimeStamp(); + else if ( sourceFile() ) + sourceFile()->checkTimeStamp(); +} + +bool SourceEditor::saveAs() +{ + if ( formWindow() ) + return formWindow()->formFile()->saveAs(); + else if ( sourceFile() ) + return sourceFile()->saveAs(); + return FALSE; +} + +SourceFile *SourceEditor::sourceFile() const +{ + if ( !::qt_cast<SourceFile*>((QObject *)obj) ) + return 0; + return (SourceFile*)(QObject*)obj; +} + +FormWindow *SourceEditor::formWindow() const +{ + if ( !::qt_cast<FormWindow*>((QObject *)obj) ) + return 0; + return (FormWindow*)(QObject*)obj; +} diff --git a/kdevdesigner/designer/sourceeditor.h b/kdevdesigner/designer/sourceeditor.h new file mode 100644 index 00000000..a554b80c --- /dev/null +++ b/kdevdesigner/designer/sourceeditor.h @@ -0,0 +1,106 @@ +/********************************************************************** +** 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 SOURCEEDITOR_H +#define SOURCEEDITOR_H + +#include "../interfaces/editorinterface.h" +#include <qvbox.h> +#include <qguardedptr.h> + +class FormWindow; +class QCloseEvent; +struct LanguageInterface; +class Project; +class SourceFile; + +class SourceEditor : public QVBox +{ + Q_OBJECT + +public: + SourceEditor( QWidget *parent, EditorInterface *iface, LanguageInterface *liface ); + ~SourceEditor(); + + void setObject( QObject *fw, Project *p ); + QObject *object() const { return obj; } + Project *project() const { return pro; } + void setFunction( const QString &func, const QString &clss = QString::null ); + void setClass( const QString &clss ); + void save(); + bool saveAs(); + void setModified( bool b ); + bool isModified() const; + + static QString sourceOfObject( QObject *fw, const QString &lang, EditorInterface *iface, LanguageInterface *lIface ); + + QString language() const; + void setLanguage( const QString &l ); + + void editCut(); + void editCopy(); + void editPaste(); + bool editIsUndoAvailable(); + bool editIsRedoAvailable(); + void editUndo(); + void editRedo(); + void editSelectAll(); + + void configChanged(); + void refresh( bool allowSave ); + void resetContext(); + + EditorInterface *editorInterface() const { return iFace; } + + void setFocus(); + int numLines() const; + void saveBreakPoints(); + void clearStep(); + void clearStackFrame(); + void resetBreakPoints(); + + QString text() const; + + void checkTimeStamp(); + + SourceFile *sourceFile() const; + FormWindow *formWindow() const; + +protected: + void closeEvent( QCloseEvent *e ); + + +private: + EditorInterface *iFace; + LanguageInterface *lIface; + QGuardedPtr<QObject> obj; + Project *pro; + QString lang; + QGuardedPtr<QWidget> editor; + +}; + +#endif diff --git a/kdevdesigner/designer/sourcefile.cpp b/kdevdesigner/designer/sourcefile.cpp new file mode 100644 index 00000000..327dc58c --- /dev/null +++ b/kdevdesigner/designer/sourcefile.cpp @@ -0,0 +1,298 @@ +/********************************************************************** +** 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 "sourcefile.h" +#include <qfile.h> +#include <qtextstream.h> +#include "designerappiface.h" +#include "sourceeditor.h" +#include "metadatabase.h" +#include "../interfaces/languageinterface.h" +#include <qfiledialog.h> +#include <qmessagebox.h> +#include "mainwindow.h" +#include "workspace.h" +#include <stdlib.h> + +#include <kfiledialog.h> +#include <klocale.h> + +SourceFile::SourceFile( const QString &fn, bool temp, Project *p ) + : filename( fn ), ed( 0 ), fileNameTemp( temp ), + timeStamp( 0, p->makeAbsolute( fn ) ), pro( p ), pkg( FALSE ) + , accepted( TRUE ) +{ + iface = 0; + + if ( !temp ) + accepted = checkFileName( TRUE ); + + if (accepted) { + load(); + pro->addSourceFile( this ); + MetaDataBase::addEntry( this ); + } + +} + +SourceFile::~SourceFile() +{ + if (iface) + delete iface; +} + +QString SourceFile::text() const +{ + return txt; +} + +void SourceFile::setText( const QString &s ) +{ + txt = s; +} + +bool SourceFile::save( bool ignoreModified ) +{ + if ( fileNameTemp ) + return saveAs(); + if ( !ignoreModified && !isModified() ) + return TRUE; + if ( ed ) + ed->save(); + + if ( QFile::exists( pro->makeAbsolute( filename ) ) ) { + QString fn( pro->makeAbsolute( filename ) ); +#if defined(Q_OS_WIN32) + fn += ".bak"; +#else + fn += "~"; +#endif + QFile f( pro->makeAbsolute( filename ) ); + if ( f.open( IO_ReadOnly ) ) { + QFile f2( fn ); + if ( f2.open( IO_WriteOnly | IO_Translate ) ) { + QCString data( f.size() ); + f.readBlock( data.data(), f.size() ); + f2.writeBlock( data ); + } + } + } + + QFile f( pro->makeAbsolute( filename ) ); + if ( !f.open( IO_WriteOnly | IO_Translate ) ) + return saveAs(); + + QTextStream ts( &f ); + ts << txt; + timeStamp.update(); + setModified( FALSE ); + return TRUE; +} + +bool SourceFile::saveAs( bool ignoreModified ) +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + QString filter; + if ( iface ) + filter = iface->fileFilterList().join("\n"); + + QString old = filename; + QString initFn = pro->makeAbsolute( filename ); + if ( ignoreModified ) { + QString dir = QStringList::split( ':', project()->iFace()->customSetting( "QTSCRIPT_PACKAGES" ) ).first(); + initFn = QFileInfo( initFn ).fileName(); + initFn.prepend( dir + "/" ); + } + QString fn = KFileDialog::getSaveFileName( initFn, filter ); + if ( fn.isEmpty() ) + return FALSE; + fileNameTemp = FALSE; + filename = pro->makeRelative( fn ); + if ( !checkFileName( TRUE ) ) { + filename = old; + return FALSE; + } + pro->setModified( TRUE ); + timeStamp.setFileName( pro->makeAbsolute( filename ) ); + if ( ed ) + ed->setCaption( i18n( "Edit %1" ).arg( filename ) ); + setModified( TRUE ); + if ( pro->isDummy() ) { + QObject *o = ed->parent(); + while ( o && !o->isA( "MainWindow" ) ) + o = o->parent(); + if ( o ) + ((MainWindow *)o)->addRecentlyOpenedFile( fn ); + } + return save( ignoreModified ); +} + +bool SourceFile::load() +{ + QFile f( pro->makeAbsolute( filename ) ); + if ( !f.open( IO_ReadOnly ) ) + return FALSE; + QTextStream ts( &f ); + txt = ts.read(); + timeStamp.update(); + return TRUE; +} + +DesignerSourceFile *SourceFile::iFace() +{ + if ( !iface ) + iface = new DesignerSourceFileImpl( this ); + return iface; +} + +void SourceFile::setEditor( SourceEditor *e ) +{ + ed = e; +} + +bool SourceFile::isModified() const +{ + if ( !ed ) + return FALSE; + return ed->isModified(); +} + +static QMap<QString, int> *extensionCounter; +QString SourceFile::createUnnamedFileName( const QString &extension ) +{ + if ( !extensionCounter ) + extensionCounter = new QMap<QString, int>; + int count = -1; + QMap<QString, int>::Iterator it; + if ( ( it = extensionCounter->find( extension ) ) != extensionCounter->end() ) { + count = *it; + ++count; + extensionCounter->replace( extension, count ); + } else { + count = 1; + extensionCounter->insert( extension, count ); + } + + return "unnamed" + QString::number( count ) + "." + extension; +} + +void SourceFile::setModified( bool m ) +{ + if ( !ed ) + return; + ed->setModified( m ); +} + +bool SourceFile::closeEvent() +{ + if ( !isModified() && fileNameTemp ) { + pro->removeSourceFile( this ); + return TRUE; + } + + if ( !isModified() ) + return TRUE; + + if ( ed ) + ed->save(); + + switch ( QMessageBox::warning( MainWindow::self, i18n( "Save Code" ), + i18n( "Save changes to '%1'?" ).arg( filename ), + i18n( "&Yes" ), i18n( "&No" ), i18n( "&Cancel" ), 0, 2 ) ) { + case 0: // save + if ( !save() ) + return FALSE; + break; + case 1: // don't save + load(); + if ( ed ) + ed->editorInterface()->setText( txt ); + if ( fileNameTemp ) { + pro->removeSourceFile( this ); + return TRUE; + } + if ( MainWindow::self ) + MainWindow::self->workspace()->update(); + break; + case 2: // cancel + return FALSE; + default: + break; + } + setModified( FALSE ); + return TRUE; +} + +bool SourceFile::close() +{ + if ( !ed ) + return TRUE; + return ed->close(); +} + +Project *SourceFile::project() const +{ + return pro; +} + +void SourceFile::checkTimeStamp() +{ + if ( timeStamp.isUpToDate() ) + return; + timeStamp.update(); + if ( QMessageBox::information( MainWindow::self, i18n( "Qt Designer" ), + i18n( "File '%1' has been changed outside Qt Designer.\n" + "Do you want to reload it?" ).arg( filename ), + i18n( "&Yes" ), i18n( "&No" ) ) == 0 ) { + load(); + if ( ed ) + ed->editorInterface()->setText( txt ); + } +} + +bool SourceFile::checkFileName( bool allowBreak ) +{ + SourceFile *sf = pro->findSourceFile( filename, this ); + if ( sf ) + QMessageBox::warning( MainWindow::self, i18n( "Invalid Filename" ), + i18n( "The project already contains a source file with \n" + "filename '%1'. Please choose a new filename." ).arg( filename ) ); + while ( sf ) { + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + QString filter; + if ( iface ) + filter = iface->fileFilterList().join("\n"); + QString fn; + while ( fn.isEmpty() ) { + fn = KFileDialog::getSaveFileName( pro->makeAbsolute( filename ), filter ); + if ( allowBreak && fn.isEmpty() ) + return FALSE; + } + filename = pro->makeRelative( fn ); + sf = pro->findSourceFile( filename, this ); + } + return TRUE; +} diff --git a/kdevdesigner/designer/sourcefile.h b/kdevdesigner/designer/sourcefile.h new file mode 100644 index 00000000..438d9b4c --- /dev/null +++ b/kdevdesigner/designer/sourcefile.h @@ -0,0 +1,86 @@ +/********************************************************************** +** 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 SOURCEFILE_H +#define SOURCEFILE_H + +#include <qobject.h> +#include "timestamp.h" + +struct DesignerSourceFile; +class SourceEditor; +class Project; + +class SourceFile : public QObject +{ + Q_OBJECT + +public: + SourceFile( const QString &fn, bool temp, Project *p ); + ~SourceFile(); + + void setText( const QString &s ); + void setModified( bool m ); + + bool save( bool ignoreModified = FALSE ); + bool saveAs( bool ignoreModified = FALSE ); + bool load(); + bool close(); + bool closeEvent(); + Project *project() const; + + QString text() const; + QString fileName() const { return filename; } + bool isModified() const; + + void checkTimeStamp(); + + DesignerSourceFile *iFace(); + + void setEditor( SourceEditor *e ); + SourceEditor *editor() const { return ed; } + + static QString createUnnamedFileName( const QString &extension ); + + bool isAccepted() const { return accepted; } + +private: + bool checkFileName( bool allowBreak ); + +private: + QString filename; + QString txt; + DesignerSourceFile *iface; + SourceEditor *ed; + bool fileNameTemp; + TimeStamp timeStamp; + Project *pro; + bool pkg; + bool accepted; + +}; + +#endif diff --git a/kdevdesigner/designer/startdialog.ui b/kdevdesigner/designer/startdialog.ui new file mode 100644 index 00000000..1301a20a --- /dev/null +++ b/kdevdesigner/designer/startdialog.ui @@ -0,0 +1,324 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>StartDialogBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>StartDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>576</width> + <height>420</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Qt Designer - New/Open</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget8</cstring> + </property> + <attribute name="title"> + <string>&New File/Project</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QIconView" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>templateView</cstring> + </property> + <property name="gridX"> + <number>120</number> + </property> + <property name="resizeMode"> + <enum>Adjust</enum> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>&Open File/Project</string> + </attribute> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + </hbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget9</cstring> + </property> + <attribute name="title"> + <string>&Recently Opened</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QIconView" row="0" column="0"> + <property name="name"> + <cstring>recentView</cstring> + </property> + <property name="focusPolicy"> + <enum>WheelFocus</enum> + </property> + <property name="gridX"> + <number>120</number> + </property> + <property name="resizeMode"> + <enum>Adjust</enum> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>fileInfoLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>2</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </grid> + </widget> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkShowInFuture</cstring> + </property> + <property name="text"> + <string>&Do not show this dialog in the future</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="accel"> + <number>4144</number> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <number>0</number> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <number>0</number> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>StartDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>StartDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>templateView</sender> + <signal>doubleClicked(QIconViewItem*)</signal> + <receiver>StartDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>templateView</sender> + <signal>returnPressed(QIconViewItem*)</signal> + <receiver>StartDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>recentView</sender> + <signal>doubleClicked(QIconViewItem*)</signal> + <receiver>StartDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>recentView</sender> + <signal>onItem(QIconViewItem*)</signal> + <receiver>StartDialogBase</receiver> + <slot>recentItemChanged(QIconViewItem*)</slot> + </connection> + <connection> + <sender>recentView</sender> + <signal>onViewport()</signal> + <receiver>StartDialogBase</receiver> + <slot>clearFileInfo()</slot> + </connection> + <connection> + <sender>recentView</sender> + <signal>returnPressed(QIconViewItem*)</signal> + <receiver>StartDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>recentView</sender> + <signal>selectionChanged(QIconViewItem*)</signal> + <receiver>StartDialogBase</receiver> + <slot>recentItemChanged(QIconViewItem*)</slot> + </connection> +</connections> +<slots> + <slot>recentItemChanged( QIconViewItem * )</slot> + <slot>clearFileInfo()</slot> + <slot>accept()</slot> + <slot>reject()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/startdialogimpl.cpp b/kdevdesigner/designer/startdialogimpl.cpp new file mode 100644 index 00000000..e408e8a5 --- /dev/null +++ b/kdevdesigner/designer/startdialogimpl.cpp @@ -0,0 +1,182 @@ +#include <kiconloader.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qptrlist.h> +#include <qiconview.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qfiledialog.h> +#include <qtabwidget.h> +#include <qpoint.h> +#include <qobjectlist.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qfileinfo.h> +#include <qmap.h> +#include <qdatetime.h> +#include <qapplication.h> +#include <qcheckbox.h> +#include <qurl.h> + +#include "kdevdesigner_part.h" + +#include "mainwindow.h" +#include "startdialogimpl.h" +#include "designerapp.h" + +#include <klocale.h> + +FileDialog::FileDialog( const QString &dir, QWidget *parent ) + : QFileDialog( dir, QString::null, parent ) +{ +} + +void FileDialog::accept() +{ + emit fileSelected(); +} + + +StartDialog::StartDialog( QWidget *parent, const QString &templatePath ) + : StartDialogBase( parent, 0 ) +{ + newForm = new NewForm( templateView, templatePath ); + recentFiles.clear(); + initFileOpen(); + showInFuture = TRUE; + + connect( buttonHelp, SIGNAL( clicked() ), + MainWindow::self, SLOT( showDialogHelp() ) ); + connect( recentView, SIGNAL( doubleClicked(QIconViewItem*) ), + this, SLOT( accept() ) ); + connect( recentView, SIGNAL( returnPressed(QIconViewItem*) ), + this, SLOT( accept() ) ); + connect( fd, SIGNAL( fileSelected() ), this, SLOT( accept() ) ); +} + +void StartDialog::accept() +{ + hide(); + showInFuture = !checkShowInFuture->isChecked(); // means don't show it anymore + + int tabindex = tabWidget->currentPageIndex(); + QString filename; + if( !tabindex ) { + if ( !templateView->currentItem() ) + return; + Project *pro = MainWindow::self->findProject( i18n( "<No Project>" ) ); + if ( !pro ) + return; + MainWindow::self->setCurrentProject( pro ); + ( (NewItem*)templateView->currentItem() )->insert( pro ); + } else if ( tabindex == 1 ) { + filename = fd->selectedFile(); + } else if ( tabindex == 2 ) { + filename = recentFiles[recentView->currentItem()->index()]; + } + if ( tabindex ) { + if ( !filename.isEmpty() ) { + QFileInfo fi( filename ); + if ( fi.extension() == "pro" ) + MainWindow::self->openProject( filename ); + else + MainWindow::self->fileOpen( "", "", filename ); + } + } + + done( Accepted ); +} + +void StartDialog::reject() +{ + done( Rejected ); +} + +void StartDialog::recentItemChanged( QIconViewItem *item ) +{ + QString msg( recentFiles[item->index()] ); + QFileInfo f( recentFiles[item->index()] ); + uint s = f.size(); + QString unit( "B" ); + if( s > 1024 ) { + s /= 1024; + unit = "KB"; + } + if ( s > 1024 ) { + s /= 1024; + unit = "MB"; + } + QDateTime dt( f.lastModified() ); + QString date( dt.toString( "MMMM dd hh:mm" )); + msg = QString( "%1 (%2 %3) %4" ).arg(msg).arg(s).arg(unit).arg(date); + fileInfoLabel->setText( msg ); +} + +void StartDialog::clearFileInfo() +{ + fileInfoLabel->clear(); +} + +void StartDialog::setRecentlyFiles( QStringList &files ) +{ + insertRecentItems( files, FALSE ); +} + +void StartDialog::setRecentlyProjects( QStringList &projects ) +{ + insertRecentItems( projects, TRUE ); +} + +void StartDialog::insertRecentItems( QStringList &files, bool isProject ) +{ + QString iconName = "designer_newform.png"; + if ( isProject ) + iconName = "designer_project.png"; + QIconViewItem *item; + QStringList::iterator it = files.begin(); + for( ; it != files.end(); ++it ) { + QFileInfo fi( *it ); + item = new QIconViewItem( recentView, fi.fileName() ); + recentFiles[recentView->index( item )] = *it; + item->setPixmap( BarIcon( iconName, KDevDesignerPartFactory::instance() ) ); + item->setDragEnabled( FALSE ); + } +} + +void StartDialog::initFileOpen() +{ + QString encode = QDir::currentDirPath(); + QUrl::encode( encode ); + fd = new FileDialog( encode, this ); + QPoint point( 0, 0 ); + fd->reparent( tab, point ); + + QObjectList *l = fd->queryList( "QPushButton" ); + QObjectListIt it( *l ); + QObject *obj; + while ( (obj = it.current()) != 0 ) { + ++it; + ((QPushButton*)obj)->hide(); + } + delete l; + + fd->setSizeGripEnabled ( FALSE ); + tabLayout->addWidget( fd ); + + QPluginManager<ImportFilterInterface> manager( IID_ImportFilter, QApplication::libraryPaths(), + MainWindow::self->pluginDirectory() ); + QStringList filterlist; + filterlist << i18n( "Designer Files (*.ui *.pro)" ); + filterlist << i18n( "Qt User-Interface Files (*.ui)" ); + filterlist << i18n( "QMAKE Project Files (*.pro)" ); + + QStringList list = manager.featureList(); + for ( QStringList::Iterator it2 = list.begin(); it2 != list.end(); ++it2 ) + filterlist << *it2; + + filterlist << i18n( "All Files (*)" ); + QString filters = filterlist.join( ";;" ); + fd->setFilters( filters ); + + fd->show(); +} diff --git a/kdevdesigner/designer/startdialogimpl.h b/kdevdesigner/designer/startdialogimpl.h new file mode 100644 index 00000000..b29b5bf1 --- /dev/null +++ b/kdevdesigner/designer/startdialogimpl.h @@ -0,0 +1,80 @@ +/********************************************************************** +** Copyright (C) 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. +** +**********************************************************************/ + +#ifndef STARTDIALOGIMPL_H +#define STARTDIALOGIMPL_H + +#include <qiconview.h> +#include <qlistview.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qfiledialog.h> +#include <qmap.h> + +#include "newformimpl.h" +#include "startdialog.h" + +class FileDialog : public QFileDialog +{ + Q_OBJECT + +public: + FileDialog( const QString &dir, QWidget *parent ); + +protected slots: + void accept(); + +signals: + void fileSelected(); +}; + + +class StartDialog : public StartDialogBase +{ + Q_OBJECT + +public: + StartDialog( QWidget *parent, const QString &templatePath ); + void setRecentlyFiles( QStringList& ); + void setRecentlyProjects( QStringList& ); + bool showDialogInFuture() const { return showInFuture; } + +protected slots: + void recentItemChanged( QIconViewItem *item ); + void clearFileInfo(); + void accept(); + void reject(); + +private: + void initFileOpen(); + void insertRecentItems( QStringList &files, bool isProject ); + NewForm *newForm; + FileDialog *fd; + QMap<int, QString> recentFiles; + bool showInFuture; +}; + +#endif diff --git a/kdevdesigner/designer/styledbutton.cpp b/kdevdesigner/designer/styledbutton.cpp new file mode 100644 index 00000000..41389684 --- /dev/null +++ b/kdevdesigner/designer/styledbutton.cpp @@ -0,0 +1,295 @@ +/********************************************************************** +** 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 <qvariant.h> // HP-UX compiler needs this here +#include "styledbutton.h" +#include "formwindow.h" +#include "pixmapchooser.h" +#include <qcolordialog.h> +#include <qpalette.h> +#include <qlabel.h> +#include <qpainter.h> +#include <qimage.h> +#include <qpixmap.h> +#include <qapplication.h> +#include <qdragobject.h> +#include <qstyle.h> + +StyledButton::StyledButton(QWidget* parent, const char* name) + : QButton( parent, name ), pix( 0 ), spix( 0 ), s( 0 ), formWindow( 0 ), mousePressed( FALSE ) +{ + setMinimumSize( minimumSizeHint() ); + setAcceptDrops( TRUE ); + + connect( this, SIGNAL(clicked()), SLOT(onEditor())); + + setEditor( ColorEditor ); +} + +StyledButton::StyledButton( const QBrush& b, QWidget* parent, const char* name, WFlags f ) + : QButton( parent, name, f ), spix( 0 ), s( 0 ), formWindow( 0 ) +{ + col = b.color(); + pix = b.pixmap(); + setMinimumSize( minimumSizeHint() ); +} + +StyledButton::~StyledButton() +{ +} + +void StyledButton::setEditor( EditorType e ) +{ + if ( edit == e ) + return; + + edit = e; + update(); +} + +StyledButton::EditorType StyledButton::editor() const +{ + return edit; +} + +void StyledButton::setColor( const QColor& c ) +{ + col = c; + update(); +} + +void StyledButton::setPixmap( const QPixmap & pm ) +{ + if ( !pm.isNull() ) { + delete pix; + pix = new QPixmap( pm ); + } else { + delete pix; + pix = 0; + } + scalePixmap(); +} + +QColor StyledButton::color() const +{ + return col; +} + +QPixmap* StyledButton::pixmap() const +{ + return pix; +} + +bool StyledButton::scale() const +{ + return s; +} + +void StyledButton::setScale( bool on ) +{ + if ( s == on ) + return; + + s = on; + scalePixmap(); +} + +QSize StyledButton::sizeHint() const +{ + return QSize( 50, 25 ); +} + +QSize StyledButton::minimumSizeHint() const +{ + return QSize( 50, 25 ); +} + +void StyledButton::scalePixmap() +{ + delete spix; + + if ( pix ) { + spix = new QPixmap( 6*width()/8, 6*height()/8 ); + QImage img = pix->convertToImage(); + + spix->convertFromImage( s? img.smoothScale( 6*width()/8, 6*height()/8 ) : img ); + } else { + spix = 0; + } + + update(); +} + +void StyledButton::resizeEvent( QResizeEvent* e ) +{ + scalePixmap(); + QButton::resizeEvent( e ); +} + +void StyledButton::drawButton( QPainter *paint ) +{ + style().drawPrimitive(QStyle::PE_ButtonBevel, paint, rect(), colorGroup(), + isDown() ? QStyle::Style_Sunken : QStyle::Style_Raised); + drawButtonLabel(paint); + + if (hasFocus()) + style().drawPrimitive(QStyle::PE_FocusRect, paint, + style().subRect(QStyle::SR_PushButtonFocusRect, this), + colorGroup(), QStyle::Style_Default); +} + +void StyledButton::drawButtonLabel( QPainter *paint ) +{ + QColor pen = isEnabled() ? + hasFocus() ? palette().active().buttonText() : palette().inactive().buttonText() + : palette().disabled().buttonText(); + paint->setPen( pen ); + + if(!isEnabled()) { + paint->setBrush( QBrush( colorGroup().button() ) ); + } + else if ( edit == PixmapEditor && spix ) { + paint->setBrush( QBrush( col, *spix ) ); + paint->setBrushOrigin( width()/8, height()/8 ); + } else + paint->setBrush( QBrush( col ) ); + + paint->drawRect( width()/8, height()/8, 6*width()/8, 6*height()/8 ); +} + +void StyledButton::onEditor() +{ + switch (edit) { + case ColorEditor: { + QColor c = QColorDialog::getColor( palette().active().background(), this ); + if ( c.isValid() ) { + setColor( c ); + emit changed(); + } + } break; + case PixmapEditor: { + QPixmap p; + if ( pixmap() ) + p = qChoosePixmap( this, formWindow, *pixmap() ); + else + p = qChoosePixmap( this, formWindow, QPixmap() ); + if ( !p.isNull() ) { + setPixmap( p ); + emit changed(); + } + } break; + default: + break; + } +} + +void StyledButton::mousePressEvent(QMouseEvent* e) +{ + QButton::mousePressEvent(e); + mousePressed = TRUE; + pressPos = e->pos(); +} + +void StyledButton::mouseMoveEvent(QMouseEvent* e) +{ + QButton::mouseMoveEvent( e ); +#ifndef QT_NO_DRAGANDDROP + if ( !mousePressed ) + return; + if ( ( pressPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() ) { + if ( edit == ColorEditor ) { + QColorDrag *drg = new QColorDrag( col, this ); + QPixmap pix( 25, 25 ); + pix.fill( col ); + QPainter p( &pix ); + p.drawRect( 0, 0, pix.width(), pix.height() ); + p.end(); + drg->setPixmap( pix ); + mousePressed = FALSE; + drg->dragCopy(); + } + else if ( edit == PixmapEditor && pix && !pix->isNull() ) { + QImage img = pix->convertToImage(); + QImageDrag *drg = new QImageDrag( img, this ); + if(spix) + drg->setPixmap( *spix ); + mousePressed = FALSE; + drg->dragCopy(); + } + } +#endif +} + +#ifndef QT_NO_DRAGANDDROP +void StyledButton::dragEnterEvent( QDragEnterEvent *e ) +{ + setFocus(); + if ( edit == ColorEditor && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( edit == PixmapEditor && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void StyledButton::dragLeaveEvent( QDragLeaveEvent * ) +{ + if ( hasFocus() ) + parentWidget()->setFocus(); +} + +void StyledButton::dragMoveEvent( QDragMoveEvent *e ) +{ + if ( edit == ColorEditor && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( edit == PixmapEditor && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void StyledButton::dropEvent( QDropEvent *e ) +{ + if ( edit == ColorEditor && QColorDrag::canDecode( e ) ) { + QColor color; + QColorDrag::decode( e, color ); + setColor(color); + emit changed(); + e->accept(); + } + else if ( edit == PixmapEditor && QImageDrag::canDecode( e ) ) { + QImage img; + QImageDrag::decode( e, img ); + QPixmap pm; + pm.convertFromImage(img); + setPixmap(pm); + emit changed(); + e->accept(); + } else { + e->ignore(); + } +} +#endif // QT_NO_DRAGANDDROP diff --git a/kdevdesigner/designer/styledbutton.h b/kdevdesigner/designer/styledbutton.h new file mode 100644 index 00000000..882090c7 --- /dev/null +++ b/kdevdesigner/designer/styledbutton.h @@ -0,0 +1,103 @@ +/********************************************************************** +** 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 STYLEDBUTTON_H +#define STYLEDBUTTON_H + +#include <qbutton.h> +#include <qpixmap.h> + +class QColor; +class QBrush; +class FormWindow; + +class StyledButton : public QButton +{ + Q_OBJECT + + Q_PROPERTY( QColor color READ color WRITE setColor ) + Q_PROPERTY( QPixmap pixmap READ pixmap WRITE setPixmap ) + Q_PROPERTY( EditorType editor READ editor WRITE setEditor ) + Q_PROPERTY( bool scale READ scale WRITE setScale ) + + Q_ENUMS( EditorType ) + +public: + enum EditorType { ColorEditor, PixmapEditor }; + + StyledButton( QWidget* parent = 0, const char* name = 0 ); + StyledButton( const QBrush& b, QWidget* parent = 0, const char* name = 0, WFlags f = 0 ); + ~StyledButton(); + + void setEditor( EditorType ); + EditorType editor() const; + + void setColor( const QColor& ); + void setPixmap( const QPixmap& ); + + QPixmap* pixmap() const; + QColor color() const; + + void setScale( bool ); + bool scale() const; + + QSize sizeHint() const; + QSize minimumSizeHint() const; + + void setFormWindow( FormWindow *fw ) { formWindow = fw; } + +public slots: + virtual void onEditor(); + +signals: + void changed(); + +protected: + void mousePressEvent(QMouseEvent*); + void mouseMoveEvent(QMouseEvent*); +#ifndef QT_NO_DRAGANDDROP + void dragEnterEvent ( QDragEnterEvent * ); + void dragMoveEvent ( QDragMoveEvent * ); + void dragLeaveEvent ( QDragLeaveEvent * ); + void dropEvent ( QDropEvent * ); +#endif // QT_NO_DRAGANDDROP + void drawButton( QPainter* ); + void drawButtonLabel( QPainter* ); + void resizeEvent( QResizeEvent* ); + void scalePixmap(); + +private: + QPixmap* pix; + QPixmap* spix; // the pixmap scaled down to fit into the button + QColor col; + EditorType edit; + bool s; + FormWindow *formWindow; + QPoint pressPos; + bool mousePressed; +}; + +#endif //STYLEDBUTTON_H diff --git a/kdevdesigner/designer/syntaxhighlighter_html.cpp b/kdevdesigner/designer/syntaxhighlighter_html.cpp new file mode 100644 index 00000000..cd0c2760 --- /dev/null +++ b/kdevdesigner/designer/syntaxhighlighter_html.cpp @@ -0,0 +1,160 @@ +/********************************************************************** +** +** 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 "syntaxhighlighter_html.h" +#include "qstring.h" +#include "qmap.h" +#include "qapplication.h" + + +SyntaxHighlighter_HTML::SyntaxHighlighter_HTML() + : QTextPreProcessor(), lastFormat( 0 ), lastFormatId( -1 ) +{ + QFont f( qApp->font() ); + + addFormat(Standard, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::Text))); + addFormat(Keyword, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::Dark))); + addFormat(Attribute, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::Link))); + addFormat(AttribValue, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::LinkVisited))); +} + +SyntaxHighlighter_HTML::~SyntaxHighlighter_HTML() +{ +} + +void SyntaxHighlighter_HTML::process( QTextDocument *doc, QTextParagraph *string, int, bool invalidate ) +{ + + QTextFormat *formatStandard = format( Standard ); + QTextFormat *formatKeyword = format( Keyword ); + QTextFormat *formatAttribute = format( Attribute ); + QTextFormat *formatAttribValue = format( AttribValue ); + + const int StateStandard = 0; + const int StateTag = 1; + const int StateAttribute = 2; + const int StateAttribVal = 3; + + QString buffer = ""; + + int state = StateStandard; + + + if ( string->prev() ) { + if ( string->prev()->endState() == -1 ) + process( doc, string->prev(), 0, FALSE ); + state = string->prev()->endState(); + } + + + int i = 0; + for ( ;; ) { + QChar c = string->at( i )->c; + + if ( c == '<' ) { + if ( state != StateStandard ) + string->setFormat( i - buffer.length(), buffer.length(), formatStandard, FALSE ); + buffer = c; + state = StateTag; + string->setFormat( i, 1, formatKeyword, FALSE ); + } + else if ( c == '>' && ( state != StateStandard ) ) { + string->setFormat( i, 1, formatKeyword, FALSE ); + buffer = ""; + state = StateStandard; + } + else if ( c == ' ' && state == StateTag ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribute; + } + else if ( c == '=' && state == StateAttribute ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribute; + } + else if ( c == '\"' && state == StateAttribute ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribVal; + } + else if ( c == '\"' && state == StateAttribVal ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribute; + } + else if ( state == StateAttribute ) { + buffer += c; + string->setFormat( i, 1, formatAttribute, FALSE ); + } + else if ( state == StateAttribVal ) { + buffer += c; + string->setFormat( i, 1, formatAttribValue, FALSE ); + } + else if ( state == StateTag ) { + string->setFormat( i, 1, formatKeyword, FALSE ); + buffer += c; + } + else if ( state == StateStandard ) { + string->setFormat( i, 1, formatStandard, FALSE ); + } + + i++; + if ( i >= string->length() ) + break; + } + + string->setEndState( state ); + string->setFirstPreProcess( FALSE ); + + if ( invalidate && string->next() && + !string->next()->firstPreProcess() && string->next()->endState() != -1 ) { + QTextParagraph *p = string->next(); + while ( p ) { + if ( p->endState() == -1 ) + return; + p->setEndState( -1 ); + p = p->next(); + } + } +} + +QTextFormat *SyntaxHighlighter_HTML::format( int id ) +{ + if ( lastFormatId == id && lastFormat ) + return lastFormat; + + QTextFormat *f = formats[ id ]; + lastFormat = f ? f : formats[ 0 ]; + lastFormatId = id; + return lastFormat; +} + +void SyntaxHighlighter_HTML::addFormat( int id, QTextFormat *f ) +{ + formats.insert( id, f ); +} diff --git a/kdevdesigner/designer/syntaxhighlighter_html.h b/kdevdesigner/designer/syntaxhighlighter_html.h new file mode 100644 index 00000000..4a135671 --- /dev/null +++ b/kdevdesigner/designer/syntaxhighlighter_html.h @@ -0,0 +1,57 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef SYNTAXHIGHLIGHTER_HTML_H +#define SYNTAXHIGHLIGHTER_HTML_H + +#include <./private/qrichtext_p.h> + +class SyntaxHighlighter_HTML : public QTextPreProcessor +{ +public: + + enum HTML { + Standard = 1, + Keyword, + Attribute, + AttribValue + }; + + SyntaxHighlighter_HTML(); + virtual ~SyntaxHighlighter_HTML(); + void process( QTextDocument *doc, QTextParagraph *string, int start, bool invalidate = TRUE ); + QTextFormat *format( int id ); + +private: + void addFormat( int id, QTextFormat *f ); + + QTextFormat *lastFormat; + int lastFormatId; + QIntDict<QTextFormat> formats; + +}; + +#endif diff --git a/kdevdesigner/designer/tableeditor.ui b/kdevdesigner/designer/tableeditor.ui new file mode 100644 index 00000000..a6f10312 --- /dev/null +++ b/kdevdesigner/designer/tableeditor.ui @@ -0,0 +1,828 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>TableEditorBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>TableEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>484</width> + <height>406</height> + </rect> + </property> + <property name="caption"> + <string>Edit Table</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QTable" row="0" column="0"> + <property name="name"> + <cstring>table</cstring> + </property> + <property name="numRows"> + <number>1</number> + </property> + <property name="numCols"> + <number>1</number> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Apply all changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QTabWidget" row="0" column="1"> + <property name="name"> + <cstring>TabWidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>columns_tab</cstring> + </property> + <attribute name="title"> + <string>Co&lumns</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer row="4" column="2"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QListBox" row="0" column="0" rowspan="6" colspan="1"> + <property name="name"> + <cstring>listColumns</cstring> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>buttonColumnUp</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move up</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item up.</b><p>The top-most column will be the first column of the list.</p></string> + </property> + </widget> + <widget class="QPushButton" row="5" column="1"> + <property name="name"> + <cstring>buttonColumnDown</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move down</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item down.</b><p>The top-most column will be the first column of the list.</p></string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>buttonDeleteColumn</cstring> + </property> + <property name="text"> + <string>&Delete Column</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>buttonNewColumn</cstring> + </property> + <property name="text"> + <string>&New Column</string> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>labelTable</cstring> + </property> + <property name="text"> + <string>Table:</string> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="1"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelColumnPixmap</cstring> + </property> + <property name="text"> + <string>Label4</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonDeleteColPixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the selected item's pixmap.</b><p>The pixmap in the current column of the selected item will be deleted.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonChooseColPixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a pixmap file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p></string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>&Label:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editColumnText</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>Label2</cstring> + </property> + <property name="text"> + <string>Pixmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemChoosePixmap</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>labelFields</cstring> + </property> + <property name="text"> + <string>&Field:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboFields</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>editColumnText</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>comboFields</cstring> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>labelTableValue</cstring> + </property> + <property name="text"> + <string><no table></string> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>rows_tab</cstring> + </property> + <attribute name="title"> + <string>&Rows</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer row="4" column="2"> + <property name="name"> + <cstring>Spacer3_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>buttonRowUp</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move up</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item up.</b><p>The top-most column will be the first column of the list.</p></string> + </property> + </widget> + <widget class="QListBox" row="0" column="0" rowspan="6" colspan="1"> + <property name="name"> + <cstring>listRows</cstring> + </property> + </widget> + <widget class="QPushButton" row="5" column="1"> + <property name="name"> + <cstring>buttonRowDown</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Move down</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Move the selected item down.</b><p>The top-most column will be the first column of the list.</p></string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>buttonNewRow</cstring> + </property> + <property name="text"> + <string>&New Row</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>buttonDeleteRow</cstring> + </property> + <property name="text"> + <string>&Delete Row</string> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout7_2</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel2_3</cstring> + </property> + <property name="text"> + <string>&Label:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editRowText</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>Label2_2</cstring> + </property> + <property name="text"> + <string>Pixmap:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>itemChoosePixmap</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout2_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelRowPixmap</cstring> + </property> + <property name="text"> + <string>Label4</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonDeleteRowPixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_editcut.png"</pixmap> + </property> + <property name="toolTip" stdset="0"> + <string>Delete Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Delete the selected item's pixmap.</b><p>The pixmap in the current column of the selected item will be deleted.</p></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonChooseRowPixmap</cstring> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>22</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>Select a Pixmap</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Select a pixmap file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p></string> + </property> + </widget> + </hbox> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editRowText</cstring> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonApply</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>applyClicked()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>listColumns</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>TableEditorBase</receiver> + <slot>currentColumnChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>listColumns</sender> + <signal>selectionChanged(QListBoxItem*)</signal> + <receiver>TableEditorBase</receiver> + <slot>currentColumnChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>editColumnText</sender> + <signal>textChanged(const QString&)</signal> + <receiver>TableEditorBase</receiver> + <slot>columnTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>buttonNewColumn</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>newColumnClicked()</slot> + </connection> + <connection> + <sender>buttonDeleteColumn</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>deleteColumnClicked()</slot> + </connection> + <connection> + <sender>buttonColumnUp</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>columnUpClicked()</slot> + </connection> + <connection> + <sender>buttonColumnDown</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>columnDownClicked()</slot> + </connection> + <connection> + <sender>comboFields</sender> + <signal>activated(const QString&)</signal> + <receiver>TableEditorBase</receiver> + <slot>currentFieldChanged(const QString&)</slot> + </connection> + <connection> + <sender>listRows</sender> + <signal>selectionChanged(QListBoxItem*)</signal> + <receiver>TableEditorBase</receiver> + <slot>currentRowChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>listRows</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>TableEditorBase</receiver> + <slot>currentRowChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>buttonNewRow</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>newRowClicked()</slot> + </connection> + <connection> + <sender>buttonDeleteRow</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>deleteRowClicked()</slot> + </connection> + <connection> + <sender>buttonRowUp</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>rowUpClicked()</slot> + </connection> + <connection> + <sender>buttonRowDown</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>rowDownClicked()</slot> + </connection> + <connection> + <sender>buttonChooseRowPixmap</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>chooseRowPixmapClicked()</slot> + </connection> + <connection> + <sender>buttonDeleteColPixmap</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>deleteColPixmapClicked()</slot> + </connection> + <connection> + <sender>editRowText</sender> + <signal>textChanged(const QString&)</signal> + <receiver>TableEditorBase</receiver> + <slot>rowTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonChooseColPixmap</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>chooseColPixmapClicked()</slot> + </connection> + <connection> + <sender>buttonDeleteRowPixmap</sender> + <signal>clicked()</signal> + <receiver>TableEditorBase</receiver> + <slot>deleteRowPixmapClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>table</tabstop> + <tabstop>TabWidget</tabstop> + <tabstop>listColumns</tabstop> + <tabstop>buttonNewColumn</tabstop> + <tabstop>buttonDeleteColumn</tabstop> + <tabstop>comboFields</tabstop> + <tabstop>editColumnText</tabstop> + <tabstop>buttonDeleteColPixmap</tabstop> + <tabstop>buttonChooseColPixmap</tabstop> + <tabstop>buttonColumnUp</tabstop> + <tabstop>buttonColumnDown</tabstop> + <tabstop>buttonApply</tabstop> + <tabstop>listRows</tabstop> + <tabstop>buttonNewRow</tabstop> + <tabstop>buttonDeleteRow</tabstop> + <tabstop>editRowText</tabstop> + <tabstop>buttonDeleteRowPixmap</tabstop> + <tabstop>buttonChooseRowPixmap</tabstop> + <tabstop>buttonRowUp</tabstop> + <tabstop>buttonRowDown</tabstop> + <tabstop>buttonHelp</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">qtable.h</include> +</includes> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">applyClicked()</slot> + <slot access="protected">chooseRowPixmapClicked()</slot> + <slot access="protected">columnTextChanged( const QString & )</slot> + <slot access="protected">columnUpClicked()</slot> + <slot access="protected">currentColumnChanged( QListBoxItem * )</slot> + <slot access="protected">currentFieldChanged( const QString & )</slot> + <slot access="protected">currentRowChanged( QListBoxItem * )</slot> + <slot access="protected">deleteColPixmapClicked()</slot> + <slot access="protected">deleteColumnClicked()</slot> + <slot access="protected">deleteRowClicked()</slot> + <slot access="protected">deleteRowPixmapClicked()</slot> + <slot access="protected">newColumnClicked()</slot> + <slot access="protected">newRowClicked()</slot> + <slot access="protected">chooseColPixmapClicked()</slot> + <slot access="protected">okClicked()</slot> + <slot access="protected">rowDownClicked()</slot> + <slot access="protected">rowTextChanged( const QString & )</slot> + <slot access="protected">rowUpClicked()</slot> + <slot access="protected">columnDownClicked()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/tableeditorimpl.cpp b/kdevdesigner/designer/tableeditorimpl.cpp new file mode 100644 index 00000000..b2a440de --- /dev/null +++ b/kdevdesigner/designer/tableeditorimpl.cpp @@ -0,0 +1,494 @@ +/********************************************************************** +** 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. +** +** 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 "tableeditorimpl.h" +#ifndef QT_NO_TABLE +#include <qtable.h> +#endif +#include "formwindow.h" +#include <qlabel.h> +#include <qcombobox.h> +#include <qheader.h> +#include <qlistbox.h> +#include <klineedit.h> +#include <qpushbutton.h> +#include "pixmapchooser.h" +#include "command.h" +#include <qvaluelist.h> +#include <qtabwidget.h> +#include <qdatatable.h> +#include "project.h" +#include "metadatabase.h" +#include "mainwindow.h" + +#include <klocale.h> + +TableEditor::TableEditor( QWidget* parent, QWidget *editWidget, FormWindow *fw, const char* name, bool modal, WFlags fl ) + : TableEditorBase( parent, name, modal, fl ), +#ifndef QT_NO_TABLE + editTable( (QTable*)editWidget ), +#endif + formWindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); +#ifndef QT_NO_TABLE + labelColumnPixmap->setText( "" ); + labelRowPixmap->setText( "" ); + +#ifndef QT_NO_SQL + if ( !::qt_cast<QDataTable*>(editTable) ) +#endif + { + labelFields->hide(); + comboFields->hide(); + labelTable->hide(); + labelTableValue->hide(); + } +#ifndef QT_NO_SQL + if ( ::qt_cast<QDataTable*>(editTable) ) { + // ## why does this behave weird? + // TabWidget->removePage( rows_tab ); + // rows_tab->hide(); + // ## do this in the meantime... + TabWidget->setTabEnabled( rows_tab, FALSE ); + } + + if ( formWindow->project() && ::qt_cast<QDataTable*>(editTable) ) { + QStringList lst = MetaDataBase::fakeProperty( editTable, "database" ).toStringList(); + if ( lst.count() == 2 && !lst[ 0 ].isEmpty() && !lst[ 1 ].isEmpty() ) { + QStringList fields; + fields << "<no field>"; + fields += formWindow->project()->databaseFieldList( lst[ 0 ], lst[ 1 ] ); + comboFields->insertStringList( fields ); + } + if ( !lst[ 1 ].isEmpty() ) + labelTableValue->setText( lst[ 1 ] ); + } +#endif + + readFromTable(); +#endif +} + +TableEditor::~TableEditor() +{ +} + +void TableEditor::columnDownClicked() +{ + if ( listColumns->currentItem() == -1 || + listColumns->currentItem() == (int)listColumns->count() - 1 || + listColumns->count() < 2 ) + return; + saveFieldMap(); + int index = listColumns->currentItem() + 1; + QListBoxItem *i = listColumns->item( listColumns->currentItem() ); + listColumns->takeItem( i ); + listColumns->insertItem( i, index ); + listColumns->setCurrentItem( i ); + readColumns(); + restoreFieldMap(); + currentColumnChanged( i ); +} + +void TableEditor::columnTextChanged( const QString &s ) +{ + if ( listColumns->currentItem() == -1 ) + return; + listColumns->blockSignals( TRUE ); + listColumns->changeItem( s, listColumns->currentItem() ); + listColumns->blockSignals( FALSE ); +#ifndef QT_NO_TABLE + if ( table->horizontalHeader()->iconSet( listColumns->currentItem() ) ) + table->horizontalHeader()->setLabel( listColumns->currentItem(), + *table->horizontalHeader()->iconSet( listColumns->currentItem() ), s ); + else + table->horizontalHeader()->setLabel( listColumns->currentItem(), s ); +#endif +} + +void TableEditor::columnUpClicked() +{ + if ( listColumns->currentItem() <= 0 || + listColumns->count() < 2 ) + return; + saveFieldMap(); + int index = listColumns->currentItem() - 1; + QListBoxItem *i = listColumns->item( listColumns->currentItem() ); + listColumns->takeItem( i ); + listColumns->insertItem( i, index ); + listColumns->setCurrentItem( i ); + readColumns(); + restoreFieldMap(); + currentColumnChanged( i ); +} + +void TableEditor::currentColumnChanged( QListBoxItem *i ) +{ + if ( !i ) + return; + editColumnText->blockSignals( TRUE ); + editColumnText->setText( i->text() ); + if ( i->pixmap() ) + labelColumnPixmap->setPixmap( *i->pixmap() ); + else + labelColumnPixmap->setText( "" ); + editColumnText->blockSignals( FALSE ); + +#ifndef QT_NO_SQL + if ( ::qt_cast<QDataTable*>(editTable) ) { + QString s = *fieldMap.find( listColumns->index( i ) ); + if ( s.isEmpty() ) + comboFields->setCurrentItem( 0 ); + else if ( comboFields->listBox()->findItem( s ) ) + comboFields->setCurrentItem( comboFields->listBox()->index( comboFields->listBox()->findItem( s ) ) ); + else + comboFields->lineEdit()->setText( s ); + } +#endif +} + +void TableEditor::currentFieldChanged( const QString &s ) +{ + if ( listColumns->currentItem() == -1 ) + return; + fieldMap.remove( listColumns->currentItem() ); + fieldMap.insert( listColumns->currentItem(), s ); + editColumnText->blockSignals( TRUE ); //## necessary + QString newColText = s.mid(0,1).upper() + s.mid(1); + editColumnText->setText( newColText ); + columnTextChanged( newColText ); + editColumnText->blockSignals( FALSE ); +} + +void TableEditor::currentRowChanged( QListBoxItem *i ) +{ + if ( !i ) + return; + editRowText->blockSignals( TRUE ); + editRowText->setText( i->text() ); + if ( i->pixmap() ) + labelRowPixmap->setPixmap( *i->pixmap() ); + else + labelRowPixmap->setText( "" ); + editRowText->blockSignals( FALSE ); +} + +void TableEditor::deleteColumnClicked() +{ + if ( listColumns->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->setNumCols( table->numCols() - 1 ); + delete listColumns->item( listColumns->currentItem() ); + readColumns(); + if ( listColumns->firstItem() ) { + listColumns->setCurrentItem( listColumns->firstItem() ); + listColumns->setSelected( listColumns->firstItem(), TRUE ); + } +#endif +} + +void TableEditor::deleteRowClicked() +{ + if ( listRows->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->setNumRows( table->numRows() - 1 ); + delete listRows->item( listRows->currentItem() ); + readRows(); + if ( listRows->firstItem() ) { + listRows->setCurrentItem( listRows->firstItem() ); + listRows->setSelected( listRows->firstItem(), TRUE ); + } +#endif +} + +void TableEditor::newColumnClicked() +{ +#ifndef QT_NO_TABLE + table->setNumCols( table->numCols() + 1 ); + QMap<QString, bool> m; + for ( int i = 0; i < table->numCols() - 1; ++i ) + m.insert( table->horizontalHeader()->label( i ), TRUE ); + int n = table->numCols() - 1; + QString t = QString::number( n ); + while ( m.find( t ) != m.end() ) + t = QString::number( ++n ); + table->horizontalHeader()->setLabel( table->numCols() - 1, t ); + listColumns->insertItem( t ); + QListBoxItem *item = listColumns->item( listColumns->count() - 1 ); + listColumns->setCurrentItem( item ); + listColumns->setSelected( item, TRUE ); +#ifndef QT_NO_SQL + if ( ::qt_cast<QDataTable*>(editTable) ) { + comboFields->setFocus(); + } else +#endif + { + editColumnText->setFocus(); + editColumnText->selectAll(); + } +#endif +} + +void TableEditor::newRowClicked() +{ +#ifndef QT_NO_TABLE + table->setNumRows( table->numRows() + 1 ); + QMap<QString, bool> m; + for ( int i = 0; i < table->numRows() - 1; ++i ) + m.insert( table->verticalHeader()->label( i ), TRUE ); + int n = table->numRows() - 1; + QString t = QString::number( n ); + while ( m.find( t ) != m.end() ) + t = QString::number( ++n ); + table->verticalHeader()->setLabel( table->numRows() - 1, t ); + listRows->insertItem( t ); + QListBoxItem *item = listRows->item( listRows->count() - 1 ); + listRows->setCurrentItem( item ); + listRows->setSelected( item, TRUE ); +#endif +} + +void TableEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void TableEditor::rowDownClicked() +{ + if ( listRows->currentItem() == -1 || + listRows->currentItem() == (int)listRows->count() - 1 || + listRows->count() < 2 ) + return; + int index = listRows->currentItem() + 1; + QListBoxItem *i = listRows->item( listRows->currentItem() ); + listRows->takeItem( i ); + listRows->insertItem( i, index ); + listRows->setCurrentItem( i ); + readRows(); +} + +void TableEditor::rowTextChanged( const QString &s ) +{ + if ( listRows->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + listRows->changeItem( s, listRows->currentItem() ); + if ( table->verticalHeader()->iconSet( listRows->currentItem() ) ) + table->verticalHeader()->setLabel( listRows->currentItem(), + *table->verticalHeader()->iconSet( listRows->currentItem() ), s ); + else + table->verticalHeader()->setLabel( listRows->currentItem(), s ); +#endif +} + +void TableEditor::rowUpClicked() +{ + if ( listRows->currentItem() <= 0 || + listRows->count() < 2 ) + return; + int index = listRows->currentItem() - 1; + QListBoxItem *i = listRows->item( listRows->currentItem() ); + listRows->takeItem( i ); + listRows->insertItem( i, index ); + listRows->setCurrentItem( i ); + readRows(); +} + +void TableEditor::applyClicked() +{ + QValueList<PopulateTableCommand::Row> rows; + QValueList<PopulateTableCommand::Column> cols; + + int i = 0; +#ifndef QT_NO_TABLE + for ( i = 0; i < table->horizontalHeader()->count(); ++i ) { + PopulateTableCommand::Column col; + col.text = table->horizontalHeader()->label( i ); + if ( table->horizontalHeader()->iconSet( i ) ) + col.pix = table->horizontalHeader()->iconSet( i )->pixmap(); + col.field = *fieldMap.find( i ); + cols.append( col ); + } + for ( i = 0; i < table->verticalHeader()->count(); ++i ) { + PopulateTableCommand::Row row; + row.text = table->verticalHeader()->label( i ); + if ( table->verticalHeader()->iconSet( i ) ) + row.pix = table->verticalHeader()->iconSet( i )->pixmap(); + rows.append( row ); + } + PopulateTableCommand *cmd = new PopulateTableCommand( i18n( "Edit the Rows and Columns of '%1' " ).arg( editTable->name() ), + formWindow, editTable, rows, cols ); + cmd->execute(); + formWindow->commandHistory()->addCommand( cmd ); +#endif +} + +void TableEditor::chooseRowPixmapClicked() +{ + if ( listRows->currentItem() == -1 ) + return; + QPixmap pix; + if ( listRows->item( listRows->currentItem() )->pixmap() ) + pix = qChoosePixmap( this, formWindow, *listRows->item( listRows->currentItem() )->pixmap() ); + else + pix = qChoosePixmap( this, formWindow, QPixmap() ); + + if ( pix.isNull() ) + return; + +#ifndef QT_NO_TABLE + table->verticalHeader()->setLabel( listRows->currentItem(), pix, table->verticalHeader()->label( listRows->currentItem() ) ); + listRows->changeItem( pix, listRows->currentText(), listRows->currentItem() ); +#endif +} + +void TableEditor::deleteRowPixmapClicked() +{ + if ( listRows->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->verticalHeader()->setLabel( listRows->currentItem(), QPixmap(), table->verticalHeader()->label( listRows->currentItem() ) ); + listRows->changeItem( listRows->currentText(), listRows->currentItem() ); +#endif +} + +void TableEditor::chooseColPixmapClicked() +{ + if ( listColumns->currentItem() == -1 ) + return; + QPixmap pix; + if ( listColumns->item( listColumns->currentItem() )->pixmap() ) + pix = qChoosePixmap( this, formWindow, *listColumns->item( listColumns->currentItem() )->pixmap() ); + else + pix = qChoosePixmap( this, formWindow, QPixmap() ); + + if ( pix.isNull() ) + return; +#ifndef QT_NO_TABLE + table->horizontalHeader()->setLabel( listColumns->currentItem(), pix, table->horizontalHeader()->label( listColumns->currentItem() ) ); + listColumns->changeItem( pix, listColumns->currentText(), listColumns->currentItem() ); +#endif +} + +void TableEditor::deleteColPixmapClicked() +{ + if ( listColumns->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->horizontalHeader()->setLabel( listColumns->currentItem(), QPixmap(), table->horizontalHeader()->label( listColumns->currentItem() ) ); + listColumns->changeItem( listColumns->currentText(), listColumns->currentItem() ); +#endif +} + +void TableEditor::readFromTable() +{ +#ifndef QT_NO_TABLE + QHeader *cols = editTable->horizontalHeader(); + table->setNumCols( cols->count() ); + QMap<QString, QString> columnFields = MetaDataBase::columnFields( editTable ); + for ( int i = 0; i < cols->count(); ++i ) { + if ( editTable->horizontalHeader()->iconSet( i ) ) { + table->horizontalHeader()->setLabel( i, *editTable->horizontalHeader()->iconSet( i ), + editTable->horizontalHeader()->label( i ) ); + listColumns->insertItem( editTable->horizontalHeader()->iconSet( i )->pixmap(), + editTable->horizontalHeader()->label( i ) ); + } else { + table->horizontalHeader()->setLabel( i, editTable->horizontalHeader()->label( i ) ); + listColumns->insertItem( editTable->horizontalHeader()->label( i ) ); + } + QString cf = *columnFields.find( editTable->horizontalHeader()->label( i ) ); + fieldMap.insert( i, cf ); + } + + if ( listColumns->firstItem() ) { + listColumns->setCurrentItem( listColumns->firstItem() ); + listColumns->setSelected( listColumns->firstItem(), TRUE ); + } + + QHeader *rows = editTable->verticalHeader(); + table->setNumRows( rows->count() ); + for ( int j = 0; j < rows->count(); ++j ) { + if ( editTable->verticalHeader()->iconSet( j ) ) { + table->verticalHeader()->setLabel( j, *editTable->verticalHeader()->iconSet( j ), + editTable->verticalHeader()->label( j ) ); + listRows->insertItem( editTable->verticalHeader()->iconSet( j )->pixmap(), + editTable->verticalHeader()->label( j ) ); + } else { + table->verticalHeader()->setLabel( j, editTable->verticalHeader()->label( j ) ); + listRows->insertItem( editTable->verticalHeader()->label( j ) ); + } + } + + if ( listRows->firstItem() ) { + listRows->setCurrentItem( listRows->firstItem() ); + listRows->setSelected( listRows->firstItem(), TRUE ); + } +#endif +} + +void TableEditor::readColumns() +{ + int j = 0; +#ifndef QT_NO_TABLE + for ( QListBoxItem *i = listColumns->firstItem(); i; i = i->next(), ++j ) { + if ( i->pixmap() ) + table->horizontalHeader()->setLabel( j, *i->pixmap(), i->text() ); + else + table->horizontalHeader()->setLabel( j, i->text() ); + } +#endif +} + +void TableEditor::readRows() +{ + int j = 0; +#ifndef QT_NO_TABLE + for ( QListBoxItem *i = listRows->firstItem(); i; i = i->next(), ++j ) { + if ( i->pixmap() ) + table->verticalHeader()->setLabel( j, *i->pixmap(), i->text() ); + else + table->verticalHeader()->setLabel( j, i->text() ); + } +#endif +} + +void TableEditor::saveFieldMap() +{ + tmpFieldMap.clear(); + for ( QMap<int, QString>::Iterator it = fieldMap.begin(); it != fieldMap.end(); ++it ) + tmpFieldMap.insert( listColumns->item( it.key() ), *it ); +} + +void TableEditor::restoreFieldMap() +{ + fieldMap.clear(); + for ( QMap<QListBoxItem*, QString>::Iterator it = tmpFieldMap.begin(); it != tmpFieldMap.end(); ++it ) + fieldMap.insert( listColumns->index( it.key() ), *it ); +} diff --git a/kdevdesigner/designer/tableeditorimpl.h b/kdevdesigner/designer/tableeditorimpl.h new file mode 100644 index 00000000..8d5ed20d --- /dev/null +++ b/kdevdesigner/designer/tableeditorimpl.h @@ -0,0 +1,82 @@ +/********************************************************************** +** 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 TABLEEDITORIMPL_H +#define TABLEEDITORIMPL_H + +#include "tableeditor.h" +#include <qmap.h> + +class QListBoxItem; +class QTable; +class FormWindow; + +class TableEditor : public TableEditorBase +{ + Q_OBJECT + +public: + TableEditor( QWidget* parent = 0, QWidget *editWidget = 0, FormWindow *fw = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~TableEditor(); + +protected slots: + void columnDownClicked(); + void columnTextChanged( const QString & ); + void columnUpClicked(); + void currentColumnChanged( QListBoxItem * ); + void currentFieldChanged( const QString & ); + void currentRowChanged( QListBoxItem * ); + void deleteColumnClicked(); + void deleteRowClicked(); + void newColumnClicked(); + void newRowClicked(); + void okClicked(); + void rowDownClicked(); + void rowTextChanged( const QString & ); + void rowUpClicked(); + void applyClicked(); + void chooseRowPixmapClicked(); + void deleteRowPixmapClicked(); + void chooseColPixmapClicked(); + void deleteColPixmapClicked(); + +private: + void readFromTable(); + void readColumns(); + void readRows(); + void saveFieldMap(); + void restoreFieldMap(); + +private: + QTable *editTable; + FormWindow *formWindow; + QMap<int, QString> fieldMap; + QMap<QListBoxItem*, QString> tmpFieldMap; + +}; + +#endif // TABLEEDITOR_H diff --git a/kdevdesigner/designer/timestamp.cpp b/kdevdesigner/designer/timestamp.cpp new file mode 100644 index 00000000..9cda96e6 --- /dev/null +++ b/kdevdesigner/designer/timestamp.cpp @@ -0,0 +1,86 @@ + /********************************************************************** +** 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 "timestamp.h" +#include <qfile.h> +#include <qfileinfo.h> + +class QTimer; + +TimeStamp::TimeStamp( QObject *parent, const QString &f ) + : QObject( parent ), filename( f ), autoCheck( FALSE ) +{ + timer = new QTimer( this ); + connect( timer, SIGNAL( timeout() ), this, SLOT( autoCheckTimeStamp() ) ); + update(); +} + +void TimeStamp::setFileName( const QString &f ) +{ + filename = f; + update(); +} + +QString TimeStamp::fileName() const +{ + return filename; +} + +void TimeStamp::setAutoCheckEnabled( bool a ) +{ + autoCheck = a; + if ( autoCheck ) + timer->start( 5000 ); + else + timer->stop(); +} + +void TimeStamp::update() +{ + QFile f( filename ); + if ( !f.exists() ) + return; + lastTimeStamp = QFileInfo( f ).lastModified(); +} + +bool TimeStamp::isUpToDate() const +{ + QFile f( filename ); + if ( !f.exists() ) + return TRUE; + return lastTimeStamp == QFileInfo( f ).lastModified(); +} + +bool TimeStamp::isAutoCheckEnabled() const +{ + return autoCheck; +} + +void TimeStamp::autoCheckTimeStamp() +{ + if ( !isUpToDate() ) + emit timeStampChanged(); +} diff --git a/kdevdesigner/designer/timestamp.h b/kdevdesigner/designer/timestamp.h new file mode 100644 index 00000000..373fb884 --- /dev/null +++ b/kdevdesigner/designer/timestamp.h @@ -0,0 +1,63 @@ + /********************************************************************** +** 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 TIMESTAMP_H +#define TIMESTAMP_H + +#include <qobject.h> +#include <qdatetime.h> +#include <qtimer.h> + +class TimeStamp : public QObject +{ + Q_OBJECT + +public: + TimeStamp( QObject *parent, const QString &f ); + + void setFileName( const QString &f ); + QString fileName() const; + void setAutoCheckEnabled( bool a ); + void update(); + + bool isUpToDate() const; + bool isAutoCheckEnabled() const; + +signals: + void timeStampChanged(); + +private slots: + void autoCheckTimeStamp(); + +private: + QDateTime lastTimeStamp; + QString filename; + bool autoCheck; + QTimer *timer; + +}; + +#endif diff --git a/kdevdesigner/designer/variabledialog.ui b/kdevdesigner/designer/variabledialog.ui new file mode 100644 index 00000000..a38954af --- /dev/null +++ b/kdevdesigner/designer/variabledialog.ui @@ -0,0 +1,294 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>VariableDialogBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>VariableDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>276</width> + <height>320</height> + </rect> + </property> + <property name="caption"> + <string>Edit Variables</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Variable</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Access</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>varView</cstring> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>deleteButton</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + </widget> + <widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>propBox</cstring> + </property> + <property name="title"> + <string>Variable Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Acc&ess:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>accessCombo</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Variable:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>varName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>varName</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>public</string> + </property> + </item> + <item> + <property name="text"> + <string>protected</string> + </property> + </item> + <item> + <property name="text"> + <string>private</string> + </property> + </item> + <property name="name"> + <cstring>accessCombo</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + <spacer row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>0</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="3" column="3"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <widget class="QPushButton" row="3" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>okButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + </widget> + <spacer row="3" column="0"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>0</width> + <height>21</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>VariableDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>addButton</sender> + <signal>clicked()</signal> + <receiver>VariableDialogBase</receiver> + <slot>addVariable()</slot> + </connection> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>VariableDialogBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>varName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>VariableDialogBase</receiver> + <slot>nameChanged()</slot> + </connection> + <connection> + <sender>deleteButton</sender> + <signal>clicked()</signal> + <receiver>VariableDialogBase</receiver> + <slot>deleteVariable()</slot> + </connection> + <connection> + <sender>accessCombo</sender> + <signal>activated(int)</signal> + <receiver>VariableDialogBase</receiver> + <slot>accessChanged()</slot> + </connection> + <connection> + <sender>varView</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>VariableDialogBase</receiver> + <slot>currentItemChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>varView</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>VariableDialogBase</receiver> + <slot>currentItemChanged(QListViewItem*)</slot> + </connection> +</connections> +<tabstops> + <tabstop>varView</tabstop> + <tabstop>addButton</tabstop> + <tabstop>deleteButton</tabstop> + <tabstop>varName</tabstop> + <tabstop>accessCombo</tabstop> + <tabstop>okButton</tabstop> + <tabstop>cancelButton</tabstop> +</tabstops> +<slots> + <slot>addVariable()</slot> + <slot>deleteVariable()</slot> + <slot>accessChanged()</slot> + <slot>nameChanged()</slot> + <slot>okClicked()</slot> + <slot>currentItemChanged( QListViewItem * i )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/variabledialogimpl.cpp b/kdevdesigner/designer/variabledialogimpl.cpp new file mode 100644 index 00000000..abaa7c68 --- /dev/null +++ b/kdevdesigner/designer/variabledialogimpl.cpp @@ -0,0 +1,180 @@ +/********************************************************************** +** 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. +** +** 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 <qlistview.h> +#include <qgroupbox.h> +#include <klineedit.h> +#include <qcombobox.h> +#include <qmessagebox.h> + +#include "metadatabase.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "hierarchyview.h" +#include "command.h" +#include "variabledialogimpl.h" + +#include <klocale.h> + + +VariableDialog::VariableDialog( FormWindow *fw, QWidget *parent ) + : VariableDialogBase( parent ), formWindow( fw ) +{ + varView->setSorting( -1 ); + QValueList<MetaDataBase::Variable> varLst = MetaDataBase::variables( formWindow ); + QValueList<MetaDataBase::Variable>::Iterator it = varLst.begin(); + for ( ; it != varLst.end(); ++it ) { + QListViewItem *i = new QListViewItem( varView ); + i->setText( 0, (*it).varName ); + i->setText( 1, (*it).varAccess ); + } + + if ( varView->firstChild() ) + varView->setCurrentItem( varView->firstChild() ); + else + propBox->setEnabled( FALSE ); +} + +VariableDialog::~VariableDialog() +{ +} + +void VariableDialog::setCurrentItem( QString text ) +{ + QListViewItem *i = varView->findItem( text, 0 ); + if ( i ) + varView->setCurrentItem( i ); +} + +void VariableDialog::okClicked() +{ + QValueList<MetaDataBase::Variable> lst; + + QListViewItemIterator it( varView ); + while ( it.current() != 0 ) { + MetaDataBase::Variable v; + v.varName = it.current()->text( 0 ).simplifyWhiteSpace(); + if ( v.varName[ (int)v.varName.length() - 1 ] != ';' ) + v.varName += ";"; + v.varAccess = it.current()->text( 1 ); + lst << v; + ++it; + } + + if ( !lst.isEmpty() ) { + QValueList<MetaDataBase::Variable> invalidLst; + QValueList<MetaDataBase::Variable>::Iterator it1 = lst.begin(); + QValueList<MetaDataBase::Variable>::Iterator it2; + for ( ; it1 != lst.end(); ++it1 ) { + it2 = it1; + ++it2; + for ( ; it2 != lst.end(); ++it2 ) { + if ( MetaDataBase::extractVariableName( (*it1).varName ) == + MetaDataBase::extractVariableName( (*it2).varName ) ) { + invalidLst << (*it1); + break; + } + } + } + if ( !invalidLst.isEmpty() ) { + if ( QMessageBox::information( this, i18n( "Edit Variables" ), + i18n( "One variable has been declared twice.\n" + "Remove this variable?" ), i18n( "&Yes" ), i18n( "&No" ) ) == 0 ) { + for ( it2 = invalidLst.begin(); it2 != invalidLst.end(); ++it2 ) { + it = varView->firstChild(); + while ( it.current() != 0 ) { + if ( MetaDataBase::extractVariableName( (*it)->text( 0 ).simplifyWhiteSpace() ) == + MetaDataBase::extractVariableName( (*it2).varName ) ) { + delete (*it); + break; + } + ++it; + } + } + } + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + return; + } + } + Command *cmd = new SetVariablesCommand( i18n( "Edit Variables" ), formWindow, lst ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + accept(); +} + +void VariableDialog::addVariable() +{ + QListViewItem *i = new QListViewItem( varView, varView->lastItem() ); + i->setText( 0, "int newVariable" ); + i->setText( 1, "protected" ); + varView->setCurrentItem( i ); + varView->setSelected( i, TRUE ); + varName->setFocus(); + varName->selectAll(); +} + +void VariableDialog::deleteVariable() +{ + QListViewItem *i = varView->selectedItem(); + if ( !i ) + return; + delete i; + i = 0; + if ( varView->firstChild() ) + varView->setSelected( varView->firstChild(), TRUE ); +} + +void VariableDialog::currentItemChanged( QListViewItem *i ) +{ + if ( !i ) { + varName->clear(); + accessCombo->setCurrentItem( 1 ); + propBox->setEnabled( FALSE ); + return; + } + varName->setText( i->text( 0 ) ); + if ( i->text( 1 ) == "public" ) + accessCombo->setCurrentItem( 0 ); + else if ( i->text( 1 ) == "protected" ) + accessCombo->setCurrentItem( 1 ); + else + accessCombo->setCurrentItem( 2 ); + propBox->setEnabled( TRUE ); +} + +void VariableDialog::nameChanged() +{ + if ( !varView->currentItem() ) + return; + varView->currentItem()->setText( 0, varName->text() ); +} + +void VariableDialog::accessChanged() +{ + if ( !varView->currentItem() ) + return; + varView->currentItem()->setText( 1, accessCombo->currentText() ); +} diff --git a/kdevdesigner/designer/variabledialogimpl.h b/kdevdesigner/designer/variabledialogimpl.h new file mode 100644 index 00000000..975e18d7 --- /dev/null +++ b/kdevdesigner/designer/variabledialogimpl.h @@ -0,0 +1,56 @@ +/********************************************************************** +** 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. +** +** 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 VARIABLEDIALOGIMPL_H +#define VARIABLEDIALOGIMPL_H + +#include "variabledialog.h" + +class FormWindow; +class QListView; + +class VariableDialog : public VariableDialogBase +{ + Q_OBJECT +public: + VariableDialog( FormWindow *fw, QWidget* parent = 0 ); + ~VariableDialog(); + + void setCurrentItem( QString text ); + +protected slots: + void okClicked(); + void addVariable(); + void deleteVariable(); + void nameChanged(); + void accessChanged(); + void currentItemChanged( QListViewItem *i ); + +private: + FormWindow *formWindow; +}; + +#endif diff --git a/kdevdesigner/designer/widgetaction.cpp b/kdevdesigner/designer/widgetaction.cpp new file mode 100644 index 00000000..36a9c14c --- /dev/null +++ b/kdevdesigner/designer/widgetaction.cpp @@ -0,0 +1,58 @@ +/********************************************************************** +** 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 "widgetaction.h" +#include <qwidget.h> +#include <qtoolbutton.h> +#include "mainwindow.h" +#include <qstylefactory.h> +#include <qstyle.h> + +static QStyle *windowsStyle = 0; + +void WidgetAction::addedTo( QWidget *w, QWidget *container ) +{ + if ( ::qt_cast<QToolButton*>(w) && ::qt_cast<QScrollView*>(container->parent()->parent()) ) { + if ( !windowsStyle ) + windowsStyle = QStyleFactory::create( "windows" ); + w->setStyle( windowsStyle ); + ( (QToolButton*)w )->setUsesTextLabel( TRUE ); + ( (QToolButton*)w )->setTextPosition( QToolButton::Right ); + w->setBackgroundMode( container->backgroundMode() ); + } +} + +WidgetAction::~WidgetAction() +{ + if ( MainWindow::self ) + MainWindow::self->toolActions.removeRef( this ); +} + +void WidgetAction::init( const QString &g ) +{ + MainWindow::self->toolActions.append( this ); + grp = g; +} diff --git a/kdevdesigner/designer/widgetaction.h b/kdevdesigner/designer/widgetaction.h new file mode 100644 index 00000000..6215d88d --- /dev/null +++ b/kdevdesigner/designer/widgetaction.h @@ -0,0 +1,65 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef WIDGETACTION_H +#define WIDGETACTION_H + +#include <qaction.h> + +class WidgetAction : public QAction +{ + Q_OBJECT + +public: + WidgetAction( const QString &grp, QObject* parent, + const char* name = 0, bool toggle = FALSE ) + : QAction( parent, name, toggle ) { init( grp ); } + WidgetAction( const QString &grp, const QString& text, + const QIconSet& icon, const QString& menuText, QKeySequence accel, + QObject* parent, const char* name = 0, bool toggle = FALSE ) + : QAction( text, icon, menuText, accel, parent, name, toggle ) { init( grp ); } + WidgetAction( const QString &grp, const QString& text, + const QString& menuText, QKeySequence accel, QObject* parent, + const char* name = 0, bool toggle = FALSE ) + : QAction( text, menuText, accel, parent, name, toggle ) { init( grp ); } + ~WidgetAction(); + +#if !defined(Q_NO_USING_KEYWORD) + using QAction::addedTo; +#endif + void addedTo( QWidget *, QWidget * ); + + QString group() const { return grp; } + +private: + void init( const QString &g ); + +private: + QString grp; + +}; + +#endif diff --git a/kdevdesigner/designer/widgetfactory.cpp b/kdevdesigner/designer/widgetfactory.cpp new file mode 100644 index 00000000..191fbb1f --- /dev/null +++ b/kdevdesigner/designer/widgetfactory.cpp @@ -0,0 +1,1797 @@ +/********************************************************************** +** 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 <qvariant.h> // HP-UX compiler need this here +#include "widgetfactory.h" +#include <widgetdatabase.h> +#include "metadatabase.h" +#include "mainwindow.h" +#include "formwindow.h" +#include "propertyeditor.h" +#include "layout.h" +#include "listboxeditorimpl.h" +#include "listvieweditorimpl.h" +#include "iconvieweditorimpl.h" +#include "formwindow.h" +#include "multilineeditorimpl.h" +#include "../interfaces/widgetinterface.h" +#ifndef QT_NO_TABLE +#include "tableeditorimpl.h" +#endif +#include "project.h" +#include "menubareditor.h" +#include "popupmenueditor.h" + +#include "kdevdesigner_part.h" + +#include <kiconloader.h> + +#include <qfeatures.h> + +#include <qpixmap.h> +#include <qgroupbox.h> +#include <qiconview.h> +#ifndef QT_NO_TABLE +#include <qtable.h> +#endif +#ifndef QT_NO_SQL +#include <qdatatable.h> +#endif +#include <qdatetimeedit.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qmultilineedit.h> +#include <qtextedit.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qwidgetstack.h> +#include <qcombobox.h> +#include <qtabbar.h> +#include <qlistbox.h> +#include <qlistview.h> +#include <qobjectlist.h> +#include <qlcdnumber.h> +#include <qslider.h> +#include <qdial.h> +#include <qprogressbar.h> +#include <qtextview.h> +#include <qtextbrowser.h> +#include <qframe.h> +#include <qmetaobject.h> +#include <qwidgetstack.h> +#include <qwizard.h> +#include <qvaluelist.h> +#include <qtimer.h> +#include <qscrollbar.h> +#include <qmainwindow.h> +#include <qmenubar.h> +#include <qapplication.h> +#include <qsplitter.h> +#include <qtoolbox.h> +#include <qsizegrip.h> +#ifndef QT_NO_SQL +#include "database.h" +#endif + +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qobject.h> + +#include <klocale.h> + +FormWindow *find_formwindow( QWidget *w ) +{ + if ( !w ) + return 0; + for (;;) { + if ( ::qt_cast<FormWindow*>(w) ) + return (FormWindow*)w; + if ( !w->parentWidget() ) + return 0; + w = w->parentWidget(); + } +} + +void QLayoutWidget::paintEvent( QPaintEvent* ) +{ + QPainter p ( this ); + p.setPen( red ); + p.drawRect( rect() ); +} + + +QDesignerTabWidget::QDesignerTabWidget( QWidget *parent, const char *name ) + : QTabWidget( parent, name ), dropIndicator( 0 ), dragPage( 0 ), mousePressed( FALSE ) +{ + tabBar()->setAcceptDrops( TRUE ); + tabBar()->installEventFilter( this ); +} + +int QDesignerTabWidget::currentPage() const +{ + return tabBar()->currentTab(); +} + +void QDesignerTabWidget::setCurrentPage( int i ) +{ + tabBar()->setCurrentTab( i ); +} + +QString QDesignerTabWidget::pageTitle() const +{ + return ((QTabWidget*)this)->tabLabel( QTabWidget::currentPage() ); +} + +void QDesignerTabWidget::setPageTitle( const QString& title ) +{ + changeTab( QTabWidget::currentPage(), title ); +} + +void QDesignerTabWidget::setPageName( const QCString& name ) +{ + if ( QTabWidget::currentPage() ) + QTabWidget::currentPage()->setName( name ); +} + +QCString QDesignerTabWidget::pageName() const +{ + if ( !QTabWidget::currentPage() ) + return 0; + return QTabWidget::currentPage()->name(); +} + +int QDesignerTabWidget::count() const +{ + return tabBar()->count(); +} + +bool QDesignerTabWidget::eventFilter( QObject *o, QEvent *e ) +{ + if ( o != tabBar() ) return FALSE; + + switch ( e->type() ) { + case QEvent::MouseButtonPress: { + mousePressed = TRUE; + QMouseEvent *me = (QMouseEvent*)e; + pressPoint = me->pos(); + } + break; + case QEvent::MouseMove: { + QMouseEvent *me = (QMouseEvent*)e; + if ( mousePressed && ( pressPoint - me->pos()).manhattanLength() > QApplication::startDragDistance() ) { + QTextDrag *drg = new QTextDrag( QString::number( (long) this ) , this ); + mousePressed = FALSE; + dragPage = QTabWidget::currentPage(); + dragLabel = QTabWidget::tabLabel( dragPage ); + + int index = indexOf( dragPage ); + + removePage( dragPage ); + if ( !drg->dragMove() ) { + insertTab( dragPage, dragLabel, index ); + showPage( dragPage ); + } + if ( dropIndicator ) + dropIndicator->hide(); + } + } + break; + case QEvent::DragLeave: { + if ( dropIndicator ) + dropIndicator->hide(); + } + break; + case QEvent::DragMove: { + QDragEnterEvent *de = (QDragEnterEvent*) e; + if ( QTextDrag::canDecode( de ) ) { + QString text; + QTextDrag::decode( de, text ); + if ( text == QString::number( (long)this ) ) + de->accept(); + else + return FALSE; + } + + int index = 0; + QRect rect; + for ( ; index < tabBar()->count(); index++ ) { + if ( tabBar()->tabAt( index )->rect().contains( de->pos() ) ) { + rect = tabBar()->tabAt( index )->rect(); + break; + } + } + + if ( index == tabBar()->count() -1 ) { + QRect rect2 = rect; + rect2.setLeft( rect2.left() + rect2.width() / 2 ); + if ( rect2.contains( de->pos() ) ) + index++; + } + + if ( ! dropIndicator ) { + dropIndicator = new QWidget( this ); + dropIndicator->setBackgroundColor( red ); + } + + QPoint pos; + if ( index == tabBar()->count() ) + pos = tabBar()->mapToParent( QPoint( rect.x() + rect.width(), rect.y() ) ); + else + pos = tabBar()->mapToParent( QPoint( rect.x(), rect.y() ) ); + + dropIndicator->setGeometry( pos.x(), pos.y() , 3, rect.height() ); + dropIndicator->show(); + } + break; + case QEvent::Drop: { + QDragEnterEvent *de = (QDragEnterEvent*) e; + if ( QTextDrag::canDecode( de ) ) { + QString text; + QTextDrag::decode( de, text ); + if ( text == QString::number( (long)this ) ) { + + int newIndex = 0; + for ( ; newIndex < tabBar()->count(); newIndex++ ) { + if ( tabBar()->tabAt( newIndex )->rect().contains( de->pos() ) ) + break; + } + + if ( newIndex == tabBar()->count() -1 ) { + QRect rect2 = tabBar()->tabAt( newIndex )->rect(); + rect2.setLeft( rect2.left() + rect2.width() / 2 ); + if ( rect2.contains( de->pos() ) ) + newIndex++; + } + + int oldIndex = 0; + for ( ; oldIndex < tabBar()->count(); oldIndex++ ) { + if ( tabBar()->tabAt( oldIndex )->rect().contains( pressPoint ) ) + break; + } + + FormWindow *fw = find_formwindow( this ); + MoveTabPageCommand *cmd = + new MoveTabPageCommand( i18n( "Move Tab Page" ), fw, this, + dragPage, dragLabel, newIndex, oldIndex ); + fw->commandHistory()->addCommand( cmd ); + cmd->execute(); + de->accept(); + } + } + } + break; + default: + break; + } + return FALSE; +} + + +QDesignerWidgetStack::QDesignerWidgetStack( QWidget *parent, const char *name ) + : QWidgetStack( parent, name ) +{ + prev = new QToolButton( Qt::LeftArrow, this, "designer_wizardstack_button" ); + prev->setAutoRaise( TRUE ); + prev->setAutoRepeat( TRUE ); + prev->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) ); + next = new QToolButton( Qt::RightArrow, this, "designer_wizardstack_button" ); + next->setAutoRaise( TRUE ); + next->setAutoRepeat( TRUE ); + next->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) ); + connect( prev, SIGNAL( clicked() ), this, SLOT( prevPage() ) ); + connect( next, SIGNAL( clicked() ), this, SLOT( nextPage() ) ); + updateButtons(); +} + +void QDesignerWidgetStack::updateButtons() +{ + prev->setGeometry( width() - 31, 1, 15, 15 ); + next->setGeometry( width() - 16, 1, 15, 15 ); + prev->show(); + next->show(); + prev->raise(); + next->raise(); +} + +void QDesignerWidgetStack::prevPage() +{ + setCurrentPage( currentPage() - 1 ); +} + +void QDesignerWidgetStack::nextPage() +{ + setCurrentPage( currentPage() + 1 ); +} + +int QDesignerWidgetStack::currentPage() const +{ + QDesignerWidgetStack* that = (QDesignerWidgetStack*) this; + return that->pages.find( visibleWidget() ); +} + +void QDesignerWidgetStack::setCurrentPage( int i ) +{ + // help next/prev page commands + if ( i < 0 ) + i += count(); + if ( i >= count() ) + i -= count(); + + if ( i < 0 || i >= count() ) + return; + raiseWidget( pages.at( i ) ); + updateButtons(); +} + +QCString QDesignerWidgetStack::pageName() const +{ + if ( !visibleWidget() ) + return 0; + return visibleWidget()->name(); +} + +void QDesignerWidgetStack::setPageName( const QCString& name ) +{ + if ( visibleWidget() ) + visibleWidget()->setName( name ); +} + +int QDesignerWidgetStack::count() const +{ + return pages.count(); +} + +QWidget* QDesignerWidgetStack::page( int i ) const +{ + if ( i < 0 || i >= count() ) + return 0; + QDesignerWidgetStack* that = (QDesignerWidgetStack*) this; + return that->pages.at( i ); +} + + +int QDesignerWidgetStack::insertPage( QWidget *p, int i ) +{ + if ( i < 0 ) + pages.append( p ); + else + pages.insert( (uint) i, p ); + addWidget( p ); + p->show(); + raiseWidget( p ); + QApplication::sendPostedEvents(); + updateButtons(); + return pages.find( p ); +} + +int QDesignerWidgetStack::removePage( QWidget *p ) +{ + int i = pages.find( p ); + pages.remove( p ); + removeWidget( p ); + setCurrentPage( 0 ); + updateButtons(); + return i; +} + + +int QDesignerWizard::currentPageNum() const +{ + for ( int i = 0; i < pageCount(); ++i ) { + if ( page( i ) == currentPage() ) + return i; + } + return 0; +} + + + + + +void QDesignerWizard::setCurrentPage( int i ) +{ + if ( i < currentPageNum() ) { + while ( i < currentPageNum() ) { + if ( currentPageNum() == 0 ) + break; + back(); + } + + } else { + while ( i > currentPageNum() ) { + if ( currentPageNum() == pageCount() - 1 ) + break; + next(); + } + } +} + +QString QDesignerWizard::pageTitle() const +{ + return title( currentPage() ); +} + +void QDesignerWizard::setPageTitle( const QString& title ) +{ + setTitle( currentPage(), title ); +} + +void QDesignerWizard::setPageName( const QCString& name ) +{ + if ( QWizard::currentPage() ) + QWizard::currentPage()->setName( name ); +} + +QCString QDesignerWizard::pageName() const +{ + if ( !QWizard::currentPage() ) + return 0; + return QWizard::currentPage()->name(); +} + +int QDesignerWizard::pageNum( QWidget *p ) +{ + for ( int i = 0; i < pageCount(); ++i ) { + if ( page( i ) == p ) + return i; + } + return -1; +} + +void QDesignerWizard::addPage( QWidget *p, const QString &t ) +{ + QWizard::addPage( p, t ); + if ( removedPages.find( p ) ) + removedPages.remove( p ); +} + +void QDesignerWizard::removePage( QWidget *p ) +{ + QWizard::removePage( p ); + removedPages.insert( p, p ); +} + +void QDesignerWizard::insertPage( QWidget *p, const QString &t, int index ) +{ + QWizard::insertPage( p, t, index ); + if ( removedPages.find( p ) ) + removedPages.remove( p ); +} + +QMap< int, QMap< QString, QVariant> > *defaultProperties = 0; +QMap< int, QStringList > *changedProperties = 0; + +/*! + \class WidgetFactory widgetfactory.h + \brief Set of static functions for creating widgets, layouts and do other stuff + + The widget factory offers functions to create widgets, create and + delete layouts find out other details - all based on the + WidgetDatabase's data. So the functions that use ids use the same + ids as in the WidgetDatabase. +*/ + + +void WidgetFactory::saveDefaultProperties( QObject *w, int id ) +{ + QMap< QString, QVariant> propMap; + QStrList lst = w->metaObject()->propertyNames( TRUE ); + for ( uint i = 0; i < lst.count(); ++i ) { + QVariant var = w->property( lst.at( i ) ); + if ( !var.isValid() && qstrcmp( "pixmap", lst.at( i ) ) == 0 ) + var = QVariant( QPixmap() ); + else if ( !var.isValid() && qstrcmp( "iconSet", lst.at( i ) ) == 0 ) + var = QVariant( QIconSet() ); + propMap.replace( lst.at( i ), var ); + } + defaultProperties->replace( id, propMap ); +} + +void WidgetFactory::saveChangedProperties( QObject *w, int id ) +{ + QStringList l = MetaDataBase::changedProperties( w ); + changedProperties->insert( id, l ); +} + +/*! Creates a widget of the type which is registered as \a id as + child of \a parent. The \a name is optional. If \a init is TRUE, the + widget is initialized with some defaults, else the plain widget is + created. +*/ + +QWidget *WidgetFactory::create( int id, QWidget *parent, const char *name, bool init, const QRect *r, Qt::Orientation orient ) +{ + QString n = WidgetDatabase::className( id ); + if ( n.isEmpty() ) + return 0; + + if ( !defaultProperties ) { + defaultProperties = new QMap< int, QMap< QString, QVariant> >(); + changedProperties = new QMap< int, QStringList >(); + } + + QWidget *w = 0; + QString str = WidgetDatabase::createWidgetName( id ); + const char *s = str.latin1(); + w = createWidget( n, parent, name ? name : s, init, r, orient ); + if ( ::qt_cast<QScrollView*>(w) ) + ( (QScrollView*)w )->disableSizeHintCaching(); + if ( !w && WidgetDatabase::isCustomWidget( id ) ) + w = createCustomWidget( parent, name ? name : s, MetaDataBase::customWidget( id ) ); + if ( !w ) + return 0; + MetaDataBase::addEntry( w ); + + if ( !defaultProperties->contains( id ) ) + saveDefaultProperties( w, id ); + if ( !changedProperties->contains( id ) ) + saveChangedProperties( w, id ); + + return w; +} + +/*! Creates a layout on the widget \a widget of the type \a type + which can be \c HBox, \c VBox or \c Grid. +*/ + +QLayout *WidgetFactory::createLayout( QWidget *widget, QLayout *layout, LayoutType type ) +{ + int spacing = MainWindow::self->currentLayoutDefaultSpacing(); + int margin = 0; + + int metaspacing = MetaDataBase::spacing( widget ); + int metamargin = MetaDataBase::margin( widget ); + + if ( ::qt_cast<QLayoutWidget*>(widget) && + ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( widget ) ) ) || + widget && ::qt_cast<FormWindow*>(widget->parentWidget()) ) ) + margin = MainWindow::self->currentLayoutDefaultMargin(); + + if ( !layout && ::qt_cast<QTabWidget*>(widget) ) + widget = ((QTabWidget*)widget)->currentPage(); + + if ( !layout && ::qt_cast<QWizard*>(widget) ) + widget = ((QWizard*)widget)->currentPage(); + + if ( !layout && ::qt_cast<QMainWindow*>(widget) ) + widget = ((QMainWindow*)widget)->centralWidget(); + + if ( !layout && ::qt_cast<QWidgetStack*>(widget) ) + widget = ((QWidgetStack*)widget)->visibleWidget(); + + if ( !layout && ::qt_cast<QToolBox*>(widget) ) + widget = ((QToolBox*)widget)->currentItem(); + + MetaDataBase::addEntry( widget ); + + QLayout *l = 0; + int align = 0; + if ( !layout && ::qt_cast<QGroupBox*>(widget) ) { + QGroupBox *gb = (QGroupBox*)widget; + gb->setColumnLayout( 0, Qt::Vertical ); + layout = gb->layout(); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + switch ( type ) { + case HBox: + l = new QHBoxLayout( layout ); + break; + case VBox: + l = new QVBoxLayout( layout ); + break; + case Grid: + l = new QDesignerGridLayout( layout ); + break; + default: + return 0; + } + align = Qt::AlignTop; + MetaDataBase::setMargin( gb, metamargin ); + MetaDataBase::setSpacing( gb, metaspacing ); + } else { + if ( layout ) { + switch ( type ) { + case HBox: + l = new QHBoxLayout( layout ); + break; + case VBox: + l = new QVBoxLayout( layout ); + break; + case Grid: + l = new QDesignerGridLayout( layout ); + break; + default: + return 0; + } + MetaDataBase::addEntry( l ); + l->setSpacing( spacing ); + l->setMargin( margin ); + } else { + switch ( type ) { + case HBox: + l = new QHBoxLayout( widget ); + break; + case VBox: + l = new QVBoxLayout( widget ); + break; + case Grid: + l = new QDesignerGridLayout( widget ); + break; + default: + return 0; + } + MetaDataBase::addEntry( l ); + if ( widget ) { + MetaDataBase::setMargin( widget, metamargin ); + MetaDataBase::setSpacing( widget, metaspacing ); + } else { + l->setMargin( margin ); + l->setSpacing( spacing ); + } + } + } + l->setAlignment( align ); + MetaDataBase::addEntry( l ); + return l; +} + +void WidgetFactory::deleteLayout( QWidget *widget ) +{ + if ( !widget ) + return; + + if ( ::qt_cast<QTabWidget*>(widget) ) + widget = ((QTabWidget*)widget)->currentPage(); + if ( ::qt_cast<QWizard*>(widget) ) + widget = ((QWizard*)widget)->currentPage(); + if ( ::qt_cast<QMainWindow*>(widget) ) + widget = ((QMainWindow*)widget)->centralWidget(); + if ( ::qt_cast<QWidgetStack*>(widget) ) + widget = ((QWidgetStack*)widget)->visibleWidget(); + if ( ::qt_cast<QToolBox*>(widget) ) + widget = ((QToolBox*)widget)->currentItem(); + delete widget->layout(); +} + +/*! Factory functions for creating a widget of the type \a className + as child of \a parent with the name \a name. + + If \a init is TRUE, some initial default properties are set. This + has to be in sync with the initChangedProperties() function! +*/ + +QWidget *WidgetFactory::createWidget( const QString &className, QWidget *parent, const char *name, bool init, + const QRect *r, Qt::Orientation orient ) +{ + if ( className == "QPushButton" ) { + QPushButton *b = 0; + if ( init ) { + b = new QDesignerPushButton( parent, name ); + b->setText( QString::fromLatin1( name ) ); + } else { + b = new QDesignerPushButton( parent, name ); + } + QWidget *w = find_formwindow( b ); + b->setAutoDefault( w && ::qt_cast<QDialog*>(((FormWindow*)w)->mainContainer()) ); + return b; + } else if ( className == "QToolButton" ) { + if ( init ) { + QDesignerToolButton *tb = new QDesignerToolButton( parent, name ); + if ( ::qt_cast<QToolBox*>(widgetOfContainer(parent))) { + tb->setUsesTextLabel(TRUE); + tb->setTextLabel("..."); + tb->setAutoRaise(TRUE); + tb->setTextPosition(QToolButton::BesideIcon); + } else { + tb->setText( "..." ); + } + return tb; + } + return new QDesignerToolButton( parent, name ); + } else if ( className == "QCheckBox" ) { + if ( init ) { + QDesignerCheckBox *cb = new QDesignerCheckBox( parent, name ); + cb->setText( QString::fromLatin1( name ) ); + return cb; + } + return new QDesignerCheckBox( parent, name ); + } else if ( className == "QRadioButton" ) { + if ( init ) { + QDesignerRadioButton *rb = new QDesignerRadioButton( parent, name ); + rb->setText( QString::fromLatin1( name ) ); + return rb; + } + return new QDesignerRadioButton( parent, name ); + } else if ( className == "QGroupBox" ) { + if ( init ) + return new QGroupBox( QString::fromLatin1( name ), parent, name ); + return new QGroupBox( parent, name ); + } else if ( className == "QButtonGroup" ) { + if ( init ) + return new QButtonGroup( QString::fromLatin1( name ), parent, name ); + return new QButtonGroup( parent, name ); + } else if ( className == "QIconView" ) { +#if !defined(QT_NO_ICONVIEW) + QIconView* iv = new QIconView( parent, name ); + if ( init ) + (void) new QIconViewItem( iv, i18n( "New Item" ) ); + return iv; +#else + return 0; +#endif + } else if ( className == "QTable" ) { +#if !defined(QT_NO_TABLE) + if ( init ) + return new QTable( 3, 3, parent, name ); + return new QTable( parent, name ); +#else + return 0; +#endif +#ifndef QT_NO_SQL + } else if ( className == "QDataTable" ) { + return new QDataTable( parent, name ); +#endif //QT_NO_SQL + } else if ( className == "QDateEdit" ) { + return new QDateEdit( parent, name ); + } else if ( className == "QTimeEdit" ) { + return new QTimeEdit( parent, name ); + } else if ( className == "QDateTimeEdit" ) { + return new QDateTimeEdit( parent, name ); + } + else if ( className == "QListBox" ) { + QListBox* lb = new QListBox( parent, name ); + if ( init ) { + lb->insertItem( i18n( "New Item" ) ); + lb->setCurrentItem( 0 ); + } + return lb; + } else if ( className == "QListView" ) { + QListView *lv = new QListView( parent, name ); + lv->setSorting( -1 ); + if ( init ) { + lv->addColumn( i18n( "Column 1" ) ); + lv->setCurrentItem( new QListViewItem( lv, i18n( "New Item" ) ) ); + } + return lv; + } else if ( className == "QLineEdit" ) + return new QLineEdit( parent, name ); + else if ( className == "QSpinBox" ) + return new QSpinBox( parent, name ); + else if ( className == "QSplitter" ) + return new QSplitter( parent, name ); + else if ( className == "QMultiLineEdit" ) + return new QMultiLineEdit( parent, name ); + else if ( className == "QTextEdit" ) + return new QTextEdit( parent, name ); + else if ( className == "QLabel" || className == "TextLabel" ) { + QDesignerLabel *l = new QDesignerLabel( parent, name ); + if ( init ) { + l->setText( QString::fromLatin1( name ) ); + MetaDataBase::addEntry( l ); + MetaDataBase::setPropertyChanged( l, "text", TRUE ); + } + return l; + } else if ( className == "PixmapLabel" ) { + QDesignerLabel *l = new QDesignerLabel( parent, name ); + if ( init ) { + l->setPixmap( BarIcon( "designer_qtlogo.png", KDevDesignerPartFactory::instance() ) ); + l->setScaledContents( TRUE ); + MetaDataBase::addEntry( l ); + MetaDataBase::setPropertyChanged( l, "pixmap", TRUE ); + MetaDataBase::setPropertyChanged( l, "scaledContents", TRUE ); + } + return l; + } else if ( className == "QLayoutWidget" ) + return new QLayoutWidget( parent, name ); + else if ( className == "QTabWidget" ) { + QTabWidget *tw = new QDesignerTabWidget( parent, name ); + if ( init ) { + FormWindow *fw = find_formwindow( parent ); + QWidget *w = fw ? new QDesignerWidget( fw, tw, "tab" ) : new QWidget( tw, "tab" ); + tw->addTab( w, i18n("Tab 1") ); + MetaDataBase::addEntry( w ); + w = fw ? new QDesignerWidget( fw, tw, "tab" ) : new QWidget( tw, "tab" ); + tw->addTab( w, i18n("Tab 2") ); + MetaDataBase::addEntry( tw ); + MetaDataBase::addEntry( w ); + } + return tw; + } else if ( className == "QWidgetStack" ) { + QDesignerWidgetStack *ws = new QDesignerWidgetStack( parent, name ); + if ( init ) { + FormWindow *fw = find_formwindow( parent ); + QWidget *w = fw ? new QDesignerWidget( fw, ws, "WStackPage" ) : new QWidget( ws, "WStackPage" ); + ws->insertPage( w ); + MetaDataBase::addEntry( w ); + MetaDataBase::addEntry( ws ); + } + return ws; + } else if ( className == "QComboBox" ) { + return new QComboBox( FALSE, parent, name ); + } else if ( className == "QWidget" ) { + if ( parent && + ( ::qt_cast<FormWindow*>(parent) || + ::qt_cast<QWizard*>(parent) || + ::qt_cast<QTabWidget*>(parent) || + ::qt_cast<QWidgetStack*>(parent) || + ::qt_cast<QToolBox*>(parent) || + ::qt_cast<QMainWindow*>(parent) ) ) { + FormWindow *fw = find_formwindow( parent ); + if ( fw ) { + QDesignerWidget *dw = new QDesignerWidget( fw, parent, name ); + MetaDataBase::addEntry( dw ); + return dw; + } + } + return new QWidget( parent, name ); + } else if ( className == "QDialog" ) { + QDialog *dia = 0; + if ( ::qt_cast<FormWindow*>(parent) ) + dia = new QDesignerDialog( (FormWindow*)parent, parent, name ); + else + dia = new QDialog( parent, name ); +#if defined(QT_NON_COMMERCIAL) + if ( ::qt_cast<MainWindow*>(parent) ) +#else + if ( parent ) +#endif + dia->reparent( parent, QPoint( 0, 0 ), TRUE ); + return dia; + } else if ( className == "QWizard" ) { + QWizard *wiz = new QDesignerWizard( parent, name ); +#if defined(QT_NON_COMMERCIAL) + if ( ::qt_cast<MainWindow*>(parent) ) +#else + if ( parent ) +#endif + wiz->reparent( parent, QPoint( 0, 0 ), TRUE ); + if ( init && ::qt_cast<FormWindow*>(parent) ) { + QDesignerWidget *dw = new QDesignerWidget( (FormWindow*)parent, wiz, "WizardPage" ); + MetaDataBase::addEntry( dw ); + wiz->addPage( dw, i18n( "Page" ) ); + QTimer::singleShot( 0, wiz, SLOT( next() ) ); + } + return wiz; + } else if ( className == "Spacer" ) { + Spacer *s = new Spacer( parent, name ); + MetaDataBase::addEntry( s ); + MetaDataBase::setPropertyChanged( s, "orientation", TRUE ); + MetaDataBase::setPropertyChanged( s, "sizeType", TRUE ); + if ( !r ) + return s; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + s->setOrientation( orient ); + else if ( r->width() < r->height() ) + s->setOrientation( Qt::Vertical ); + else + s->setOrientation( Qt::Horizontal ); + return s; + } else if ( className == "QLCDNumber" ) + return new QLCDNumber( parent, name ); + else if ( className == "QProgressBar" ) + return new QProgressBar( parent, name ); + else if ( className == "QTextView" ) + return new QTextView( parent, name ); + else if ( className == "QTextBrowser" ) + return new QTextBrowser( parent, name ); + else if ( className == "QDial" ) + return new QDial( parent, name ); + else if ( className == "QSlider" ) { + QSlider *s = new QSlider( parent, name ); + if ( !r ) + return s; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + s->setOrientation( orient ); + else if ( r->width() > r->height() ) + s->setOrientation( Qt::Horizontal ); + MetaDataBase::addEntry( s ); + MetaDataBase::setPropertyChanged( s, "orientation", TRUE ); + return s; + } else if ( className == "QScrollBar" ) { + QScrollBar *s = new QScrollBar( parent, name ); + if ( !r ) + return s; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + s->setOrientation( orient ); + else if ( r->width() > r->height() ) + s->setOrientation( Qt::Horizontal ); + MetaDataBase::addEntry( s ); + MetaDataBase::setPropertyChanged( s, "orientation", TRUE ); + return s; + } else if ( className == "QFrame" ) { + if ( !init ) + return new QFrame( parent, name ); + QFrame *f = new QFrame( parent, name ); + f->setFrameStyle( QFrame::StyledPanel | QFrame::Raised ); + return f; + } else if ( className == "Line" ) { + Line *l = new Line( parent, name ); + MetaDataBase::addEntry( l ); + MetaDataBase::setPropertyChanged( l, "orientation", TRUE ); + MetaDataBase::setPropertyChanged( l, "frameShadow", TRUE ); + MetaDataBase::setPropertyChanged( l, "frameShape", TRUE ); + if ( !r ) + return l; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + l->setOrientation( orient ); + else if ( r->width() < r->height() ) + l->setOrientation( Qt::Vertical ); + return l; + } else if ( className == "QMainWindow" ) { + QMainWindow *mw = new QMainWindow( parent, name, 0 ); + mw->setDockEnabled( Qt::DockMinimized, FALSE ); + QDesignerWidget *dw = new QDesignerWidget( (FormWindow*)parent, mw, "central widget" ); + mw->setDockMenuEnabled( FALSE ); + MetaDataBase::addEntry( dw ); + mw->setCentralWidget( dw ); + (void)mw->statusBar(); + dw->show(); + return mw; + } else if ( className == "QToolBox" ) { + if ( !init ) + return new QDesignerToolBox( parent, name ); + QToolBox *tb = new QDesignerToolBox( parent, name ); + FormWindow *fw = find_formwindow( parent ); + QWidget *w = fw ? new QDesignerWidget( fw, tb, "page1" ) : + new QWidget( tb, "page1" ); + tb->addItem( w, i18n("Page 1") ); + MetaDataBase::addEntry( w ); + w = fw ? new QDesignerWidget( fw, tb, "page2" ) : new QWidget( tb, "page2" ); + tb->addItem( w, i18n("Page 2") ); + MetaDataBase::addEntry( tb ); + MetaDataBase::addEntry( w ); + return tb; + } +#ifndef QT_NO_SQL + else if ( className == "QDataBrowser" ) { + QWidget *w = new QDesignerDataBrowser( parent, name ); + if ( parent ) + w->reparent( parent, QPoint( 0, 0 ), TRUE ); + return w; + } else if ( className == "QDataView" ) { + QWidget *w = new QDesignerDataView( parent, name ); + if ( parent ) + w->reparent( parent, QPoint( 0, 0 ), TRUE ); + return w; + } +#endif + + WidgetInterface *iface = 0; + widgetManager()->queryInterface( className, &iface ); + if ( !iface ) + return 0; + + QWidget *w = iface->create( className, parent, name ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( init && WidgetDatabase::isCustomPluginWidget( WidgetDatabase::idFromClassName( className ) ) ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + iface2->addPage( className, w, "Page", -1 ); + iface2->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + iface->release(); + return w; +} + + + +/*! Find out which type the layout of the widget is. Returns \c HBox, + \c VBox, \c Grid or \c NoLayout. \a layout points to this + QWidget::layout() of \a w or to 0 after the function call. +*/ + +WidgetFactory::LayoutType WidgetFactory::layoutType( QWidget *w, QLayout *&layout ) +{ + layout = 0; + + if ( ::qt_cast<QTabWidget*>(w) ) + w = ((QTabWidget*)w)->currentPage(); + if ( ::qt_cast<QWizard*>(w) ) + w = ((QWizard*)w)->currentPage(); + if ( ::qt_cast<QMainWindow*>(w) ) + w = ((QMainWindow*)w)->centralWidget(); + if ( ::qt_cast<QWidgetStack*>(w) ) + w = ((QWidgetStack*)w)->visibleWidget(); + if ( ::qt_cast<QToolBox*>(w) ) + w = ((QToolBox*)w)->currentItem(); + + if ( ::qt_cast<QSplitter*>(w) ) + return ( (QSplitter*)w )->orientation() == Horizontal ? HBox : VBox; + + if ( !w || !w->layout() ) + return NoLayout; + QLayout *lay = w->layout(); + + if ( ::qt_cast<QGroupBox*>(w) ) { + QObjectList *l = lay->queryList( "QLayout" ); + if ( l && l->first() ) + lay = (QLayout*)l->first(); + delete l; + } + layout = lay; + + if ( ::qt_cast<QHBoxLayout*>(lay) ) + return HBox; + else if ( ::qt_cast<QVBoxLayout*>(lay) ) + return VBox; + else if ( ::qt_cast<QGridLayout*>(lay) ) + return Grid; + return NoLayout; +} + +/*! + \overload +*/ +WidgetFactory::LayoutType WidgetFactory::layoutType( QLayout *layout ) +{ + if ( ::qt_cast<QHBoxLayout*>(layout) ) + return HBox; + else if ( ::qt_cast<QVBoxLayout*>(layout) ) + return VBox; + else if ( ::qt_cast<QGridLayout*>(layout) ) + return Grid; + return NoLayout; +} + +/*! + \overload +*/ +WidgetFactory::LayoutType WidgetFactory::layoutType( QWidget *w ) +{ + QLayout *l = 0; + return layoutType( w, l ); +} + + +QWidget *WidgetFactory::layoutParent( QLayout *layout ) +{ + QObject *o = layout; + while ( o ) { + if ( o->isWidgetType() ) + return (QWidget*)o; + o = o->parent(); + } + return 0; +} + +/*! Returns the widget into which children should be inserted when \a + w is a container known to the designer. + + Usually that is \a w itself, sometimes it is different (e.g. a + tabwidget is known to the designer as a container but the child + widgets should be inserted into the current page of the + tabwidget. So in this case this function returns the current page of + the tabwidget.) + */ +QWidget* WidgetFactory::containerOfWidget( QWidget *w ) +{ + if ( !w ) + return w; + if ( ::qt_cast<QTabWidget*>(w) ) + return ((QTabWidget*)w)->currentPage(); + if ( ::qt_cast<QWizard*>(w) ) + return ((QWizard*)w)->currentPage(); + if ( ::qt_cast<QWidgetStack*>(w) ) + return ((QWidgetStack*)w)->visibleWidget(); + if ( ::qt_cast<QToolBox*>(w) ) + return ((QToolBox*)w)->currentItem(); + if ( ::qt_cast<QMainWindow*>(w) ) + return ((QMainWindow*)w)->centralWidget(); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( !WidgetDatabase::isCustomPluginWidget( WidgetDatabase::idFromClassName( classNameOf( w ) ) ) ) + return w; + WidgetInterface *iface = 0; + widgetManager()->queryInterface( classNameOf( w ), &iface ); + if ( !iface ) + return w; + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( !iface2 ) + return w; + QWidget *c = iface2->containerOfWidget( w->className(), w ); + iface2->release(); + iface->release(); + if ( c ) + return c; +#endif // QT_CONTAINER_CUSTOM_WIDGETS + return w; +} + +/*! Returns the actual designer widget of the container \a w. This is + normally \a w itself, but might be a parent or grand parent of \a w + (e.g. when working with a tabwidget and \a w is the container which + contains and layouts childs, but the actual widget known to the + designer is the tabwidget which is the parent of \a w. So this + function returns the tabwidget then.) +*/ + +QWidget* WidgetFactory::widgetOfContainer( QWidget *w ) +{ + if ( w && ::qt_cast<QWidgetStack*>(w->parentWidget()) ) + w = w->parentWidget(); + if ( w->parentWidget() && w->parentWidget()->parentWidget() && + w->parentWidget()->parentWidget()->parentWidget() && + ::qt_cast<QToolBox*>(w->parentWidget()->parentWidget()->parentWidget()) ) + return w->parentWidget()->parentWidget()->parentWidget(); + while ( w ) { + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ); + if ( WidgetDatabase::isContainer( id ) || + w && ::qt_cast<FormWindow*>(w->parentWidget()) ) + return w; + w = w->parentWidget(); + } + return w; +} + +/*! + Returns whether \a o is a passive interactor or not. + */ + +bool WidgetFactory::lastWasAPassiveInteractor = FALSE; +QGuardedPtr<QObject> *WidgetFactory::lastPassiveInteractor = new QGuardedPtr<QObject>(); + +bool WidgetFactory::isPassiveInteractor( QObject* o ) +{ + if ( lastPassiveInteractor && *lastPassiveInteractor && (QObject*)(*lastPassiveInteractor) == o ) + return lastWasAPassiveInteractor; + lastWasAPassiveInteractor = FALSE; + (*lastPassiveInteractor) = o; + if ( QApplication::activePopupWidget() ) // if a popup is open, we have to make sure that this one is closed, else X might do funny things + return ( lastWasAPassiveInteractor = TRUE ); + + if ( ::qt_cast<QTabBar*>(o) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast<QSizeGrip*>(o) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast<QButton*>(o) && + ( ::qt_cast<QTabBar*>(o->parent()) || ::qt_cast<QToolBox*>(o->parent()) ) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast<QPushButton*>(o) && ::qt_cast<QWizard*>(o->parent()) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast<QMenuBar*>(o) && ::qt_cast<QMainWindow*>(o->parent()) ) + return ( lastWasAPassiveInteractor = TRUE ); +// else if ( ::qt_cast<QDockWindowHandle*>(o) ) + else if ( o->inherits( "QDockWindowHandle" ) ) + return ( lastWasAPassiveInteractor = TRUE ); +// else if ( ::qt_cast<QHideDock*>(o) ) + else if ( o->inherits( "QHideDock" ) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( qstrcmp( o->name(), "designer_wizardstack_button" ) == 0 ) + return ( lastWasAPassiveInteractor = TRUE ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( !o->isWidgetType() ) + return ( lastWasAPassiveInteractor = FALSE ); + WidgetInterface *iface = 0; + QWidget *w = (QWidget*)o; + while ( !iface && w && !::qt_cast<FormWindow*>(w) ) { + widgetManager()->queryInterface( classNameOf( w ), &iface ); + w = w->parentWidget(); + } + if ( !iface ) + return ( lastWasAPassiveInteractor = FALSE ); + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( !iface2 ) + return ( lastWasAPassiveInteractor = FALSE ); + QWidget *fw = MainWindow::self->isAFormWindowChild( (QWidget*)o ); + if ( !fw ) + return ( lastWasAPassiveInteractor = FALSE ); + QWidget *dw = ( (FormWindow*)fw )->designerWidget( (QWidget*)o ); + if ( !dw ) + return ( lastWasAPassiveInteractor = FALSE ); + lastWasAPassiveInteractor = iface2->isPassiveInteractor( dw->className(), (QWidget*)o ); + iface2->release(); + iface->release(); +#endif // QT_CONTAINER_CUSTOM_WIDGETS + return lastWasAPassiveInteractor; +} + + +/*! + Returns the class name of object \a o that should be used for externally (i.e. for saving) + */ +const char* WidgetFactory::classNameOf( QObject* o ) +{ + if ( o->isA( "PropertyObject" ) ) + return o->className(); + if (WidgetDatabase::isCustomPluginWidget(WidgetDatabase::idFromClassName(o->className()))) + return o->className(); + else if ( ::qt_cast<QDesignerTabWidget*>(o) ) + return "QTabWidget"; + else if ( ::qt_cast<QDesignerWidgetStack*>(o) ) + return "QWidgetStack"; + else if ( ::qt_cast<QWidgetStack*>(o) ) + return "QWeDoNotWantToBreakTabWidget"; + else if ( ::qt_cast<QDesignerDialog*>(o) ) + return "QDialog"; + else if ( ::qt_cast<QDesignerWidget*>(o) ) + return "QWidget"; + else if ( o->inherits( "CustomWidget" ) ) + return ( (CustomWidget*)o )->realClassName().latin1(); + else if ( ::qt_cast<QDesignerLabel*>(o) ) + return "QLabel"; + else if ( ::qt_cast<QDesignerWizard*>(o) ) + return "QWizard"; + else if ( ::qt_cast<QDesignerPushButton*>(o) ) + return "QPushButton"; + else if ( ::qt_cast<QDesignerToolButton*>(o) ) + return "QToolButton"; + else if ( ::qt_cast<QDesignerRadioButton*>(o) ) + return "QRadioButton"; + else if ( ::qt_cast<QDesignerCheckBox*>(o) ) + return "QCheckBox"; + else if ( ::qt_cast<MenuBarEditor*>(o) ) + return "QMenuBar"; + else if ( ::qt_cast<QDesignerToolBar*>(o) ) + return "QToolBar"; + else if ( ::qt_cast<QDesignerAction*>(o) ) + return "QAction"; + else if ( ::qt_cast<QDesignerActionGroup*>(o) ) + return "QActionGroup"; + else if ( ::qt_cast<PopupMenuEditor*>(o) ) + return "QPopupMenu"; + else if ( ::qt_cast<QDesignerToolBox*>(o) ) + return "QToolBox"; +#ifndef QT_NO_SQL + else if ( ::qt_cast<QDesignerDataBrowser*>(o) ) + return "QDataBrowser"; + else if ( ::qt_cast<QDesignerDataView*>(o) ) + return "QDataView"; +#endif + return o->className(); +} + +QString WidgetFactory::defaultSignal( QObject *w ) +{ + if ( ::qt_cast<QRadioButton*>(w) || ::qt_cast<QCheckBox*>(w) ) + return "toggled"; + else if ( ::qt_cast<QButton*>(w) || ::qt_cast<QButtonGroup*>(w) ) + return "clicked"; + else if ( ::qt_cast<QTextBrowser*>(w) ) + return "linkClicked"; + else if ( ::qt_cast<QLineEdit*>(w) || ::qt_cast<QTextEdit*>(w) ) + return "textChanged"; + else if ( ::qt_cast<QListView*>(w) || ::qt_cast<QIconView*>(w) || + ::qt_cast<QListBox*>(w) || ::qt_cast<QTable*>(w) ) + return "selectionChanged"; + else if ( ::qt_cast<QTabWidget*>(w) ) + return "selected"; + else if ( ::qt_cast<QToolBox*>(w) ) + return "currentChanged"; + else if ( ::qt_cast<QWidgetStack*>(w) ) + return "aboutToShow"; + else if ( ::qt_cast<QSpinBox*>(w) || ::qt_cast<QSlider*>(w) || + ::qt_cast<QScrollBar*>(w) || ::qt_cast<QDateEdit*>(w) || + ::qt_cast<QTimeEdit*>(w) || ::qt_cast<QDateTimeEdit*>(w) || + ::qt_cast<QDial*>(w) ) + return "valueChanged"; + else if ( ::qt_cast<QComboBox*>(w) ) + return "activated"; + return QString::null; +} + +/*! As some properties are set by default when creating a widget this + functions markes this properties as changed. Has to be in sync with + createWidget()! +*/ + +void WidgetFactory::initChangedProperties( QObject *o ) +{ + if ( MainWindow::self && MainWindow::self->currProject() && + MainWindow::self->currProject()->fakeFormFileFor( o ) ) + return; + MetaDataBase::setPropertyChanged( o, "name", TRUE ); + if ( !::qt_cast<QDesignerToolBar*>(o) && !::qt_cast<MenuBarEditor*>(o) ) + MetaDataBase::setPropertyChanged( o, "geometry", TRUE ); + + if ( ::qt_cast<QPushButton*>(o) || + ::qt_cast<QRadioButton*>(o) || + ::qt_cast<QCheckBox*>(o) || + ::qt_cast<QToolButton*>(o) ) { + if (::qt_cast<QToolButton*>(o) && ::qt_cast<QToolBox*>(widgetOfContainer((QWidget*)o->parent()))) { + MetaDataBase::setPropertyChanged( o, "usesTextLabel", TRUE ); + MetaDataBase::setPropertyChanged( o, "textLabel", TRUE ); + MetaDataBase::setPropertyChanged( o, "autoRaise", TRUE ); + MetaDataBase::setPropertyChanged( o, "textPosition", TRUE ); + } else { + MetaDataBase::setPropertyChanged( o, "text", TRUE ); + } + } + else if ( ::qt_cast<QGroupBox*>(o) ) + MetaDataBase::setPropertyChanged( o, "title", TRUE ); + else if ( o->isA( "QFrame" ) ) { + MetaDataBase::setPropertyChanged( o, "frameShadow", TRUE ); + MetaDataBase::setPropertyChanged( o, "frameShape", TRUE ); + } else if ( ::qt_cast<QTabWidget*>(o) || ::qt_cast<QWizard*>(o) ) { + MetaDataBase::setPropertyChanged( o, "pageTitle", TRUE ); + MetaDataBase::setPropertyChanged( o, "pageName", TRUE ); + MetaDataBase::setPropertyChanged( o, "currentPage", TRUE ); + } else if ( ::qt_cast<QWidgetStack*>(o) ) { + MetaDataBase::setPropertyChanged( o, "currentPage", TRUE ); + MetaDataBase::setPropertyChanged( o, "pageName", TRUE ); + } else if ( ::qt_cast<QToolBox*>(o) ) { + MetaDataBase::setPropertyChanged( o, "currentIndex", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemName", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemLabel", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemIconSet", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemToolTip", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemBackgroundMode", TRUE ); +#ifndef QT_NO_TABLE + } else if ( ::qt_cast<QTable*>(o) ) { +# ifndef QT_NO_SQL + if (!::qt_cast<QDataTable*>(o) ) +# endif + { + MetaDataBase::setPropertyChanged( o, "numRows", TRUE ); + MetaDataBase::setPropertyChanged( o, "numCols", TRUE ); + QTable *t = (QTable*)o; + for ( int i = 0; i < 3; ++i ) { + t->horizontalHeader()->setLabel( i, QString::number( i + 1 ) ); + t->verticalHeader()->setLabel( i, QString::number( i + 1 ) ); + } + } +#endif + } else if ( ::qt_cast<QSplitter*>(o) ) { + MetaDataBase::setPropertyChanged( o, "orientation", TRUE ); + } else if ( ::qt_cast<QDesignerToolBar*>(o) ) { + MetaDataBase::setPropertyChanged( o, "label", TRUE ); + } else if ( ::qt_cast<MenuBarEditor*>(o) ) { + MetaDataBase::setPropertyChanged( o, "itemName", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemNumber", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemText", TRUE ); + } +} + +bool WidgetFactory::hasSpecialEditor( int id, QObject *editorWidget ) +{ + QString className = WidgetDatabase::className( id ); + + if ( className.contains( "ListBox" ) ) + return TRUE; + if ( className.contains( "ComboBox" ) ) + return TRUE; + if ( className.contains( "ListView" ) ) + return TRUE; + if ( className.contains( "IconView" ) ) + return TRUE; + if ( className == "QTextEdit" || className == "QMultiLineEdit" ) + return TRUE; + if ( ::qt_cast<QTable*>(editorWidget) != 0 ) + return TRUE; + + return FALSE; +} + +bool WidgetFactory::hasItems( int id, QObject *editorWidget ) +{ + QString className = WidgetDatabase::className( id ); + + if ( className.contains( "ListBox" ) || className.contains( "ListView" ) || + className.contains( "IconView" ) || className.contains( "ComboBox" ) || + ::qt_cast<QTable*>(editorWidget) != 0 ) + return TRUE; + + return FALSE; +} + +void WidgetFactory::editWidget( int id, QWidget *parent, QWidget *editWidget, FormWindow *fw ) +{ + QString className = WidgetDatabase::className( id ); + + if ( className.contains( "ListBox" ) ) { + if ( !::qt_cast<QListBox*>(editWidget) ) + return; + ListBoxEditor *e = new ListBoxEditor( parent, editWidget, fw ); + e->exec(); + delete e; + return; + } + + if ( className.contains( "ComboBox" ) ) { + if ( !::qt_cast<QComboBox*>(editWidget) ) + return; + QComboBox *cb = (QComboBox*)editWidget; + ListBoxEditor *e = new ListBoxEditor( parent, cb->listBox(), fw ); + e->exec(); + delete e; + cb->update(); + return; + } + + if ( className.contains( "ListView" ) ) { + if ( !::qt_cast<QListView*>(editWidget) ) + return; + QListView *lv = (QListView*)editWidget; + ListViewEditor *e = new ListViewEditor( parent, lv, fw ); + e->exec(); + delete e; + return; + } + + if ( className.contains( "IconView" ) ) { + if ( !::qt_cast<QIconView*>(editWidget) ) + return; + IconViewEditor *e = new IconViewEditor( parent, editWidget, fw ); + e->exec(); + delete e; + return; + } + + if ( className == "QMultiLineEdit" || className == "QTextEdit" ) { + MultiLineEditor *e = new MultiLineEditor( FALSE, TRUE, parent, editWidget, fw ); + e->exec(); + delete e; + return; + } +#ifndef QT_NO_TABLE + if (::qt_cast<QTable*>(editWidget) != 0) { + TableEditor *e = new TableEditor( parent, editWidget, fw ); + e->exec(); + delete e; + return; + } +#endif +} + +bool WidgetFactory::canResetProperty( QObject *w, const QString &propName ) +{ + if ( propName == "name" || propName == "geometry" ) + return FALSE; + QStringList l = *changedProperties->find( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ); + return l.findIndex( propName ) == -1; +} + +bool WidgetFactory::resetProperty( QObject *w, const QString &propName ) +{ + const QMetaProperty *p = w->metaObject()->property( w->metaObject()-> + findProperty( propName, TRUE ), TRUE ); + if (!p ) + return FALSE; + return p->reset( w ); +} + +QVariant WidgetFactory::defaultValue( QObject *w, const QString &propName ) +{ + if ( propName == "wordwrap" ) { + int v = defaultValue( w, "alignment" ).toInt(); + return QVariant( ( v & WordBreak ) == WordBreak, 0 ); + } else if ( propName == "toolTip" || propName == "whatsThis" ) { + return QVariant( QString::fromLatin1( "" ) ); + } else if ( w->inherits( "CustomWidget" ) ) { + return QVariant(); + } else if ( propName == "frameworkCode" ) { + return QVariant( TRUE, 0 ); + } else if ( propName == "layoutMargin" || propName == "layoutSpacing" ) { + return QVariant( -1 ); + } + + return *( *defaultProperties->find( WidgetDatabase::idFromClassName( classNameOf( w ) ) ) ).find( propName ); +} + +QString WidgetFactory::defaultCurrentItem( QObject *w, const QString &propName ) +{ + const QMetaProperty *p = w->metaObject()-> + property( w->metaObject()->findProperty( propName, TRUE ), TRUE ); + if ( !p ) { + int v = defaultValue( w, "alignment" ).toInt(); + if ( propName == "hAlign" ) { + if ( ( v & AlignAuto ) == AlignAuto ) + return "AlignAuto"; + if ( ( v & AlignLeft ) == AlignLeft ) + return "AlignLeft"; + if ( ( v & AlignCenter ) == AlignCenter || ( v & AlignHCenter ) == AlignHCenter ) + return "AlignHCenter"; + if ( ( v & AlignRight ) == AlignRight ) + return "AlignRight"; + if ( ( v & AlignJustify ) == AlignJustify ) + return "AlignJustify"; + } else if ( propName == "vAlign" ) { + if ( ( v & AlignTop ) == AlignTop ) + return "AlignTop"; + if ( ( v & AlignCenter ) == AlignCenter || ( v & AlignVCenter ) == AlignVCenter ) + return "AlignVCenter"; + if ( ( v & AlignBottom ) == AlignBottom ) + return "AlignBottom"; + } else if ( propName == "resizeMode" ) { + return "Auto"; + } + return QString::null; + + } + return p->valueToKey( defaultValue( w, propName ).toInt() ); +} + +QWidget *WidgetFactory::createCustomWidget( QWidget *parent, const char *name, MetaDataBase::CustomWidget *w ) +{ + if ( !w ) + return 0; + return new CustomWidget( parent, name, w ); +} + +QVariant WidgetFactory::property( QObject *w, const char *name ) +{ + int id = w->metaObject()->findProperty( name, TRUE ); + const QMetaProperty* p = w->metaObject()->property( id, TRUE ); + if ( !p || !p->isValid() ) + return MetaDataBase::fakeProperty( w, name ); + return w->property( name ); +} + +void QDesignerLabel::updateBuddy() +{ + + if ( myBuddy.isEmpty() ) + return; + + QObjectList *l = topLevelWidget()->queryList( "QWidget", myBuddy, FALSE, TRUE ); + if ( !l || !l->first() ) { + delete l; + return; + } + + QLabel::setBuddy( (QWidget*)l->first() ); + delete l; +} + + +void QDesignerWidget::resizeEvent( QResizeEvent* e) +{ + if ( need_frame ) { + QPainter p(this); + p.setPen( backgroundColor() ); + p.drawRect( QRect( QPoint(0,0), e->oldSize() ) ); + } +} + +void QDesignerWidget::paintEvent( QPaintEvent *e ) +{ + if ( need_frame ) { + QPainter p(this); + p.setPen( backgroundColor().dark() ); + p.drawRect( rect() ); + } + formwindow->paintGrid( this, e ); +} + +void QDesignerDialog::paintEvent( QPaintEvent *e ) +{ + formwindow->paintGrid( this, e ); +} + +QSizePolicy QLayoutWidget::sizePolicy() const +{ + return sp; +} + +bool QLayoutWidget::event( QEvent *e ) +{ + if ( e && ( e->type() == QEvent::ChildInserted || + e->type() == QEvent::ChildRemoved || + e->type() == QEvent::LayoutHint || + e->type() == QEvent::Reparent ) ) + updateSizePolicy(); + return QWidget::event( e ); +} + +/* + This function must be called on QLayoutWidget creation and whenever + the QLayoutWidget's parent layout changes (e.g., from a QHBoxLayout + to a QVBoxLayout), because of the (illogical) way layouting works. +*/ +void QLayoutWidget::updateSizePolicy() +{ + if ( !children() || children()->count() == 0 ) { + sp = QWidget::sizePolicy(); + return; + } + + /* + QSizePolicy::MayShrink & friends are private. Here we assume the + following: + + Fixed = 0 + Maximum = MayShrink + Minimum = MayGrow + Preferred = MayShrink | MayGrow + */ + + int ht = (int) QSizePolicy::Preferred; + int vt = (int) QSizePolicy::Preferred; + + if ( layout() ) { + /* + parentLayout is set to the parent layout if there is one and if it is + top level, in which case layouting is illogical. + */ + QLayout *parentLayout = 0; + if ( parent() && parent()->isWidgetType() ) { + parentLayout = ((QWidget *)parent())->layout(); + if ( parentLayout && + ::qt_cast<QLayoutWidget*>(parentLayout->mainWidget()) ) + parentLayout = 0; + } + + QObjectListIt it( *children() ); + QObject *o; + + if ( ::qt_cast<QVBoxLayout*>(layout()) ) { + if ( ::qt_cast<QHBoxLayout*>(parentLayout) ) + vt = QSizePolicy::Minimum; + else + vt = QSizePolicy::Fixed; + + while ( ( o = it.current() ) ) { + ++it; + if ( !o->isWidgetType() || ( (QWidget*)o )->testWState( WState_ForceHide ) ) + continue; + QWidget *w = (QWidget*)o; + + if ( !w->sizePolicy().mayGrowHorizontally() ) + ht &= ~QSizePolicy::Minimum; + if ( !w->sizePolicy().mayShrinkHorizontally() ) + ht &= ~QSizePolicy::Maximum; + if ( w->sizePolicy().mayGrowVertically() ) + vt |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkVertically() ) + vt |= QSizePolicy::Maximum; + } + } else if ( ::qt_cast<QHBoxLayout*>(layout()) ) { + if ( ::qt_cast<QVBoxLayout*>(parentLayout) ) + ht = QSizePolicy::Minimum; + else + ht = QSizePolicy::Fixed; + + while ( ( o = it.current() ) ) { + ++it; + if ( !o->isWidgetType() || ( (QWidget*)o )->testWState( WState_ForceHide ) ) + continue; + QWidget *w = (QWidget*)o; + + if ( w->sizePolicy().mayGrowHorizontally() ) + ht |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkHorizontally() ) + ht |= QSizePolicy::Maximum; + if ( !w->sizePolicy().mayGrowVertically() ) + vt &= ~QSizePolicy::Minimum; + if ( !w->sizePolicy().mayShrinkVertically() ) + vt &= ~QSizePolicy::Maximum; + } + } else if ( ::qt_cast<QGridLayout*>(layout()) ) { + ht = QSizePolicy::Fixed; + vt = QSizePolicy::Fixed; + if ( parentLayout ) { + if ( ::qt_cast<QVBoxLayout*>(parentLayout) ) + ht = QSizePolicy::Minimum; + else if ( ::qt_cast<QHBoxLayout*>(parentLayout) ) + vt = QSizePolicy::Minimum; + } + + while ( ( o = it.current() ) ) { + ++it; + if ( !o->isWidgetType() || ( (QWidget*)o )->testWState( WState_ForceHide ) ) + continue; + QWidget *w = (QWidget*)o; + + if ( w->sizePolicy().mayGrowHorizontally() ) + ht |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkHorizontally() ) + ht |= QSizePolicy::Maximum; + if ( w->sizePolicy().mayGrowVertically() ) + vt |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkVertically() ) + vt |= QSizePolicy::Maximum; + } + } + if ( layout()->expanding() & QSizePolicy::Horizontally ) + ht = QSizePolicy::Expanding; + if ( layout()->expanding() & QSizePolicy::Vertically ) + vt = QSizePolicy::Expanding; + + layout()->invalidate(); + } + + sp = QSizePolicy( (QSizePolicy::SizeType) ht, (QSizePolicy::SizeType) vt ); + updateGeometry(); +} + +void CustomWidget::paintEvent( QPaintEvent *e ) +{ + if ( ::qt_cast<FormWindow*>(parentWidget()) ) { + ( (FormWindow*)parentWidget() )->paintGrid( this, e ); + } else { + QPainter p( this ); + p.fillRect( rect(), colorGroup().dark() ); + p.setPen( colorGroup().light() ); + p.drawText( 2, 2, width() - 4, height() - 4, Qt::AlignAuto | Qt::AlignTop, cusw->className ); + p.drawPixmap( ( width() - cusw->pixmap->width() ) / 2, + ( height() - cusw->pixmap->height() ) / 2, + *cusw->pixmap ); + } +} + + +CustomWidgetFactory::CustomWidgetFactory() +{ +} + +QWidget *CustomWidgetFactory::createWidget( const QString &className, QWidget *parent, const char *name ) const +{ + MetaDataBase::CustomWidget *w = MetaDataBase::customWidget( WidgetDatabase::idFromClassName( className ) ); + if ( !w ) + return 0; + return WidgetFactory::createCustomWidget( parent, name, w ); +} + + +QDesignerToolBox::QDesignerToolBox( QWidget *parent, const char *name ) + : QToolBox( parent, name ) +{ +} + +QString QDesignerToolBox::itemLabel() const +{ + return QToolBox::itemLabel( currentIndex() ); +} + +void QDesignerToolBox::setItemLabel( const QString &l ) +{ + QToolBox::setItemLabel( currentIndex(), l ); +} + +QCString QDesignerToolBox::itemName() const +{ + return currentItem() ? currentItem()->name() : 0; +} + +void QDesignerToolBox::setItemName( const QCString &n ) +{ + if (currentItem()) + currentItem()->setName( n ); +} + + +Qt::BackgroundMode QDesignerToolBox::itemBackgroundMode() const +{ + return (item(0) ? item(0)->backgroundMode() : PaletteBackground); +} + +void QDesignerToolBox::setItemBackgroundMode( BackgroundMode bmode ) +{ + for (int i = 0; i < count(); ++i) { + QWidget *w = item(i); + w->setBackgroundMode( bmode ); + w->update(); + } +} + +void QDesignerToolBox::itemInserted( int index ) +{ + if (count() > 1) + item(index)->setBackgroundMode(item(index>0?0:1)->backgroundMode()); +} diff --git a/kdevdesigner/designer/widgetfactory.h b/kdevdesigner/designer/widgetfactory.h new file mode 100644 index 00000000..b235b8f4 --- /dev/null +++ b/kdevdesigner/designer/widgetfactory.h @@ -0,0 +1,501 @@ +/********************************************************************** +** 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 WIDGETFACTORY_H +#define WIDGETFACTORY_H + +#include <qvariant.h> +#include <qiconset.h> +#include <qstring.h> +#include <qintdict.h> +#include <qtabwidget.h> +#include <qpixmap.h> +#include <qsize.h> +#include <qpainter.h> +#include <qevent.h> +#include <qobjectlist.h> +#include <qlabel.h> +#include <qwizard.h> +#include <qptrdict.h> +#include <qpushbutton.h> +#include <qtoolbutton.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qwidgetstack.h> +#include <qguardedptr.h> +#include <qtoolbox.h> + +#include "metadatabase.h" +#include "qwidgetfactory.h" + +class QWidget; +class QLayout; +class FormWindow; + +class CustomWidgetFactory : public QWidgetFactory +{ +public: + CustomWidgetFactory(); + QWidget *createWidget( const QString &className, QWidget *parent, const char *name ) const; + +}; + +class WidgetFactory : public Qt +{ + friend class CustomWidgetFactory; + +public: + enum LayoutType { + HBox, + VBox, + Grid, + NoLayout + }; + + static QWidget *create( int id, QWidget *parent, const char *name = 0, bool init = TRUE, + const QRect *rect = 0, Qt::Orientation orient = Qt::Horizontal ); + static QLayout *createLayout( QWidget *widget, QLayout* layout, LayoutType type ); + static void deleteLayout( QWidget *widget ); + + static LayoutType layoutType( QWidget *w ); + static LayoutType layoutType( QWidget *w, QLayout *&layout ); + static LayoutType layoutType( QLayout *layout ); + static QWidget *layoutParent( QLayout *layout ); + + static QWidget* containerOfWidget( QWidget *w ); + static QWidget* widgetOfContainer( QWidget *w ); + + static bool isPassiveInteractor( QObject* o ); + static const char* classNameOf( QObject* o ); + + static void initChangedProperties( QObject *o ); + + static bool hasSpecialEditor( int id, QObject *editorWidget ); + static bool hasItems( int id, QObject *editorWidget ); + static void editWidget( int id, QWidget *parent, QWidget *editWidget, FormWindow *fw ); + + static bool canResetProperty( QObject *w, const QString &propName ); + static bool resetProperty( QObject *w, const QString &propName ); + static QVariant defaultValue( QObject *w, const QString &propName ); + static QString defaultCurrentItem( QObject *w, const QString &propName ); + + static QVariant property( QObject *w, const char *name ); + static void saveDefaultProperties( QObject *w, int id ); + static void saveChangedProperties( QObject *w, int id ); + + static QString defaultSignal( QObject *w ); + +private: + static QWidget *createWidget( const QString &className, QWidget *parent, const char *name, bool init, + const QRect *r = 0, Qt::Orientation orient = Qt::Horizontal ); + static QWidget *createCustomWidget( QWidget *parent, const char *name, MetaDataBase::CustomWidget *w ); + + static QGuardedPtr<QObject> *lastPassiveInteractor; + static bool lastWasAPassiveInteractor; +}; + + +class QDesignerTabWidget : public QTabWidget +{ + Q_OBJECT + Q_PROPERTY( int currentPage READ currentPage WRITE setCurrentPage STORED false DESIGNABLE true ) + Q_PROPERTY( QString pageTitle READ pageTitle WRITE setPageTitle STORED false DESIGNABLE true ) + Q_PROPERTY( QCString pageName READ pageName WRITE setPageName STORED false DESIGNABLE true ) +public: + QDesignerTabWidget( QWidget *parent, const char *name ); + + int currentPage() const; + void setCurrentPage( int i ); + QString pageTitle() const; + void setPageTitle( const QString& title ); + QCString pageName() const; + void setPageName( const QCString& name ); + + int count() const; + QTabBar *tabBar() const { return QTabWidget::tabBar(); } + + bool eventFilter( QObject*, QEvent* ); + +private: + QPoint pressPoint; + QWidget *dropIndicator; + QWidget *dragPage; + QString dragLabel; + bool mousePressed; +}; + +class QDesignerWidgetStack : public QWidgetStack +{ + Q_OBJECT + Q_PROPERTY( int currentPage READ currentPage WRITE setCurrentPage STORED false DESIGNABLE true ) + Q_PROPERTY( QCString pageName READ pageName WRITE setPageName STORED false DESIGNABLE true ) +public: + QDesignerWidgetStack( QWidget *parent, const char *name ); + + int currentPage() const; + void setCurrentPage( int i ); + QCString pageName() const; + void setPageName( const QCString& name ); + + int count() const; + QWidget* page( int i ) const; + + int insertPage( QWidget *p, int i = -1 ); + int removePage( QWidget *p ); + +public slots: + void updateButtons(); + +protected: + void resizeEvent( QResizeEvent *e ) { + QWidgetStack::resizeEvent( e ); + updateButtons(); + } + + void showEvent( QShowEvent *e ) { + QWidgetStack::showEvent( e ); + updateButtons(); + } + +private slots: + void prevPage(); + void nextPage(); + +private: + QPtrList<QWidget> pages; + QToolButton *prev, *next; + +}; + +class QDesignerWizard : public QWizard +{ + Q_OBJECT + Q_PROPERTY( int currentPage READ currentPageNum WRITE setCurrentPage STORED false DESIGNABLE true ) + Q_PROPERTY( QString pageTitle READ pageTitle WRITE setPageTitle STORED false DESIGNABLE true ) + Q_PROPERTY( QCString pageName READ pageName WRITE setPageName STORED false DESIGNABLE true ) + Q_OVERRIDE( bool modal READ isModal WRITE setModal ) + +public: + QDesignerWizard( QWidget *parent, const char *name ) + : QWizard( parent, name ), modal(FALSE) {} + + int currentPageNum() const; + void setCurrentPage( int i ); + QString pageTitle() const; + void setPageTitle( const QString& title ); + QCString pageName() const; + void setPageName( const QCString& name ); + int pageNum( QWidget *page ); + void addPage( QWidget *p, const QString & ); + void removePage( QWidget *p ); + void insertPage( QWidget *p, const QString &t, int index ); + bool isPageRemoved( QWidget *p ) { return (removedPages.find( p ) != 0); } + + bool isModal() const { return modal; } + void setModal(bool b) { modal = b; } + + void reject() {} + +private: + struct Page + { + Page( QWidget *a, const QString &b ) : p( a ), t( b ) {} + Page() : p( 0 ), t( QString::null ) {} + QWidget *p; + QString t; + }; + QPtrDict<QWidget> removedPages; + bool modal; + +}; + +class QLayoutWidget : public QWidget +{ + Q_OBJECT + +public: + QLayoutWidget( QWidget *parent, const char *name ) : QWidget( parent, name ), sp( QWidget::sizePolicy() ) {} + + QSizePolicy sizePolicy() const; + void updateSizePolicy(); + +protected: + void paintEvent( QPaintEvent * ); + bool event( QEvent * ); + QSizePolicy sp; + +}; + + +class CustomWidget : public QWidget +{ + Q_OBJECT + +public: + CustomWidget( QWidget *parent, const char *name, MetaDataBase::CustomWidget *cw ) + : QWidget( parent, name ), cusw( cw ) { + alwaysExpand = parentWidget() && parentWidget()->inherits( "FormWindow" ); + setSizePolicy( cw->sizePolicy ); + if ( !alwaysExpand ) + setBackgroundMode( PaletteDark ); + } + + QSize sizeHint() const { + QSize sh = cusw->sizeHint; + if ( sh.isValid() ) + return sh; + return QWidget::sizeHint(); + } + + QString realClassName() { return cusw->className; } + MetaDataBase::CustomWidget *customWidget() const { return cusw; } + +protected: + void paintEvent( QPaintEvent *e ); + + MetaDataBase::CustomWidget *cusw; + bool alwaysExpand; + +}; + + +class Line : public QFrame +{ + Q_OBJECT + + Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation ) + Q_OVERRIDE( int frameWidth DESIGNABLE false ) + Q_OVERRIDE( Shape frameShape DESIGNABLE false ) + Q_OVERRIDE( QRect frameRect DESIGNABLE false ) + Q_OVERRIDE( QRect contentsRect DESIGNABLE false ) +public: + Line( QWidget *parent, const char *name ) + : QFrame( parent, name, WMouseNoMask ) { + setFrameStyle( HLine | Sunken ); + } + + void setOrientation( Orientation orient ) { + if ( orient == Horizontal ) + setFrameShape( HLine ); + else + setFrameShape( VLine ); + } + Orientation orientation() const { + return frameShape() == HLine ? Horizontal : Vertical; + } +}; + +class QDesignerLabel : public QLabel +{ + Q_OBJECT + + Q_PROPERTY( QCString buddy READ buddyWidget WRITE setBuddyWidget ) + +public: + QDesignerLabel( QWidget *parent = 0, const char *name = 0 ) + : QLabel( parent, name ) { myBuddy = 0; } + + void setBuddyWidget( const QCString &b ) { + myBuddy = b; + updateBuddy(); + } + QCString buddyWidget() const { + return myBuddy; + }; + +protected: + void showEvent( QShowEvent *e ) { + QLabel::showEvent( e ); + updateBuddy(); + } + + +private: + void updateBuddy(); + + QCString myBuddy; + +}; + +class QDesignerWidget : public QWidget +{ + Q_OBJECT + +public: + QDesignerWidget( FormWindow *fw, QWidget *parent, const char *name ) + : QWidget( parent, name, WResizeNoErase ), formwindow( fw ) { + need_frame = parent && parent->inherits("QDesignerWidgetStack" ); + } + +protected: + void resizeEvent( QResizeEvent* e); + void paintEvent( QPaintEvent *e ); + +private: + FormWindow *formwindow; + uint need_frame : 1; + +}; + +class QDesignerDialog : public QDialog +{ + Q_OBJECT + Q_OVERRIDE( bool modal READ isModal WRITE setModal ) + +public: + QDesignerDialog( FormWindow *fw, QWidget *parent, const char *name ) + : QDialog( parent, name, FALSE, WResizeNoErase ), formwindow( fw ), modal(FALSE) {} + + bool isModal() const { return modal; } + void setModal(bool b) { modal = b; } + +protected: + void paintEvent( QPaintEvent *e ); + +private: + FormWindow *formwindow; + bool modal; + +}; + +class QDesignerToolButton : public QToolButton +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerToolButton( QWidget *parent, const char *name ) + : QToolButton( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } +}; + +class QDesignerRadioButton : public QRadioButton +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerRadioButton( QWidget *parent, const char *name ) + : QRadioButton( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } + +}; + +class QDesignerPushButton : public QPushButton +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerPushButton( QWidget *parent, const char *name ) + : QPushButton( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } + +}; + +class QDesignerCheckBox : public QCheckBox +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerCheckBox( QWidget *parent, const char *name ) + : QCheckBox( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } + +}; + +class QDesignerToolBox : public QToolBox +{ + Q_OBJECT + Q_PROPERTY( QString itemLabel READ itemLabel WRITE setItemLabel STORED false DESIGNABLE true ) + Q_PROPERTY( QCString itemName READ itemName WRITE setItemName STORED false DESIGNABLE true ) + Q_PROPERTY( BackgroundMode itemBackgroundMode READ itemBackgroundMode WRITE setItemBackgroundMode STORED false DESIGNABLE true ) + +public: + QDesignerToolBox( QWidget *parent, const char *name ); + + QString itemLabel() const; + void setItemLabel( const QString &l ); + QCString itemName() const; + void setItemName( const QCString &n ); + BackgroundMode itemBackgroundMode() const; + void setItemBackgroundMode( BackgroundMode ); + +protected: + void itemInserted( int index ); +}; + +#endif diff --git a/kdevdesigner/designer/wizardeditor.ui b/kdevdesigner/designer/wizardeditor.ui new file mode 100644 index 00000000..45450be2 --- /dev/null +++ b/kdevdesigner/designer/wizardeditor.ui @@ -0,0 +1,342 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>WizardEditorBase</class> +<comment>********************************************************************* +** Copyright (C) 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. +** +** 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. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>WizardEditorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>396</width> + <height>233</height> + </rect> + </property> + <property name="caption"> + <string>Wizard Page Editor</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout19</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout14</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>2</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>pagesLabel</cstring> + </property> + <property name="text"> + <string>Wizard pages:</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>listBox</cstring> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout18</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonAdd</cstring> + </property> + <property name="text"> + <string>A&dd</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonRemove</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonUp</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_up.png"</pixmap> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonDown</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>"designer_s_down.png"</pixmap> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and apply all the changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Apply all changes.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Close the dialog and discard any changes.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonHelp</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>helpClicked()</slot> + </connection> + <connection> + <sender>buttonApply</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>applyClicked()</slot> + </connection> + <connection> + <sender>buttonUp</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>upClicked()</slot> + </connection> + <connection> + <sender>buttonDown</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>downClicked()</slot> + </connection> + <connection> + <sender>buttonAdd</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>addClicked()</slot> + </connection> + <connection> + <sender>buttonRemove</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>removeClicked()</slot> + </connection> + <connection> + <sender>listBox</sender> + <signal>selected(int)</signal> + <receiver>WizardEditorBase</receiver> + <slot>itemSelected(int)</slot> + </connection> + <connection> + <sender>listBox</sender> + <signal>highlighted(int)</signal> + <receiver>WizardEditorBase</receiver> + <slot>itemHighlighted(int)</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>okClicked()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>WizardEditorBase</receiver> + <slot>cancelClicked()</slot> + </connection> +</connections> +<slots> + <slot access="protected">init()</slot> + <slot access="protected">destroy()</slot> + <slot access="protected">addClicked()</slot> + <slot access="protected">applyClicked()</slot> + <slot access="protected">cancelClicked()</slot> + <slot access="protected">downClicked()</slot> + <slot access="protected">helpClicked()</slot> + <slot access="protected">itemHighlighted(int)</slot> + <slot access="protected">itemSelected(int)</slot> + <slot access="protected">okClicked()</slot> + <slot access="protected">removeClicked()</slot> + <slot access="protected">upClicked()</slot> +</slots> +<includes> + <include location="local" impldecl="in implementation">myiconloader.h</include> +</includes> +<pixmapfunction>BarIcon2</pixmapfunction> + +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kdevdesigner/designer/wizardeditorimpl.cpp b/kdevdesigner/designer/wizardeditorimpl.cpp new file mode 100644 index 00000000..089bf746 --- /dev/null +++ b/kdevdesigner/designer/wizardeditorimpl.cpp @@ -0,0 +1,253 @@ +/********************************************************************** +** 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 "wizardeditorimpl.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "command.h" +#include "listboxdnd.h" +#include "listboxrename.h" + +#include <qwizard.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qinputdialog.h> + +#include <klocale.h> + +WizardEditor::WizardEditor( QWidget *parent, QWizard *w, FormWindow *fw ) + : WizardEditorBase( parent, 0 ), formwindow( fw ), wizard( w ), draggedItem( 0 ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + fillListBox(); + + // Add drag and drop + ListBoxDnd *listBoxDnd = new ListBoxDnd( listBox ); + listBoxDnd->setDragMode( ListBoxDnd::Internal | ListBoxDnd::Move ); + QObject::connect( listBoxDnd, SIGNAL( dropped( QListBoxItem * ) ), + listBoxDnd, SLOT( confirmDrop( QListBoxItem * ) ) ); + + QObject::connect( listBoxDnd, SIGNAL( dragged( QListBoxItem * ) ), + this, SLOT( itemDragged( QListBoxItem * ) ) ); + QObject::connect( listBoxDnd, SIGNAL( dropped( QListBoxItem * ) ), + this, SLOT( itemDropped( QListBoxItem * ) ) ); + + // Add in-place rename + new ListBoxRename( listBox ); +} + +WizardEditor::~WizardEditor() +{ + commands.setAutoDelete( TRUE ); +} + +void WizardEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void WizardEditor::cancelClicked() +{ + reject(); +} + +void WizardEditor::applyClicked() +{ + if ( commands.isEmpty() ) return; + + // schedule macro command + MacroCommand* cmd = new MacroCommand( i18n( "Edit Wizard Pages" ), formwindow, commands ); + formwindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + + // clear command list + commands.clear(); + + // fix wizard buttons + for ( int i = 0; i < wizard->pageCount(); i++ ) { + + QWidget * page = wizard->page( i ); + if ( i == 0 ) { // first page + + wizard->setBackEnabled( page, FALSE ); + wizard->setNextEnabled( page, TRUE ); + } + else if ( i == wizard->pageCount() - 1 ) { // last page + + wizard->setBackEnabled( page, TRUE ); + wizard->setNextEnabled( page, FALSE ); + } + else { + + wizard->setBackEnabled( page, TRUE ); + wizard->setNextEnabled( page, TRUE ); + } + wizard->setFinishEnabled( page, FALSE ); + } + + // update listbox + int index = listBox->currentItem(); + fillListBox(); + listBox->setCurrentItem( index ); + + // show current page + wizard->showPage( wizard->page( 0 ) ); +} + +void WizardEditor::helpClicked() +{ + +} + +void WizardEditor::addClicked() +{ + int index = listBox->currentItem() + 1; + // update listbox + listBox->insertItem( i18n( "Page" ), index ); + + // schedule add command + AddWizardPageCommand *cmd = new AddWizardPageCommand( i18n( "Add Page to %1" ).arg( wizard->name() ), + formwindow, wizard, "Page", index, FALSE); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::removeClicked() +{ + if ( listBox->count() < 2 ) return; + + int index = listBox->currentItem(); + + // update listbox + listBox->removeItem( index ); + + // schedule remove command + DeleteWizardPageCommand *cmd = new DeleteWizardPageCommand( i18n( "Delete Page %1 of %2" ) + .arg( listBox->text( index ) ).arg( wizard->name() ), + formwindow, wizard, index, FALSE ); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::upClicked() +{ + int index1 = listBox->currentItem(); + int index2 = index1 - 1; + + // swap listbox items + QString item1 = listBox->text( index1 ); + listBox->removeItem( index1 ); + listBox->insertItem( item1, index2 ); + listBox->setCurrentItem( index2 ); + + // schedule swap command + SwapWizardPagesCommand *cmd = new SwapWizardPagesCommand( i18n( "Swap Pages %1 and %2 of %3" ).arg( index1 ).arg( index2 ) + .arg( wizard->name() ), formwindow, wizard, index1, index2); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::downClicked() +{ + int index1 = listBox->currentItem(); + int index2 = index1 + 1; + + // swap listbox items + QString item1 = listBox->text( index1 ); + listBox->removeItem( index1 ); + listBox->insertItem( item1, index2 ); + listBox->setCurrentItem( index2 ); + + // schedule swap command + SwapWizardPagesCommand *cmd = new SwapWizardPagesCommand( i18n( "Swap Pages %1 and %2 of %3" ).arg( index1 ).arg( index2 ).arg( wizard->name() ), formwindow, wizard, index2, index1); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::fillListBox() +{ + listBox->clear(); + + if ( !wizard ) return; + for ( int i = 0; i < wizard->pageCount(); i++ ) + listBox->insertItem( wizard->title( wizard->page( i ) ) ); + + updateButtons(); +} + +void WizardEditor::itemHighlighted( int ) +{ + updateButtons(); +} + +void WizardEditor::itemSelected( int index ) +{ + if ( index < 0 ) return; + // Called when Qt::Key_Enter was pressed. + // ListBoxRename has renamed the list item, so we only need to rename the page to the same name. + QString pn( i18n( "Rename page %1 of %2" ).arg( wizard->title( wizard->page( index ) ) ).arg( wizard->name() ) ); + RenameWizardPageCommand *cmd = new RenameWizardPageCommand( pn, formwindow, wizard, index, listBox->text( index ) ); + commands.append( cmd ); +} + +void WizardEditor::updateButtons() +{ + int index = listBox->currentItem(); + + buttonUp->setEnabled( index > 0 ); + buttonDown->setEnabled( index < (int)listBox->count() - 1 ); + buttonRemove->setEnabled( index >= 0 ); + + if ( listBox->count() < 2 ) + buttonRemove->setEnabled( FALSE ); +} + +void WizardEditor::itemDragged( QListBoxItem * i ) +{ + // Store item index + draggedItem = listBox->index( i ); +} + +void WizardEditor::itemDropped( QListBoxItem * i ) +{ + if ( draggedItem < 0 ) return; + // The reorder the pages acording to the listBox list of items + // Assumes that only one item has been moved. + int droppedItem = listBox->index( i ); + + //qDebug( "Moving page %d -> %d", draggedItem, droppedItem ); + MoveWizardPageCommand *cmd = new MoveWizardPageCommand( i18n( "Move Page %1 to %2 in %3" ).arg( draggedItem ).arg( droppedItem ).arg( wizard->name() ), formwindow, wizard, draggedItem, droppedItem ); + commands.append( cmd ); +} diff --git a/kdevdesigner/designer/wizardeditorimpl.h b/kdevdesigner/designer/wizardeditorimpl.h new file mode 100644 index 00000000..0089cb39 --- /dev/null +++ b/kdevdesigner/designer/wizardeditorimpl.h @@ -0,0 +1,74 @@ +/********************************************************************** +** 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 WIZARDEDITORIMPL_H +#define WIZARDEDITORIMPL_H + +class QWizard; +class FormWindow; + +#include <qptrlist.h> + +#include "wizardeditor.h" +#include "command.h" + +class WizardEditor : public WizardEditorBase +{ + Q_OBJECT + +public: + WizardEditor( QWidget *parent, QWizard *wizard, FormWindow *fw ); + ~WizardEditor(); + +protected slots: + void okClicked(); + void applyClicked(); + void cancelClicked(); + void helpClicked(); + + void addClicked(); + void removeClicked(); + void upClicked(); + void downClicked(); + + void itemHighlighted( int ); + void itemSelected( int ); + + void itemDragged( QListBoxItem * ); + void itemDropped( QListBoxItem * ); + +private: + void updateButtons(); + void fillListBox(); + +private: + FormWindow *formwindow; + QWizard *wizard; + QPtrList<Command> commands; + int draggedItem; +}; + +#endif diff --git a/kdevdesigner/designer/workspace.cpp b/kdevdesigner/designer/workspace.cpp new file mode 100644 index 00000000..db9bd7be --- /dev/null +++ b/kdevdesigner/designer/workspace.cpp @@ -0,0 +1,711 @@ +/********************************************************************** +** 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 <qvariant.h> // HP-UX compiler needs this here +#include "workspace.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "globaldefs.h" +#include "command.h" +#include "project.h" +#include "pixmapcollection.h" +#include "sourcefile.h" +#include "sourceeditor.h" +#include "propertyeditor.h" + +#include <kiconloader.h> +#include "kdevdesigner_part.h" + +#include <qheader.h> +#include <qdragobject.h> +#include <qfileinfo.h> +#include <qapplication.h> +#include <qpainter.h> +#include <qpen.h> +#include <qobjectlist.h> +#include <qworkspace.h> +#include <qpopupmenu.h> +#include <qtextstream.h> +#include "qcompletionedit.h" + +#include <klocale.h> + +WorkspaceItem::WorkspaceItem( QListView *parent, Project* p ) + : QListViewItem( parent ) +{ + init(); + project = p; + t = ProjectType; + setPixmap( 0, SmallIcon( "designer_folder.png" , KDevDesignerPartFactory::instance()) ); + setExpandable( FALSE ); +} + +WorkspaceItem::WorkspaceItem( QListViewItem *parent, SourceFile* sf ) + : QListViewItem( parent ) +{ + init(); + sourceFile = sf; + t = SourceFileType; + setPixmap( 0, SmallIcon( "designer_filenew.png" , KDevDesignerPartFactory::instance()) ); +} + +WorkspaceItem::WorkspaceItem( QListViewItem *parent, QObject *o, Project *p ) + : QListViewItem( parent ) +{ + init(); + object = o; + project = p; + t = ObjectType; + setPixmap( 0, SmallIcon( "designer_object.png" , KDevDesignerPartFactory::instance()) ); + QObject::connect( p->fakeFormFileFor( o ), SIGNAL( somethingChanged(FormFile*) ), + listView(), SLOT( update() ) ); +} + +WorkspaceItem::WorkspaceItem( QListViewItem *parent, FormFile* ff, Type type ) + : QListViewItem( parent ) +{ + init(); + formFile = ff; + t = type; + if ( type == FormFileType ) { + setPixmap( 0, SmallIcon( "designer_form.png" , KDevDesignerPartFactory::instance()) ); + QObject::connect( ff, SIGNAL( somethingChanged(FormFile*) ), listView(), SLOT( update(FormFile*) ) ); + if ( formFile->supportsCodeFile() ) { + (void) new WorkspaceItem( this, formFile, FormSourceType ); + } + } else if ( type == FormSourceType ) { + setPixmap( 0, SmallIcon( "designer_filenew.png" , KDevDesignerPartFactory::instance()) ); + } +} + + +void WorkspaceItem::init() +{ + autoOpen = FALSE; + useOddColor = FALSE; + project = 0; + sourceFile = 0; + formFile = 0; +} + +void WorkspaceItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + g.setColor( QColorGroup::Foreground, Qt::black ); + + if ( type() == FormSourceType && + ( !formFile->hasFormCode() || ( formFile->codeFileState() == FormFile::Deleted && formFile->formWindow() ) ) && + parent() && parent()->parent() && ( (WorkspaceItem*)parent()->parent() )->project && + ( (WorkspaceItem*)parent()->parent() )->project->isCpp() ) { + g.setColor( QColorGroup::Text, listView()->palette().disabled().color( QColorGroup::Text) ); + g.setColor( QColorGroup::HighlightedText, listView()->palette().disabled().color( QColorGroup::Text) ); + } else { + g.setColor( QColorGroup::Text, Qt::black ); + } + p->save(); + + if ( isModified() ) { + QFont f = p->font(); + f.setBold( TRUE ); + p->setFont( f ); + } + + QListViewItem::paintCell( p, g, column, width, align ); + p->setPen( QPen( cg.dark(), 1 ) ); + if ( column == 0 ) + p->drawLine( 0, 0, 0, height() - 1 ); + if ( listView()->firstChild() != this ) { + if ( nextSibling() != itemBelow() && itemBelow()->depth() < depth() ) { + int d = depth() - itemBelow()->depth(); + p->drawLine( -listView()->treeStepSize() * d, height() - 1, 0, height() - 1 ); + } + } + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); +} + +QString WorkspaceItem::text( int column ) const +{ + if ( column != 0 ) + return QListViewItem::text( column ); + switch( t ) { + case ProjectType: + if ( project->isDummy() ) { + return i18n("<No Project>" ); + } else if ( MainWindow::self->singleProjectMode() ) { + return QFileInfo( project->fileName() ).baseName(); + } + return project->makeRelative( project->fileName() ); + case FormFileType: + if ( !MainWindow::self->singleProjectMode() ) + return formFile->formName() + ": " + formFile->fileName(); + return formFile->formName(); + case FormSourceType: + if ( !MainWindow::self->singleProjectMode() ) + return formFile->codeFile(); + return formFile->formName() + " [Source]"; + case SourceFileType: + return sourceFile->fileName(); + case ObjectType: + if ( !project->hasParentObject( object ) ) + return object->name(); + return project->qualifiedName( object ); + } + + return QString::null; // shut up compiler +} + +void WorkspaceItem::fillCompletionList( QStringList& completion ) +{ + switch( t ) { + case ProjectType: + break; + case FormFileType: + completion += formFile->formName(); + completion += formFile->fileName(); + break; + case FormSourceType: + completion += formFile->codeFile(); + break; + case SourceFileType: + completion += sourceFile->fileName(); + break; + case ObjectType: + completion += object->name(); + } +} + +bool WorkspaceItem::checkCompletion( const QString& completion ) +{ + switch( t ) { + case ProjectType: + break; + case FormFileType: + return completion == formFile->formName() + || completion == formFile->fileName(); + case FormSourceType: + return completion == formFile->codeFile(); + case SourceFileType: + return completion == sourceFile->fileName(); + case ObjectType: + return completion == object->name(); + } + return FALSE; +} + + +bool WorkspaceItem::isModified() const +{ + switch( t ) { + case ProjectType: + return project->isModified(); + case FormFileType: + return formFile->isModified( FormFile::WFormWindow ); + case FormSourceType: + return formFile->isModified( FormFile::WFormCode ); + case SourceFileType: + return sourceFile->isModified(); + case ObjectType: + return project->fakeFormFileFor( object )->isModified(); + break; + } + return FALSE; // shut up compiler +} + +QString WorkspaceItem::key( int column, bool ) const +{ + QString key = text( column ); + if ( t == FormFileType ) + key.prepend( "0" ); + else if ( t == ObjectType ) + key.prepend( "a" ); + else + key.prepend( "A" ); + return key; +} + +QColor WorkspaceItem::backgroundColor() +{ + bool b = useOddColor; + if ( t == FormSourceType && parent() ) + b = ( ( WorkspaceItem*)parent() )->useOddColor; + return b ? *backColor2 : *backColor1; +} + + +void WorkspaceItem::setOpen( bool b ) +{ + QListViewItem::setOpen( b ); + autoOpen = FALSE; +} + +void WorkspaceItem::setAutoOpen( bool b ) +{ + QListViewItem::setOpen( b ); + autoOpen = b; +} + +Workspace::Workspace( QWidget *parent, MainWindow *mw ) + : QListView( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_Tool | WStyle_MinMax | WStyle_SysMenu ), mainWindow( mw ), + project( 0 ), completionDirty( FALSE ) +{ + init_colors(); + + setDefaultRenameAction( Accept ); + blockNewForms = FALSE; + bufferEdit = 0; + header()->setStretchEnabled( TRUE ); + header()->hide(); + setSorting( 0 ); + setResizePolicy( QScrollView::Manual ); +#ifndef Q_WS_MAC + QPalette p( palette() ); + p.setColor( QColorGroup::Base, QColor( *backColor2 ) ); + (void)*selectedBack; // hack + setPalette( p ); +#endif + addColumn( i18n( "Files" ) ); + setAllColumnsShowFocus( TRUE ); + connect( this, SIGNAL( mouseButtonClicked( int, QListViewItem *, const QPoint &, int ) ), + this, SLOT( itemClicked( int, QListViewItem *, const QPoint& ) ) ), + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( itemDoubleClicked( QListViewItem * ) ) ), + connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ), + this, SLOT( rmbClicked( QListViewItem *, const QPoint& ) ) ), + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + viewport()->setAcceptDrops( TRUE ); + setAcceptDrops( TRUE ); + setColumnWidthMode( 1, Manual ); +} + + +void Workspace::projectDestroyed( QObject* o ) +{ + if ( o == project ) { + project = 0; + clear(); + } +} + +void Workspace::setCurrentProject( Project *pro ) +{ + if ( project == pro ) + return; + if ( project ) { + disconnect( project, SIGNAL( sourceFileAdded(SourceFile*) ), this, SLOT( sourceFileAdded(SourceFile*) ) ); + disconnect( project, SIGNAL( sourceFileRemoved(SourceFile*) ), this, SLOT( sourceFileRemoved(SourceFile*) ) ); + disconnect( project, SIGNAL( formFileAdded(FormFile*) ), this, SLOT( formFileAdded(FormFile*) ) ); + disconnect( project, SIGNAL( formFileRemoved(FormFile*) ), this, SLOT( formFileRemoved(FormFile*) ) ); + disconnect( project, SIGNAL( objectAdded(QObject*) ), this, SLOT( objectAdded(QObject*) ) ); + disconnect( project, SIGNAL( objectRemoved(QObject*) ), this, SLOT( objectRemoved(QObject*) ) ); + disconnect( project, SIGNAL( projectModified() ), this, SLOT( update() ) ); + } + project = pro; + connect( project, SIGNAL( sourceFileAdded(SourceFile*) ), this, SLOT( sourceFileAdded(SourceFile*) ) ); + connect( project, SIGNAL( sourceFileRemoved(SourceFile*) ), this, SLOT( sourceFileRemoved(SourceFile*) ) ); + connect( project, SIGNAL( formFileAdded(FormFile*) ), this, SLOT( formFileAdded(FormFile*) ) ); + connect( project, SIGNAL( formFileRemoved(FormFile*) ), this, SLOT( formFileRemoved(FormFile*) ) ); + connect( project, SIGNAL( destroyed(QObject*) ), this, SLOT( projectDestroyed(QObject*) ) ); + connect( project, SIGNAL( objectAdded(QObject*) ), this, SLOT( objectAdded(QObject*) ) ); + connect( project, SIGNAL( objectRemoved(QObject*) ), this, SLOT( objectRemoved(QObject*) ) ); + connect( project, SIGNAL( projectModified() ), this, SLOT( update() ) ); + clear(); + + if ( bufferEdit ) + bufferEdit->clear(); + + projectItem = new WorkspaceItem( this, project ); + + projectItem->setOpen( TRUE ); + + for ( QPtrListIterator<SourceFile> sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + (void) new WorkspaceItem( projectItem, f ); + } + + for ( QPtrListIterator<FormFile> forms = project->formFiles(); + forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->isFake() ) + continue; + + (void) new WorkspaceItem( projectItem, f ); + } + + QObjectList l = project->objects(); + QObjectListIt objs( l ); + for ( ;objs.current(); ++objs ) { + QObject* o = objs.current(); + (void) new WorkspaceItem( projectItem, o, project ); + } + + updateColors(); + completionDirty = TRUE; +} + +void Workspace::sourceFileAdded( SourceFile* sf ) +{ + (void) new WorkspaceItem( projectItem, sf ); + updateColors(); +} + +void Workspace::sourceFileRemoved( SourceFile* sf ) +{ + delete findItem( sf ); + updateColors(); +} + +void Workspace::formFileAdded( FormFile* ff ) +{ + if ( ff->isFake() ) + return; + (void) new WorkspaceItem( projectItem, ff ); + updateColors(); +} + +void Workspace::formFileRemoved( FormFile* ff ) +{ + delete findItem( ff ); + updateColors(); +} + +void Workspace::objectAdded( QObject *o ) +{ + (void) new WorkspaceItem( projectItem, o, project ); + updateColors(); +} + +void Workspace::objectRemoved( QObject *o ) +{ + delete findItem( o ); + updateColors(); +} + +void Workspace::update() +{ + completionDirty = TRUE; + triggerUpdate(); +} + +void Workspace::update( FormFile* ff ) +{ + QListViewItem* i = findItem( ff ); + if ( i ) { + i->repaint(); + if ( (i = i->firstChild()) ) + i->repaint(); + } +} + + +void Workspace::activeFormChanged( FormWindow *fw ) +{ + WorkspaceItem *i = findItem( fw->formFile() ); + if ( i ) { + setCurrentItem( i ); + setSelected( i, TRUE ); + if ( !i->isOpen() ) + i->setAutoOpen( TRUE ); + } + + closeAutoOpenItems(); + +} + +void Workspace::activeEditorChanged( SourceEditor *se ) +{ + if ( !se->object() ) + return; + + if ( se->formWindow() ) { + WorkspaceItem *i = findItem( se->formWindow()->formFile() ); + if ( i && i->firstChild() ) { + if ( !i->isOpen() ) + i->setAutoOpen( TRUE ); + setCurrentItem( i->firstChild() ); + setSelected( i->firstChild(), TRUE ); + } + } else { + WorkspaceItem *i = findItem( se->sourceFile() ); + if ( i ) { + setCurrentItem( i ); + setSelected( i, TRUE ); + } + } + + closeAutoOpenItems(); +} + +WorkspaceItem *Workspace::findItem( FormFile* ff) +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->formFile == ff ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +WorkspaceItem *Workspace::findItem( SourceFile *sf ) +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->sourceFile == sf ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +WorkspaceItem *Workspace::findItem( QObject *o ) +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->object == o ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +void Workspace::closeAutoOpenItems() +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + WorkspaceItem* i = (WorkspaceItem*) it.current(); + WorkspaceItem* ip = (WorkspaceItem*) i->parent(); + if ( i->type() == WorkspaceItem::FormSourceType ) { + if ( !i->isSelected() && !ip->isSelected() + && ip->isAutoOpen() ) { + ip->setAutoOpen( FALSE ); + } + } + } +} + + +void Workspace::closeEvent( QCloseEvent *e ) +{ + e->accept(); +} + +void Workspace::itemDoubleClicked( QListViewItem *i ) +{ + if ( ( (WorkspaceItem*)i)->type()== WorkspaceItem::ProjectType ) + i->setOpen( TRUE ); +} + +void Workspace::itemClicked( int button, QListViewItem *i, const QPoint& ) +{ + if ( !i || button != LeftButton ) + return; + + closeAutoOpenItems(); + + WorkspaceItem* wi = (WorkspaceItem*)i; + switch( wi->type() ) { + case WorkspaceItem::ProjectType: + break; // ### TODO + case WorkspaceItem::FormFileType: + wi->formFile->showFormWindow(); + break; + case WorkspaceItem::FormSourceType: + wi->formFile->showEditor( FALSE ); + break; + case WorkspaceItem::SourceFileType: + mainWindow->editSource( wi->sourceFile ); + break; + case WorkspaceItem::ObjectType: + project->fakeFormFileFor( wi->object )->formWindow()->setFocus(); + mainWindow->propertyeditor()->setWidget( wi->object, + project->fakeFormFileFor( wi->object )->formWindow() ); + mainWindow->objectHierarchy()-> + setFormWindow( project->fakeFormFileFor( wi->object )->formWindow(), wi->object ); + project->fakeFormFileFor( wi->object )->showEditor(); + break; + } +} + +void Workspace::contentsDropEvent( QDropEvent *e ) +{ + if ( !QUriDrag::canDecode( e ) ) { + e->ignore(); + } else { + QStringList files; + QUriDrag::decodeLocalFiles( e, files ); + if ( !files.isEmpty() ) { + for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it ) { + QString fn = *it; + mainWindow->fileOpen( "", "", fn ); + } + } + } +} + +void Workspace::contentsDragEnterEvent( QDragEnterEvent *e ) +{ + if ( !QUriDrag::canDecode( e ) ) + e->ignore(); + else + e->accept(); +} + +void Workspace::contentsDragMoveEvent( QDragMoveEvent *e ) +{ + if ( !QUriDrag::canDecode( e ) ) + e->ignore(); + else + e->accept(); +} + +void Workspace::rmbClicked( QListViewItem *i, const QPoint& pos ) +{ + if ( !i ) + return; + WorkspaceItem* wi = (WorkspaceItem*)i; + enum { OPEN_SOURCE, REMOVE_SOURCE, OPEN_FORM, REMOVE_FORM, + OPEN_FORM_SOURCE, REMOVE_FORM_SOURCE, OPEN_OBJECT_SOURCE }; + QPopupMenu menu( this ); + menu.setCheckable( TRUE ); + switch ( wi->type() ) { + case WorkspaceItem::SourceFileType: + menu.insertItem( i18n( "&Open Source File" ), OPEN_SOURCE ); + menu.insertSeparator(); + menu.insertItem( SmallIcon( "designer_editcut.png" , KDevDesignerPartFactory::instance()), + i18n( "&Remove Source File From Project" ), REMOVE_SOURCE ); + break; + case WorkspaceItem::FormFileType: + menu.insertItem( i18n( "&Open Form" ), OPEN_FORM ); + menu.insertSeparator(); + menu.insertItem( SmallIcon( "designer_editcut.png" , KDevDesignerPartFactory::instance()), + i18n( "&Remove Form From Project" ), REMOVE_FORM ); + break; + case WorkspaceItem::FormSourceType: + menu.insertItem( i18n( "&Open Form Source" ), OPEN_FORM_SOURCE ); + menu.insertSeparator(); + if ( project->isCpp() ) + menu.insertItem( SmallIcon( "designer_editcut.png" , KDevDesignerPartFactory::instance()), + i18n( "&Remove Source File From Form" ), REMOVE_FORM_SOURCE ); + else + menu.insertItem( SmallIcon( "designer_editcut.png" , KDevDesignerPartFactory::instance()), + i18n( "&Remove Form From Project" ), REMOVE_FORM ); + break; + case WorkspaceItem::ProjectType: + MainWindow::self->popupProjectMenu( pos ); + return; + case WorkspaceItem::ObjectType: + menu.insertItem( i18n( "&Open Source" ), OPEN_OBJECT_SOURCE ); + break; + } + + switch ( menu.exec( pos ) ) { + case REMOVE_SOURCE: + project->removeSourceFile( wi->sourceFile ); + break; + case REMOVE_FORM: + project->removeFormFile( wi->formFile ); + break; + case REMOVE_FORM_SOURCE: + ( (WorkspaceItem*)i )->formFile->setModified( TRUE ); + ( (WorkspaceItem*)i )->formFile->setCodeFileState( FormFile::Deleted ); + delete ( (WorkspaceItem*)i )->formFile->editor(); + break; + case OPEN_OBJECT_SOURCE: + case OPEN_SOURCE: + case OPEN_FORM: + case OPEN_FORM_SOURCE: + itemClicked( LeftButton, i, pos ); + break; + } +} + +bool Workspace::eventFilter( QObject *o, QEvent * e ) +{ + // Reggie, on what type of events do we have to execute updateBufferEdit() + if ( o ==bufferEdit && e->type() != QEvent::ChildRemoved ) + updateBufferEdit(); + return QListView::eventFilter( o, e ); +} + +void Workspace::setBufferEdit( QCompletionEdit *edit ) +{ + bufferEdit = edit; + connect( bufferEdit, SIGNAL( chosen( const QString & ) ), + this, SLOT( bufferChosen( const QString & ) ) ); + bufferEdit->installEventFilter( this ); +} + +void Workspace::updateBufferEdit() +{ + if ( !bufferEdit || !completionDirty || !MainWindow::self) + return; + completionDirty = FALSE; + QStringList completion = MainWindow::self->projectFileNames(); + QListViewItemIterator it( this ); + while ( it.current() ) { + ( (WorkspaceItem*)it.current())->fillCompletionList( completion ); + ++it; + } + completion.sort(); + bufferEdit->setCompletionList( completion ); +} + +void Workspace::bufferChosen( const QString &buffer ) +{ + if ( bufferEdit ) + bufferEdit->setText( "" ); + + if ( MainWindow::self->projectFileNames().contains( buffer ) ) { + MainWindow::self->setCurrentProjectByFilename( buffer ); + return; + } + + QListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (WorkspaceItem*)it.current())->checkCompletion( buffer ) ) { + itemClicked( LeftButton, it.current(), QPoint() ); + break; + } + ++it; + } +} + +void Workspace::updateColors() +{ + QListViewItem* i = firstChild(); + if ( i ) + i = i->firstChild(); + bool b = TRUE; + while ( i ) { + WorkspaceItem* wi = ( WorkspaceItem*) i; + i = i->nextSibling(); + wi->useOddColor = b; + b = !b; + } +} diff --git a/kdevdesigner/designer/workspace.h b/kdevdesigner/designer/workspace.h new file mode 100644 index 00000000..8e710725 --- /dev/null +++ b/kdevdesigner/designer/workspace.h @@ -0,0 +1,151 @@ +/********************************************************************** +** 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 WORKSPACE_H +#define WORKSPACE_H + +#include <qlistview.h> + +class FormWindow; +class QResizeEvent; +class QCloseEvent; +class QDropEvent; +class QDragMoveEvent; +class QDragEnterEvent; +class MainWindow; +class Project; +class SourceFile; +class FormFile; +class QCompletionEdit; +class SourceEditor; + +class WorkspaceItem : public QListViewItem +{ +public: + enum Type { ProjectType, FormFileType, FormSourceType, SourceFileType, ObjectType }; + + WorkspaceItem( QListView *parent, Project* p ); + WorkspaceItem( QListViewItem *parent, SourceFile* sf ); + WorkspaceItem( QListViewItem *parent, FormFile* ff, Type t = FormFileType ); + WorkspaceItem( QListViewItem *parent, QObject *o, Project *p ); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ); + + Type type() const { return t; } + + bool isModified() const; + + QString text( int ) const; + + void fillCompletionList( QStringList& completion ); + bool checkCompletion( const QString& completion ); + + QString key( int, bool ) const; // column sorting key + + Project* project; + SourceFile* sourceFile; + FormFile* formFile; + QObject *object; + + void setOpen( bool ); + + void setAutoOpen( bool ); + bool isAutoOpen() const { return isOpen() && autoOpen; } + + bool useOddColor; + +private: + void init(); + bool autoOpen; + QColor backgroundColor(); + Type t; +}; + +class Workspace : public QListView +{ + Q_OBJECT + +public: + Workspace( QWidget *parent , MainWindow *mw ); + + void setCurrentProject( Project *pro ); + + void contentsDropEvent( QDropEvent *e ); + void contentsDragEnterEvent( QDragEnterEvent *e ); + void contentsDragMoveEvent( QDragMoveEvent *e ); + + void setBufferEdit( QCompletionEdit *edit ); + +public slots: + + void update(); + void update( FormFile* ); + + void activeFormChanged( FormWindow *fw ); + void activeEditorChanged( SourceEditor *se ); + +protected: + void closeEvent( QCloseEvent *e ); + bool eventFilter( QObject *, QEvent * ); + + +private slots: + void itemClicked( int, QListViewItem *i, const QPoint& pos ); + void itemDoubleClicked( QListViewItem *i ); + void rmbClicked( QListViewItem *i, const QPoint& pos ); + void bufferChosen( const QString &buffer ); + + void projectDestroyed( QObject* ); + + void sourceFileAdded( SourceFile* ); + void sourceFileRemoved( SourceFile* ); + + void formFileAdded( FormFile* ); + void formFileRemoved( FormFile* ); + + void objectAdded( QObject* ); + void objectRemoved( QObject * ); + +private: + WorkspaceItem *findItem( FormFile *ff ); + WorkspaceItem *findItem( SourceFile *sf ); + WorkspaceItem *findItem( QObject *o ); + + void closeAutoOpenItems(); + +private: + MainWindow *mainWindow; + Project *project; + WorkspaceItem *projectItem; + QCompletionEdit *bufferEdit; + bool blockNewForms; + void updateBufferEdit(); + bool completionDirty; + void updateColors(); + +}; + +#endif diff --git a/kdevdesigner/interfaces/actioninterface.h b/kdevdesigner/interfaces/actioninterface.h new file mode 100644 index 00000000..75396f04 --- /dev/null +++ b/kdevdesigner/interfaces/actioninterface.h @@ -0,0 +1,78 @@ + /********************************************************************** +** 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. +** +** 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 ACTIONINTERFACE_H +#define ACTIONINTERFACE_H + +#include <private/qcom_p.h> + +class QAction; +class QObject; + +// {bb206e09-84e5-4777-9fce-706babfab931} +#ifndef IID_Action +#define IID_Action QUuid( 0xbb206e09, 0x84e5, 0x4777, 0x9f, 0xce, 0x70, 0x6b, 0xab, 0xfa, 0xb9, 0x31 ) +#endif + +/*! To add actions to the Qt Designer menubars and toolbars, implement + this interface. You have to implement the create(), group() and + connectTo() functions. + + You also have to implement the function featureList() (\sa + QFeatureListInterface) to return the names of all actions + which this interface provides. +*/ + +class ActionInterface : public QFeatureListInterface +{ +public: + enum Location { + Toolbar, + Menu + }; + + /*! This functions is called to create the action with the name \a + name. \a parent should be used as parent of the action. + + In the implementation return the QAction object for the action + \a name. + */ + virtual QAction* create( const QString &name, QObject* parent = 0 ) = 0; + + /*! In the implementation of the interface return the name of the + group of the action \a name. + */ + virtual QString group( const QString &name ) const = 0; + + /*! In the implementation of the interface return whether the + action \a name should appear in the location \a l */ + virtual bool location( const QString &name, Location l ) const = 0; + + /*! \internal */ + virtual void connectTo( QUnknownInterface *appInterface ) = 0; +}; + +#endif diff --git a/kdevdesigner/interfaces/classbrowserinterface.h b/kdevdesigner/interfaces/classbrowserinterface.h new file mode 100644 index 00000000..2db43afe --- /dev/null +++ b/kdevdesigner/interfaces/classbrowserinterface.h @@ -0,0 +1,63 @@ + /********************************************************************** +** 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. +** +** 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 CLASSBROWSERINTERFACE_H +#define CLASSBROWSERINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qobject.h> +class QListView; + +// {4ede3c32-ae96-4b7a-9e38-9f1d93592391} +#ifndef IID_ClassBrowser +#define IID_ClassBrowser QUuid( 0x4ede3c32, 0xae96, 0x4b7a, 0x9e, 0x38, 0x9f, 0x1d, 0x93, 0x59, 0x23, 0x91 ) +#endif + +struct ClassBrowserInterface : public QUnknownInterface +{ + enum Type { Class, Function }; + + virtual QListView *createClassBrowser( QWidget *parent ) const = 0; + virtual void update( const QString &code ) const = 0; + virtual void clear() const = 0; + + virtual void onClick( QObject *receiver, const char *slot ) = 0; +}; + +#endif diff --git a/kdevdesigner/interfaces/designerinterface.h b/kdevdesigner/interfaces/designerinterface.h new file mode 100644 index 00000000..de7487e2 --- /dev/null +++ b/kdevdesigner/interfaces/designerinterface.h @@ -0,0 +1,261 @@ + /********************************************************************** +** 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. +** +** 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 DESIGNERINTERFACE_H +#define DESIGNERINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qptrlist.h> +#include <qstring.h> +#include <qmap.h> +#include <qstringlist.h> +#include <qwidgetlist.h> +#include <qobjectlist.h> + +struct DesignerProject; +struct DesignerDatabase; +struct DesignerFormWindow; +struct DesignerDock; +struct DesignerOutputDock; +struct DesignerOutput; +struct DesignerOutputError; +struct DesignerPixmapCollection; +struct DesignerSourceFile; + +class QDockWindow; +class QWidget; +class QObject; +class QAction; +class QIconSet; +class QSqlDatabase; + +// {0e661da-f45c-4830-af47-03ec53eb1633} +#ifndef IID_Designer +#define IID_Designer QUuid( 0xa0e661da, 0xf45c, 0x4830, 0xaf, 0x47, 0x3, 0xec, 0x53, 0xeb, 0x16, 0x33 ) +#endif + +/*! These are the interfaces implemented by the Qt Designer which should + be used by plugins to access and use functionality of the Qt Designer. +*/ + +struct DesignerInterface : public QUnknownInterface +{ + virtual DesignerProject *currentProject() const = 0; + virtual DesignerFormWindow *currentForm() const = 0; + virtual DesignerSourceFile *currentSourceFile() const = 0; + virtual QPtrList<DesignerProject> projectList() const = 0; + virtual void showStatusMessage( const QString &, int ms = 0 ) const = 0; + virtual DesignerDock *createDock() const = 0; + virtual DesignerOutputDock *outputDock() const = 0; + virtual void setModified( bool b, QWidget *window ) = 0; + virtual void updateFunctionList() = 0; + + virtual void onProjectChange( QObject *receiver, const char *slot ) = 0; + virtual void onFormChange( QObject *receiver, const char *slot ) = 0; + + virtual bool singleProjectMode() const = 0; + virtual void showError( QWidget *widget, int line, const QString &message ) = 0; + virtual void runFinished() = 0; + virtual void showStackFrame( QWidget *w, int line ) = 0; + virtual void showDebugStep( QWidget *w, int line ) = 0; + virtual void runProjectPrecondition() = 0; + virtual void runProjectPostcondition( QObjectList *l ) = 0; + + }; + +struct DesignerProject +{ + virtual QPtrList<DesignerFormWindow> formList() const = 0; + virtual QStringList formNames() const = 0; + virtual QString formFileName( const QString &form ) const = 0; + virtual void addForm( DesignerFormWindow * ) = 0; + virtual void removeForm( DesignerFormWindow * ) = 0; + virtual QString fileName() const = 0; + virtual void setFileName( const QString & ) = 0; + virtual QString projectName() const = 0; + virtual void setProjectName( const QString & ) = 0; + virtual QString databaseFile() const = 0; + virtual void setDatabaseFile( const QString & ) = 0; + virtual void setupDatabases() const = 0; + virtual QPtrList<DesignerDatabase> databaseConnections() const = 0; + virtual void addDatabase( DesignerDatabase * ) = 0; + virtual void removeDatabase( DesignerDatabase * ) = 0; + virtual void save() const = 0; + virtual void setLanguage( const QString & ) = 0; + virtual QString language() const = 0; + virtual void setCustomSetting( const QString &key, const QString &value ) = 0; + virtual QString customSetting( const QString &key ) const = 0; + virtual DesignerPixmapCollection *pixmapCollection() const = 0; + virtual void breakPoints( QMap<QString, QValueList<uint> > &bps ) const = 0; + virtual QString breakPointCondition( QObject *o, int line ) const = 0; + virtual void setBreakPointCondition( QObject *o, int line, const QString &condition ) = 0; + virtual void clearAllBreakpoints() const = 0; + virtual void setIncludePath( const QString &platform, const QString &path ) = 0; + virtual void setLibs( const QString &platform, const QString &path ) = 0; + virtual void setDefines( const QString &platform, const QString &path ) = 0; + virtual void setConfig( const QString &platform, const QString &config ) = 0; + virtual void setTemplate( const QString &t ) = 0; + virtual QString config( const QString &platform ) const = 0; + virtual QString libs( const QString &platform ) const = 0; + virtual QString defines( const QString &platform ) const = 0; + virtual QString includePath( const QString &platform ) const = 0; + virtual QString templte() const = 0; + virtual bool isGenericObject( QObject *o ) const = 0; + +}; + +struct DesignerDatabase +{ + virtual QString name() const = 0; + virtual void setName( const QString & ) = 0; + virtual QString driver() const = 0; + virtual void setDriver( const QString & ) = 0; + virtual QString database() const = 0; + virtual void setDatabase( const QString & ) = 0; + virtual QString userName() const = 0; + virtual void setUserName( const QString & ) = 0; + virtual QString password() const = 0; + virtual void setPassword( const QString & ) = 0; + virtual QString hostName() const = 0; + virtual void setHostName( const QString & ) = 0; + virtual QStringList tables() const = 0; + virtual void setTables( const QStringList & ) = 0; + virtual QMap<QString, QStringList> fields() const = 0; + virtual void setFields( const QMap<QString, QStringList> & ) = 0; + virtual void open( bool suppressDialog = FALSE ) const = 0; + virtual void close() const = 0; + virtual QSqlDatabase* connection() = 0; + +}; + +struct DesignerPixmapCollection +{ + virtual void addPixmap( const QPixmap &p, const QString &name, bool force ) = 0; + virtual QPixmap pixmap( const QString &name ) const = 0; +}; + +struct DesignerFormWindow +{ + virtual QString name() const = 0; + virtual void setName( const QString &n ) = 0; + virtual QString fileName() const = 0; + virtual void setFileName( const QString & ) = 0; + virtual void save() const = 0; + virtual bool isModified() const = 0; + virtual void insertWidget( QWidget * ) = 0; + virtual void removeWidget( QWidget * ) = 0; + virtual QWidget *create( const char *className, QWidget *parent, const char *name ) = 0; + virtual QWidgetList widgets() const = 0; + virtual void undo() = 0; + virtual void redo() = 0; + virtual void cut() = 0; + virtual void copy() = 0; + virtual void paste() = 0; + virtual void adjustSize() = 0; + virtual void editConnections() = 0; + virtual void checkAccels() = 0; + virtual void layoutH() = 0; + virtual void layoutV() = 0; + virtual void layoutHSplit() = 0; + virtual void layoutVSplit() = 0; + virtual void layoutG() = 0; + virtual void layoutHContainer( QWidget* w ) = 0; + virtual void layoutVContainer( QWidget* w ) = 0; + virtual void layoutGContainer( QWidget* w ) = 0; + virtual void breakLayout() = 0; + virtual void selectWidget( QWidget * w ) = 0; + virtual void selectAll() = 0; + virtual void clearSelection() = 0; + virtual bool isWidgetSelected( QWidget * ) const = 0; + virtual QWidgetList selectedWidgets() const = 0; + virtual QWidget *currentWidget() const = 0; + virtual QWidget *form() const = 0; + virtual void setCurrentWidget( QWidget * ) = 0; + virtual QPtrList<QAction> actionList() const = 0; + virtual QAction *createAction( const QString& text, const QIconSet& icon, const QString& menuText, int accel, + QObject* parent, const char* name = 0, bool toggle = FALSE ) = 0; + virtual void addAction( QAction * ) = 0; + virtual void removeAction( QAction * ) = 0; + virtual void preview() const = 0; + virtual void addFunction( const QCString &slot, const QString &specifier, const QString &access, + const QString &type, const QString &language, const QString &returnType ) = 0; + virtual void addConnection( QObject *sender, const char *signal, QObject *receiver, const char *slot ) = 0; + virtual void setProperty( QObject *o, const char *property, const QVariant &value ) = 0; + virtual QVariant property( QObject *o, const char *property ) const = 0; + virtual void setPropertyChanged( QObject *o, const char *property, bool changed ) = 0; + virtual bool isPropertyChanged( QObject *o, const char *property ) const = 0; + virtual void setColumnFields( QObject *o, const QMap<QString, QString> & ) = 0; + virtual QStringList implementationIncludes() const = 0; + virtual QStringList declarationIncludes() const = 0; + virtual void setImplementationIncludes( const QStringList &lst ) = 0; + virtual void setDeclarationIncludes( const QStringList &lst ) = 0; + virtual QStringList forwardDeclarations() const = 0; + virtual void setForwardDeclarations( const QStringList &lst ) = 0; + virtual QStringList signalList() const = 0; + virtual void setSignalList( const QStringList &lst ) = 0; + virtual void addMenu( const QString &text, const QString &name ) = 0; + virtual void addMenuAction( const QString &menu, QAction *a ) = 0; + virtual void addMenuSeparator( const QString &menu ) = 0; + virtual void addToolBar( const QString &text, const QString &name ) = 0; + virtual void addToolBarAction( const QString &tb, QAction *a ) = 0; + virtual void addToolBarSeparator( const QString &tb ) = 0; + + virtual void onModificationChange( QObject *receiver, const char *slot ) = 0; +}; + +struct DesignerSourceFile +{ + virtual QString fileName() const = 0; +}; + +struct DesignerDock +{ + virtual QDockWindow *dockWindow() const = 0; +}; + +struct DesignerOutputDock +{ + virtual QWidget *addView( const QString &pageName ) = 0; + virtual void appendDebug( const QString & ) = 0; + virtual void clearDebug() = 0; + virtual void appendError( const QString &, int ) = 0; + virtual void clearError() = 0; +}; + +#endif diff --git a/kdevdesigner/interfaces/editorinterface.h b/kdevdesigner/interfaces/editorinterface.h new file mode 100644 index 00000000..0aff6c4f --- /dev/null +++ b/kdevdesigner/interfaces/editorinterface.h @@ -0,0 +1,102 @@ + /********************************************************************** +** 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. +** +** 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 EDITORINTERFACE_H +#define EDITORINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qmap.h> +#include <qvaluelist.h> + +class QWidget; +class QObjectList; +class QObject; + +// {8668161a-6037-4220-86b6-ccaa20127df8} +#ifndef IID_Editor +#define IID_Editor QUuid( 0x8668161a, 0x6037, 0x4220, 0x86, 0xb6, 0xcc, 0xaa, 0x20, 0x12, 0x7d, 0xf8 ) +#endif + +struct EditorInterface : public QUnknownInterface +{ + enum Mode + { + Editing, + Debugging + }; + + virtual QWidget *editor( bool readOnly, + QWidget *parent, + QUnknownInterface *designerIface ) = 0; + + virtual void setText( const QString &txt ) = 0; + virtual QString text() const = 0; + virtual bool isUndoAvailable() const = 0; + virtual bool isRedoAvailable() const = 0; + virtual void undo() = 0; + virtual void redo() = 0; + virtual void cut() = 0; + virtual void copy() = 0; + virtual void paste() = 0; + virtual void selectAll() = 0; + virtual bool find( const QString &expr, bool cs, bool wo, bool forward, bool startAtCursor ) = 0; + virtual bool replace( const QString &find, const QString &replace, bool cs, bool wo, bool forward, bool startAtCursor, bool replaceAll ) = 0; + virtual void gotoLine( int line ) = 0; + virtual void indent() = 0; + virtual void scrollTo( const QString &txt, const QString &first ) = 0; + virtual void splitView() = 0; + virtual void setContext( QObject *this_ ) = 0; + virtual void setError( int line ) = 0; + virtual void setStep( int line ) = 0; + virtual void setStackFrame( int line ) = 0; + virtual void clearStep() = 0; + virtual void clearStackFrame() = 0; + virtual void readSettings() = 0; + virtual void setModified( bool m ) = 0; + virtual bool isModified() const = 0; + virtual int numLines() const = 0; + virtual void breakPoints( QValueList<uint> &l ) const = 0; + virtual void setBreakPoints( const QValueList<uint> &l ) = 0; + virtual void setMode( Mode m ) = 0; + + virtual void onBreakPointChange( QObject *receiver, const char *slot ) = 0; + +}; + +#endif diff --git a/kdevdesigner/interfaces/filterinterface.h b/kdevdesigner/interfaces/filterinterface.h new file mode 100644 index 00000000..98abd250 --- /dev/null +++ b/kdevdesigner/interfaces/filterinterface.h @@ -0,0 +1,68 @@ + /********************************************************************** +** 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. +** +** 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 FILTERINTERFACE_H +#define FILTERINTERFACE_H + +#include <private/qcom_p.h> + +// {ea8cb381-59b5-44a8-bae5-9bea8295762a} +#ifndef IID_ImportFilter +#define IID_ImportFilter QUuid( 0xea8cb381, 0x59b5, 0x44a8, 0xba, 0xe5, 0x9b, 0xea, 0x82, 0x95, 0x76, 0x2a ) +#endif + +/*! If you write a filter plugin to import dialogs or other user + interfaces from a different format than .ui into the Qt Designer, + implement this interface in that plugin. + + You also have to implement the function featureList() (\sa + QFeatureListInterface) and return there all filters (names of it) + which this interface provides. +*/ + +struct ImportFilterInterface : public QFeatureListInterface +{ + /*! This function is called by Qt Designer to open the file \a + filename using the filter \a filter. Qt Designer expects to get + back one or more .ui files, which it can open then. In the + implementation of the interface you have to return these + filenames, which the filter created, in this function.*/ + virtual QStringList import( const QString &filter, const QString &filename ) = 0; +}; + +// *************** INTERNAL ************************* + +// {c32a07e0-b006-471e-afca-d227457a1280} +#ifndef IID_ExportFilterInterface +#define IID_ExportFilterInterface QUuid( 0xc32a07e0, 0xb006, 0x471e, 0xaf, 0xca, 0xd2, 0x27, 0x45, 0x7a, 0x12, 0x80 ) +#endif + +struct ExportFilterInterface : public QFeatureListInterface +{ +// virtual QStringList export( const QString& filter, const QString& filename ) = 0; +}; + +#endif diff --git a/kdevdesigner/interfaces/interpreterinterface.h b/kdevdesigner/interfaces/interpreterinterface.h new file mode 100644 index 00000000..8a64e6fc --- /dev/null +++ b/kdevdesigner/interfaces/interpreterinterface.h @@ -0,0 +1,59 @@ + /********************************************************************** +** 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. +** +** 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 INTERPRETERINTERFACE_H +#define INTERPRETERINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> + +class QObject; + +// {11cad9ec-4e3c-418b-8e90-e1b8c0c1f48f} +#ifndef IID_Interpreter +#define IID_Interpreter QUuid( 0x11cad9ec, 0x4e3c, 0x418b, 0x8e, 0x90, 0xe1, 0xb8, 0xc0, 0xc1, 0xf4, 0x8f ) +#endif + +struct InterpreterInterface : public QUnknownInterface +{ + virtual void setBreakPoints( QObject *obj, const QValueList<uint> &lst ) = 0; +}; + + + +#endif diff --git a/kdevdesigner/interfaces/languageinterface.h b/kdevdesigner/interfaces/languageinterface.h new file mode 100644 index 00000000..6fc0b8f9 --- /dev/null +++ b/kdevdesigner/interfaces/languageinterface.h @@ -0,0 +1,131 @@ + /********************************************************************** +** 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. +** +** 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 LANGUAGEINTERFACE_H +#define LANGUAGEINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qvaluelist.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qstrlist.h> + +// {f208499a-6f69-4883-9219-6e936e55a330} +#ifndef IID_Language +#define IID_Language QUuid( 0xf208499a, 0x6f69, 0x4883, 0x92, 0x19, 0x6e, 0x93, 0x6e, 0x55, 0xa3, 0x30 ) +#endif + +struct LanguageInterface : public QUnknownInterface +{ + struct Function + { + QString name; + QString body; + QString returnType; + QString comments; + int start; + int end; + QString access; + bool operator==( const Function &f ) const { + return ( name == f.name && + body == f.body && + returnType == f.returnType && + comments == f.comments ); + } + }; + + struct Connection + { + QString sender; + QString signal; + QString slot; + bool operator==( const Connection &c ) const { + return ( sender == c.sender && + signal == c.signal && + slot == c.slot ); + } + }; + + enum Support + { + ReturnType, + ConnectionsToCustomSlots, + CompressProject + }; + + virtual void functions( const QString &code, QValueList<Function> *funcs ) const = 0; + virtual void connections( const QString &code, QValueList<Connection> *connections ) const = 0; + virtual QString createFunctionStart( const QString &className, const QString &func, + const QString &returnType, const QString &access ) = 0; + virtual QString createArguments( const QString &cpp_signature ) = 0; + virtual QString createEmptyFunction() = 0; + virtual QStringList definitions() const = 0; + virtual QStringList definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const = 0; + virtual void setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ) = 0; + virtual bool supports( Support s ) const = 0; + virtual QStringList fileFilterList() const = 0; + virtual QStringList fileExtensionList() const = 0; + virtual void preferedExtensions( QMap<QString, QString> &extensionMap ) const = 0; + virtual QString projectKeyForExtension( const QString &extension ) const = 0; + virtual void sourceProjectKeys( QStringList &keys ) const = 0; + virtual QString cleanSignature( const QString &sig ) = 0; + virtual void loadFormCode( const QString &form, const QString &filename, + QValueList<Function> &functions, + QStringList &vars, + QValueList<Connection> &connections ) = 0; + virtual QString formCodeExtension() const = 0; + + virtual bool canConnect( const QString &signal, const QString &slot ) = 0; + + virtual void compressProject( const QString &projectFile, const QString &compressedFile, + bool withWarning ) = 0; + virtual QString uncompressProject( const QString &projectFile, const QString &destDir ) = 0; + virtual QString aboutText() const = 0; + + virtual void addConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot, + QString *code ) = 0; + virtual void removeConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot, + QString *code ) = 0; + virtual QStrList signalNames( QObject *obj ) const = 0; + +}; + +#endif diff --git a/kdevdesigner/interfaces/preferenceinterface.h b/kdevdesigner/interfaces/preferenceinterface.h new file mode 100644 index 00000000..880fe285 --- /dev/null +++ b/kdevdesigner/interfaces/preferenceinterface.h @@ -0,0 +1,68 @@ + /********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PREFERENCEINTERFACE_H +#define PREFERENCEINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qwidgetlist.h> +#include <qcstring.h> + +// {5c168ee7-4bee-469f-9995-6afdb04ce5a2} +#ifndef IID_Preference +#define IID_Preference QUuid( 0x5c168ee7, 0x4bee, 0x469f, 0x99, 0x95, 0x6a, 0xfd, 0xb0, 0x4c, 0xe5, 0xa2 ) +#endif + +struct PreferenceInterface : public QUnknownInterface +{ + struct Preference + { + QWidget *tab; + QString title; + QObject *receiver; + const char *init_slot; + const char *accept_slot; + }; + + virtual Preference *preference() = 0; + virtual void connectTo( QUnknownInterface *appInterface ) = 0; + virtual void deletePreferenceObject( Preference * ) = 0; +}; + +#endif diff --git a/kdevdesigner/interfaces/projectsettingsiface.h b/kdevdesigner/interfaces/projectsettingsiface.h new file mode 100644 index 00000000..ee571a7b --- /dev/null +++ b/kdevdesigner/interfaces/projectsettingsiface.h @@ -0,0 +1,69 @@ + /********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef PROJECTSETTINGSIFACE_H +#define PROJECTSETTINGSIFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qwidgetlist.h> +#include <qcstring.h> + +// {d332785d-17fb-4894-84fe-50dbd0ad9512} +#ifndef IID_ProjectSettings +#define IID_ProjectSettings QUuid( 0xd332785d, 0x17fb, 0x4894, 0x84, 0xfe, 0x50, 0xdb, 0xd0, 0xad, 0x95, 0x12 ) +#endif + +struct ProjectSettingsInterface : public QUnknownInterface +{ + struct ProjectSettings + { + QWidget *tab; + QString title; + QObject *receiver; + const char *init_slot; + const char *accept_slot; + }; + + virtual ProjectSettings *projectSetting() = 0; + virtual QStringList projectSettings() const = 0; + virtual void connectTo( QUnknownInterface *appInterface ) = 0; + virtual void deleteProjectSettingsObject( ProjectSettings * ) = 0; +}; + +#endif diff --git a/kdevdesigner/interfaces/sourcetemplateiface.h b/kdevdesigner/interfaces/sourcetemplateiface.h new file mode 100644 index 00000000..c1dc2a74 --- /dev/null +++ b/kdevdesigner/interfaces/sourcetemplateiface.h @@ -0,0 +1,65 @@ + /********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef SOURCETEMPLATEIFACE_H +#define SOURCETEMPLATEIFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> +#include <qstring.h> + +// {1b3446a4-1c71-424b-8789-1f34eb5697d8} +#ifndef IID_SourceTemplate +#define IID_SourceTemplate QUuid( 0x1b3446a4, 0x1c71, 0x424b, 0x87, 0x89, 0x1f, 0x34, 0xeb, 0x56, 0x97, 0xd8 ) +#endif + +struct SourceTemplateInterface : public QFeatureListInterface +{ + struct Source + { + QString code; + enum Type { FileName, Unnamed, Invalid } type; + QString filename; + QString extension; + }; + virtual Source create( const QString &templ, QUnknownInterface *appIface ) = 0; + virtual QString language( const QString &templ ) const = 0; + +}; + +#endif diff --git a/kdevdesigner/interfaces/templatewizardiface.h b/kdevdesigner/interfaces/templatewizardiface.h new file mode 100644 index 00000000..82b204da --- /dev/null +++ b/kdevdesigner/interfaces/templatewizardiface.h @@ -0,0 +1,60 @@ + /********************************************************************** +** 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. +** +** 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 TEMPLATEWIZARDIFACE_H +#define TEMPLATEWIZARDIFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include <private/qcom_p.h> + +class QWidget; +struct DesignerFormWindow; + +// {983d3eab-fea3-49cc-97ad-d8cc89b7c17b} +#ifndef IID_TemplateWizard +#define IID_TemplateWizard QUuid( 0x983d3eab, 0xfea3, 0x49cc, 0x97, 0xad, 0xd8, 0xcc, 0x89, 0xb7, 0xc1, 0x7b ) +#endif + +class TemplateWizardInterface : public QFeatureListInterface +{ +public: + virtual void setup( const QString &templ, QWidget *widget, DesignerFormWindow *fw, QUnknownInterface *appIface ) = 0; + +}; + +#endif diff --git a/kdevdesigner/interfaces/widgetinterface.h b/kdevdesigner/interfaces/widgetinterface.h new file mode 100644 index 00000000..9b6d8f8e --- /dev/null +++ b/kdevdesigner/interfaces/widgetinterface.h @@ -0,0 +1,35 @@ + /********************************************************************** +** 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. +** +** 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 WIDGETINTERFACE_H +#define WIDGETINTERFACE_H + +#include <private/qwidgetinterface_p.h> + +#define WidgetInterface QWidgetFactoryInterface +#define IID_Widget IID_QWidgetFactory + +#endif diff --git a/kdevdesigner/plugins/Makefile.am b/kdevdesigner/plugins/Makefile.am new file mode 100644 index 00000000..defe80c4 --- /dev/null +++ b/kdevdesigner/plugins/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/interfaces $(all_includes) +METASOURCES = AUTO +kdevdesignerdir = $(kde_moduledir)/plugins/kdevdesigner +kdevdesigner_LTLIBRARIES = libkdevdesigner_lang.la +libkdevdesigner_lang_la_LDFLAGS = -module $(all_libraries) $(KDE_PLUGIN) +libkdevdesigner_lang_la_SOURCES = languageinterfaceimpl.cpp +libkdevdesigner_lang_la_LIBADD = $(LIB_QT) + diff --git a/kdevdesigner/plugins/languageinterfaceimpl.cpp b/kdevdesigner/plugins/languageinterfaceimpl.cpp new file mode 100644 index 00000000..37077922 --- /dev/null +++ b/kdevdesigner/plugins/languageinterfaceimpl.cpp @@ -0,0 +1,237 @@ +/********************************************************************** +** +** 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 "languageinterfaceimpl.h" +#include <qobject.h> +#include "../interfaces/designerinterface.h" +#include <qfile.h> +//#include "yyreg.h" +#include <qmetaobject.h> + +LanguageInterfaceImpl::LanguageInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), ref( 0 ) +{ +} + +ulong LanguageInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong LanguageInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +QRESULT LanguageInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Language ) + *iface = (LanguageInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +void LanguageInterfaceImpl::functions( const QString &code, QValueList<Function> *functionMap ) const +{ +/* QValueList<CppFunction> l; + extractCppFunctions( code, &l ); + for ( QValueList<CppFunction>::Iterator it = l.begin(); it != l.end(); ++it ) { + Function func; + func.name = (*it).prototype(); + func.name.remove( 0, (*it).returnType().length() ); + if ( func.name.find( "::" ) == -1 ) + continue; + func.name.remove( (uint)0, func.name.find( "::" ) + 2 ); + func.body = (*it).body(); + func.returnType = (*it).returnType(); + func.start = (*it).functionStartLineNum(); + func.end = (*it).closingBraceLineNum(); + functionMap->append( func ); + }*/ +} + +QString LanguageInterfaceImpl::createFunctionStart( const QString &className, const QString &func, + const QString &returnType, + const QString & ) +{ + return returnType + " " + className + "::" + func; +} + +QStringList LanguageInterfaceImpl::definitions() const +{ + QStringList lst; + lst << "Includes (in Implementation)" << "Includes (in Declaration)" << "Forward Declarations" << "Signals"; + return lst; +} + +QStringList LanguageInterfaceImpl::definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const +{ + DesignerInterface *iface = 0; + designerIface->queryInterface( IID_Designer, (QUnknownInterface**) &iface ); + if ( !iface ) + return QStringList(); + DesignerFormWindow *fw = iface->currentForm(); + if ( !fw ) + return QStringList(); + QStringList lst; + if ( definition == "Includes (in Implementation)" ) { + lst = fw->implementationIncludes(); + } else if ( definition == "Includes (in Declaration)" ) { + lst = fw->declarationIncludes(); + } else if ( definition == "Forward Declarations" ) { + lst = fw->forwardDeclarations(); + } else if ( definition == "Signals" ) { + lst = fw->signalList(); + } + iface->release(); + return lst; +} + +void LanguageInterfaceImpl::setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ) +{ + DesignerInterface *iface = 0; + designerIface->queryInterface( IID_Designer, (QUnknownInterface**) &iface ); + if ( !iface ) + return; + DesignerFormWindow *fw = iface->currentForm(); + if ( !fw ) + return; + if ( definition == "Includes (in Implementation)" ) { + fw->setImplementationIncludes( entries ); + } else if ( definition == "Includes (in Declaration)" ) { + fw->setDeclarationIncludes( entries ); + } else if ( definition == "Forward Declarations" ) { + fw->setForwardDeclarations( entries ); + } else if ( definition == "Signals" ) { + fw->setSignalList( entries ); + } + iface->release(); +} + +QString LanguageInterfaceImpl::createEmptyFunction() +{ + return "{\n\n}\n"; +} + +bool LanguageInterfaceImpl::supports( Support s ) const +{ + if ( s == ReturnType ) + return TRUE; + if ( s == ConnectionsToCustomSlots ) + return TRUE; + return FALSE; +} + +QStringList LanguageInterfaceImpl::fileFilterList() const +{ + QStringList f; + f << "C++ Files (*.cpp *.C *.cxx *.c++ *.ocl *.c *.h *.H *.hpp *.hxx)"; + return f; + +} +QStringList LanguageInterfaceImpl::fileExtensionList() const +{ + QStringList f; + f << "cpp" << "ocl" << "C" << "cxx" << "c++" << "c" <<"h" << "H" << "hpp" << "hxx"; + return f; +} + +QString LanguageInterfaceImpl::projectKeyForExtension( const QString &extension ) const +{ + if ( extension[ 0 ] == 'c' || extension[ 0 ] == 'C' ) + return "SOURCES"; + return "HEADERS"; +} + +void LanguageInterfaceImpl::sourceProjectKeys( QStringList &keys ) const +{ + keys << "HEADERS" << "SOURCES"; +} + + class CheckObject : public QObject +{ +public: + CheckObject() {} + bool checkConnectArgs( const char *signal, const char *member ) { return QObject::checkConnectArgs( signal, 0, member ); } + +}; + +bool LanguageInterfaceImpl::canConnect( const QString &signal, const QString &slot ) +{ + CheckObject o; + return o.checkConnectArgs( signal.latin1(), slot.latin1() ); +} + +void LanguageInterfaceImpl::loadFormCode( const QString &, const QString &filename, + QValueList<Function> &functions, + QStringList &, + QValueList<Connection> & ) +{ + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + QString code( ts.read() ); + this->functions( code, &functions ); +} + +void LanguageInterfaceImpl::preferedExtensions( QMap<QString, QString> &extensionMap ) const +{ + extensionMap.insert( "cpp", "C++ Source File" ); + extensionMap.insert( "h", "C++ Header File" ); +} + +QStrList LanguageInterfaceImpl::signalNames( QObject *obj ) const +{ + QStrList sigs; + sigs = obj->metaObject()->signalNames( TRUE ); + sigs.remove( "destroyed()" ); + return sigs; +} diff --git a/kdevdesigner/plugins/languageinterfaceimpl.h b/kdevdesigner/plugins/languageinterfaceimpl.h new file mode 100644 index 00000000..d8cb9cf2 --- /dev/null +++ b/kdevdesigner/plugins/languageinterfaceimpl.h @@ -0,0 +1,83 @@ +/********************************************************************** +** +** 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 LANGUAGEINTERFACEIMPL_H +#define LANGUAGEINTERFACEIMPL_H + +#include "../interfaces/languageinterface.h" + +class LanguageInterfaceImpl : public LanguageInterface +{ +public: + LanguageInterfaceImpl( QUnknownInterface *outer = 0 ); + + ulong addRef(); + ulong release(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + + void functions( const QString &code, QValueList<Function> *funcs ) const; + void connections( const QString &, QValueList<Connection> * ) const {}; + QString createFunctionStart( const QString &className, const QString &func, + const QString &returnType, const QString &access ); + QStringList definitions() const; + QStringList definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const; + void setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ); + QString createArguments( const QString & ) { return QString::null; } + QString createEmptyFunction(); + bool supports( Support s ) const; + QStringList fileFilterList() const; + QStringList fileExtensionList() const; + void preferedExtensions( QMap<QString, QString> &extensionMap ) const; + void sourceProjectKeys( QStringList &keys ) const; + QString projectKeyForExtension( const QString &extension ) const; + QString cleanSignature( const QString &sig ) { return sig; } // #### implement me + void loadFormCode( const QString &, const QString &, + QValueList<Function> &, + QStringList &, + QValueList<Connection> & ); + QString formCodeExtension() const { return ".h"; } + bool canConnect( const QString &signal, const QString &slot ); + void compressProject( const QString &, const QString &, bool ) {} + QString uncompressProject( const QString &, const QString & ) { return QString::null; } + QString aboutText() const { return ""; } + + void addConnection( const QString &, const QString &, + const QString &, const QString &, + QString * ) {} + void removeConnection( const QString &, const QString &, + const QString &, const QString &, + QString * ) {} + QStrList signalNames( QObject *obj ) const; + +private: + QUnknownInterface *parent; + ulong ref; + +}; + +#endif diff --git a/kdevdesigner/shared/Makefile.am b/kdevdesigner/shared/Makefile.am new file mode 100644 index 00000000..ea86ae94 --- /dev/null +++ b/kdevdesigner/shared/Makefile.am @@ -0,0 +1,6 @@ +KDE_CXXFLAGS = -UQT_NO_ASCII_CAST +INCLUDES = -I$(top_srcdir)/lib/interfaces/external $(all_includes) +METASOURCES = AUTO +libshared_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libshared.la +libshared_la_SOURCES = domtool.cpp parser.cpp ui2uib.cpp uib.cpp widgetdatabase.cpp diff --git a/kdevdesigner/shared/domtool.cpp b/kdevdesigner/shared/domtool.cpp new file mode 100644 index 00000000..492ce88e --- /dev/null +++ b/kdevdesigner/shared/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/kdevdesigner/shared/domtool.h b/kdevdesigner/shared/domtool.h new file mode 100644 index 00000000..61b4269a --- /dev/null +++ b/kdevdesigner/shared/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/kdevdesigner/shared/globaldefs.h b/kdevdesigner/shared/globaldefs.h new file mode 100644 index 00000000..653c4fa5 --- /dev/null +++ b/kdevdesigner/shared/globaldefs.h @@ -0,0 +1,62 @@ +/********************************************************************** +** 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 GLOBALDEFS_H +#define GLOBALDEFS_H + +#include <qcolor.h> +#include <qapplication.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; + +#if 0 // a calculated alternative for backColor1 + QColorGroup myCg = qApp->palette().active(); + int h1, s1, v1; + int h2, s2, v2; + myCg.color( QColorGroup::Base ).hsv( &h1, &s1, &v1 ); + myCg.color( QColorGroup::Background ).hsv( &h2, &s2, &v2 ); + QColor c( h1, s1, ( v1 + v2 ) / 2, QColor::Hsv ); +#endif + + backColor1 = new QColor( 250, 248, 235 ); + backColor2 = new QColor( 255, 255, 255 ); + selectedBack = new QColor( 230, 230, 230 ); +} + +#endif + +#endif diff --git a/kdevdesigner/shared/parser.cpp b/kdevdesigner/shared/parser.cpp new file mode 100644 index 00000000..e1b54ca1 --- /dev/null +++ b/kdevdesigner/shared/parser.cpp @@ -0,0 +1,72 @@ +/********************************************************************** +** 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 "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/kdevdesigner/shared/parser.h b/kdevdesigner/shared/parser.h new file mode 100644 index 00000000..10d83027 --- /dev/null +++ b/kdevdesigner/shared/parser.h @@ -0,0 +1,39 @@ +/********************************************************************** +** 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 PARSER_H +#define PARSER_H + +#include <qstring.h> + +class Parser +{ +public: + static QString cleanArgs( const QString &func ); + +}; + +#endif diff --git a/kdevdesigner/shared/ui2uib.cpp b/kdevdesigner/shared/ui2uib.cpp new file mode 100644 index 00000000..72c09320 --- /dev/null +++ b/kdevdesigner/shared/ui2uib.cpp @@ -0,0 +1,893 @@ +/********************************************************************** +** 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 "ui2uib.h" +#include "uib.h" + +#include <domtool.h> + +#include <qcolor.h> +#include <qcursor.h> +#include <qdatetime.h> +#include <qdom.h> +#include <qfile.h> +#include <qfont.h> +#include <qobject.h> +#include <qrect.h> +#include <qsizepolicy.h> + +/* + The .uib file format is the binary counterpart of the .ui file + format. It is generated by the ui2uib converter and understood by + QWidgetFactory; in a future version, it might also be understood + by a uib2ui converter. Experiments show that .uib files are about + 2.5 times faster to load and 6 times smaller than .ui files. + + The .uib format, unlike the .ui format, is internal to Trolltech + and is not officially documented; it is assumed that anybody who + needs to understand the file format can read the ui2uib and + QWidgetFactory source code, with some guidance. And here's some + guidance. + + A .uib file starts with a 32-bit magic number that allows + QWidgetFactory to determine the file type. The magic number is + followed by '\n' (0x0a) and '\r' (0x0d), which ensure that the + file wasn't corrupted during transfer between different + platforms. For example, transferring a .ui file from Windows to + Unix using FTP with type ASCII will produce a file with '\r\n\r' + in place of '\n\r'. This is followed by the QDataStream format + version number used. + + The rest of the file is made up of blocks, each of which starts + with a block type (Block_XXX) and a block length. Block_Intro and + Block_Widget are mandatory; the others are optional. + QWidgetFactory makes certain assumptions about the order of the + blocks; for example, it expects Block_String before any other + block that refers to a string and Block_Images before + Block_Widget. The order generated by ui2uib is one of the orders + that make sense. Just after the last block, a Block_End marker + indicates the end of the file. + + The division of .uib files into blocks corresponds grossly to the + division of .ui files in top-level XML elements. Thus, + Block_Widget corresponds to <widget> and Block_Toolbars to + <toolbars>. The internal organization of each block also mimics + the organization of the corresponding XML elements. + + These are the major differences, all of which contribute to + making .uib files more compact: + + 1. The strings are gathered in Block_Strings, a string-table. + When a string is needed later, it is referenced by a 32-bit + index into that table. The UicStringTable class makes the + whole process of inserting and looking up strings very + simple. The advantage of this scheme is that if a string is + used more than once, it is stored only once. Also, the + string-table is preinitialized with very common strings, so + that these need not be stored along with .uib files. + + 2. QObjects are referred to by index in a table rather than by + name. The table itself is not stored in the .uib file; it is + rather build dynamically by ui2uib and QWidgetFactory as new + objects are specified. In ui2uib, the table is represented by + a UibIndexMap object; in QWidgetFactory, a plain array of + QObject pointers suffices. + + 3. The data is packed to take as little place as possible, + without slowing down QLayoutFactory too much. For example, an + index into the string-table is a 32-bit integer, but in + practice it is rarely above 65534, so only 16 bits are used + for them; when an index above 65534 is met, the index is + saved as 65535 followed by the 32-bit index, for a total of + 48 bits. + + 4. The name of a signal or slot and its signature are saved + separately. That way, if a signal 'foo(const QString&)' is + connected to a slot 'bar(const QString&)', the string-table + will only contain 'foo', 'bar', and '(const QString&)', + instead of the longer 'foo(const QString&)' and 'bar(const + QString&)'. The signatures are normalized beforehand to + ensure that trivial spacing problems don't result in multiple + string-table entries. + + 5. In a signal-to-slot connection, a sender, signal, receiver, + or slot is not repeated if it's the same as for the previous + connection. Bit flags indicate what is repeated and what is + specified. + + 6. Some of the information stored in a .ui file is useful only + by uic, not to QLayoutFactory. That information is, for now, + not taken along in the .uib file. Likewise, needless + QLayoutWidget objects are not taken along. + + The arbitrary constants related to the .uib file formats are + defined in uib.h. Constants such as Block_Actions and + Object_SubWidget are given values such as 'A' and 'W' to make + .uib files easier to read in a hexadecimal editor. + + The file format isn't designed to be extensible. Any extension + that prevents an older version of QLayoutWidget of reading the + file correctly must have a different magic number. The plan is to + use UibMagic + 1 for version 2, UibMagic + 2 for version 3, etc. +*/ + +static QCString layoutForTag( const QString& tag ) +{ + if ( tag == "grid" ) { + return "QGridLayout"; + } else if ( tag == "hbox" ) { + return "QHBoxLayout"; + } else if ( tag == "vbox" ) { + return "QVBoxLayout"; + } else { + return "QLayout"; + } +} + +class UibHack : public QObject +{ +public: + static QString normalize( const QString& member ) { + return QString::fromUtf8( QObject::normalizeSignalSlot(member.utf8()) ); + } +}; + +class UibIndexMap +{ +public: + UibIndexMap() : next( 0 ) { } + + void insert( const QString& name ) { setName( insert(), name ); } + int insert() { return next++; } + void setName( int no, const QString& name ); + + int find( const QString& name, int deflt = -1 ) const; + int count() const { return next; } + +private: + QMap<QString, int> nameMap; + QMap<QString, int> conflicts; + int next; +}; + +void UibIndexMap::setName( int no, const QString& name ) +{ + if ( !name.isEmpty() ) { + if ( *nameMap.insert(name, no, FALSE) != no ) + conflicts.insert( name, 0 ); + } +} + +int UibIndexMap::find( const QString& name, int deflt ) const +{ + QMap<QString, int>::ConstIterator no = nameMap.find( name ); + if ( no == nameMap.end() || conflicts.contains(name) ) { + return deflt; + } else { + return *no; + } +} + +static void packUInt16( QDataStream& out, Q_UINT16 n ) +{ + if ( n < 255 ) { + out << (Q_UINT8) n; + } else { + out << (Q_UINT8) 255; + out << n; + } +} + +static void packUInt32( QDataStream& out, Q_UINT32 n ) +{ + if ( n < 65535 ) { + out << (Q_UINT16) n; + } else { + out << (Q_UINT16) 65535; + out << n; + } +} + +static void packByteArray( QDataStream& out, const QByteArray& array ) +{ + packUInt32( out, array.size() ); + out.writeRawBytes( array.data(), array.size() ); +} + +static void packCString( UibStrTable& strings, QDataStream& out, + const char *cstr ) +{ + packUInt32( out, strings.insertCString(cstr) ); +} + +static void packString( UibStrTable& strings, QDataStream& out, + const QString& str ) +{ + packUInt32( out, strings.insertString(str) ); +} + +static void packStringSplit( UibStrTable& strings, QDataStream& out, + const QString& str, QChar sep ) +{ + int pos = str.find( sep ); + if ( pos == -1 ) + pos = str.length(); + packString( strings, out, str.left(pos) ); + packString( strings, out, str.mid(pos) ); +} + +static void packVariant( UibStrTable& strings, QDataStream& out, + QVariant value, QString tag = "" ) +{ + QStringList::ConstIterator s; + + Q_UINT8 type = value.type(); + if ( tag == "pixmap" ) { + type = QVariant::Pixmap; + } else if ( tag == "image" ) { + type = QVariant::Image; + } else if ( tag == "iconset" ) { + type = QVariant::IconSet; + } + out << type; + + switch ( type ) { + case QVariant::String: + case QVariant::Pixmap: + case QVariant::Image: + case QVariant::IconSet: + packString( strings, out, value.asString() ); + break; + case QVariant::StringList: + packUInt16( out, value.asStringList().count() ); + s = value.asStringList().begin(); + while ( s != value.asStringList().end() ) { + packString( strings, out, *s ); + ++s; + } + break; + case QVariant::Font: + out << value.asFont(); + break; + case QVariant::Rect: + packUInt16( out, value.asRect().x() ); + packUInt16( out, value.asRect().y() ); + packUInt16( out, value.asRect().width() ); + packUInt16( out, value.asRect().height() ); + break; + case QVariant::Size: + packUInt16( out, value.asSize().width() ); + packUInt16( out, value.asSize().height() ); + break; + case QVariant::Color: + out << value.asColor(); + break; + case QVariant::Point: + packUInt16( out, value.asPoint().x() ); + packUInt16( out, value.asPoint().y() ); + break; + case QVariant::Int: + packUInt32( out, value.asInt() ); + break; + case QVariant::Bool: + out << (Q_UINT8) value.asBool(); + break; + case QVariant::Double: + out << value.asDouble(); + break; + case QVariant::CString: + packCString( strings, out, value.asCString() ); + break; + case QVariant::Cursor: + out << value.asCursor(); + break; + case QVariant::Date: + out << value.asDate(); + break; + case QVariant::Time: + out << value.asTime(); + break; + case QVariant::DateTime: + out << value.asDateTime(); + break; + default: + out << value; + } +} + +static void outputProperty( QMap<int, QStringList>& buddies, int objectNo, + UibStrTable& strings, QDataStream& out, + QDomElement elem ) +{ + QCString name = elem.attribute( "name" ).latin1(); + QDomElement f = elem.firstChild().toElement(); + QString tag = f.tagName(); + QString comment; + QVariant value; + + if ( name == "resizeable" ) + name = "resizable"; + + if ( tag == "font" ) { + QString family; + Q_UINT16 pointSize = 65535; + Q_UINT8 fontFlags = 0; + + QDomElement g = f.firstChild().toElement(); + while ( !g.isNull() ) { + QString text = g.firstChild().toText().data(); + if ( g.tagName() == "family" ) { + fontFlags |= Font_Family; + family = text; + } else if ( g.tagName() == "pointsize" ) { + fontFlags |= Font_PointSize; + pointSize = (Q_UINT16) text.toUInt(); + } else { + if ( g.firstChild().toText().data().toInt() != 0 ) { + if ( g.tagName() == "bold" ) { + fontFlags |= Font_Bold; + } else if ( g.tagName() == "italic" ) { + fontFlags |= Font_Italic; + } else if ( g.tagName() == "underline" ) { + fontFlags |= Font_Underline; + } else if ( g.tagName() == "strikeout" ) { + fontFlags |= Font_StrikeOut; + } + } + } + g = g.nextSibling().toElement(); + } + + out << (Q_UINT8) Object_FontProperty; + packCString( strings, out, name ); + out << fontFlags; + if ( fontFlags & Font_Family ) + packString( strings, out, family ); + if ( fontFlags & Font_PointSize ) + packUInt16( out, pointSize ); + } else if ( tag == "palette" ) { + out << (Q_UINT8) Object_PaletteProperty; + packCString( strings, out, name ); + + QDomElement g = f.firstChild().toElement(); + while ( !g.isNull() ) { + QDomElement h = g.firstChild().toElement(); + while ( !h.isNull() ) { + value = DomTool::elementToVariant( h, Qt::gray ); + if ( h.tagName() == "color" ) { + out << (Q_UINT8) Palette_Color; + out << value.asColor(); + } else if ( h.tagName() == "pixmap" ) { + out << (Q_UINT8) Palette_Pixmap; + packVariant( strings, out, value, "pixmap" ); + } + h = h.nextSibling().toElement(); + } + + if ( g.tagName() == "active" ) { + out << (Q_UINT8) Palette_Active; + } else if ( g.tagName() == "inactive" ) { + out << (Q_UINT8) Palette_Inactive; + } else { + out << (Q_UINT8) Palette_Disabled; + } + g = g.nextSibling().toElement(); + } + out << (Q_UINT8) Palette_End; + } else { + value = DomTool::elementToVariant( f, value, comment ); + if ( value.isValid() ) { + if ( name == "buddy" ) { + buddies[objectNo] += value.asString(); + } else { + if ( tag == "string" ) { + out << (Q_UINT8) Object_TextProperty; + packCString( strings, out, name ); + packCString( strings, out, value.asString().utf8() ); + packCString( strings, out, comment.utf8() ); + } else { + out << (Q_UINT8) Object_VariantProperty; + packCString( strings, out, name ); + packVariant( strings, out, value, tag ); + } + } + } + } +} + +static void outputGridCell( QDataStream& out, QDomElement elem ) +{ + int column = elem.attribute( "column", "0" ).toInt(); + int row = elem.attribute( "row", "0" ).toInt(); + int colspan = elem.attribute( "colspan", "1" ).toInt(); + int rowspan = elem.attribute( "rowspan", "1" ).toInt(); + if ( colspan < 1 ) + colspan = 1; + if ( rowspan < 1 ) + rowspan = 1; + + if ( column != 0 || row != 0 || colspan != 1 || rowspan != 1 ) { + out << (Q_UINT8) Object_GridCell; + packUInt16( out, column ); + packUInt16( out, row ); + packUInt16( out, colspan ); + packUInt16( out, rowspan ); + } +} + +static int outputObject( QMap<int, QStringList>& buddies, + UibIndexMap& objects, UibStrTable& strings, + QDataStream& out, QDomElement elem, + QCString className = "" ); + +static void outputLayoutWidgetsSubLayout( QMap<int, QStringList>& buddies, + UibIndexMap& objects, + UibStrTable& strings, + QDataStream& out, QDomElement elem ) +{ + int subLayoutNo = -1; + QCString name; + QDomElement nameElem; + + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + QString tag = f.tagName(); + if ( tag == "grid" || tag == "hbox" || tag == "vbox" ) { + out << (Q_UINT8) Object_SubLayout; + subLayoutNo = outputObject( buddies, objects, strings, out, f, + layoutForTag(tag) ); + } else if ( tag == "property" ) { + if ( f.attribute("name") == "name" ) { + name = DomTool::elementToVariant( f, name ).asCString(); + nameElem = f; + } + } + f = f.nextSibling().toElement(); + } + + if ( subLayoutNo != -1 ) { + /* + Remove the sub-layout's Object_End marker, append the grid + cell and the correct name property, and put the Object_End + marker back. + */ + out.device()->at( out.device()->at() - 1 ); + outputGridCell( out, elem ); + outputProperty( buddies, subLayoutNo, strings, out, nameElem ); + out << (Q_UINT8) Object_End; + + objects.setName( subLayoutNo, name ); + } +} + +static int outputObject( QMap<int, QStringList>& buddies, + UibIndexMap& objects, UibStrTable& strings, + QDataStream& out, QDomElement elem, + QCString className ) +{ + bool isQObject = !className.isEmpty(); + + if ( className == "QToolBar" ) + out << (Q_UINT8) elem.attribute( "dock", "0" ).toInt(); + if ( className == "QWidget" ) + className = elem.attribute( "class", className ).latin1(); + + int objectNo = -1; + if ( isQObject ) { + packCString( strings, out, className ); + objectNo = objects.insert(); + } + + outputGridCell( out, elem ); + + // optimization: insert '&Foo' into string-table before 'Foo' + if ( className == "QAction" || className == "QActionGroup" ) { + QVariant value = DomTool::readProperty( elem, "menuText", QVariant() ); + if ( value.asString().startsWith("&") ) + strings.insertString( value.asString() ); + } + + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + QString tag = f.tagName(); + if ( tag == "action" ) { + if ( elem.tagName() == "item" || elem.tagName() == "toolbar" ) { + QString actionName = f.attribute( "name" ); + int no = objects.find( actionName ); + if ( no != -1 ) { + out << (Q_UINT8) Object_ActionRef; + packUInt16( out, no ); + } + } else { + out << (Q_UINT8) Object_SubAction; + outputObject( buddies, objects, strings, out, f, "QAction" ); + } + } else if ( tag == "actiongroup" ) { + out << (Q_UINT8) Object_SubAction; + outputObject( buddies, objects, strings, out, f, "QActionGroup" ); + } else if ( tag == "attribute" ) { + out << (Q_UINT8) Object_Attribute; + outputProperty( buddies, objectNo, strings, out, f ); + } else if ( tag == "column" ) { + out << (Q_UINT8) Object_Column; + outputObject( buddies, objects, strings, out, f ); + } else if ( tag == "event" ) { + out << (Q_UINT8) Object_Event; + packCString( strings, out, f.attribute("name").latin1() ); + packVariant( strings, out, + QStringList::split(',', f.attribute("functions")) ); + } else if ( tag == "grid" || tag == "hbox" || tag == "vbox" ) { + out << (Q_UINT8) Object_SubLayout; + outputObject( buddies, objects, strings, out, f, + layoutForTag(tag) ); + } else if ( tag == "item" ) { + if ( elem.tagName() == "menubar" ) { + out << (Q_UINT8) Object_MenuItem; + packCString( strings, out, f.attribute("name").latin1() ); + packCString( strings, out, f.attribute("text").utf8() ); + outputObject( buddies, objects, strings, out, f ); + } else { + out << (Q_UINT8) Object_Item; + outputObject( buddies, objects, strings, out, f ); + } + } else if ( tag == "property" ) { + outputProperty( buddies, objectNo, strings, out, f ); + } else if ( tag == "row" ) { + out << (Q_UINT8) Object_Row; + outputObject( buddies, objects, strings, out, f ); + } else if ( tag == "separator" ) { + out << (Q_UINT8) Object_Separator; + } else if ( tag == "spacer" ) { + out << (Q_UINT8) Object_Spacer; + outputObject( buddies, objects, strings, out, f ); + } else if ( tag == "widget" ) { + if ( f.attribute("class") == "QLayoutWidget" && + elem.tagName() != "widget" ) { + outputLayoutWidgetsSubLayout( buddies, objects, strings, out, + f ); + } else { + out << (Q_UINT8) Object_SubWidget; + outputObject( buddies, objects, strings, out, f, "QWidget" ); + } + } + f = f.nextSibling().toElement(); + } + out << (Q_UINT8) Object_End; + if ( isQObject ) + objects.setName( objectNo, + DomTool::readProperty(elem, "name", "").asString() ); + return objectNo; +} + +static void outputBlock( QDataStream& out, BlockTag tag, + const QByteArray& data ) +{ + if ( !data.isEmpty() ) { + out << (Q_UINT8) tag; + packByteArray( out, data ); + } +} + +void convertUiToUib( QDomDocument& doc, QDataStream& out ) +{ + QByteArray introBlock; + QByteArray actionsBlock; + QByteArray buddiesBlock; + QByteArray connectionsBlock; + QByteArray functionsBlock; + QByteArray imagesBlock; + QByteArray menubarBlock; + QByteArray slotsBlock; + QByteArray tabstopsBlock; + QByteArray toolbarsBlock; + QByteArray variablesBlock; + QByteArray widgetBlock; + + QDomElement actionsElem; + QDomElement connectionsElem; + QDomElement imagesElem; + QDomElement menubarElem; + QDomElement tabstopsElem; + QDomElement toolbarsElem; + QDomElement widgetElem; + + QMap<int, QStringList> buddies; + UibStrTable strings; + UibIndexMap objects; + int widgetNo = -1; + QCString className; + Q_INT16 defaultMargin = -32768; + Q_INT16 defaultSpacing = -32768; + Q_UINT8 introFlags = 0; + + QDomElement elem = doc.firstChild().toElement().firstChild().toElement(); + while ( !elem.isNull() ) { + QString tag = elem.tagName(); + + switch ( tag[0].latin1() ) { + case 'a': + if ( tag == "actions" ) + actionsElem = elem; + break; + case 'c': + if ( tag == "class" ) { + className = elem.firstChild().toText().data().latin1(); + } else if ( tag == "connections" ) { + connectionsElem = elem; + } + break; + case 'f': + if ( tag == "functions" ) { + QDataStream out2( functionsBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "function" ) { + packStringSplit( strings, out2, + f.attribute("name").latin1(), '(' ); + packString( strings, out2, + f.firstChild().toText().data() ); + } + f = f.nextSibling().toElement(); + } + } + break; + case 'i': + if ( tag == "images" ) { + QDataStream out2( imagesBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "image" ) { + QString name = f.attribute( "name" ); + QDomElement g = f.firstChild().toElement(); + if ( g.tagName() == "data" ) { + QString format = g.attribute( "format", "PNG" ); + QString hex = g.firstChild().toText().data(); + int n = hex.length() / 2; + QByteArray data( n ); + for ( int i = 0; i < n; i++ ) + data[i] = (char) hex.mid( 2 * i, 2 ) + .toUInt( 0, 16 ); + + packString( strings, out2, name ); + packString( strings, out2, format ); + packUInt32( out2, g.attribute("length").toInt() ); + packByteArray( out2, data ); + } + } + f = f.nextSibling().toElement(); + } + } + break; + case 'l': + if ( tag == "layoutdefaults" ) { + QString margin = elem.attribute( "margin" ); + if ( !margin.isEmpty() ) + defaultMargin = margin.toInt(); + QString spacing = elem.attribute( "spacing" ); + if ( !spacing.isEmpty() ) + defaultSpacing = spacing.toInt(); + } + break; + case 'm': + if ( tag == "menubar" ) + menubarElem = elem; + break; + case 'p': + if ( tag == "pixmapinproject" ) + introFlags |= Intro_Pixmapinproject; + break; + case 's': + if ( tag == "slots" ) { + QDataStream out2( slotsBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "slot" ) { + QString language = f.attribute( "language", "C++" ); + QString slot = UibHack::normalize( + f.firstChild().toText().data() ); + packString( strings, out2, language ); + packStringSplit( strings, out2, slot, '(' ); + } + f = f.nextSibling().toElement(); + } + } + break; + case 't': + if ( tag == "tabstops" ) { + tabstopsElem = elem; + } else if ( tag == "toolbars" ) { + toolbarsElem = elem; + } + break; + case 'v': + if ( tag == "variable" ) { + QDataStream out2( variablesBlock, IO_WriteOnly | IO_Append ); + packString( strings, out2, elem.firstChild().toText().data() ); + } else if ( tag == "variables" ) { + QDataStream out2( variablesBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "variable" ) + packString( strings, out2, + f.firstChild().toText().data() ); + f = f.nextSibling().toElement(); + } + } + break; + case 'w': + if ( tag == "widget" ) + widgetElem = elem; + } + elem = elem.nextSibling().toElement(); + } + + { + QDataStream out2( widgetBlock, IO_WriteOnly ); + widgetNo = outputObject( buddies, objects, strings, out2, widgetElem, + "QWidget" ); + } + + if ( !tabstopsElem.isNull() ) { + QDataStream out2( tabstopsBlock, IO_WriteOnly ); + QDomElement f = tabstopsElem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "tabstop" ) { + QString widgetName = f.firstChild().toText().data(); + int no = objects.find( widgetName ); + if ( no != -1 ) + packUInt16( out2, no ); + } + f = f.nextSibling().toElement(); + } + } + + if ( !actionsElem.isNull() ) { + QDataStream out2( actionsBlock, IO_WriteOnly ); + outputObject( buddies, objects, strings, out2, actionsElem ); + } + + if ( !menubarElem.isNull() ) { + QDataStream out2( menubarBlock, IO_WriteOnly ); + outputObject( buddies, objects, strings, out2, menubarElem, + "QMenuBar" ); + } + + if ( !toolbarsElem.isNull() ) { + QDataStream out2( toolbarsBlock, IO_WriteOnly ); + QDomElement f = toolbarsElem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "toolbar" ) + outputObject( buddies, objects, strings, out2, f, "QToolBar" ); + f = f.nextSibling().toElement(); + } + } + + if ( !buddies.isEmpty() ) { + QDataStream out2( buddiesBlock, IO_WriteOnly ); + QMap<int, QStringList>::ConstIterator a = buddies.begin(); + while ( a != buddies.end() ) { + QStringList::ConstIterator b = (*a).begin(); + while ( b != (*a).end() ) { + int no = objects.find( *b ); + if ( no != -1 ) { + packUInt16( out2, a.key() ); + packUInt16( out2, no ); + } + ++b; + } + ++a; + } + } + + if ( !connectionsElem.isNull() ) { + QString prevLanguage = "C++"; + int prevSenderNo = 0; + QString prevSignal = "clicked()"; + int prevReceiverNo = 0; + QString prevSlot = "accept()"; + + QDataStream out2( connectionsBlock, IO_WriteOnly ); + QDomElement f = connectionsElem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "connection" ) { + QMap<QString, QString> argMap; + + QDomElement g = f.firstChild().toElement(); + while ( !g.isNull() ) { + argMap[g.tagName()] = g.firstChild().toText().data(); + g = g.nextSibling().toElement(); + } + + QString language = f.attribute( "language", "C++" ); + int senderNo = objects.find( argMap["sender"], widgetNo ); + int receiverNo = objects.find( argMap["receiver"], widgetNo ); + QString signal = UibHack::normalize( argMap["signal"] ); + QString slot = UibHack::normalize( argMap["slot"] ); + + Q_UINT8 connectionFlags = 0; + if ( language != prevLanguage ) + connectionFlags |= Connection_Language; + if ( senderNo != prevSenderNo ) + connectionFlags |= Connection_Sender; + if ( signal != prevSignal ) + connectionFlags |= Connection_Signal; + if ( receiverNo != prevReceiverNo ) + connectionFlags |= Connection_Receiver; + if ( slot != prevSlot ) + connectionFlags |= Connection_Slot; + out2 << connectionFlags; + + if ( connectionFlags & Connection_Language ) + packString( strings, out2, language ); + if ( connectionFlags & Connection_Sender ) + packUInt16( out2, senderNo ); + if ( connectionFlags & Connection_Signal ) + packStringSplit( strings, out2, signal, '(' ); + if ( connectionFlags & Connection_Receiver ) + packUInt16( out2, receiverNo ); + if ( connectionFlags & Connection_Slot ) + packStringSplit( strings, out2, slot, '(' ); + + prevLanguage = language; + prevSenderNo = senderNo; + prevSignal = signal; + prevReceiverNo = receiverNo; + prevSlot = slot; + } else if ( f.tagName() == "slot" ) { + // ### + } + f = f.nextSibling().toElement(); + } + } + + { + QDataStream out2( introBlock, IO_WriteOnly ); + out2 << introFlags; + out2 << defaultMargin; + out2 << defaultSpacing; + packUInt16( out2, objects.count() ); + packCString( strings, out2, className ); + } + + out << UibMagic; + out << (Q_UINT8) '\n'; + out << (Q_UINT8) '\r'; + out << (Q_UINT8) out.version(); + outputBlock( out, Block_Strings, strings.block() ); + outputBlock( out, Block_Intro, introBlock ); + outputBlock( out, Block_Images, imagesBlock ); + outputBlock( out, Block_Widget, widgetBlock ); + outputBlock( out, Block_Slots, slotsBlock ); + outputBlock( out, Block_Tabstops, tabstopsBlock ); + outputBlock( out, Block_Actions, actionsBlock ); + outputBlock( out, Block_Menubar, menubarBlock ); + outputBlock( out, Block_Toolbars, toolbarsBlock ); + outputBlock( out, Block_Variables, variablesBlock ); + outputBlock( out, Block_Functions, functionsBlock ); + outputBlock( out, Block_Buddies, buddiesBlock ); + outputBlock( out, Block_Connections, connectionsBlock ); + out << (Q_UINT8) Block_End; +} diff --git a/kdevdesigner/shared/ui2uib.h b/kdevdesigner/shared/ui2uib.h new file mode 100644 index 00000000..674fd589 --- /dev/null +++ b/kdevdesigner/shared/ui2uib.h @@ -0,0 +1,35 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef UI2UIB_H +#define UI2UIB_H + +class QDataStream; +class QDomDocument; + +void convertUiToUib( QDomDocument& doc, QDataStream& out ); + +#endif diff --git a/kdevdesigner/shared/uib.cpp b/kdevdesigner/shared/uib.cpp new file mode 100644 index 00000000..72d73b45 --- /dev/null +++ b/kdevdesigner/shared/uib.cpp @@ -0,0 +1,42 @@ +/********************************************************************** +** 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 "uib.h" + +static const char commonStrings[] = + "\0()\0(bool)\0(const QString&)\0(int)\0C++\0Layout1\0PNG\0QCheckBox\0" + "QComboBox\0QDialog\0QFrame\0QGridLayout\0QGroupBox\0QHBoxLayout\0QLabel\0" + "QLineEdit\0QListView\0QPushButton\0QRadioButton\0QVBoxLayout\0QWidget\0" + "TextLabel1\0XPM.GZ\0accept\0autoDefault\0buddy\0caption\0clicked\0" + "default\0destroy\0frameShadow\0frameShape\0geometry\0init\0margin\0" + "maximumSize\0minimumSize\0name\0reject\0sizePolicy\0spacing\0text\0title\0" + "toolTip\0unnamed\0whatsThis"; + +UibStrTable::UibStrTable() + : out( table, IO_WriteOnly ), start( sizeof(commonStrings) ) +{ + out.writeRawBytes( commonStrings, start ); +} diff --git a/kdevdesigner/shared/uib.h b/kdevdesigner/shared/uib.h new file mode 100644 index 00000000..00adac13 --- /dev/null +++ b/kdevdesigner/shared/uib.h @@ -0,0 +1,152 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#ifndef UIB_H +#define UIB_H + +#include <qdatastream.h> + +const Q_UINT32 UibMagic = 0xb77c61d8; + +enum BlockTag { Block_End = '$', Block_Actions = 'A', Block_Buddies = 'B', + Block_Connections = 'C', Block_Functions = 'F', + Block_Images = 'G', Block_Intro = 'I', Block_Menubar = 'M', + Block_Slots = 'S', Block_Strings = 'Z', Block_Tabstops = 'T', + Block_Toolbars = 'O', Block_Variables = 'V', + Block_Widget = 'W' }; + +enum ObjectTag { Object_End = '$', Object_ActionRef = 'X', + Object_Attribute = 'B', Object_Column = 'C', + Object_Event = 'E', Object_FontProperty = 'F', + Object_GridCell = 'G', Object_Item = 'I', + Object_MenuItem = 'M', Object_PaletteProperty = 'P', + Object_Row = 'R', Object_Separator = 'S', Object_Spacer = 'Y', + Object_SubAction = 'A', Object_SubLayout = 'L', + Object_SubWidget = 'W', Object_TextProperty = 'T', + Object_VariantProperty = 'V' }; + +enum PaletteTag { Palette_End = '$', Palette_Active = 'A', + Palette_Inactive = 'I', Palette_Disabled = 'D', + Palette_Color = 'C', Palette_Pixmap = 'P' }; + +enum IntroFlag { Intro_Pixmapinproject = 0x1 }; + +enum FontFlag { Font_Family = 0x1, Font_PointSize = 0x2, Font_Bold = 0x4, + Font_Italic = 0x8, Font_Underline = 0x10, + Font_StrikeOut = 0x20 }; + +enum ConnectionFlag { Connection_Language = 0x1, Connection_Sender = 0x2, + Connection_Signal = 0x4, Connection_Receiver = 0x8, + Connection_Slot = 0x10 }; + +class UibStrTable +{ +public: + UibStrTable(); + + inline int insertCString( const char *cstr ); + inline int insertString( const QString& str ); + inline void readBlock( QDataStream& in, int size ); + + inline const char *asCString( int offset ) const; + inline QString asString( int offset ) const; + inline QByteArray block() const; + +private: + QCString table; + QDataStream out; + int start; +}; + +/* + uic uses insertCString(), insertString(), and block(); + QWidgetFactory uses readBlock(), asCString(), and asString(). By + implementing these functions inline, we ensure that the binaries + don't contain needless code. +*/ + +inline int UibStrTable::insertCString( const char *cstr ) +{ + if ( cstr == 0 || cstr[0] == 0 ) { + return 0; + } else { + int nextPos = table.size(); + int len = strlen( cstr ); + int i; + for ( i = 0; i < nextPos - len; i++ ) { + if ( memcmp(table.data() + i, cstr, len + 1) == 0 ) + return i; + } + for ( i = 0; i < len + 1; i++ ) + out << (Q_UINT8) cstr[i]; + return nextPos; + } +} + +inline int UibStrTable::insertString( const QString& str ) +{ + if ( str.contains('\0') || str[0] == QChar(0x7f) ) { + int nextPos = table.size(); + out << (Q_UINT8) 0x7f; + out << str; + return nextPos; + } else { + return insertCString( str.utf8() ); + } +} + +inline void UibStrTable::readBlock( QDataStream& in, int size ) +{ + table.resize( start + size ); + in.readRawBytes( table.data() + start, size ); +} + +inline QString UibStrTable::asString( int offset ) const +{ + if ( table[offset] == 0x7f ) { + QDataStream in( table, IO_ReadOnly ); + in.device()->at( offset + 1 ); + QString str; + in >> str; + return str; + } else { + return QString::fromUtf8( asCString(offset) ); + } +} + +inline const char *UibStrTable::asCString( int offset ) const +{ + return table.data() + offset; +} + +inline QByteArray UibStrTable::block() const +{ + QByteArray block; + block.duplicate( table.data() + start, table.size() - start ); + return block; +} + +#endif diff --git a/kdevdesigner/shared/widgetdatabase.cpp b/kdevdesigner/shared/widgetdatabase.cpp new file mode 100644 index 00000000..8b80b03f --- /dev/null +++ b/kdevdesigner/shared/widgetdatabase.cpp @@ -0,0 +1,960 @@ +/********************************************************************** +** 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 "../interfaces/widgetinterface.h" + +#include "../designer/kdevdesigner_part.h" + +#include <kiconloader.h> +#include <kdebug.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> + +#include <klocale.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 = BarIcon( r->iconSet, KDevDesignerPartFactory::instance() ); + 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/kdevdesigner/shared/widgetdatabase.h b/kdevdesigner/shared/widgetdatabase.h new file mode 100644 index 00000000..03060fa3 --- /dev/null +++ b/kdevdesigner/shared/widgetdatabase.h @@ -0,0 +1,96 @@ +/********************************************************************** +** 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 WIDGETDATABASE_H +#define WIDGETDATABASE_H + +#include <qiconset.h> +#include <qstring.h> +#include "../interfaces/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/kdevdesigner/src/Makefile.am b/kdevdesigner/src/Makefile.am new file mode 100644 index 00000000..f6e1b854 --- /dev/null +++ b/kdevdesigner/src/Makefile.am @@ -0,0 +1,47 @@ +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# these are the headers for your project +noinst_HEADERS = kdevdesigner.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kdevdesigner.pot + + +# this Makefile creates both a KPart application and a KPart +######################################################################### +# APPLICATION SECTION +######################################################################### +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = kdevdesigner + +# the application source, library search path, and link libraries +kdevdesigner_SOURCES = main.cpp kdevdesigner.cpp +kdevdesigner_LDFLAGS = $(KDE_RPATH) $(all_libraries) +kdevdesigner_LDADD = $(LIB_KPARTS) + +# this is where the desktop file will go +#shelldesktopdir = $(kde_appsdir)/Development +#shelldesktop_DATA = kdevdesigner.desktop +xdg_apps_DATA = kdevdesigner.desktop + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/kdevdesigner +shellrc_DATA = kdevdesigner_shell.rc + +######################################################################### +# KPART SECTION +######################################################################### + +# the Part's source, library search path, and link libraries + + +# this is where the desktop file will go +partdesktopdir = $(kde_servicesdir) + +# this is where the part's XML-GUI resource file goes +partrcdir = $(kde_datadir)/kdevdesignerpart diff --git a/kdevdesigner/src/kdevdesigner.cpp b/kdevdesigner/src/kdevdesigner.cpp new file mode 100644 index 00000000..4e2b0d0d --- /dev/null +++ b/kdevdesigner/src/kdevdesigner.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "kdevdesigner.h" + +#include <kxmlguiclient.h> +#include <kkeydialog.h> +#include <kfiledialog.h> +#include <kconfig.h> +#include <kurl.h> +#include <kdebug.h> + +#include <kedittoolbar.h> + +#include <kaction.h> +#include <kstdaction.h> + +#include <klibloader.h> +#include <kmessagebox.h> +#include <kstatusbar.h> +#include <klocale.h> + +KDevDesigner::KDevDesigner() + : KParts::MainWindow( 0L, "KDevDesigner" ) +{ + // set the shell's ui resource file + setXMLFile("kdevdesigner_shell.rc"); + + // then, setup our actions + setupActions(); + + // and a status bar + statusBar()->show(); + + // this routine will find and load our Part. it finds the Part by + // name which is a bad idea usually.. but it's alright in this + // case since our Part is made for this Shell + KLibFactory *factory = KLibLoader::self()->factory("libkdevdesignerpart"); + if (factory) + { + // now that the Part is loaded, we cast it to a Part to get + // our hands on it + QStringList args; + args.append("in shell"); + m_part = static_cast<KParts::ReadWritePart *>(factory->create(this, + "kdevdesigner_part", "KParts::ReadWritePart", args)); + + if (m_part) + { + // tell the KParts::MainWindow that this is indeed the main widget + setCentralWidget(m_part->widget()); + + // and integrate the part's GUI with the shell's + createGUI(m_part); + } + } + else + { + // if we couldn't find our Part, we exit since the Shell by + // itself can't do anything useful + KMessageBox::error(this, i18n("Could not find the KDevDesigner part.")); + kapp->quit(); + // we return here, cause kapp->quit() only means "exit the + // next time we enter the event loop... + return; + } + + // apply the saved mainwindow settings, if any, and ask the mainwindow + // to automatically save settings if changed: window size, toolbar + // position, icon size, etc. + setAutoSaveSettings(); +} + +KDevDesigner::~KDevDesigner() +{ +} + +void KDevDesigner::load(const KURL& url) +{ + m_part->openURL( url ); +} + +void KDevDesigner::setupActions() +{ +/* KStdAction::openNew(this, SLOT(fileNew()), actionCollection()); + KStdAction::open(this, SLOT(fileOpen()), actionCollection());*/ + + KStdAction::quit(kapp, SLOT(quit()), actionCollection()); + + m_toolbarAction = KStdAction::showToolbar(this, SLOT(optionsShowToolbar()), actionCollection()); + m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection()); + + KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection()); + KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection()); +} + +void KDevDesigner::saveProperties(KConfig* /*config*/) +{ + // the 'config' object points to the session managed + // config file. anything you write here will be available + // later when this app is restored +} + +void KDevDesigner::readProperties(KConfig* /*config*/) +{ + // the 'config' object points to the session managed + // config file. this function is automatically called whenever + // the app is being restored. read in here whatever you wrote + // in 'saveProperties' +} + +void KDevDesigner::fileNew() +{ + // this slot is called whenever the File->New menu is selected, + // the New shortcut is pressed (usually CTRL+N) or the New toolbar + // button is clicked + + // About this function, the style guide ( + // http://developer.kde.org/documentation/standards/kde/style/basics/index.html ) + // says that it should open a new window if the document is _not_ + // in its initial state. This is what we do here.. + if ( ! m_part->url().isEmpty() || m_part->isModified() ) + { + (new KDevDesigner)->show(); + }; +} + + +void KDevDesigner::optionsShowToolbar() +{ + // this is all very cut and paste code for showing/hiding the + // toolbar + if (m_toolbarAction->isChecked()) + toolBar()->show(); + else + toolBar()->hide(); +} + +void KDevDesigner::optionsShowStatusbar() +{ + // this is all very cut and paste code for showing/hiding the + // statusbar + if (m_statusbarAction->isChecked()) + statusBar()->show(); + else + statusBar()->hide(); +} + +void KDevDesigner::optionsConfigureKeys() +{ + KKeyDialog::configureKeys(m_part->actionCollection(), "kdevdesigner_part.rc"); +} + +void KDevDesigner::optionsConfigureToolbars() +{ + saveMainWindowSettings(KGlobal::config(), autoSaveGroup()); + + // use the standard toolbar editor + KEditToolbar dlg(factory()); + connect(&dlg, SIGNAL(newToolbarConfig()), + this, SLOT(applyNewToolbarConfig())); + dlg.exec(); +} + +void KDevDesigner::applyNewToolbarConfig() +{ + applyMainWindowSettings(KGlobal::config(), autoSaveGroup()); +} + +void KDevDesigner::fileOpen() +{ + // this slot is called whenever the File->Open menu is selected, + // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar + // button is clicked + KURL url = + KFileDialog::getOpenURL( QString::null, QString::null, this ); + + if (url.isEmpty() == false) + { + // About this function, the style guide ( + // http://developer.kde.org/documentation/standards/kde/style/basics/index.html ) + // says that it should open a new window if the document is _not_ + // in its initial state. This is what we do here.. + if ( m_part->url().isEmpty() && ! m_part->isModified() ) + { + // we open the file in this window... + load( url ); + } + else + { + // we open the file in a new window... + KDevDesigner* newWin = new KDevDesigner; + newWin->load( url ); + newWin->show(); + } + } +} + +#include "kdevdesigner.moc" diff --git a/kdevdesigner/src/kdevdesigner.desktop b/kdevdesigner/src/kdevdesigner.desktop new file mode 100644 index 00000000..7bced6fb --- /dev/null +++ b/kdevdesigner/src/kdevdesigner.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +Name=KDevelop Designer +Name[el]=Σχεδιαστής KDevelop +Name[es]=Diseñador de KDevelop +Name[et]=KDevelopi Disainer +Name[eu]=KDevelop disenatzailea +Name[fa]=طراح KDevelop +Name[fr]=Concepteur KDevelop +Name[ga]=Dearthóir KDevelop +Name[it]=Designer di KDevelop +Name[ja]=KDevelop デザイナー +Name[ms]=Pereka KDevelop +Name[nds]=KDevelop-Maker +Name[ne]=केडीई विकास डिजाइनर +Name[pl]=Projektant KDevelop +Name[pt]=Desenhador do KDevelop +Name[pt_BR]=Designer do KDevelop +Name[sk]=KDevelop Dizajnér +Name[sl]=Snovalnik KDevelop +Name[sv]=KDevelop designer +Name[ta]=கேமேம்பாட்டு வடிவமைப்பாளர் +Name[tg]=Дизайнгари KDevelop +Name[zh_CN]=KDevelop 设计师 +Name[zh_TW]=KDevelop 設計器 +GenericName=Interface Designer +GenericName[br]=Ergrafer etrefas +GenericName[ca]=Dissenyador de interfícies +GenericName[cy]=Dylunydd Rhyngwyneb +GenericName[de]=Oberflächen-Designer +GenericName[el]=Σχεδιαστής διασυνδέσεων +GenericName[es]=Diseñador de interfaces +GenericName[et]=Liidesedisainer +GenericName[eu]=Interfazeen diseinatzailea +GenericName[fa]=طراح واسط +GenericName[fr]=Concepteur d'interfaces graphiques +GenericName[ga]=Dearthóir Comhéadain +GenericName[gl]=Deseñador de interfaces +GenericName[hu]=Felülettervező +GenericName[it]=Interfaccia del Designer +GenericName[ja]=インターフェースデザイナー +GenericName[lt]=Sąsajos redaktorius +GenericName[ms]=Pereka Antaramuka +GenericName[nds]=Böversietmaker +GenericName[ne]=इन्टरफेस डिजाइनर +GenericName[pl]=Projektowanie interfejsu +GenericName[pt]=Editor de Interfaces +GenericName[pt_BR]=Desenhador de Interface +GenericName[ru]=Дизайнер пользовательского интерфейса +GenericName[rw]=Umuhanzi w'Imigaragarire +GenericName[sk]=Interface Dizajnér +GenericName[sl]=Snovalnik vmesnikov +GenericName[sr]=Дизајнер интерфејса +GenericName[sr@Latn]=Dizajner interfejsa +GenericName[sv]=Gränssnittsdesign +GenericName[tr]=Arayüz Tasarlayıcısı +GenericName[zh_CN]=界面设计师 +GenericName[zh_TW]=介面設計器 +Exec=kdevdesigner %i -caption "%c" +Icon=kdevdesigner +Type=Application +X-DocPath=kdevdesigner/kdevdesigner.html +Comment=GUI Designer for Qt/KDE +Comment[ca]=Dissenyador de IGU per Qt/KDE +Comment[da]=Grafisk brugerfladedesigner til Qt/KDE +Comment[de]=Auf Qt-Designer basierender GUI-Designer +Comment[el]=Σχεδιαστής GUI για Qt/KDE +Comment[es]=Diseñador de interfaces para Qt/KDE +Comment[et]=Qt/KDE graafilise kasutajaliidese disainer +Comment[eu]=GUI diseinatzailea Qt/KDE-rako +Comment[fa]=طراح ونک برای Qt/KDE +Comment[fr]=Concepteur d'interfaces graphiques pour Qt / KDE +Comment[ga]=Dearthóir Comhéadan Grafach le haghaidh Qt/KDE +Comment[gl]=Deseñador GUI para Qt/KDE +Comment[hu]=Qt/KDE felülettervező +Comment[it]=Designer di GUI per Qt/KDE +Comment[ja]=Qt/KDE のための GUI デザイナー +Comment[ms]=Pereka GUI untuk Qt/KDE +Comment[nds]=Böversietmaker för Qt/KDE +Comment[ne]=Qt/KDE का लागि जी यू आई डिजाइनर +Comment[nl]=GUI Designer voor Qt/KDE +Comment[pl]=Projektant graficznego interfejsu użytkownika dla Qt/KDE +Comment[pt]=Editor de Interfaces para Qt/KDE +Comment[pt_BR]=Designer de GUI para o Qt/KDE +Comment[ru]=Среда создания графических форм Qt/KDE +Comment[sk]=GUI Dizajnér pre Qt/KDE +Comment[sl]=Snovalnik grafičnega vmesnika za Qt/KDE +Comment[sr]=Дизајнер GUI-ја за Qt/KDE +Comment[sr@Latn]=Dizajner GUI-ja za Qt/KDE +Comment[sv]=Grafisk gränssnittsdesign för Qt och KDE +Comment[ta]=Qtக்கான GUI வடிவமைப்பாளர் +Comment[tg]=Муҳит барои сохтани Qt/KDE ба шакли графикӣ +Comment[tr]=Qt/KDE için Arayüz Tasarlayıcısı +Comment[zh_CN]=Qt/KDE 的 GUI 设计师 +Comment[zh_TW]=Qt/KDE 的使用者介面設計器 +Terminal=false +Categories=Qt;KDE;Development;GUIDesigner;X-KDE-KDevelopIDE; diff --git a/kdevdesigner/src/kdevdesigner.h b/kdevdesigner/src/kdevdesigner.h new file mode 100644 index 00000000..52a5a259 --- /dev/null +++ b/kdevdesigner/src/kdevdesigner.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _KDEVDESIGNER_H_ +#define _KDEVDESIGNER_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kxmlguiclient.h> +#include <kapplication.h> +#include <kparts/mainwindow.h> + +class KToggleAction; + +/** + * This is the application "Shell". It has a menubar, toolbar, and + * statusbar but relies on the "Part" to do all the real work. + * + * @short Application Shell + * @author Alexander Dymo <cloudtemple@mksat.net> + * @version 0.1 + */ +class KDevDesigner : public KParts::MainWindow +{ + Q_OBJECT +public: + /** + * Default Constructor + */ + KDevDesigner(); + + /** + * Default Destructor + */ + virtual ~KDevDesigner(); + + /** + * Use this method to load whatever file/URL you have + */ + void load(const KURL& url); + +protected: + /** + * This method is called when it is time for the app to save its + * properties for session management purposes. + */ + void saveProperties(KConfig *); + + /** + * This method is called when this app is restored. The KConfig + * object points to the session management config file that was saved + * with @ref saveProperties + */ + void readProperties(KConfig *); + +private slots: + void fileNew(); + void fileOpen(); + void optionsShowToolbar(); + void optionsShowStatusbar(); + void optionsConfigureKeys(); + void optionsConfigureToolbars(); + + void applyNewToolbarConfig(); + +private: + void setupAccel(); + void setupActions(); + +private: + KParts::ReadWritePart *m_part; + + KToggleAction *m_toolbarAction; + KToggleAction *m_statusbarAction; +}; + +#endif // _KDEVDESIGNER_H_ diff --git a/kdevdesigner/src/kdevdesigner_shell.rc b/kdevdesigner/src/kdevdesigner_shell.rc new file mode 100644 index 00000000..1bb33a25 --- /dev/null +++ b/kdevdesigner/src/kdevdesigner_shell.rc @@ -0,0 +1,37 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kdevdesigner_shell" version="2"> +<MenuBar> + <Menu noMerge="1" name="file"><text>&File</text> + <Merge/> + <Separator/> + <Action name="file_quit"/> + </Menu> + <Menu noMerge="1" name="edit"><text>&Edit</text> + <Merge/> + </Menu> + <Menu noMerge="1" name="project"><text>&Project</text> + <Merge/> + </Menu> + <Menu noMerge="1" name="tools"><text>&Tools</text> + <Merge/> + </Menu> + <Menu noMerge="1" name="layout"><text>&Layout</text> + <Merge/> + </Menu> + <Menu noMerge="1" name="window"><text>&Window</text> + <Merge/> + </Menu> + <Merge/> + <Menu noMerge="1" name="settings"><text>&Settings</text> + <Action name="options_show_toolbar"/> + <Action name="options_show_statusbar"/> + <Merge name="show_merge"/> + <Separator/> + <Action name="options_configure_keybinding"/> + <Action name="options_configure_toolbars"/> + <Action name="options_configure"/> + <Merge name="configure_merge"/> + <Separator/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/kdevdesigner/src/main.cpp b/kdevdesigner/src/main.cpp new file mode 100644 index 00000000..cf432f9d --- /dev/null +++ b/kdevdesigner/src/main.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <qsplashscreen.h> + +#include <kxmlguiclient.h> +#include "kdevdesigner.h" +#include <kapplication.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kstandarddirs.h> + +static const char description[] = + I18N_NOOP("KDE GUI Designer"); + +static const char version[] = "0.2"; + +static KCmdLineOptions options[] = +{ + { "+[URL]", I18N_NOOP( "Document to open" ), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("kdevdesigner", I18N_NOOP("KDevDesigner"), version, description, + KAboutData::License_GPL, "KDevDesigner Copyright: (C) 2004-2005 Alexander Dymo\nQt Designer Copyright: (C) 2000-2005 Trolltech AS All Rights Reserved", 0, 0); + about.addAuthor( "Trolltech AS", "Qt Designer code (Free Edition)" ); + about.addAuthor( "Alexander Dymo", "Port to KDE, partification", "adymo@kdevelop.org" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + + // see if we are starting with session management + if (app.isRestored()) + { + RESTORE(KDevDesigner); + } + else + { + // no session.. just start up normally + QSplashScreen * splash = 0; + QString splashFile = locate("data", "kdevelop/pics/kdevdesigner-splash.png"); + if (!splashFile.isNull()) + { + QPixmap pm; + pm.load(splashFile); + splash = new QSplashScreen( pm ); + splash->show(); + } + + app.processEvents(); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if ( args->count() == 0 ) + { + KDevDesigner *widget = new KDevDesigner; + widget->show(); + } + else + { + int i = 0; + for (; i < args->count(); i++ ) + { + KDevDesigner *widget = new KDevDesigner; + widget->show(); + widget->load( args->url( i ) ); + } + } + args->clear(); + if (splash) + delete splash; + } + + return app.exec(); +} diff --git a/kdevdesigner/uilib/Makefile.am b/kdevdesigner/uilib/Makefile.am new file mode 100644 index 00000000..0480cd50 --- /dev/null +++ b/kdevdesigner/uilib/Makefile.am @@ -0,0 +1,9 @@ +KDE_CXXFLAGS=-UQT_NO_ASCII_CAST + +INCLUDES = -I$(top_srcdir)/kdevdesigner/shared $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libkdevqui.la +libkdevqui_la_SOURCES = database.cpp qwidgetfactory.cpp + +libkdevqui_la_LDFLAGS = $(all_libraries) diff --git a/kdevdesigner/uilib/database.cpp b/kdevdesigner/uilib/database.cpp new file mode 100644 index 00000000..a92a04c8 --- /dev/null +++ b/kdevdesigner/uilib/database.cpp @@ -0,0 +1,122 @@ +/********************************************************************** +** 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. +** +**********************************************************************/ + +#if defined(DESIGNER) +#include "database.h" +#else +#include "database2.h" +#endif + +#ifndef QT_NO_SQL + +#if defined(DESIGNER) +#include "formwindow.h" +#include "mainwindow.h" +#endif + +#include <qsqldatabase.h> +#include <qsqlform.h> +#include <qsqlcursor.h> +#include <qsqlrecord.h> + +DatabaseSupport::DatabaseSupport() +{ + con = 0; + frm = 0; + parent = 0; +} + +void DatabaseSupport::initPreview( const QString &connection, const QString &table, QObject *o, + const QMap<QString, QString> &databaseControls ) +{ + tbl = table; + dbControls = databaseControls; + parent = o; + + if ( connection != "(default)" ) + con = QSqlDatabase::database( connection ); + else + con = QSqlDatabase::database(); + frm = new QSqlForm( o, table ); + for ( QMap<QString, QString>::Iterator it = dbControls.begin(); it != dbControls.end(); ++it ) { + QObject *chld = parent->child( it.key(), "QWidget" ); + if ( !chld ) + continue; + frm->insert( (QWidget*)chld, *it ); + } +} + +QDesignerDataBrowser::QDesignerDataBrowser( QWidget *parent, const char *name ) + : QDataBrowser( parent, name ) +{ +} + +bool QDesignerDataBrowser::event( QEvent* e ) +{ + bool b = QDataBrowser::event( e ); +#if defined(DESIGNER) + if ( MainWindow::self->isPreviewing() ) { +#endif + if ( e->type() == QEvent::Show ) { + if ( con ) { + QSqlCursor* cursor = new QSqlCursor( tbl, TRUE, con ); + setSqlCursor( cursor, TRUE ); + setForm( frm ); + refresh(); + first(); + } + return TRUE; + } +#if defined(DESIGNER) + } +#endif + return b; +} + +QDesignerDataView::QDesignerDataView( QWidget *parent, const char *name ) + : QDataView( parent, name ) +{ +} + +bool QDesignerDataView::event( QEvent* e ) +{ + bool b = QDataView::event( e ); +#if defined(DESIGNER) + if ( MainWindow::self->isPreviewing() ) { +#endif + if ( e->type() == QEvent::Show ) { + setForm( frm ); + readFields(); + return TRUE; + } +#if defined(DESIGNER) + } +#endif + return b; +} + + +#endif diff --git a/kdevdesigner/uilib/database2.h b/kdevdesigner/uilib/database2.h new file mode 100644 index 00000000..05a04712 --- /dev/null +++ b/kdevdesigner/uilib/database2.h @@ -0,0 +1,88 @@ +/********************************************************************** +** 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 DATABASE2_H +#define DATABASE2_H + +#include "qfeatures.h" + +#ifndef QT_NO_SQL +#include <qdataview.h> +#include <qdatabrowser.h> +#include <qsqlcursor.h> +#include <qstring.h> + +class QSqlDatabase; +class QSqlForm; + +class DatabaseSupport2 +{ +public: + DatabaseSupport2(); + virtual ~DatabaseSupport2() {} + + void initPreview( const QString &connection, const QString &table, QObject *o, + const QMap<QString, QString> &databaseControls ); + +protected: + QSqlDatabase* con; + QSqlForm* frm; + QString tbl; + QMap<QString, QString> dbControls; + QObject *parent; + +}; + +class QDesignerDataBrowser2 : public QDataBrowser, public DatabaseSupport2 +{ + Q_OBJECT + +public: + QDesignerDataBrowser2( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); +}; + +class QDesignerDataView2 : public QDataView, public DatabaseSupport2 +{ + Q_OBJECT + +public: + QDesignerDataView2( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); + +}; + +#define DatabaseSupport DatabaseSupport2 +#define QDesignerDataBrowser QDesignerDataBrowser2 +#define QDesignerDataView QDesignerDataView2 + +#endif + +#endif diff --git a/kdevdesigner/uilib/qwidgetfactory.cpp b/kdevdesigner/uilib/qwidgetfactory.cpp new file mode 100644 index 00000000..43c7c11e --- /dev/null +++ b/kdevdesigner/uilib/qwidgetfactory.cpp @@ -0,0 +1,2606 @@ +/********************************************************************** +** 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 "qwidgetfactory.h" + +#include "../interfaces/languageinterface.h" +#include "../interfaces/widgetinterface.h" + +#include <qfeatures.h> +#include "database2.h" +#include <qdom.h> +#include <qdir.h> +#include <qlayout.h> +#include <qmetaobject.h> +#include <domtool.h> +#include <uib.h> +#include <qapplication.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qobjectlist.h> +#include <private/qpluginmanager_p.h> +#include <qmime.h> +#include <qdragobject.h> + +#ifndef QT_NO_SQL +#include <qsqlrecord.h> +#include <qsqldatabase.h> +#include <qdatatable.h> +#endif + +// include all Qt widgets we support +#include <qpushbutton.h> +#include <qtoolbutton.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qgroupbox.h> +#include <qbuttongroup.h> +#include <qiconview.h> +#include <qheader.h> +#ifndef QT_NO_TABLE +#include <qtable.h> +#endif +#include <qlistbox.h> +#include <qlistview.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qmultilineedit.h> +#include <qlabel.h> +#include <qwidget.h> +#include <qtabwidget.h> +#include <qcombobox.h> +#include <qdialog.h> +#include <qwizard.h> +#include <qlcdnumber.h> +#include <qprogressbar.h> +#include <qtextview.h> +#include <qtextbrowser.h> +#include <qdial.h> +#include <qslider.h> +#include <qframe.h> +#include <qwidgetstack.h> +#include <qtoolbox.h> +#include <qtextedit.h> +#include <qscrollbar.h> +#include <qmainwindow.h> +#include <qsplitter.h> +#include <qaction.h> +#include <qpopupmenu.h> +#include <qmenubar.h> +#include <qpopupmenu.h> +#include <qdatetimeedit.h> +#include <qvbox.h> +#include <qhbox.h> +#include <qgrid.h> + +#include <stdlib.h> + +class QWidgetFactoryPrivate +{ +public: + QCString translationContext; + QListViewItem *lastItem; + QDict<bool> customWidgets; +}; + +static QPtrList<QWidgetFactory> widgetFactories; +static QPluginManager<LanguageInterface> *languageInterfaceManager = 0; +static QPluginManager<WidgetInterface> *widgetInterfaceManager = 0; + +static QMap<QString, bool> *availableWidgetMap = 0; +static QStringList *availableWidgetList = 0; + +QMap<QWidget*, QString> *qwf_forms = 0; +QString *qwf_language = 0; +bool qwf_execute_code = TRUE; +bool qwf_stays_on_top = FALSE; +QString qwf_currFileName = ""; +QObject *qwf_form_object = 0; +QString *qwf_plugin_dir = 0; + +static void setupPluginDir() +{ + if ( !qwf_plugin_dir ) + qwf_plugin_dir = new QString( "/designer" ); +} + +static void setupWidgetListAndMap() +{ + if ( availableWidgetMap ) + return; + setupPluginDir(); + availableWidgetList = new QStringList; + (*availableWidgetList) << "QPushButton" << "QToolButton" << "QCheckBox" << "QRadioButton" + << "QGroupBox" << "QButtonGroup" << "QIconView" << "QTable" + << "QListBox" << "QListView" << "QLineEdit" << "QSpinBox" + << "QMultiLineEdit" << "QLabel" << "TextLabel" << "PixmapLabel" + << "QLayoutWidget" << "QTabWidget" << "QComboBox" + << "QWidget" << "QDialog" << "QWizard" << "QLCDNumber"; + // put less stress on the compiler by limiting the template nesting depth + (*availableWidgetList) << "QProgressBar" << "QTextView" << "QTextBrowser" + << "QDial" << "QSlider" << "QFrame" << "Line" << "QTextEdit" + << "QDateEdit" << "QTimeEdit" << "QDateTimeEdit" << "QScrollBar" + << "QPopupMenu" << "QWidgetStack" << "QMainWindow" + << "QDataTable" << "QDataBrowser" << "QDataView" + << "QVBox" << "QHBox" << "QGrid" << "QToolBox"; + + if ( !widgetInterfaceManager ) + widgetInterfaceManager = + new QPluginManager<WidgetInterface>( IID_Widget, QApplication::libraryPaths(), *qwf_plugin_dir ); + + QStringList l = widgetInterfaceManager->featureList(); + QStringList::Iterator it; + for ( it = l.begin(); it != l.end(); ++it ) + (*availableWidgetList) << *it; + + availableWidgetMap = new QMap<QString, bool>; + for ( it = availableWidgetList->begin(); it != availableWidgetList->end(); ++it ) + availableWidgetMap->insert( *it, TRUE ); +} + +static QImage loadImageData( const QString& format, ulong len, QByteArray data ) +{ + QImage img; + if ( format == "XPM.GZ" || format == "XBM.GZ" ) { + if ( len < data.size() * 10 ) + len = data.size() * 10; + // qUncompress() expects the first 4 bytes to be the expected length of + // the uncompressed data + QByteArray dataTmp( data.size() + 4 ); + memcpy( dataTmp.data()+4, data.data(), data.size() ); + dataTmp[0] = ( len & 0xff000000 ) >> 24; + dataTmp[1] = ( len & 0x00ff0000 ) >> 16; + dataTmp[2] = ( len & 0x0000ff00 ) >> 8; + dataTmp[3] = ( len & 0x000000ff ); + QByteArray baunzip = qUncompress( dataTmp ); + len = baunzip.size(); + img.loadFromData( (const uchar*)baunzip.data(), len, format.left(format.find('.')) ); + } else { + img.loadFromData( (const uchar*)data.data(), data.size(), format ); + } + return img; +} + +static QSizePolicy::SizeType stringToSizeType( const QString& str ) +{ + if ( str == "Fixed" ) { + return QSizePolicy::Fixed; + } else if ( str == "Minimum" ) { + return QSizePolicy::Minimum; + } else if ( str == "Maximum" ) { + return QSizePolicy::Maximum; + } else if ( str == "Preferred" ) { + return QSizePolicy::Preferred; + } else if ( str == "MinimumExpanding" ) { + return QSizePolicy::MinimumExpanding; + } else if ( str == "Expanding" ) { + return QSizePolicy::Expanding; + } else { + return QSizePolicy::Ignored; + } +} + + +/*! + \class QWidgetFactory + + \brief The QWidgetFactory class provides for the dynamic creation of widgets + from Qt Designer .ui files. + + This class basically offers two things: + + \list + + \i Dynamically creating widgets from \link designer-manual.book Qt + Designer\endlink user interface description files. + You can do this using the static function QWidgetFactory::create(). + This function also performs signal and slot connections, tab + ordering, etc., as defined in the .ui file, and returns the + top-level widget in the .ui file. After creating the widget you can + use QObject::child() and QObject::queryList() to access child + widgets of this returned widget. + + \i Adding additional widget factories to be able to create custom + widgets. See createWidget() for details. + + \endlist + + This class is not included in the Qt library itself. To use it you + must link against \c libqui.so (Unix) or \c qui.lib (Windows), which is + built into \c INSTALL/lib if you built \e{Qt Designer} (\c INSTALL is + the directory where Qt is installed ). + + See the "Creating Dynamic Dialogs from .ui Files" section of the \link + designer-manual.book Qt Designer manual\endlink for an example. See + also the \l{QWidgetPlugin} class and the \link plugins-howto.html + Plugins documentation\endlink. +*/ + +/*! Constructs a QWidgetFactory. */ + +QWidgetFactory::QWidgetFactory() + : d( new QWidgetFactoryPrivate() ), dbControls( 0 ), + usePixmapCollection( FALSE ), defMargin( 11 ), defSpacing( 6 ) +{ + widgetFactories.setAutoDelete( TRUE ); + d->customWidgets.setAutoDelete( TRUE ); +} + +/*! \fn QWidgetFactory::~QWidgetFactory() + Destructor. +*/ +QWidgetFactory::~QWidgetFactory() +{ + delete d; +} + +/*! + + Loads the \e{Qt Designer} user interface description file \a uiFile + and returns the top-level widget in that description. \a parent and + \a name are passed to the constructor of the top-level widget. + + This function also performs signal and slot connections, tab + ordering, etc., as described in the .ui file. In \e{Qt Designer} it + is possible to add custom slots to a form and connect to them. If + you want these connections to be made, you must create a class + derived from QObject, which implements all these slots. Then pass an + instance of the object as \a connector to this function. If you do + this, the connections to the custom slots will be done using the \a + connector as slot. + + If something fails, 0 is returned. + + The ownership of the returned widget is passed to the caller. +*/ + +QWidget *QWidgetFactory::create( const QString &uiFile, QObject *connector, + QWidget *parent, const char *name ) +{ + setupPluginDir(); + QFile f( uiFile ); + bool failed = FALSE; + if ( !f.open( IO_ReadOnly ) ) + failed = TRUE; + if ( failed && qApp->type() == QApplication::Tty ) { + // for QSA: If we have no GUI, we have no form definition + // files, but just the code. So try if only the code exists. + f.setName( uiFile + ".qs" ); + failed = !f.open( IO_ReadOnly ); + } + if ( failed ) + return 0; + + qwf_currFileName = uiFile; + QWidget *w = QWidgetFactory::create( &f, connector, parent, name ); + if ( !qwf_forms ) + qwf_forms = new QMap<QWidget*, QString>; + qwf_forms->insert( w, uiFile ); + return w; +} + +#undef slots + +/*! \overload + Loads the user interface description from device \a dev. + */ + +QWidget *QWidgetFactory::create( QIODevice *dev, QObject *connector, QWidget *parent, const char *name ) +{ + setupPluginDir(); + QWidget *w = 0; + QDomDocument doc; + QString errMsg; + int errLine; + + QWidgetFactory *widgetFactory = new QWidgetFactory; + widgetFactory->toplevel = 0; + + // If we have no GUI, we only want to load the code + if ( qApp->type() != QApplication::Tty ) { + QIODevice::Offset start = dev->at(); + Q_UINT32 magic; + QDataStream in( dev ); + in >> magic; + if ( magic == UibMagic ) { + w = widgetFactory->createFromUibFile( in, connector, parent, name ); + } else { + in.unsetDevice(); + dev->at( start ); + if ( doc.setContent( dev, &errMsg, &errLine ) ) { + w = widgetFactory->createFromUiFile( doc, connector, parent, name ); + } else { + // qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine ); + } + } + if ( !w ) { + delete widgetFactory; + return 0; + } + } + + if ( !languageInterfaceManager ) + languageInterfaceManager = + new QPluginManager<LanguageInterface>( IID_Language, QApplication::libraryPaths(), *qwf_plugin_dir ); + widgetFactory->loadExtraSource(); + + if ( widgetFactory->toplevel ) { +#ifndef QT_NO_SQL + QMap<QWidget*, SqlWidgetConnection>::Iterator cit = widgetFactory->sqlWidgetConnections.begin(); + for( ; cit != widgetFactory->sqlWidgetConnections.end(); ++cit ) { + if ( widgetFactory->noDatabaseWidgets.find( cit.key()->name() ) != + widgetFactory->noDatabaseWidgets.end() ) + continue; + if ( cit.key()->inherits( "QDesignerDataBrowser2" ) ) + ( (QDesignerDataBrowser2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, + cit.key(), *(*cit).dbControls ); + else if ( cit.key()->inherits( "QDesignerDataView2" ) ) + ( (QDesignerDataView2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, + cit.key(), *(*cit).dbControls ); + } + + for ( QMap<QString, QStringList>::Iterator it = widgetFactory->dbTables.begin(); + it != widgetFactory->dbTables.end(); ++it ) { + QDataTable *table = (QDataTable*)widgetFactory->toplevel->child( it.key(), "QDataTable" ); + if ( !table ) + continue; + if ( widgetFactory->noDatabaseWidgets.find( table->name() ) != + widgetFactory->noDatabaseWidgets.end() ) + continue; + QValueList<Field> fieldMap = *widgetFactory->fieldMaps.find( table ); + QString conn = (*it)[ 0 ]; + QSqlCursor* c = 0; + QSqlDatabase *db = 0; + if ( conn.isEmpty() || conn == "(default)" ) { + db = QSqlDatabase::database(); + c = new QSqlCursor( (*it)[ 1 ] ); + } else { + db = QSqlDatabase::database( conn ); + c = new QSqlCursor( (*it)[ 1 ], TRUE, db ); + } + if ( db ) { + table->setSqlCursor( c, fieldMap.isEmpty(), TRUE ); + table->refresh( QDataTable::RefreshAll ); + } + } +#endif + } + + for ( QMap<QString, QString>::Iterator it = widgetFactory->buddies.begin(); + it != widgetFactory->buddies.end(); ++it ) { + QLabel *label = (QLabel*)widgetFactory->toplevel->child( it.key(), "QLabel" ); + QWidget *buddy = (QWidget*)widgetFactory->toplevel->child( *it, "QWidget" ); + if ( label && buddy ) + label->setBuddy( buddy ); + } + + delete widgetFactory; + + QApplication::sendPostedEvents(); + + return w; +} + +QWidget *QWidgetFactory::createFromUiFile( QDomDocument doc, QObject *connector, + QWidget *parent, const char *name ) +{ + DomTool::fixDocument( doc ); + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + QDomElement e = doc.firstChild().toElement().firstChild().toElement(); + + QDomElement variables = e; + while ( variables.tagName() != "variables" && !variables.isNull() ) + variables = variables.nextSibling().toElement(); + + QDomElement slots = e; + while ( slots.tagName() != "slots" && !slots.isNull() ) + slots = slots.nextSibling().toElement(); + + QDomElement connections = e; + while ( connections.tagName() != "connections" && !connections.isNull() ) + connections = connections.nextSibling().toElement(); + + QDomElement imageCollection = e; + while ( imageCollection.tagName() != "images" && !imageCollection.isNull() ) + imageCollection = imageCollection.nextSibling().toElement(); + + QDomElement tabOrder = e; + while ( tabOrder.tagName() != "tabstops" && !tabOrder.isNull() ) + tabOrder = tabOrder.nextSibling().toElement(); + + QDomElement actions = e; + while ( actions.tagName() != "actions" && !actions.isNull() ) + actions = actions.nextSibling().toElement(); + + QDomElement toolbars = e; + while ( toolbars.tagName() != "toolbars" && !toolbars.isNull() ) + toolbars = toolbars.nextSibling().toElement(); + + QDomElement menubar = e; + while ( menubar.tagName() != "menubar" && !menubar.isNull() ) + menubar = menubar.nextSibling().toElement(); + + QDomElement functions = e; + while ( functions.tagName() != "functions" && !functions.isNull() ) + functions = functions.nextSibling().toElement(); + + QDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "class" ) { + d->translationContext = e.firstChild().toText().data(); + } else if ( e.tagName() == "widget" ) { + widget = e; + } else if ( e.tagName() == "pixmapinproject" ) { + usePixmapCollection = TRUE; + } else if ( e.tagName() == "layoutdefaults" ) { + defSpacing = e.attribute( "spacing", QString::number( defSpacing ) ).toInt(); + defMargin = e.attribute( "margin", QString::number( defMargin ) ).toInt(); + } + e = e.nextSibling().toElement(); + } + + if ( !imageCollection.isNull() ) + loadImageCollection( imageCollection ); + + createWidgetInternal( widget, parent, 0, widget.attribute("class", "QWidget") ); + QWidget *w = toplevel; + if ( !w ) + return 0; + + if ( !actions.isNull() ) + loadActions( actions ); + if ( !toolbars.isNull() ) + loadToolBars( toolbars ); + if ( !menubar.isNull() ) + loadMenuBar( menubar ); + + if ( !connections.isNull() ) + loadConnections( connections, connector ); + if ( w && name && qstrlen( name ) > 0 ) + w->setName( name ); + + if ( !tabOrder.isNull() ) + loadTabOrder( tabOrder ); + +#if 0 + if ( !functions.isNull() ) // compatibiliy with early 3.0 betas + loadFunctions( functions ); +#endif + + return w; +} + +void QWidgetFactory::unpackUInt16( QDataStream& in, Q_UINT16& n ) +{ + Q_UINT8 half; + in >> half; + if ( half == 255 ) { + in >> n; + } else { + n = half; + } +} + +void QWidgetFactory::unpackUInt32( QDataStream& in, Q_UINT32& n ) +{ + Q_UINT16 half; + in >> half; + if ( half == 65535 ) { + in >> n; + } else { + n = half; + } +} + +void QWidgetFactory::unpackByteArray( QDataStream& in, QByteArray& array ) +{ + Q_UINT32 size; + unpackUInt32( in, size ); + array.resize( size ); + in.readRawBytes( array.data(), size ); +} + +void QWidgetFactory::unpackCString( const UibStrTable& strings, QDataStream& in, + QCString& cstr ) +{ + Q_UINT32 n; + unpackUInt32( in, n ); + cstr = strings.asCString( n ); +} + +void QWidgetFactory::unpackString( const UibStrTable& strings, QDataStream& in, + QString& str ) +{ + Q_UINT32 n; + unpackUInt32( in, n ); + str = strings.asString( n ); +} + +void QWidgetFactory::unpackStringSplit( const UibStrTable& strings, + QDataStream& in, QString& str ) +{ + QString remainder; + unpackString( strings, in, str ); + unpackString( strings, in, remainder ); + str += remainder; +} + +void QWidgetFactory::unpackVariant( const UibStrTable& strings, QDataStream& in, + QVariant& value ) +{ + QString imageName; + Q_UINT32 number; + Q_UINT16 count; + Q_UINT16 x; + Q_UINT16 y; + Q_UINT16 width; + Q_UINT16 height; + Q_UINT8 bit; + Q_UINT8 type; + + in >> type; + + switch ( type ) { + case QVariant::String: + unpackString( strings, in, value.asString() ); + break; + case QVariant::Pixmap: + unpackString( strings, in, imageName ); + if ( imageName.isEmpty() ) { + value.asPixmap() = QPixmap(); + } else { + value.asPixmap() = loadPixmap( imageName ); + } + break; + case QVariant::Image: + unpackString( strings, in, imageName ); + if ( imageName.isEmpty() ) { + value.asImage() = QImage(); + } else { + value.asImage() = loadFromCollection( imageName ); + } + break; + case QVariant::IconSet: + unpackString( strings, in, imageName ); + if ( imageName.isEmpty() ) { + value.asIconSet() = QIconSet(); + } else { + value.asIconSet() = QIconSet( loadPixmap(imageName) ); + } + break; + case QVariant::StringList: + unpackUInt16( in, count ); + while ( count-- ) { + QString str; + unpackString( strings, in, str ); + value.asStringList().append( str ); + } + break; + case QVariant::Rect: + unpackUInt16( in, x ); + unpackUInt16( in, y ); + unpackUInt16( in, width ); + unpackUInt16( in, height ); + value = QRect( x, y, width, height ); + break; + case QVariant::Size: + unpackUInt16( in, width ); + unpackUInt16( in, height ); + value = QSize( width, height ); + break; + case QVariant::Color: + in >> value.asColor(); + break; + case QVariant::Point: + unpackUInt16( in, x ); + unpackUInt16( in, y ); + value = QPoint( x, y ); + break; + case QVariant::Int: + unpackUInt32( in, number ); + value = (int) number; + break; + case QVariant::Bool: + in >> bit; + value = QVariant( bit != 0, 0 ); + break; + case QVariant::Double: + in >> value.asDouble(); + break; + case QVariant::CString: + unpackCString( strings, in, value.asCString() ); + break; + case QVariant::Cursor: + in >> value.asCursor(); + break; + case QVariant::Date: + in >> value.asDate(); + break; + case QVariant::Time: + in >> value.asTime(); + break; + case QVariant::DateTime: + in >> value.asDateTime(); + break; + default: + in >> value; + } +} + +void QWidgetFactory::inputSpacer( const UibStrTable& strings, QDataStream& in, + QLayout *parent ) +{ + QCString name; + QVariant value; + QCString comment; + QSizePolicy::SizeType sizeType = QSizePolicy::Preferred; + bool vertical = FALSE; + int w = 0; + int h = 0; + Q_UINT16 column = 0; + Q_UINT16 row = 0; + Q_UINT16 colspan = 1; + Q_UINT16 rowspan = 1; + Q_UINT8 objectTag; + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_GridCell: + unpackUInt16( in, column ); + unpackUInt16( in, row ); + unpackUInt16( in, colspan ); + unpackUInt16( in, rowspan ); + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( name == "orientation" ) { + vertical = ( value == "Vertical" ); + } else if ( name == "sizeHint" ) { + w = value.toSize().width(); + h = value.toSize().height(); + } else if ( name == "sizeType" ) { + sizeType = stringToSizeType( value.toString() ); + } + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + + if ( parent != 0 ) { + QSpacerItem *spacer; + if ( vertical ) { + spacer = new QSpacerItem( w, h, QSizePolicy::Minimum, sizeType ); + } else { + spacer = new QSpacerItem( w, h, sizeType, QSizePolicy::Minimum ); + } + + if ( parent->inherits("QGridLayout") ) { + ((QGridLayout *) parent)->addMultiCell( spacer, row, + row + rowspan - 1, column, column + colspan - 1, + vertical ? Qt::AlignHCenter : Qt::AlignVCenter ); + } else { + parent->addItem( spacer ); + } + } +} + +void QWidgetFactory::inputColumnOrRow( const UibStrTable& strings, + QDataStream& in, QObject *parent, + bool isRow ) +{ + QString text; + QPixmap pixmap; + QString field; + bool clickable = TRUE; + bool resizable = TRUE; + + QCString name; + QVariant value; + QCString comment; + QString str; + Q_UINT8 objectTag; + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_TextProperty: + unpackCString( strings, in, name ); + unpackCString( strings, in, value.asCString() ); + unpackCString( strings, in, comment ); + str = translate( value.asCString().data(), comment.data() ); + + if ( name == "field" ) { + field = str; + } else if ( name == "text" ) { + text = str; + } + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( name == "clickable" ) { + clickable = value.toBool(); + } else if ( name == "pixmap" ) { + pixmap = value.asPixmap(); + } else if ( name == "resizable" ) { + resizable = value.toBool(); + } + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + + if ( parent != 0 ) { + if ( parent->inherits("QListView") ) { + createListViewColumn( (QListView *) parent, text, pixmap, clickable, + resizable ); +#ifndef QT_NO_TABLE + } else if ( parent->inherits("QTable") ) { + createTableColumnOrRow( (QTable *) parent, text, pixmap, field, + isRow ); +#endif + } + } +} + +void QWidgetFactory::inputItem( const UibStrTable& strings, QDataStream& in, + QObject *parent, QListViewItem *parentItem ) +{ + QStringList texts; + QValueList<QPixmap> pixmaps; + QCString name; + QVariant value; + QCString comment; + Q_UINT8 objectTag; + + QListView *listView = 0; + if ( parent != 0 && parent->inherits("QListView") ) + parent = (QListView *) parent; + QListViewItem *item = 0; + if ( listView != 0 ) { + if ( parentItem == 0 ) { + item = new QListViewItem( listView, d->lastItem ); + } else { + item = new QListViewItem( parentItem, d->lastItem ); + } + d->lastItem = item; + } + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_Item: + if ( listView != 0 ) + d->lastItem->setOpen( TRUE ); + inputItem( strings, in, parent, item ); + break; + case Object_TextProperty: + unpackCString( strings, in, name ); + unpackCString( strings, in, value.asCString() ); + unpackCString( strings, in, comment ); + + if ( name == "text" ) + texts << translate( value.asCString().data(), comment.data() ); + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( name == "pixmap" ) + pixmaps << value.asPixmap(); + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + + if ( listView != 0 ) { + int i = 0; + QStringList::ConstIterator t = texts.begin(); + while ( t != texts.end() ) { + item->setText( i, *t ); + ++i; + ++t; + } + + int j = 0; + QValueList<QPixmap>::ConstIterator p = pixmaps.begin(); + while ( p != pixmaps.end() ) { + item->setPixmap( j, *p ); + ++j; + ++p; + } + } else { + QString text = texts.last(); + QPixmap pixmap = pixmaps.last(); + + if ( parent != 0 ) { + if ( parent->inherits("QComboBox") || + parent->inherits("QListBox") ) { + QListBox *listBox = (QListBox *) parent->qt_cast( "QListBox" ); + if ( listBox == 0 ) + listBox = ((QComboBox *) parent)->listBox(); + + if ( pixmap.isNull() ) { + (void) new QListBoxText( listBox, text ); + } else { + (void) new QListBoxPixmap( listBox, pixmap, text ); + } + #ifndef QT_NO_ICONVIEW + } else if ( parent->inherits("QIconView") ) { + (void) new QIconViewItem( (QIconView *) parent, text, pixmap ); + #endif + } + } + } +} + +void QWidgetFactory::inputMenuItem( QObject **objects, + const UibStrTable& strings, QDataStream& in, + QMenuBar *menuBar ) +{ + QCString name; + QCString text; + Q_UINT16 actionNo; + Q_UINT8 objectTag; + + unpackCString( strings, in, name ); + unpackCString( strings, in, text ); + + QPopupMenu *popupMenu = new QPopupMenu( menuBar->parentWidget(), name ); + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_ActionRef: + unpackUInt16( in, actionNo ); + ((QAction *) objects[actionNo])->addTo( popupMenu ); + break; + case Object_Separator: + popupMenu->insertSeparator(); + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + menuBar->insertItem( translate(text.data()), popupMenu ); +} + +QObject *QWidgetFactory::inputObject( QObject **objects, int& numObjects, + const UibStrTable& strings, + QDataStream& in, QWidget *ancestorWidget, + QObject *parent, QCString className ) +{ + QObject *obj = 0; + QWidget *widget = 0; + QLayout *layout = 0; + QWidget *parentWidget = 0; + QLayout *parentLayout = 0; + + bool isQObject = !className.isEmpty(); + if ( isQObject ) { + if ( parent != 0 ) { + if ( parent->isWidgetType() ) { + if ( parent->inherits("QMainWindow") ) { + parentWidget = ((QMainWindow *) parent)->centralWidget(); + } else { + parentWidget = (QWidget *) parent; + } + } else if ( parent->inherits("QLayout") ) { + parentLayout = (QLayout *) parent; + parentWidget = ancestorWidget; + } + } + + if ( className == "QAction" ) { + unpackCString( strings, in, className ); + if ( className == "QActionGroup" ) { + obj = new QActionGroup( parent ); + } else { + obj = new QAction( parent ); + } + } else if ( className == "QLayout" ) { + unpackCString( strings, in, className ); + LayoutType type = Grid; + if ( className == "QHBoxLayout" ) { + type = HBox; + } else if ( className == "QVBoxLayout" ) { + type = VBox; + } + if ( parentLayout != 0 && parentLayout->inherits("QGridLayout") ) { + layout = createLayout( 0, 0, type ); + } else { + layout = createLayout( parentWidget, parentLayout, type ); + } + obj = layout; + } else if ( className == "QMenuBar" ) { + unpackCString( strings, in, className ); + widget = ((QMainWindow *) parent)->menuBar(); + obj = widget; + } else if ( className == "QToolBar" ) { + Q_UINT8 dock; + in >> dock; + unpackCString( strings, in, className ); + widget = new QToolBar( QString::null, (QMainWindow *) parent, + (Qt::Dock) dock ); + obj = widget; + } else if ( className == "QWidget" ) { + unpackCString( strings, in, className ); + widget = createWidget( className, parentWidget, 0 ); + obj = widget; + } + + if ( widget != 0 ) + ancestorWidget = widget; + d->lastItem = 0; + objects[numObjects++] = obj; + } + + QCString name; + QVariant value; + QCString comment; + QString str; + Q_UINT16 actionNo; + int metAttribute = 0; + Q_UINT16 column = 0; + Q_UINT16 row = 0; + Q_UINT16 colspan = 1; + Q_UINT16 rowspan = 1; + Q_UINT8 paletteTag; + Q_UINT8 objectTag; + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_ActionRef: + unpackUInt16( in, actionNo ); + ((QAction *) objects[actionNo])->addTo( (QToolBar *) widget ); + break; + case Object_Attribute: + metAttribute = 2; + break; + case Object_Column: + inputColumnOrRow( strings, in, obj, FALSE ); + break; + case Object_Event: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + // ### do something with value.asStringList() + break; + case Object_FontProperty: + { + QFont font; + QString family; + Q_UINT16 pointSize; + Q_UINT8 fontFlags; + + unpackCString( strings, in, name ); + in >> fontFlags; + + if ( fontFlags & Font_Family ) { + unpackString( strings, in, family ); + font.setFamily( family ); + } + if ( fontFlags & Font_PointSize ) { + unpackUInt16( in, pointSize ); + font.setPointSize( pointSize ); + } + if ( fontFlags & Font_Bold ) + font.setBold( TRUE ); + if ( fontFlags & Font_Italic ) + font.setItalic( TRUE ); + if ( fontFlags & Font_Underline ) + font.setUnderline( TRUE ); + if ( fontFlags & Font_StrikeOut ) + font.setStrikeOut( TRUE ); + + if ( obj != 0 ) + setProperty( obj, name, font ); + } + break; + case Object_GridCell: + unpackUInt16( in, column ); + unpackUInt16( in, row ); + unpackUInt16( in, colspan ); + unpackUInt16( in, rowspan ); + break; + case Object_Item: + inputItem( strings, in, obj ); + break; + case Object_MenuItem: + inputMenuItem( objects, strings, in, (QMenuBar *) widget ); + break; + case Object_PaletteProperty: + { + QPalette palette; + QColorGroup colorGroup; + QColor color; + int role = -1; + + unpackCString( strings, in, name ); + + in >> paletteTag; + while ( !in.atEnd() && paletteTag != Palette_End ) { + switch ( paletteTag ) { + case Palette_Active: + palette.setActive( colorGroup ); + role = -1; + break; + case Palette_Inactive: + palette.setInactive( colorGroup ); + role = -1; + break; + case Palette_Disabled: + palette.setDisabled( colorGroup ); + role = -1; + break; + case Palette_Color: + role++; + in >> color; + colorGroup.setColor( (QColorGroup::ColorRole) role, + color ); + break; + case Palette_Pixmap: + unpackVariant( strings, in, value ); + colorGroup.setBrush( (QColorGroup::ColorRole) role, + QBrush(color, value.asPixmap()) ); + break; + default: + qFatal( "Corrupt" ); + } + in >> paletteTag; + } + if ( obj != 0 ) + setProperty( obj, name, palette ); + } + break; + case Object_Row: + inputColumnOrRow( strings, in, obj, TRUE ); + break; + case Object_Spacer: + inputSpacer( strings, in, layout ); + break; + case Object_Separator: + ((QToolBar *) widget)->addSeparator(); + break; + case Object_SubAction: + inputObject( objects, numObjects, strings, in, parentWidget, + obj != 0 ? obj : parent, "QAction" ); + break; + case Object_SubLayout: + inputObject( objects, numObjects, strings, in, parentWidget, obj, + "QLayout" ); + break; + case Object_SubWidget: + inputObject( objects, numObjects, strings, in, parentWidget, obj, + "QWidget" ); + break; + case Object_TextProperty: + unpackCString( strings, in, name ); + unpackCString( strings, in, value.asCString() ); + unpackCString( strings, in, comment ); + str = translate( value.asCString().data(), comment.data() ); + + if ( metAttribute > 0 ) { + if ( name == "title" ) { + if ( parent != 0 ) { + if ( parent->inherits("QTabWidget") ) { + ((QTabWidget *) parent)->insertTab( widget, str ); + } else if ( parent->inherits("QWizard") ) { + ((QWizard *) parent)->addPage( widget, str ); + } + } + } + } else { + if ( obj != 0 ) + setProperty( obj, name, str ); + } + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( metAttribute > 0 ) { + if ( name == "id" ) { + if ( parent != 0 && parent->inherits("QWidgetStack") ) + ((QWidgetStack *) parent)->addWidget( widget, value.toInt() ); + } + } else { + if ( obj != 0 ) + setProperty( obj, name, value ); + } + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + metAttribute--; + } + + if ( parentLayout != 0 ) { + if ( widget != 0 ) { + if ( parentLayout->inherits("QGridLayout") ) { + ((QGridLayout *) parentLayout)->addMultiCellWidget( + widget, row, row + rowspan - 1, column, + column + colspan - 1 ); + } else { + ((QBoxLayout *) parentLayout)->addWidget( widget ); + } + } else if ( layout != 0 ) { + if ( parentLayout->inherits("QGridLayout") ) { + ((QGridLayout *) parentLayout)->addMultiCellLayout( + layout, row, row + rowspan - 1, column, + column + colspan - 1 ); + } + } + } + return obj; +} + +QWidget *QWidgetFactory::createFromUibFile( QDataStream& in, + QObject * /* connector */ , QWidget *parent, const char *name ) +{ +#define END_OF_BLOCK() \ + ( in.atEnd() || in.device()->at() >= nextBlock ) + + Q_UINT8 lf; + Q_UINT8 cr; + in >> lf; + in >> cr; + if ( lf != '\n' || cr != '\r' ) { + qWarning( "File corrupted" ); + return 0; + } + + Q_UINT8 qdatastreamVersion; + in >> qdatastreamVersion; + if ( (int) qdatastreamVersion > in.version() ) { + qWarning( "Incompatible version of Qt" ); + return 0; + } + in.setVersion( qdatastreamVersion ); + + UibStrTable strings; + QObject **objects = 0; + int numObjects = 0; + + Q_UINT8 blockType; + Q_UINT32 blockSize; + + in >> blockType; + while ( !in.atEnd() && blockType != Block_End ) { + unpackUInt32( in, blockSize ); + QIODevice::Offset nextBlock = in.device()->at() + blockSize; + + switch ( blockType ) { + case Block_Actions: + inputObject( objects, numObjects, strings, in, toplevel, toplevel ); + break; + case Block_Buddies: + { + Q_UINT16 labelNo; + Q_UINT16 buddyNo; + + do { + unpackUInt16( in, labelNo ); + unpackUInt16( in, buddyNo ); + QLabel *label = + (QLabel *) objects[labelNo]->qt_cast( "QLabel" ); + if ( label != 0 ) + label->setBuddy( (QWidget *) objects[buddyNo] ); + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Connections: + { + QString language = "C++"; + Q_UINT16 senderNo = 0; + QString signal = "clicked()"; + Q_UINT16 receiverNo = 0; + QString slot = "accept()"; + Q_UINT8 connectionFlags; + + do { + in >> connectionFlags; + if ( connectionFlags & Connection_Language ) + unpackString( strings, in, language ); + if ( connectionFlags & Connection_Sender ) + unpackUInt16( in, senderNo ); + if ( connectionFlags & Connection_Signal ) + unpackStringSplit( strings, in, signal ); + if ( connectionFlags & Connection_Receiver ) + unpackUInt16( in, receiverNo ); + if ( connectionFlags & Connection_Slot ) + unpackStringSplit( strings, in, slot ); + // ### +#if 0 + qWarning( "connect( %p, %s, %p, %s )", objects[senderNo], + signal.latin1(), objects[receiverNo], + slot.latin1() ); +#endif + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Functions: + // ### + qWarning( "Block_Functions not supported" ); + in.device()->at( nextBlock ); + break; + case Block_Images: + { + QString format; + Q_UINT32 length; + QByteArray data; + Image image; + + do { + unpackString( strings, in, image.name ); + unpackString( strings, in, format ); + unpackUInt32( in, length ); + unpackByteArray( in, data ); + image.img = loadImageData( format, length, data ); + images += image; + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Intro: + { + Q_INT16 defaultMargin; + Q_INT16 defaultSpacing; + Q_UINT16 maxObjects; + Q_UINT8 introFlags; + + in >> introFlags; + in >> defaultMargin; + in >> defaultSpacing; + unpackUInt16( in, maxObjects ); + unpackCString( strings, in, d->translationContext ); + + if ( introFlags & Intro_Pixmapinproject ) + usePixmapCollection = TRUE; + if ( defaultMargin != -32768 ) + defMargin = defaultMargin; + if ( defaultSpacing != -32768 ) + defSpacing = defaultSpacing; + objects = new QObject *[maxObjects]; + } + break; + case Block_Menubar: + inputObject( objects, numObjects, strings, in, toplevel, toplevel, + "QMenuBar" ); + break; + case Block_Slots: + { + QString language; + QString slot; + + do { + unpackString( strings, in, language ); + unpackStringSplit( strings, in, slot ); + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Strings: + strings.readBlock( in, blockSize ); + break; + case Block_Tabstops: + { + Q_UINT16 beforeNo; + Q_UINT16 afterNo; + + unpackUInt16( in, beforeNo ); + while ( !END_OF_BLOCK() ) { + unpackUInt16( in, afterNo ); + toplevel->setTabOrder( (QWidget *) objects[beforeNo], + (QWidget *) objects[afterNo] ); + beforeNo = afterNo; + } + } + break; + case Block_Toolbars: + do { + inputObject( objects, numObjects, strings, in, toplevel, + toplevel, "QToolBar" ); + } while ( !END_OF_BLOCK() ); + break; + case Block_Variables: + // ### + qWarning( "Block_Variables not supported" ); + in.device()->at( nextBlock ); + break; + case Block_Widget: + toplevel = (QWidget *) + inputObject( objects, numObjects, strings, in, toplevel, parent, + "QWidget" ); + if ( toplevel != 0 ) + toplevel->setName( name ); + break; + default: + qWarning( "Version error" ); + return 0; + } + in >> blockType; + } + delete[] objects; + return toplevel; +} + +/*! Installs a widget factory \a factory, which normally contains + additional widgets that can then be created using a QWidgetFactory. + See createWidget() for further details. +*/ + +void QWidgetFactory::addWidgetFactory( QWidgetFactory *factory ) +{ + widgetFactories.append( factory ); +} + +/*! + Creates a widget of the type \a className passing \a parent and \a + name to its constructor. + + If \a className is a widget in the Qt library, it is directly + created by this function. If the widget isn't in the Qt library, + each of the installed widget plugins is asked, in turn, to create + the widget. As soon as a plugin says it can create the widget it + is asked to do so. It may occur that none of the plugins can + create the widget, in which case each installed widget factory is + asked to create the widget (see addWidgetFactory()). If the widget + cannot be created by any of these means, 0 is returned. + + If you have a custom widget, and want it to be created using the + widget factory, there are two approaches you can use: + + \list 1 + + \i Write a widget plugin. This allows you to use the widget in + \e{Qt Designer} and in this QWidgetFactory. See the widget plugin + documentation for further details. (See the "Creating Custom + Widgets with Plugins" section of the \link designer-manual.book Qt + Designer manual\endlink for an example. + + \i Subclass QWidgetFactory. Then reimplement this function to + create and return an instance of your custom widget if \a + className equals the name of your widget, otherwise return 0. Then + at the beginning of your program where you want to use the widget + factory to create widgets do a: + \code + QWidgetFactory::addWidgetFactory( new MyWidgetFactory ); + \endcode + where MyWidgetFactory is your QWidgetFactory subclass. + + \endlist +*/ + +QWidget *QWidgetFactory::createWidget( const QString &className, QWidget *parent, + const char *name ) const +{ + // create widgets we know + if ( className == "QPushButton" ) { + return new QPushButton( parent, name ); + } else if ( className == "QToolButton" ) { + return new QToolButton( parent, name ); + } else if ( className == "QCheckBox" ) { + return new QCheckBox( parent, name ); + } else if ( className == "QRadioButton" ) { + return new QRadioButton( parent, name ); + } else if ( className == "QGroupBox" ) { + return new QGroupBox( parent, name ); + } else if ( className == "QButtonGroup" ) { + return new QButtonGroup( parent, name ); + } else if ( className == "QIconView" ) { +#if !defined(QT_NO_ICONVIEW) + return new QIconView( parent, name ); +#endif + } else if ( className == "QTable" ) { +#if !defined(QT_NO_TABLE) + return new QTable( parent, name ); +#endif + } else if ( className == "QListBox" ) { + return new QListBox( parent, name ); + } else if ( className == "QListView" ) { + return new QListView( parent, name ); + } else if ( className == "QLineEdit" ) { + return new QLineEdit( parent, name ); + } else if ( className == "QSpinBox" ) { + return new QSpinBox( parent, name ); + } else if ( className == "QMultiLineEdit" ) { + return new QMultiLineEdit( parent, name ); + } else if ( className == "QLabel" || className == "TextLabel" || className == "PixmapLabel" ) { + return new QLabel( parent, name ); + } else if ( className == "QLayoutWidget" ) { + return new QWidget( parent, name ); + } else if ( className == "QTabWidget" ) { + return new QTabWidget( parent, name ); + } else if ( className == "QComboBox" ) { + return new QComboBox( FALSE, parent, name ); + } else if ( className == "QWidget" ) { + if ( !qwf_stays_on_top ) + return new QWidget( parent, name ); + return new QWidget( parent, name, Qt::WStyle_StaysOnTop ); + } else if ( className == "QDialog" ) { + if ( !qwf_stays_on_top ) + return new QDialog( parent, name ); + return new QDialog( parent, name, FALSE, Qt::WStyle_StaysOnTop ); + } else if ( className == "QWizard" ) { + return new QWizard( parent, name ); + } else if ( className == "QLCDNumber" ) { + return new QLCDNumber( parent, name ); + } else if ( className == "QProgressBar" ) { + return new QProgressBar( parent, name ); + } else if ( className == "QTextView" ) { + return new QTextView( parent, name ); + } else if ( className == "QTextBrowser" ) { + return new QTextBrowser( parent, name ); + } else if ( className == "QDial" ) { + return new QDial( parent, name ); + } else if ( className == "QSlider" ) { + return new QSlider( parent, name ); + } else if ( className == "QFrame" ) { + return new QFrame( parent, name ); + } else if ( className == "QSplitter" ) { + return new QSplitter( parent, name ); + } else if ( className == "Line" ) { + QFrame *f = new QFrame( parent, name ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + return f; + } else if ( className == "QTextEdit" ) { + return new QTextEdit( parent, name ); + } else if ( className == "QDateEdit" ) { + return new QDateEdit( parent, name ); + } else if ( className == "QTimeEdit" ) { + return new QTimeEdit( parent, name ); + } else if ( className == "QDateTimeEdit" ) { + return new QDateTimeEdit( parent, name ); + } else if ( className == "QScrollBar" ) { + return new QScrollBar( parent, name ); + } else if ( className == "QPopupMenu" ) { + return new QPopupMenu( parent, name ); + } else if ( className == "QWidgetStack" ) { + return new QWidgetStack( parent, name ); + } else if ( className == "QToolBox" ) { + return new QToolBox( parent, name ); + } else if ( className == "QVBox" ) { + return new QVBox( parent, name ); + } else if ( className == "QHBox" ) { + return new QHBox( parent, name ); + } else if ( className == "QGrid" ) { + return new QGrid( 4, parent, name ); + } else if ( className == "QMainWindow" ) { + QMainWindow *mw = 0; + if ( !qwf_stays_on_top ) + mw = new QMainWindow( parent, name ); + else + mw = new QMainWindow( parent, name, Qt::WType_TopLevel | Qt::WStyle_StaysOnTop ); + mw->setCentralWidget( new QWidget( mw, "qt_central_widget" ) ); + mw->centralWidget()->show(); + (void)mw->statusBar(); + return mw; + + } +#if !defined(QT_NO_SQL) + else if ( className == "QDataTable" ) { + return new QDataTable( parent, name ); + } else if ( className == "QDataBrowser" ) { + return new QDesignerDataBrowser2( parent, name ); + } else if ( className == "QDataView" ) { + return new QDesignerDataView2( parent, name ); + } +#endif + + setupPluginDir(); + // try to create it using the loaded widget plugins + if ( !widgetInterfaceManager ) + widgetInterfaceManager = + new QPluginManager<WidgetInterface>( IID_Widget, QApplication::libraryPaths(), + *qwf_plugin_dir ); + + QInterfacePtr<WidgetInterface> iface = 0; + widgetInterfaceManager->queryInterface( className, &iface ); + if ( iface ) { + QWidget *w = iface->create( className, parent, name ); + if ( w ) { + d->customWidgets.replace( className.latin1(), new bool(TRUE) ); + return w; + } + } + + // hope we have a factory which can do it + for ( QWidgetFactory* f = widgetFactories.first(); f; f = widgetFactories.next() ) { + QWidget *w = f->createWidget( className, parent, name ); + if ( w ) + return w; + } + + // no success + return 0; +} + +/*! Returns the names of the widgets, which this facory can create. */ + +QStringList QWidgetFactory::widgets() +{ + setupWidgetListAndMap(); + return *availableWidgetList; +} + +/*! Returns whether this widget factory can create the widget \a + widget */ + +bool QWidgetFactory::supportsWidget( const QString &widget ) +{ + setupWidgetListAndMap(); + return ( availableWidgetMap->find( widget ) != availableWidgetMap->end() ); +} + +QWidget *QWidgetFactory::createWidgetInternal( const QDomElement &e, QWidget *parent, + QLayout* layout, const QString &classNameArg ) +{ + d->lastItem = 0; + QDomElement n = e.firstChild().toElement(); + QWidget *w = 0; // the widget that got created + QObject *obj = 0; // gets the properties + + QString className = classNameArg; + + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + + bool isQLayoutWidget = FALSE; + + if ( !className.isEmpty() ) { + if ( !layout && className == "QLayoutWidget" ) { + className = "QWidget"; + isQLayoutWidget = TRUE; + } + if ( layout && className == "QLayoutWidget" ) { + // hide layout widgets + w = parent; + } else { + obj = QWidgetFactory::createWidget( className, parent, 0 ); + if ( !obj ) + return 0; + w = (QWidget*)obj; + if ( !toplevel ) + toplevel = w; + if ( w->inherits( "QMainWindow" ) ) + w = ( (QMainWindow*)w )->centralWidget(); + if ( layout ) { + switch( layoutType( layout ) ) { + case HBox: + ( (QHBoxLayout*)layout )->addWidget( w ); + break; + case VBox: + ( (QVBoxLayout*)layout )->addWidget( w ); + break; + case Grid: + ( (QGridLayout*)layout )->addMultiCellWidget( w, row, row + rowspan - 1, + col, col + colspan - 1 ); + break; + default: + break; + } + } + + layout = 0; + } + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + QString parentClassName = parent ? parent->className() : 0; + bool isPlugin = parent ? !!d->customWidgets.find( parent->className() ) : FALSE; + if ( isPlugin ) + qWarning( "####### loading custom container widgets without page support not implemented!" ); + // ### TODO loading for custom container widgets without pages +#endif + + int idx = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "spacer" ) { + createSpacer( n, layout ); + } else if ( n.tagName() == "widget" ) { + QMap< QString, QString> *oldDbControls = dbControls; + createWidgetInternal( n, w, layout, n.attribute( "class", "QWidget" ) ); + dbControls = oldDbControls; + } else if ( n.tagName() == "hbox" ) { + QLayout *parentLayout = layout; + if ( layout && layout->inherits( "QGridLayout" ) ) + layout = createLayout( 0, 0, QWidgetFactory::HBox, isQLayoutWidget ); + else + layout = createLayout( w, layout, QWidgetFactory::HBox, isQLayoutWidget ); + obj = layout; + n = n.firstChild().toElement(); + if ( parentLayout && parentLayout->inherits( "QGridLayout" ) ) + ( (QGridLayout*)parentLayout )->addMultiCellLayout( layout, row, + row + rowspan - 1, col, col + colspan - 1 ); + continue; + } else if ( n.tagName() == "grid" ) { + QLayout *parentLayout = layout; + if ( layout && layout->inherits( "QGridLayout" ) ) + layout = createLayout( 0, 0, QWidgetFactory::Grid, isQLayoutWidget ); + else + layout = createLayout( w, layout, QWidgetFactory::Grid, isQLayoutWidget ); + obj = layout; + n = n.firstChild().toElement(); + if ( parentLayout && parentLayout->inherits( "QGridLayout" ) ) + ( (QGridLayout*)parentLayout )->addMultiCellLayout( layout, row, + row + rowspan - 1, col, col + colspan - 1 ); + continue; + } else if ( n.tagName() == "vbox" ) { + QLayout *parentLayout = layout; + if ( layout && layout->inherits( "QGridLayout" ) ) + layout = createLayout( 0, 0, QWidgetFactory::VBox, isQLayoutWidget ); + else + layout = createLayout( w, layout, QWidgetFactory::VBox, isQLayoutWidget ); + obj = layout; + n = n.firstChild().toElement(); + if ( parentLayout && parentLayout->inherits( "QGridLayout" ) ) + ( (QGridLayout*)parentLayout )->addMultiCellLayout( layout, row, + row + rowspan - 1, col, col + colspan - 1 ); + continue; + } else if ( n.tagName() == "property" && obj ) { + setProperty( obj, n.attribute( "name" ), n.firstChild().toElement() ); + } else if ( n.tagName() == "attribute" && w ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( parent ) { + if ( parent->inherits( "QTabWidget" ) ) { + if ( attrib == "title" ) + ( (QTabWidget*)parent )->insertTab( w, translate( v.toString() ) ); + } else if ( parent->inherits( "QWidgetStack" ) ) { + if ( attrib == "id" ) + ( (QWidgetStack*)parent )->addWidget( w, v.toInt() ); + } else if ( parent->inherits( "QToolBox" ) ) { + if ( attrib == "label" ) + ( (QToolBox*)parent )->addItem( w, v.toString() ); + } else if ( parent->inherits( "QWizard" ) ) { + if ( attrib == "title" ) + ( (QWizard*)parent )->addPage( w, translate( v.toString() ) ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( isPlugin ) { + if ( attrib == "label" ) { + WidgetInterface *iface = 0; + widgetInterfaceManager->queryInterface( parentClassName, &iface ); + if ( iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, + (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + iface2->insertPage( parentClassName, + (QWidget*)parent, translate( v.toString() ), -1, w ); + iface2->release(); + } + iface->release(); + } + } +#endif + } + } + } else if ( n.tagName() == "item" ) { + createItem( n, w ); + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + createColumn( n, w ); + } + + n = n.nextSibling().toElement(); + idx++; + } + + return w; +} + +QLayout *QWidgetFactory::createLayout( QWidget *widget, QLayout* layout, + LayoutType type, bool isQLayoutWidget ) +{ + int spacing = defSpacing; + int margin = defMargin; + + if ( layout || !widget || isQLayoutWidget ) + margin = 0; + + if ( !layout && widget && widget->inherits( "QTabWidget" ) ) + widget = ((QTabWidget*)widget)->currentPage(); + + if ( !layout && widget && widget->inherits( "QWizard" ) ) + widget = ((QWizard*)widget)->currentPage(); + + if ( !layout && widget && widget->inherits( "QWidgetStack" ) ) + widget = ((QWidgetStack*)widget)->visibleWidget(); + + if ( !layout && widget && widget->inherits( "QToolBox" ) ) + widget = ((QToolBox*)widget)->currentItem(); + + QLayout *l = 0; + int align = 0; + if ( !layout && widget && widget->inherits( "QGroupBox" ) ) { + QGroupBox *gb = (QGroupBox*)widget; + gb->setColumnLayout( 0, Qt::Vertical ); + layout = gb->layout(); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + align = Qt::AlignTop; + } + if ( layout ) { + switch ( type ) { + case HBox: + l = new QHBoxLayout( layout ); + break; + case VBox: + l = new QVBoxLayout( layout ); + break; + case Grid: + l = new QGridLayout( layout ); + break; + default: + return 0; + } + } else { + switch ( type ) { + case HBox: + l = new QHBoxLayout( widget ); + break; + case VBox: + l = new QVBoxLayout( widget ); + break; + case Grid: + l = new QGridLayout( widget ); + break; + default: + return 0; + } + } + l->setAlignment( align ); + l->setMargin( margin ); + l->setSpacing( spacing ); + return l; +} + +QWidgetFactory::LayoutType QWidgetFactory::layoutType( QLayout *layout ) const +{ + if ( layout->inherits( "QHBoxLayout" ) ) + return HBox; + else if ( layout->inherits( "QVBoxLayout" ) ) + return VBox; + else if ( layout->inherits( "QGridLayout" ) ) + return Grid; + return NoLayout; +} + +void QWidgetFactory::setProperty( QObject* obj, const QString &prop, + QVariant value ) +{ + int offset = obj->metaObject()->findProperty( prop, TRUE ); + + if ( offset != -1 ) { + if ( prop == "geometry" && obj == toplevel ) { + toplevel->resize( value.toRect().size() ); + } else if ( prop == "accel" ) { + obj->setProperty( prop, value.toKeySequence() ); + } else { + if ( value.type() == QVariant::String || + value.type() == QVariant::CString ) { + const QMetaProperty *metaProp = + obj->metaObject()->property( offset, TRUE ); + if ( metaProp != 0 && metaProp->isEnumType() ) { + if ( metaProp->isSetType() ) { + QStrList flagsCStr; + QStringList flagsStr = + QStringList::split( '|', value.asString() ); + QStringList::ConstIterator f = flagsStr.begin(); + while ( f != flagsStr.end() ) { + flagsCStr.append( *f ); + ++f; + } + value = QVariant( metaProp->keysToValue(flagsCStr) ); + } else { + QCString key = value.toCString(); + value = QVariant( metaProp->keyToValue(key) ); + } + } + } + obj->setProperty( prop, value ); + } + } else { + if ( obj->isWidgetType() ) { + if ( prop == "toolTip" ) { + if ( !value.toString().isEmpty() ) + QToolTip::add( (QWidget*)obj, translate( value.toString() ) ); + } else if ( prop == "whatsThis" ) { + if ( !value.toString().isEmpty() ) + QWhatsThis::add( (QWidget*)obj, translate( value.toString() ) ); + } else if ( prop == "buddy" ) { + buddies.insert( obj->name(), value.toCString() ); + } else if ( prop == "buttonGroupId" ) { + if ( obj->inherits( "QButton" ) && obj->parent()->inherits( "QButtonGroup" ) ) + ( (QButtonGroup*)obj->parent() )->insert( (QButton*)obj, value.toInt() ); +#ifndef QT_NO_SQL + } else if ( prop == "database" && !obj->inherits( "QDataView" ) + && !obj->inherits( "QDataBrowser" ) ) { + const QStringList& lst = value.asStringList(); + if ( lst.count() > 2 ) { + if ( dbControls ) + dbControls->insert( obj->name(), lst[ 2 ] ); + } else if ( lst.count() == 2 ) { + dbTables.insert( obj->name(), lst ); + } + } else if ( prop == "database" ) { + const QStringList& lst = value.asStringList(); + if ( lst.count() == 2 && obj->inherits( "QWidget" ) ) { + SqlWidgetConnection conn( lst[ 0 ], lst[ 1 ] ); + sqlWidgetConnections.insert( (QWidget*)obj, conn ); + dbControls = conn.dbControls; + } +#endif + } else if ( prop == "frameworkCode" ) { + if ( value.isValid() && !value.toBool() ) + noDatabaseWidgets << obj->name(); + } + } + } +} + +void QWidgetFactory::setProperty( QObject* widget, const QString &prop, const QDomElement &e ) +{ + QString comment; + QVariant value( DomTool::elementToVariant( e, QVariant(), comment ) ); + + if ( e.tagName() == "string" ) { + value = translate( value.asString(), comment ); + } else if ( e.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( value.toString() ); + if ( !pix.isNull() ) + value = pix; + } else if ( e.tagName() == "iconset" ) { + QPixmap pix = loadPixmap( value.toString() ); + if ( !pix.isNull() ) + value = QIconSet( pix ); + } else if ( e.tagName() == "image" ) { + value = loadFromCollection( value.toString() ); + } else if ( e.tagName() == "palette" ) { + QDomElement n = e.firstChild().toElement(); + QPalette p; + while ( !n.isNull() ) { + QColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + p.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + p.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + p.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + value = p; + } + setProperty( widget, prop, value ); +} + +void QWidgetFactory::createSpacer( const QDomElement &e, QLayout *layout ) +{ + QDomElement n = e.firstChild().toElement(); + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + + Qt::Orientation orient = Qt::Horizontal; + int w = 0, h = 0; + QSizePolicy::SizeType sizeType = QSizePolicy::Preferred; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString prop = n.attribute( "name" ); + if ( prop == "orientation" ) { + if ( n.firstChild().firstChild().toText().data() == "Horizontal" ) + orient = Qt::Horizontal; + else + orient = Qt::Vertical; + } else if ( prop == "sizeType" ) { + sizeType = stringToSizeType( n.firstChild().firstChild().toText().data() ); + } else if ( prop == "sizeHint" ) { + w = n.firstChild().firstChild().firstChild().toText().data().toInt(); + h = n.firstChild().firstChild().nextSibling().firstChild().toText().data().toInt(); + } + } + n = n.nextSibling().toElement(); + } + + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + QSpacerItem *item = new QSpacerItem( w, h, orient == Qt::Horizontal ? sizeType : QSizePolicy::Minimum, + orient == Qt::Vertical ? sizeType : QSizePolicy::Minimum ); + if ( layout ) { + if ( layout->inherits( "QBoxLayout" ) ) + ( (QBoxLayout*)layout )->addItem( item ); + else + ( (QGridLayout*)layout )->addMultiCell( item, row, row + rowspan - 1, col, col + colspan - 1, + orient == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter ); + } +} + +static QImage loadImageData( QDomElement &n2 ) +{ + QString format = n2.attribute( "format", "PNG" ); + QString hex = n2.firstChild().toText().data(); + int n = hex.length() / 2; + QByteArray data( n ); + for ( int i = 0; i < n; i++ ) + data[i] = (char) hex.mid( 2 * i, 2 ).toUInt( 0, 16 ); + return loadImageData( format, n2.attribute("length").toULong(), data ); +} + +void QWidgetFactory::loadImageCollection( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "image" ) { + Image img; + img.name = n.attribute( "name" ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "data" ) + img.img = loadImageData( n2 ); + n2 = n2.nextSibling().toElement(); + } + images.append( img ); + n = n.nextSibling().toElement(); + } + } +} + +QImage QWidgetFactory::loadFromCollection( const QString &name ) +{ + QValueList<Image>::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + if ( ( *it ).name == name ) + return ( *it ).img; + } + return QImage(); +} + +QPixmap QWidgetFactory::loadPixmap( const QString& name ) +{ + QPixmap pix; + if ( usePixmapCollection ) { + const QMimeSource *m = QMimeSourceFactory::defaultFactory()->data( name ); + if ( m ) + QImageDrag::decode( m, pix ); + } else { + pix.convertFromImage( loadFromCollection(name) ); + } + return pix; +} + +QPixmap QWidgetFactory::loadPixmap( const QDomElement &e ) +{ + return loadPixmap( e.firstChild().toText().data() ); +} + +QColorGroup QWidgetFactory::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 ) ) ); + } else if ( n.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( n ); + cg.setBrush( (QColorGroup::ColorRole)r, QBrush( col, pix ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +struct Connection +{ + QObject *sender, *receiver; + QCString signal, slot; + bool operator==( const Connection &c ) const { + return sender == c.sender && receiver == c.receiver && + signal == c.signal && slot == c.slot ; + } + + Connection() : sender( 0 ), receiver( 0 ) { } +}; + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +void QWidgetFactory::loadConnections( const QDomElement &e, QObject *connector ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "connection" ) { + QString lang = n.attribute( "language", "C++" ); + QDomElement n2 = n.firstChild().toElement(); + Connection conn; + while ( !n2.isNull() ) { + if ( n2.tagName() == "sender" ) { + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.sender = toplevel; + } else { + if ( name == "this" ) + name = toplevel->name(); + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.sender = l->first(); + delete l; + } + } + if ( !conn.sender ) + conn.sender = findAction( name ); + } else if ( n2.tagName() == "signal" ) { + conn.signal = n2.firstChild().toText().data(); + } else if ( n2.tagName() == "receiver" ) { + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.receiver = toplevel; + } else { + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.receiver = l->first(); + delete l; + } + } + } else if ( n2.tagName() == "slot" ) { + conn.slot = n2.firstChild().toText().data(); + } + n2 = n2.nextSibling().toElement(); + } + + conn.signal = NormalizeObject::normalizeSignalSlot( conn.signal ); + conn.slot = NormalizeObject::normalizeSignalSlot( conn.slot ); + + if ( !conn.sender || !conn.receiver ) { + n = n.nextSibling().toElement(); + continue; + } + + QObject *sender = 0, *receiver = 0; + QObjectList *l = toplevel->queryList( 0, conn.sender->name(), FALSE ); + if ( qstrcmp( conn.sender->name(), toplevel->name() ) == 0 ) { + sender = toplevel; + } else { + if ( !l || !l->first() ) { + delete l; + n = n.nextSibling().toElement(); + continue; + } + sender = l->first(); + delete l; + } + if ( !sender ) + sender = findAction( conn.sender->name() ); + + if ( qstrcmp( conn.receiver->name(), toplevel->name() ) == 0 ) { + receiver = toplevel; + } else { + l = toplevel->queryList( 0, conn.receiver->name(), FALSE ); + if ( !l || !l->first() ) { + delete l; + n = n.nextSibling().toElement(); + continue; + } + receiver = l->first(); + delete l; + } + + QString s = "2""%1"; + s = s.arg( conn.signal ); + QString s2 = "1""%1"; + s2 = s2.arg( conn.slot ); + + QStrList signalList = sender->metaObject()->signalNames( TRUE ); + QStrList slotList = receiver->metaObject()->slotNames( TRUE ); + + // if this is a connection to a custom slot and we have a connector, try this as receiver + if ( slotList.find( conn.slot ) == -1 && receiver == toplevel && connector ) { + slotList = connector->metaObject()->slotNames( TRUE ); + receiver = connector; + } + + // avoid warnings + if ( signalList.find( conn.signal ) == -1 || + slotList.find( conn.slot ) == -1 ) { + n = n.nextSibling().toElement(); + continue; + } + QObject::connect( sender, s, receiver, s2 ); + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadTabOrder( const QDomElement &e ) +{ + QWidget *last = 0; + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "tabstop" ) { + QString name = n.firstChild().toText().data(); + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) { + QWidget *w = (QWidget*)l->first(); + if ( last ) + toplevel->setTabOrder( last, w ); + last = w; + } + delete l; + } + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::createListViewColumn( QListView *lv, const QString& txt, + const QPixmap& pix, bool clickable, + bool resizable ) +{ + if ( pix.isNull() ) { + lv->addColumn( txt ); + } else { + lv->addColumn( pix, txt ); + } + + int i = lv->header()->count() - 1; + if ( !pix.isNull() ) + lv->header()->setLabel( i, pix, txt ); + if ( !clickable ) + lv->header()->setClickEnabled( clickable, i ); + if ( !resizable ) + lv->header()->setResizeEnabled( resizable, i ); +} + +#ifndef QT_NO_TABLE +void QWidgetFactory::createTableColumnOrRow( QTable *table, const QString& txt, + const QPixmap& pix, + const QString& field, bool isRow ) +{ +#ifndef QT_NO_SQL + bool isSql = table->inherits( "QDataTable" ); +#endif + if ( isRow ) + table->setNumRows( table->numRows() + 1 ); + else { +#ifndef QT_NO_SQL + if ( !isSql ) +#endif + table->setNumCols( table->numCols() + 1 ); + } + + QValueList<Field> fieldMap; + if ( fieldMaps.find( table ) != fieldMaps.end() ) { + fieldMap = *fieldMaps.find( table ); + fieldMaps.remove( table ); + } + + int i = isRow ? table->numRows() - 1 : table->numCols() - 1; + QHeader *h = !isRow ? table->horizontalHeader() : table->verticalHeader(); + if ( !pix.isNull() ) { +#ifndef QT_NO_SQL + if ( isSql ) + ((QDataTable*)table)->addColumn( field, txt, -1, pix ); + else +#endif + h->setLabel( i, pix, txt ); + } else { +#ifndef QT_NO_SQL + if ( isSql ) + ((QDataTable*)table)->addColumn( field, txt ); + else +#endif + h->setLabel( i, txt ); + } + if ( !isRow && !field.isEmpty() ) { + fieldMap.append( Field( txt, pix, field ) ); + fieldMaps.insert( table, fieldMap ); + } + +} +#endif + +void QWidgetFactory::createColumn( const QDomElement &e, QWidget *widget ) +{ + if ( widget->inherits( "QListView" ) && e.tagName() == "column" ) { + QListView *lv = (QListView*)widget; + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QString txt; + bool clickable = TRUE, resizable = TRUE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = translate( v.toString() ); + else if ( attrib == "pixmap" ) + pix = loadPixmap( n.firstChild().toElement().toElement() ); + else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" || attrib == "resizeable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + createListViewColumn( lv, txt, pix, clickable, resizable ); + } +#ifndef QT_NO_TABLE + else if ( widget->inherits( "QTable" ) ) { + QTable *table = (QTable*)widget; + + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QString txt; + QString field; + + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = translate( v.toString() ); + else if ( attrib == "pixmap" ) { + if ( !n.firstChild().firstChild().toText().data().isEmpty() ) + pix = loadPixmap( n.firstChild().toElement().toElement() ); + } else if ( attrib == "field" ) + field = translate( v.toString() ); + } + n = n.nextSibling().toElement(); + } + createTableColumnOrRow( table, txt, pix, field, e.tagName() == "row" ); + } +#endif +} + +void QWidgetFactory::loadItem( const QDomElement &e, QPixmap &pix, QString &txt, bool &hasPixmap ) +{ + QDomElement n = e; + hasPixmap = 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 = translate( v.toString() ); + else if ( attrib == "pixmap" ) { + pix = loadPixmap( n.firstChild().toElement() ); + hasPixmap = !pix.isNull(); + } + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::createItem( const QDomElement &e, QWidget *widget, QListViewItem *i ) +{ + if ( widget->inherits( "QListBox" ) || widget->inherits( "QComboBox" ) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + QListBox *lb = 0; + if ( widget->inherits( "QListBox" ) ) + lb = (QListBox*)widget; + else + lb = ( (QComboBox*)widget)->listBox(); + if ( hasPixmap ) { + new QListBoxPixmap( lb, pix, txt ); + } else { + new QListBoxText( lb, txt ); + } +#ifndef QT_NO_ICONVIEW + } else if ( widget->inherits( "QIconView" ) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + + QIconView *iv = (QIconView*)widget; + new QIconViewItem( iv, txt, pix ); +#endif + } else if ( widget->inherits( "QListView" ) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QValueList<QPixmap> pixmaps; + QStringList textes; + QListViewItem *item = 0; + QListView *lv = (QListView*)widget; + if ( i ) + item = new QListViewItem( i, d->lastItem ); + else + item = new QListViewItem( lv, d->lastItem ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + textes << translate( v.toString() ); + else if ( attrib == "pixmap" ) { + QString s = v.toString(); + if ( s.isEmpty() ) { + pixmaps << QPixmap(); + } else { + pix = loadPixmap( n.firstChild().toElement() ); + pixmaps << pix; + } + } + } else if ( n.tagName() == "item" ) { + item->setOpen( TRUE ); + createItem( n, widget, item ); + } + + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < lv->columns(); ++i ) { + item->setText( i, textes[ i ] ); + item->setPixmap( i, pixmaps[ i ] ); + } + d->lastItem = item; + } +} + + + +void QWidgetFactory::loadChildAction( QObject *parent, const QDomElement &e ) +{ + QDomElement n = e; + QAction *a = 0; + bool hasMenuText = FALSE; + if ( n.tagName() == "action" ) { + a = new QAction( parent ); + QDomElement n2 = n.firstChild().toElement(); + + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QString prop(n2.attribute("name")); + if (prop == "menuText") + hasMenuText = TRUE; + setProperty( a, prop, n2.firstChild().toElement() ); + } + n2 = n2.nextSibling().toElement(); + } + if ( !parent->inherits( "QAction" ) ) + actionList.append( a ); + } else if ( n.tagName() == "actiongroup" ) { + a = new QActionGroup( parent ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QString prop(n2.attribute("name")); + if (prop == "menuText") + hasMenuText = TRUE; + setProperty( a, prop, n2.firstChild().toElement() ); + } else if ( n2.tagName() == "action" || + n2.tagName() == "actiongroup" ) { + loadChildAction( a, n2 ); + + } + n2 = n2.nextSibling().toElement(); + } + if ( !parent->inherits( "QAction" ) ) + actionList.append( a ); + } + + if (a && !hasMenuText && !a->text().isEmpty() && uiFileVersion < "3.3") + a->setMenuText(a->text()); +} + +void QWidgetFactory::loadActions( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "action" ) { + loadChildAction( toplevel, n ); + } else if ( n.tagName() == "actiongroup" ) { + loadChildAction( toplevel, n ); + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadToolBars( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = ( (QMainWindow*)toplevel ); + QToolBar *tb = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "toolbar" ) { + Qt::Dock dock = (Qt::Dock)n.attribute( "dock" ).toInt(); + tb = new QToolBar( QString::null, mw, dock ); + tb->setLabel( n.attribute( "label" ) ); + tb->setName( n.attribute( "name" ) ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "action" ) { + QAction *a = findAction( n2.attribute( "name" ) ); + if ( a ) + a->addTo( tb ); + } else if ( n2.tagName() == "separator" ) { + tb->addSeparator(); + } else if ( n2.tagName() == "widget" ) { + (void)createWidgetInternal( n2, tb, 0, n2.attribute( "class", "QWidget" ) ); + } else if ( n2.tagName() == "property" ) { + setProperty( tb, n2.attribute( "name" ), n2.firstChild().toElement() ); + } + n2 = n2.nextSibling().toElement(); + } + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadMenuBar( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = ( (QMainWindow*)toplevel ); + QMenuBar *mb = mw->menuBar(); + while ( !n.isNull() ) { + if ( n.tagName() == "item" ) { + QPopupMenu *popup = new QPopupMenu( mw ); + loadPopupMenu( popup, n ); + popup->setName( n.attribute( "name" ) ); + mb->insertItem( translate( n.attribute( "text" ) ), popup ); + } else if ( n.tagName() == "property" ) { + setProperty( mb, n.attribute( "name" ), n.firstChild().toElement() ); + } else if ( n.tagName() == "separator" ) { + mb->insertSeparator(); + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadPopupMenu( QPopupMenu *p, const QDomElement &e ) +{ + QMainWindow *mw = ( (QMainWindow*)toplevel ); + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "action" ) { + QAction *a = findAction( n.attribute( "name" ) ); + QDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item") { // load submenu + QPopupMenu *popup = new QPopupMenu( mw ); + popup->setName( n2.attribute( "name" ) ); + if ( a ) { + p->setAccel( a->accel(), p->insertItem( a->iconSet(), + translate( n2.attribute( "text" ).utf8().data() ), + popup ) ); + } else { + p->insertItem( translate( n2.attribute( "text" ).utf8().data() ), popup ); + } + loadPopupMenu( popup, n2 ); + n = n2; + } else { + if ( a ) { + a->addTo( p ); + } + } + a = 0; + } else if ( n.tagName() == "separator" ) { + p->insertSeparator(); + } + n = n.nextSibling().toElement(); + } +} + +// compatibility with early 3.0 betas +// ### remove for 4.0 +void QWidgetFactory::loadFunctions( const QDomElement & ) +{ +} + +QAction *QWidgetFactory::findAction( const QString &name ) +{ + for ( QAction *a = actionList.first(); a; a = actionList.next() ) { + if ( QString( a->name() ) == name ) + return a; + QAction *ac = (QAction*)a->child( name.latin1(), "QAction" ); + if ( ac ) + return ac; + } + return 0; +} + +/*! + If you use a pixmap collection (which is the default for new + projects) rather than saving the pixmaps within the .ui XML file, + you must load the pixmap collection. QWidgetFactory looks in the + default QMimeSourceFactory for the pixmaps. Either add it there + manually, or call this function and specify the directory where + the images can be found, as \a dir. This is normally the + directory called \c images in the project's directory. +*/ + +void QWidgetFactory::loadImages( const QString &dir ) +{ + QDir d( dir ); + QStringList l = d.entryList( QDir::Files ); + for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) + QMimeSourceFactory::defaultFactory()->setPixmap( *it, QPixmap( d.path() + "/" + *it, "PNG" ) ); + +} + +void QWidgetFactory::loadExtraSource() +{ + if ( !qwf_language || !languageInterfaceManager ) + return; + QString lang = *qwf_language; + LanguageInterface *iface = 0; + languageInterfaceManager->queryInterface( lang, &iface ); + if ( !iface ) + return; + QFile f( qwf_currFileName + iface->formCodeExtension() ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + code = ts.read(); + } +} + +QString QWidgetFactory::translate( const QString& sourceText, const QString& comment ) +{ + return qApp->translate( d->translationContext, sourceText.utf8(), comment.utf8(), + QApplication::UnicodeUTF8 ); +} + +QString QWidgetFactory::translate( const char *sourceText, const char *comment ) +{ + return qApp->translate( d->translationContext, sourceText, comment, + QApplication::UnicodeUTF8 ); +} diff --git a/kdevdesigner/uilib/qwidgetfactory.h b/kdevdesigner/uilib/qwidgetfactory.h new file mode 100644 index 00000000..9146e9a7 --- /dev/null +++ b/kdevdesigner/uilib/qwidgetfactory.h @@ -0,0 +1,180 @@ +/********************************************************************** +** 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 QWIDGETFACTORY_H +#define QWIDGETFACTORY_H + +#ifndef QT_H +#include <qstring.h> +#include <qptrlist.h> +#include <qimage.h> +#include <qpixmap.h> +#include <qvaluelist.h> +#include <qmap.h> +#include <qaction.h> +#endif // QT_H + +class QDomDocument; +class QDomElement; +class QLayout; +class QListView; +class QListViewItem; +class QMenuBar; +class QTable; +class QWidget; +class QWidgetFactoryPrivate; +class UibStrTable; + +class QWidgetFactory +{ +public: + QWidgetFactory(); + virtual ~QWidgetFactory(); + + static QWidget *create( const QString &uiFile, QObject *connector = 0, QWidget *parent = 0, const char *name = 0 ); + static QWidget *create( QIODevice *dev, QObject *connector = 0, QWidget *parent = 0, const char *name = 0 ); + static void addWidgetFactory( QWidgetFactory *factory ); + static void loadImages( const QString &dir ); + + virtual QWidget *createWidget( const QString &className, QWidget *parent, const char *name ) const; + static QStringList widgets(); + static bool supportsWidget( const QString &widget ); + +private: + enum LayoutType { HBox, VBox, Grid, NoLayout }; + void loadImageCollection( const QDomElement &e ); + void loadConnections( const QDomElement &e, QObject *connector ); + void loadTabOrder( const QDomElement &e ); + QWidget *createWidgetInternal( const QDomElement &e, QWidget *parent, QLayout* layout, const QString &classNameArg ); + QLayout *createLayout( QWidget *widget, QLayout* layout, LayoutType type, bool isQLayoutWidget = FALSE ); + LayoutType layoutType( QLayout *l ) const; + void setProperty( QObject* widget, const QString &prop, QVariant value ); + void setProperty( QObject* widget, const QString &prop, const QDomElement &e ); + void createSpacer( const QDomElement &e, QLayout *layout ); + QImage loadFromCollection( const QString &name ); + QPixmap loadPixmap( const QString &name ); + QPixmap loadPixmap( const QDomElement &e ); + QColorGroup loadColorGroup( const QDomElement &e ); + void createListViewColumn( QListView *lv, const QString& txt, + const QPixmap& pix, bool clickable, + bool resizable ); +#ifndef QT_NO_TABLE + void createTableColumnOrRow( QTable *table, const QString& txt, + const QPixmap& pix, const QString& field, + bool isRow ); +#endif + void createColumn( const QDomElement &e, QWidget *widget ); + void loadItem( const QDomElement &e, QPixmap &pix, QString &txt, bool &hasPixmap ); + void createItem( const QDomElement &e, QWidget *widget, QListViewItem *i = 0 ); + void loadChildAction( QObject *parent, const QDomElement &e ); + void loadActions( const QDomElement &e ); + void loadToolBars( const QDomElement &e ); + void loadMenuBar( const QDomElement &e ); + void loadPopupMenu( QPopupMenu *p, const QDomElement &e ); + void loadFunctions( const QDomElement &e ); + QAction *findAction( const QString &name ); + void loadExtraSource(); + QString translate( const char *sourceText, const char *comment = "" ); + QString translate( const QString& sourceText, const QString& comment = QString::null ); + + void unpackUInt16( QDataStream& in, Q_UINT16& n ); + void unpackUInt32( QDataStream& in, Q_UINT32& n ); + void unpackByteArray( QDataStream& in, QByteArray& array ); + void unpackCString( const UibStrTable& strings, QDataStream& in, + QCString& cstr ); + void unpackString( const UibStrTable& strings, QDataStream& in, + QString& str ); + void unpackStringSplit( const UibStrTable& strings, QDataStream& in, + QString& str ); + void unpackVariant( const UibStrTable& strings, QDataStream& in, + QVariant& value ); + void inputSpacer( const UibStrTable& strings, QDataStream& in, + QLayout *parent ); + void inputColumnOrRow( const UibStrTable& strings, QDataStream& in, + QObject *parent, bool isRow ); + void inputItem( const UibStrTable& strings, QDataStream& in, + QObject *parent, QListViewItem *parentItem = 0 ); + void inputMenuItem( QObject **objects, const UibStrTable& strings, + QDataStream& in, QMenuBar *menuBar ); + QObject *inputObject( QObject **objects, int& numObjects, + const UibStrTable& strings, QDataStream& in, + QWidget *ancestorWidget, QObject *parent, + QCString className = "" ); + QWidget *createFromUiFile( QDomDocument doc, QObject *connector, + QWidget *parent, const char *name ); + QWidget *createFromUibFile( QDataStream& in, QObject *connector, + QWidget *parent, const char *name ); + +private: + struct Image { + QImage img; + QString name; + bool operator==( const Image &i ) const { + return ( i.name == name && + i.img == img ); + } + }; + + struct Field + { + Field() {} + Field( const QString &s1, const QPixmap &p, const QString &s2 ) : name( s1 ), pix( p ), field( s2 ) {} + QString name; + QPixmap pix; + QString field; + Q_DUMMY_COMPARISON_OPERATOR( Field ) + }; + + struct SqlWidgetConnection + { + SqlWidgetConnection() {} + SqlWidgetConnection( const QString &c, const QString &t ) + : conn( c ), table( t ), dbControls( new QMap<QString, QString>() ) {} + QString conn; + QString table; + QMap<QString, QString> *dbControls; + Q_DUMMY_COMPARISON_OPERATOR( SqlWidgetConnection ) + }; + + QValueList<Image> images; + QWidget *toplevel; + QWidgetFactoryPrivate *d; + QMap<QString, QString> *dbControls; + QMap<QString, QStringList> dbTables; + QMap<QWidget*, SqlWidgetConnection> sqlWidgetConnections; + QMap<QString, QString> buddies; + QMap<QTable*, QValueList<Field> > fieldMaps; + QPtrList<QAction> actionList; + QMap<QString, QString> languageSlots; + QStringList noDatabaseWidgets; + bool usePixmapCollection; + int defMargin; + int defSpacing; + QString code; + QString uiFileVersion; +}; + +#endif |