summaryrefslogtreecommitdiffstats
path: root/tools/designer/src/components/formeditor
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:34:13 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:34:13 (GMT)
commit67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch)
tree1dbf50b3dff8d5ca7e9344733968c72704eb15ff /tools/designer/src/components/formeditor
downloadQt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2
Long live Qt!
Diffstat (limited to 'tools/designer/src/components/formeditor')
-rw-r--r--tools/designer/src/components/formeditor/brushmanagerproxy.cpp305
-rw-r--r--tools/designer/src/components/formeditor/brushmanagerproxy.h77
-rw-r--r--tools/designer/src/components/formeditor/default_actionprovider.cpp208
-rw-r--r--tools/designer/src/components/formeditor/default_actionprovider.h131
-rw-r--r--tools/designer/src/components/formeditor/default_container.cpp173
-rw-r--r--tools/designer/src/components/formeditor/default_container.h213
-rw-r--r--tools/designer/src/components/formeditor/default_layoutdecoration.cpp79
-rw-r--r--tools/designer/src/components/formeditor/default_layoutdecoration.h69
-rw-r--r--tools/designer/src/components/formeditor/defaultbrushes.xml542
-rw-r--r--tools/designer/src/components/formeditor/deviceprofiledialog.cpp203
-rw-r--r--tools/designer/src/components/formeditor/deviceprofiledialog.h104
-rw-r--r--tools/designer/src/components/formeditor/deviceprofiledialog.ui100
-rw-r--r--tools/designer/src/components/formeditor/dpi_chooser.cpp207
-rw-r--r--tools/designer/src/components/formeditor/dpi_chooser.h94
-rw-r--r--tools/designer/src/components/formeditor/embeddedoptionspage.cpp453
-rw-r--r--tools/designer/src/components/formeditor/embeddedoptionspage.h103
-rw-r--r--tools/designer/src/components/formeditor/formeditor.cpp203
-rw-r--r--tools/designer/src/components/formeditor/formeditor.h69
-rw-r--r--tools/designer/src/components/formeditor/formeditor.pri75
-rw-r--r--tools/designer/src/components/formeditor/formeditor.qrc173
-rw-r--r--tools/designer/src/components/formeditor/formeditor_global.h57
-rw-r--r--tools/designer/src/components/formeditor/formeditor_optionspage.cpp189
-rw-r--r--tools/designer/src/components/formeditor/formeditor_optionspage.h79
-rw-r--r--tools/designer/src/components/formeditor/formwindow.cpp2917
-rw-r--r--tools/designer/src/components/formeditor/formwindow.h385
-rw-r--r--tools/designer/src/components/formeditor/formwindow_dnditem.cpp116
-rw-r--r--tools/designer/src/components/formeditor/formwindow_dnditem.h65
-rw-r--r--tools/designer/src/components/formeditor/formwindow_widgetstack.cpp213
-rw-r--r--tools/designer/src/components/formeditor/formwindow_widgetstack.h103
-rw-r--r--tools/designer/src/components/formeditor/formwindowcursor.cpp211
-rw-r--r--tools/designer/src/components/formeditor/formwindowcursor.h93
-rw-r--r--tools/designer/src/components/formeditor/formwindowmanager.cpp1016
-rw-r--r--tools/designer/src/components/formeditor/formwindowmanager.h200
-rw-r--r--tools/designer/src/components/formeditor/formwindowsettings.cpp282
-rw-r--r--tools/designer/src/components/formeditor/formwindowsettings.h85
-rw-r--r--tools/designer/src/components/formeditor/formwindowsettings.ui328
-rw-r--r--tools/designer/src/components/formeditor/iconcache.cpp121
-rw-r--r--tools/designer/src/components/formeditor/iconcache.h78
-rw-r--r--tools/designer/src/components/formeditor/images/color.pngbin0 -> 117 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/configure.pngbin0 -> 1016 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/arrow.pngbin0 -> 171 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/busy.pngbin0 -> 201 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/closedhand.pngbin0 -> 147 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/cross.pngbin0 -> 130 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/hand.pngbin0 -> 159 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/hsplit.pngbin0 -> 155 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/ibeam.pngbin0 -> 124 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/no.pngbin0 -> 199 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/openhand.pngbin0 -> 160 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/sizeall.pngbin0 -> 174 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/sizeb.pngbin0 -> 161 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/sizef.pngbin0 -> 161 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/sizeh.pngbin0 -> 145 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/sizev.pngbin0 -> 141 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/uparrow.pngbin0 -> 132 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/vsplit.pngbin0 -> 161 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/wait.pngbin0 -> 172 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/cursors/whatsthis.pngbin0 -> 191 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/downplus.pngbin0 -> 562 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/dropdownbutton.pngbin0 -> 527 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/edit.pngbin0 -> 929 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/editdelete-16.pngbin0 -> 553 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/emptyicon.pngbin0 -> 108 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/filenew-16.pngbin0 -> 454 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/fileopen-16.pngbin0 -> 549 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/leveldown.pngbin0 -> 557 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/levelup.pngbin0 -> 564 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/adjustsize.pngbin0 -> 1929 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/back.pngbin0 -> 678 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/buddytool.pngbin0 -> 2046 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/down.pngbin0 -> 594 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editbreaklayout.pngbin0 -> 2067 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editcut.pngbin0 -> 1512 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editdelete.pngbin0 -> 1097 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editform.pngbin0 -> 621 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editgrid.pngbin0 -> 751 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/edithlayout.pngbin0 -> 1395 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/edithlayoutsplit.pngbin0 -> 1188 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editlower.pngbin0 -> 595 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editpaste.pngbin0 -> 1906 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editraise.pngbin0 -> 1213 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editvlayout.pngbin0 -> 586 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/editvlayoutsplit.pngbin0 -> 872 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/filenew.pngbin0 -> 772 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/fileopen.pngbin0 -> 904 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/filesave.pngbin0 -> 1206 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/forward.pngbin0 -> 655 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/insertimage.pngbin0 -> 1280 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/minus.pngbin0 -> 488 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/plus.pngbin0 -> 810 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/redo.pngbin0 -> 1752 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/resetproperty.pngbin0 -> 169 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/resourceeditortool.pngbin0 -> 2171 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/signalslottool.pngbin0 -> 1989 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/tabordertool.pngbin0 -> 1963 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textanchor.pngbin0 -> 2543 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textbold.pngbin0 -> 1611 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textcenter.pngbin0 -> 1404 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textitalic.pngbin0 -> 1164 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textjustify.pngbin0 -> 1257 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textleft.pngbin0 -> 1235 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textright.pngbin0 -> 1406 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textsubscript.pngbin0 -> 1054 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textsuperscript.pngbin0 -> 1109 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/textunder.pngbin0 -> 1183 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/undo.pngbin0 -> 1746 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/up.pngbin0 -> 692 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/mac/widgettool.pngbin0 -> 1874 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/minus-16.pngbin0 -> 296 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/plus-16.pngbin0 -> 383 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/prefix-add.pngbin0 -> 411 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/qt3logo.pngbin0 -> 1101 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/qtlogo.pngbin0 -> 825 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/reload.pngbin0 -> 1363 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/resetproperty.pngbin0 -> 169 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/sort.pngbin0 -> 563 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/submenu.pngbin0 -> 179 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/calendarwidget.pngbin0 -> 968 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/checkbox.pngbin0 -> 817 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/columnview.pngbin0 -> 518 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/combobox.pngbin0 -> 853 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/commandlinkbutton.pngbin0 -> 1208 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/dateedit.pngbin0 -> 672 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/datetimeedit.pngbin0 -> 1132 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/dial.pngbin0 -> 978 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/dialogbuttonbox.pngbin0 -> 1003 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/dockwidget.pngbin0 -> 638 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/doublespinbox.pngbin0 -> 749 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/fontcombobox.pngbin0 -> 966 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/frame.pngbin0 -> 721 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/graphicsview.pngbin0 -> 1182 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/groupbox.pngbin0 -> 439 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/groupboxcollapsible.pngbin0 -> 702 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/hscrollbar.pngbin0 -> 408 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/hslider.pngbin0 -> 729 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/hsplit.pngbin0 -> 164 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/label.pngbin0 -> 953 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/lcdnumber.pngbin0 -> 555 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/line.pngbin0 -> 287 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/lineedit.pngbin0 -> 405 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/listbox.pngbin0 -> 797 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/listview.pngbin0 -> 756 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/mdiarea.pngbin0 -> 643 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/plaintextedit.pngbin0 -> 807 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/progress.pngbin0 -> 559 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/pushbutton.pngbin0 -> 408 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/radiobutton.pngbin0 -> 586 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/scrollarea.pngbin0 -> 548 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/spacer.pngbin0 -> 686 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/spinbox.pngbin0 -> 680 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/tabbar.pngbin0 -> 623 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/table.pngbin0 -> 483 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/tabwidget.pngbin0 -> 572 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/textedit.pngbin0 -> 823 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/timeedit.pngbin0 -> 1353 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/toolbox.pngbin0 -> 783 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/toolbutton.pngbin0 -> 1167 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/vline.pngbin0 -> 314 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/vscrollbar.pngbin0 -> 415 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/vslider.pngbin0 -> 726 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/vspacer.pngbin0 -> 677 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/widget.pngbin0 -> 716 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/widgetstack.pngbin0 -> 828 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/widgets/wizard.pngbin0 -> 898 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/adjustsize.pngbin0 -> 1262 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/back.pngbin0 -> 678 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/buddytool.pngbin0 -> 997 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/down.pngbin0 -> 594 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editbreaklayout.pngbin0 -> 1321 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editcut.pngbin0 -> 1384 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editdelete.pngbin0 -> 850 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editform.pngbin0 -> 349 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editgrid.pngbin0 -> 349 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/edithlayout.pngbin0 -> 455 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/edithlayoutsplit.pngbin0 -> 860 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editlower.pngbin0 -> 1038 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editpaste.pngbin0 -> 1482 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editraise.pngbin0 -> 1045 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editvlayout.pngbin0 -> 340 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/editvlayoutsplit.pngbin0 -> 740 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/filenew.pngbin0 -> 768 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/fileopen.pngbin0 -> 1662 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/filesave.pngbin0 -> 1205 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/forward.pngbin0 -> 655 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/insertimage.pngbin0 -> 885 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/minus.pngbin0 -> 429 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/plus.pngbin0 -> 709 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/redo.pngbin0 -> 1212 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/resourceeditortool.pngbin0 -> 1429 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/signalslottool.pngbin0 -> 1128 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/tabordertool.pngbin0 -> 1205 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textanchor.pngbin0 -> 1581 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textbold.pngbin0 -> 1134 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textcenter.pngbin0 -> 627 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textitalic.pngbin0 -> 829 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textjustify.pngbin0 -> 695 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textleft.pngbin0 -> 673 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textright.pngbin0 -> 677 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textsubscript.pngbin0 -> 897 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textsuperscript.pngbin0 -> 864 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/textunder.pngbin0 -> 971 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/undo.pngbin0 -> 1181 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/up.pngbin0 -> 692 bytes
-rw-r--r--tools/designer/src/components/formeditor/images/win/widgettool.pngbin0 -> 1039 bytes
-rw-r--r--tools/designer/src/components/formeditor/itemview_propertysheet.cpp291
-rw-r--r--tools/designer/src/components/formeditor/itemview_propertysheet.h88
-rw-r--r--tools/designer/src/components/formeditor/layout_propertysheet.cpp546
-rw-r--r--tools/designer/src/components/formeditor/layout_propertysheet.h82
-rw-r--r--tools/designer/src/components/formeditor/line_propertysheet.cpp86
-rw-r--r--tools/designer/src/components/formeditor/line_propertysheet.h71
-rw-r--r--tools/designer/src/components/formeditor/previewactiongroup.cpp149
-rw-r--r--tools/designer/src/components/formeditor/previewactiongroup.h90
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.cpp2665
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.h182
-rw-r--r--tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp83
-rw-r--r--tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.h72
-rw-r--r--tools/designer/src/components/formeditor/qmainwindow_container.cpp199
-rw-r--r--tools/designer/src/components/formeditor/qmainwindow_container.h81
-rw-r--r--tools/designer/src/components/formeditor/qmdiarea_container.cpp280
-rw-r--r--tools/designer/src/components/formeditor/qmdiarea_container.h119
-rw-r--r--tools/designer/src/components/formeditor/qtbrushmanager.cpp143
-rw-r--r--tools/designer/src/components/formeditor/qtbrushmanager.h89
-rw-r--r--tools/designer/src/components/formeditor/qwizard_container.cpp226
-rw-r--r--tools/designer/src/components/formeditor/qwizard_container.h123
-rw-r--r--tools/designer/src/components/formeditor/qworkspace_container.cpp100
-rw-r--r--tools/designer/src/components/formeditor/qworkspace_container.h79
-rw-r--r--tools/designer/src/components/formeditor/spacer_propertysheet.cpp82
-rw-r--r--tools/designer/src/components/formeditor/spacer_propertysheet.h72
-rw-r--r--tools/designer/src/components/formeditor/templateoptionspage.cpp183
-rw-r--r--tools/designer/src/components/formeditor/templateoptionspage.h110
-rw-r--r--tools/designer/src/components/formeditor/templateoptionspage.ui59
-rw-r--r--tools/designer/src/components/formeditor/tool_widgeteditor.cpp363
-rw-r--r--tools/designer/src/components/formeditor/tool_widgeteditor.h107
-rw-r--r--tools/designer/src/components/formeditor/widgetselection.cpp746
-rw-r--r--tools/designer/src/components/formeditor/widgetselection.h145
237 files changed, 17830 insertions, 0 deletions
diff --git a/tools/designer/src/components/formeditor/brushmanagerproxy.cpp b/tools/designer/src/components/formeditor/brushmanagerproxy.cpp
new file mode 100644
index 0000000..b1c056e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/brushmanagerproxy.cpp
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbrushmanager.h"
+#include "brushmanagerproxy.h"
+#include "qsimpleresource_p.h"
+#include "qdesigner_utils_p.h"
+#include "ui4_p.h"
+
+#include <QtXml/QXmlStreamWriter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class BrushManagerProxyPrivate
+{
+ BrushManagerProxy *q_ptr;
+ Q_DECLARE_PUBLIC(BrushManagerProxy)
+
+public:
+ BrushManagerProxyPrivate(BrushManagerProxy *bp, QDesignerFormEditorInterface *core);
+ void brushAdded(const QString &name, const QBrush &brush);
+ void brushRemoved(const QString &name);
+ QString uniqueBrushFileName(const QString &brushName) const;
+
+ QtBrushManager *m_Manager;
+ QString m_designerFolder;
+ const QString m_BrushFolder;
+ QString m_BrushPath;
+ QDesignerFormEditorInterface *m_Core;
+ QMap<QString, QString> m_FileToBrush;
+ QMap<QString, QString> m_BrushToFile;
+};
+
+BrushManagerProxyPrivate::BrushManagerProxyPrivate(BrushManagerProxy *bp, QDesignerFormEditorInterface *core) :
+ q_ptr(bp),
+ m_Manager(0),
+ m_BrushFolder(QLatin1String("brushes")),
+ m_Core(core)
+{
+ m_designerFolder = QDir::homePath();
+ m_designerFolder += QDir::separator();
+ m_designerFolder += QLatin1String(".designer");
+ m_BrushPath = m_designerFolder;
+ m_BrushPath += QDir::separator();
+ m_BrushPath += m_BrushFolder;
+}
+} // namespace qdesigner_internal
+
+using namespace qdesigner_internal;
+
+void BrushManagerProxyPrivate::brushAdded(const QString &name, const QBrush &brush)
+{
+ const QString filename = uniqueBrushFileName(name);
+
+ QDir designerDir(m_designerFolder);
+ if (!designerDir.exists(m_BrushFolder))
+ designerDir.mkdir(m_BrushFolder);
+
+ QFile file(m_BrushPath + QDir::separator() +filename);
+ if (file.open(QIODevice::WriteOnly)) {
+ QSimpleResource resource(m_Core);
+
+ DomBrush *dom = resource.saveBrush(brush);
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ writer.writeStartElement(QLatin1String("description"));
+ writer.writeAttribute(QLatin1String("name"), name);
+ dom->write(writer);
+ writer.writeEndElement();
+ writer.writeEndDocument();
+
+ delete dom;
+ file.close();
+
+ m_FileToBrush[filename] = name;
+ m_BrushToFile[name] = filename;
+ }
+}
+
+void BrushManagerProxyPrivate::brushRemoved(const QString &name)
+{
+ QDir brushDir(m_BrushPath);
+
+ QString filename = m_BrushToFile[name];
+ brushDir.remove(filename);
+ m_BrushToFile.remove(name);
+ m_FileToBrush.remove(filename);
+}
+
+QString BrushManagerProxyPrivate::uniqueBrushFileName(const QString &brushName) const
+{
+ const QString extension = QLatin1String(".br");
+ QString filename = brushName.toLower();
+ filename += extension;
+ int i = 0;
+ while (m_FileToBrush.contains(filename)) {
+ filename = brushName.toLower();
+ filename += QString::number(++i);
+ filename += extension;
+ }
+ return filename;
+}
+
+
+BrushManagerProxy::BrushManagerProxy(QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent)
+{
+ d_ptr = new BrushManagerProxyPrivate(this, core);
+}
+
+BrushManagerProxy::~BrushManagerProxy()
+{
+ delete d_ptr;
+}
+
+void BrushManagerProxy::setBrushManager(QtBrushManager *manager)
+{
+ if (d_ptr->m_Manager == manager)
+ return;
+
+ if (d_ptr->m_Manager) {
+ disconnect(d_ptr->m_Manager, SIGNAL(brushAdded(const QString &, const QBrush &)),
+ this, SLOT(brushAdded(const QString &, const QBrush &)));
+ disconnect(d_ptr->m_Manager, SIGNAL(brushRemoved(const QString &)),
+ this, SLOT(brushRemoved(const QString &)));
+ }
+
+ d_ptr->m_Manager = manager;
+
+ if (!d_ptr->m_Manager)
+ return;
+
+ // clear the manager
+ QMap<QString, QBrush> brushes = d_ptr->m_Manager->brushes();
+ QMap<QString, QBrush>::ConstIterator it = brushes.constBegin();
+ while (it != brushes.constEnd()) {
+ QString name = it.key();
+ d_ptr->m_Manager->removeBrush(name);
+
+ it++;
+ }
+
+ // fill up the manager from compiled resources or from brush folder here
+ const QString nameAttribute = QLatin1String("name");
+ const QString brush = QLatin1String("brush");
+ const QString description = QLatin1String("description");
+
+ QDir brushDir(d_ptr->m_BrushPath);
+ bool customBrushesExist = brushDir.exists();
+ if (customBrushesExist) {
+ // load brushes from brush folder
+ QStringList nameFilters;
+ nameFilters.append(QLatin1String("*.br"));
+
+ QFileInfoList infos = brushDir.entryInfoList(nameFilters);
+ QListIterator<QFileInfo> it(infos);
+ while (it.hasNext()) {
+ const QFileInfo fi = it.next();
+
+ QString filename = fi.absoluteFilePath();
+
+ QFile file(filename);
+ if (file.open(QIODevice::ReadOnly)) {
+ QXmlStreamReader reader(&file);
+
+ //<description name="black" >
+ // <brush brushstyle="SolidPattern" >
+ // <color alpha="255" .../>
+ // </brush>
+ //</description>
+
+ QString descname;
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ const QString tag = reader.name().toString().toLower();
+ if (tag == description) {
+ if (!reader.attributes().hasAttribute(nameAttribute))
+ reader.raiseError(tr("The element '%1' is missing the required attribute '%2'.")
+ .arg(tag, nameAttribute));
+ else
+ descname = reader.attributes().value(nameAttribute).toString();
+ continue;
+ }
+ if (tag == brush) {
+ DomBrush brush;
+ brush.read(reader);
+
+ if (descname.isEmpty()) {
+ reader.raiseError(tr("Empty brush name encountered."));
+ } else {
+ QSimpleResource resource(d_ptr->m_Core);
+ QBrush br = resource.setupBrush(&brush);
+ d_ptr->m_Manager->addBrush(descname, br);
+ d_ptr->m_FileToBrush[filename] = descname;
+ d_ptr->m_BrushToFile[descname] = filename;
+ }
+ continue;
+ }
+ reader.raiseError(tr("An unexpected element '%1' was encountered.").arg(tag));
+ }
+ }
+
+ file.close();
+
+ if (reader.hasError()) {
+ qdesigner_internal::designerWarning(tr("An error occurred when reading the brush definition file '%1' at line line %2, column %3: %4")
+ .arg(fi.fileName())
+ .arg(reader.lineNumber())
+ .arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ continue;
+ }
+ }
+ }
+ }
+
+ connect(d_ptr->m_Manager, SIGNAL(brushAdded(QString,QBrush)),
+ this, SLOT(brushAdded(QString, QBrush)));
+ connect(d_ptr->m_Manager, SIGNAL(brushRemoved(QString)),
+ this, SLOT(brushRemoved(QString)));
+
+ if (!customBrushesExist) {
+ // load brushes from resources
+ QFile qrcFile(QLatin1String(":trolltech/brushes/defaultbrushes.xml"));
+ if (!qrcFile.open(QIODevice::ReadOnly))
+ Q_ASSERT(0);
+
+ QXmlStreamReader reader(&qrcFile);
+
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().toString().toLower() == QLatin1String("description")) {
+ const QString name = reader.attributes().value(nameAttribute).toString();
+ do { // forward to <brush> element, which DomBrush expects
+ reader.readNext();
+ } while (!reader.atEnd() && reader.tokenType() != QXmlStreamReader::StartElement);
+ DomBrush brushDom;
+ brushDom.read(reader);
+ if (!reader.hasError()) {
+ QSimpleResource resource(d_ptr->m_Core);
+ QBrush br = resource.setupBrush(&brushDom);
+ d_ptr->m_Manager->addBrush(name, br);
+ }
+ }
+ }
+ }
+ if (reader.hasError()) {
+ // Should never happen
+ qdesigner_internal::designerWarning(tr("An error occurred when reading the resource file '%1' at line %2, column %3: %4")
+ .arg(qrcFile.fileName())
+ .arg(reader.lineNumber())
+ .arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ }
+
+ qrcFile.close();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_brushmanagerproxy.cpp"
diff --git a/tools/designer/src/components/formeditor/brushmanagerproxy.h b/tools/designer/src/components/formeditor/brushmanagerproxy.h
new file mode 100644
index 0000000..cbe50ae
--- /dev/null
+++ b/tools/designer/src/components/formeditor/brushmanagerproxy.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BRUSHMANAGERPROXY_H
+#define BRUSHMANAGERPROXY_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class QtBrushManager;
+class BrushManagerProxyPrivate;
+
+class BrushManagerProxy : public QObject
+{
+ Q_OBJECT
+public:
+ explicit BrushManagerProxy(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ ~BrushManagerProxy();
+
+ void setBrushManager(QtBrushManager *manager);
+
+private:
+ BrushManagerProxyPrivate *d_ptr;
+ Q_DECLARE_PRIVATE(BrushManagerProxy)
+ Q_DISABLE_COPY(BrushManagerProxy)
+ Q_PRIVATE_SLOT(d_func(), void brushAdded(const QString &, const QBrush &))
+ Q_PRIVATE_SLOT(d_func(), void brushRemoved(const QString &name))
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/designer/src/components/formeditor/default_actionprovider.cpp b/tools/designer/src/components/formeditor/default_actionprovider.cpp
new file mode 100644
index 0000000..49bf095
--- /dev/null
+++ b/tools/designer/src/components/formeditor/default_actionprovider.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "default_actionprovider.h"
+#include "invisible_widget_p.h"
+#include "qdesigner_toolbar_p.h"
+
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtCore/QRect>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------ ActionProviderBase:
+// Draws the drag indicator when dragging an action over a widget
+// that receives action Dnd, such as ToolBar, Menu or MenuBar.
+ActionProviderBase::ActionProviderBase(QWidget *widget) :
+ m_indicator(new InvisibleWidget(widget))
+{
+ Q_ASSERT(widget != 0);
+
+ m_indicator->setAutoFillBackground(true);
+ m_indicator->setBackgroundRole(QPalette::Window);
+
+ QPalette p;
+ p.setColor(m_indicator->backgroundRole(), Qt::red);
+ m_indicator->setPalette(p);
+ m_indicator->hide();
+}
+
+enum { indicatorSize = 2 };
+
+// Position an indicator horizontally over the rectangle, indicating
+// 'Insert before' (left or right according to layout direction)
+static inline QRect horizontalIndicatorRect(const QRect &rect)
+{
+ const Qt::LayoutDirection layoutDirection = QApplication::layoutDirection();
+ // Position right?
+ QRect rc = QRect(rect.x(), 0, indicatorSize, rect.height() - 1);
+ if (layoutDirection == Qt::RightToLeft)
+ rc.moveLeft(rc.x() + rect.width() - indicatorSize);
+ return rc;
+}
+
+// Position an indicator vertically over the rectangle, indicating 'Insert before' (top)
+static inline QRect verticalIndicatorRect(const QRect &rect)
+{
+ return QRect(0, rect.top(), rect.width() - 1, indicatorSize);
+}
+
+// Determine the geometry of the indicator by retrieving
+// the action under mouse and positioning the bar within its geometry.
+QRect ActionProviderBase::indicatorGeometry(const QPoint &pos) const
+{
+ QAction *action = actionAt(pos);
+ if (!action)
+ return QRect();
+ QRect rc = actionGeometry(action);
+ return orientation() == Qt::Horizontal ? horizontalIndicatorRect(rc) : verticalIndicatorRect(rc);
+}
+
+// Adjust the indicator while dragging. (-1,1) is called to finish a DND operation
+void ActionProviderBase::adjustIndicator(const QPoint &pos)
+{
+ if (pos == QPoint(-1, -1)) {
+ m_indicator->hide();
+ return;
+ }
+ const QRect ig = indicatorGeometry(pos);
+ if (ig.isValid()) {
+ m_indicator->setGeometry(ig);
+ QPalette p = m_indicator->palette();
+ if (p.color(m_indicator->backgroundRole()) != Qt::red) {
+ p.setColor(m_indicator->backgroundRole(), Qt::red);
+ m_indicator->setPalette(p);
+ }
+ m_indicator->show();
+ m_indicator->raise();
+ } else {
+ m_indicator->hide();
+ }
+}
+
+// ------------- QToolBarActionProvider
+QToolBarActionProvider::QToolBarActionProvider(QToolBar *widget, QObject *parent) :
+ QObject(parent),
+ ActionProviderBase(widget),
+ m_widget(widget)
+{
+}
+
+QRect QToolBarActionProvider::actionGeometry(QAction *action) const
+{
+ return m_widget->actionGeometry(action);
+}
+
+QAction *QToolBarActionProvider::actionAt(const QPoint &pos) const
+{
+ return ToolBarEventFilter::actionAt(m_widget, pos);
+}
+
+Qt::Orientation QToolBarActionProvider::orientation() const
+{
+ return m_widget->orientation();
+}
+
+QRect QToolBarActionProvider::indicatorGeometry(const QPoint &pos) const
+{
+ const QRect actionRect = ActionProviderBase::indicatorGeometry(pos);
+ if (actionRect.isValid())
+ return actionRect;
+ // Toolbar differs in that is has no dummy placeholder to 'insert before'
+ // when intending to append. Check the free area.
+ const QRect freeArea = ToolBarEventFilter::freeArea(m_widget);
+ if (!freeArea.contains(pos))
+ return QRect();
+ return orientation() == Qt::Horizontal ? horizontalIndicatorRect(freeArea) : verticalIndicatorRect(freeArea);
+}
+
+// ------------- QMenuBarActionProvider
+QMenuBarActionProvider::QMenuBarActionProvider(QMenuBar *widget, QObject *parent) :
+ QObject(parent),
+ ActionProviderBase(widget),
+ m_widget(widget)
+{
+}
+
+QRect QMenuBarActionProvider::actionGeometry(QAction *action) const
+{
+ return m_widget->actionGeometry(action);
+}
+
+QAction *QMenuBarActionProvider::actionAt(const QPoint &pos) const
+{
+ return m_widget->actionAt(pos);
+}
+
+Qt::Orientation QMenuBarActionProvider::orientation() const
+{
+ return Qt::Horizontal;
+}
+
+// ------------- QMenuActionProvider
+QMenuActionProvider::QMenuActionProvider(QMenu *widget, QObject *parent) :
+ QObject(parent),
+ ActionProviderBase(widget),
+ m_widget(widget)
+{
+}
+
+QRect QMenuActionProvider::actionGeometry(QAction *action) const
+{
+ return m_widget->actionGeometry(action);
+}
+
+QAction *QMenuActionProvider::actionAt(const QPoint &pos) const
+{
+ return m_widget->actionAt(pos);
+}
+
+Qt::Orientation QMenuActionProvider::orientation() const
+{
+ return Qt::Vertical;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/default_actionprovider.h b/tools/designer/src/components/formeditor/default_actionprovider.h
new file mode 100644
index 0000000..6c81ec6
--- /dev/null
+++ b/tools/designer/src/components/formeditor/default_actionprovider.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_ACTIONPROVIDER_H
+#define DEFAULT_ACTIONPROVIDER_H
+
+#include "formeditor_global.h"
+#include "actionprovider_p.h"
+#include <extensionfactory_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QToolBar>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class FormWindow;
+
+class QT_FORMEDITOR_EXPORT ActionProviderBase: public QDesignerActionProviderExtension
+{
+protected:
+ explicit ActionProviderBase(QWidget *widget);
+
+public:
+ virtual void adjustIndicator(const QPoint &pos);
+ virtual Qt::Orientation orientation() const = 0;
+
+protected:
+ virtual QRect indicatorGeometry(const QPoint &pos) const;
+
+private:
+ QWidget *m_indicator;
+};
+
+class QT_FORMEDITOR_EXPORT QToolBarActionProvider: public QObject, public ActionProviderBase
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerActionProviderExtension)
+public:
+ explicit QToolBarActionProvider(QToolBar *widget, QObject *parent = 0);
+
+ virtual QRect actionGeometry(QAction *action) const;
+ virtual QAction *actionAt(const QPoint &pos) const;
+ Qt::Orientation orientation() const;
+
+protected:
+ virtual QRect indicatorGeometry(const QPoint &pos) const;
+
+private:
+ QToolBar *m_widget;
+};
+
+class QT_FORMEDITOR_EXPORT QMenuBarActionProvider: public QObject, public ActionProviderBase
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerActionProviderExtension)
+public:
+ explicit QMenuBarActionProvider(QMenuBar *widget, QObject *parent = 0);
+
+ virtual QRect actionGeometry(QAction *action) const;
+ virtual QAction *actionAt(const QPoint &pos) const;
+ Qt::Orientation orientation() const;
+
+private:
+ QMenuBar *m_widget;
+};
+
+class QT_FORMEDITOR_EXPORT QMenuActionProvider: public QObject, public ActionProviderBase
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerActionProviderExtension)
+public:
+ explicit QMenuActionProvider(QMenu *widget, QObject *parent = 0);
+
+ virtual QRect actionGeometry(QAction *action) const;
+ virtual QAction *actionAt(const QPoint &pos) const;
+ Qt::Orientation orientation() const;
+
+private:
+ QMenu *m_widget;
+};
+
+typedef ExtensionFactory<QDesignerActionProviderExtension, QToolBar, QToolBarActionProvider> QToolBarActionProviderFactory;
+typedef ExtensionFactory<QDesignerActionProviderExtension, QMenuBar, QMenuBarActionProvider> QMenuBarActionProviderFactory;
+typedef ExtensionFactory<QDesignerActionProviderExtension, QMenu, QMenuActionProvider> QMenuActionProviderFactory;
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DEFAULT_ACTIONPROVIDER_H
diff --git a/tools/designer/src/components/formeditor/default_container.cpp b/tools/designer/src/components/formeditor/default_container.cpp
new file mode 100644
index 0000000..eb3cd4f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/default_container.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "default_container.h"
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+template <class Container>
+static inline void setCurrentContainerIndex(int index, Container *container)
+{
+ const bool blocked = container->signalsBlocked();
+ container->blockSignals(true);
+ container->setCurrentIndex(index);
+ container->blockSignals(blocked);
+}
+
+static inline void ensureNoParent(QWidget *widget)
+{
+ if (widget->parentWidget())
+ widget->setParent(0);
+}
+
+static const char *PageLabel = "Page";
+
+namespace qdesigner_internal {
+
+// --------- QStackedWidgetContainer
+QStackedWidgetContainer::QStackedWidgetContainer(QStackedWidget *widget, QObject *parent) :
+ QObject(parent),
+ m_widget(widget)
+{
+}
+
+void QStackedWidgetContainer::setCurrentIndex(int index)
+{
+ setCurrentContainerIndex(index, m_widget);
+}
+
+void QStackedWidgetContainer::addWidget(QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->addWidget(widget);
+}
+
+void QStackedWidgetContainer::insertWidget(int index, QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->insertWidget(index, widget);
+}
+
+void QStackedWidgetContainer::remove(int index)
+{
+ m_widget->removeWidget(widget(index));
+}
+
+// --------- QTabWidgetContainer
+QTabWidgetContainer::QTabWidgetContainer(QTabWidget *widget, QObject *parent) :
+ QObject(parent),
+ m_widget(widget)
+{
+}
+
+void QTabWidgetContainer::setCurrentIndex(int index)
+{
+ setCurrentContainerIndex(index, m_widget);
+}
+
+void QTabWidgetContainer::addWidget(QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->addTab(widget, QString::fromUtf8(PageLabel));
+}
+
+void QTabWidgetContainer::insertWidget(int index, QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->insertTab(index, widget, QString::fromUtf8(PageLabel));
+}
+
+void QTabWidgetContainer::remove(int index)
+{
+ m_widget->removeTab(index);
+}
+
+// ------------------- QToolBoxContainer
+QToolBoxContainer::QToolBoxContainer(QToolBox *widget, QObject *parent) :
+ QObject(parent),
+ m_widget(widget)
+{
+}
+
+void QToolBoxContainer::setCurrentIndex(int index)
+{
+ setCurrentContainerIndex(index, m_widget);
+}
+
+void QToolBoxContainer::addWidget(QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->addItem(widget, QString::fromUtf8(PageLabel));
+}
+
+void QToolBoxContainer::insertWidget(int index, QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->insertItem(index, widget, QString::fromUtf8(PageLabel));
+}
+
+void QToolBoxContainer::remove(int index)
+{
+ m_widget->removeItem(index);
+}
+
+// ------------------- QScrollAreaContainer
+// We pass on active=true only if there are no children yet.
+// If there are children, it is a legacy custom widget QScrollArea that has an internal,
+// unmanaged child, in which case we deactivate the extension (otherwise we crash).
+// The child will then not show up in the task menu
+
+QScrollAreaContainer::QScrollAreaContainer(QScrollArea *widget, QObject *parent) :
+ QObject(parent),
+ SingleChildContainer<QScrollArea>(widget, widget->widget() == 0)
+{
+}
+// ------------------- QDockWidgetContainer
+QDockWidgetContainer::QDockWidgetContainer(QDockWidget *widget, QObject *parent) :
+ QObject(parent),
+ SingleChildContainer<QDockWidget>(widget)
+{
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/default_container.h b/tools/designer/src/components/formeditor/default_container.h
new file mode 100644
index 0000000..e8547638
--- /dev/null
+++ b/tools/designer/src/components/formeditor/default_container.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_CONTAINER_H
+#define DEFAULT_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/extension.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QScrollArea>
+#include <QtGui/QDockWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------ QStackedWidgetContainer
+class QStackedWidgetContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QStackedWidgetContainer(QStackedWidget *widget, QObject *parent = 0);
+
+ virtual int count() const { return m_widget->count(); }
+ virtual QWidget *widget(int index) const { return m_widget->widget(index); }
+
+ virtual int currentIndex() const { return m_widget->currentIndex(); }
+ virtual void setCurrentIndex(int index);
+
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QStackedWidget *m_widget;
+};
+
+// ------------ QTabWidgetContainer
+class QTabWidgetContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QTabWidgetContainer(QTabWidget *widget, QObject *parent = 0);
+
+ virtual int count() const { return m_widget->count(); }
+ virtual QWidget *widget(int index) const { return m_widget->widget(index); }
+
+ virtual int currentIndex() const { return m_widget->currentIndex(); }
+ virtual void setCurrentIndex(int index);
+
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QTabWidget *m_widget;
+};
+
+// ------------ QToolBoxContainer
+class QToolBoxContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QToolBoxContainer(QToolBox *widget, QObject *parent = 0);
+
+ virtual int count() const { return m_widget->count(); }
+ virtual QWidget *widget(int index) const { return m_widget->widget(index); }
+
+ virtual int currentIndex() const { return m_widget->currentIndex(); }
+ virtual void setCurrentIndex(int index);
+
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QToolBox *m_widget;
+};
+
+// ------------ SingleChildContainer:
+// Template for containers that have a single child widget using widget()/setWidget().
+
+template <class Container>
+class SingleChildContainer: public QDesignerContainerExtension
+{
+protected:
+ explicit SingleChildContainer(Container *widget, bool active = true);
+public:
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int /*index*/) {}
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int /*index*/) {}
+
+private:
+ const bool m_active;
+ Container *m_container;
+};
+
+template <class Container>
+SingleChildContainer<Container>::SingleChildContainer(Container *widget, bool active) :
+ m_active(active),
+ m_container(widget)
+{
+}
+
+template <class Container>
+int SingleChildContainer<Container>::count() const
+{
+ return m_active && m_container->widget() ? 1 : 0;
+}
+
+template <class Container>
+QWidget *SingleChildContainer<Container>::widget(int /* index */) const
+{
+ return m_container->widget();
+}
+
+template <class Container>
+int SingleChildContainer<Container>::currentIndex() const
+{
+ return m_active && m_container->widget() ? 0 : -1;
+}
+
+template <class Container>
+void SingleChildContainer<Container>::addWidget(QWidget *widget)
+{
+ Q_ASSERT(m_container->widget() == 0);
+ widget->setParent(m_container);
+ m_container->setWidget(widget);
+}
+
+template <class Container>
+void SingleChildContainer<Container>::insertWidget(int /* index */, QWidget *widget)
+{
+ addWidget(widget);
+}
+
+// ------------ QScrollAreaContainer
+class QScrollAreaContainer: public QObject, public SingleChildContainer<QScrollArea>
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QScrollAreaContainer(QScrollArea *widget, QObject *parent = 0);
+};
+
+// --------------- QDockWidgetContainer
+class QDockWidgetContainer: public QObject, public SingleChildContainer<QDockWidget>
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QDockWidgetContainer(QDockWidget *widget, QObject *parent = 0);
+};
+
+typedef ExtensionFactory<QDesignerContainerExtension, QStackedWidget, QStackedWidgetContainer> QDesignerStackedWidgetContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QTabWidget, QTabWidgetContainer> QDesignerTabWidgetContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QToolBox, QToolBoxContainer> QDesignerToolBoxContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QScrollArea, QScrollAreaContainer> QScrollAreaContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QDockWidget, QDockWidgetContainer> QDockWidgetContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DEFAULT_CONTAINER_H
diff --git a/tools/designer/src/components/formeditor/default_layoutdecoration.cpp b/tools/designer/src/components/formeditor/default_layoutdecoration.cpp
new file mode 100644
index 0000000..5558068
--- /dev/null
+++ b/tools/designer/src/components/formeditor/default_layoutdecoration.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "default_layoutdecoration.h"
+#include "qlayout_widget_p.h"
+
+#include <layoutinfo_p.h>
+
+#include <QtDesigner/QDesignerMetaDataBaseItemInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ---- QDesignerLayoutDecorationFactory ----
+QDesignerLayoutDecorationFactory::QDesignerLayoutDecorationFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+
+QObject *QDesignerLayoutDecorationFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (!object->isWidgetType() || iid != Q_TYPEID(QDesignerLayoutDecorationExtension))
+ return 0;
+
+ QWidget *widget = qobject_cast<QWidget*>(object);
+
+ if (const QLayoutWidget *layoutWidget = qobject_cast<const QLayoutWidget*>(widget))
+ return QLayoutSupport::createLayoutSupport(layoutWidget->formWindow(), widget, parent);
+
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget))
+ if (LayoutInfo::managedLayout(fw->core(), widget))
+ return QLayoutSupport::createLayoutSupport(fw, widget, parent);
+
+ return 0;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/default_layoutdecoration.h b/tools/designer/src/components/formeditor/default_layoutdecoration.h
new file mode 100644
index 0000000..770372f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/default_layoutdecoration.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_LAYOUTDECORATION_H
+#define DEFAULT_LAYOUTDECORATION_H
+
+#include "formeditor_global.h"
+#include <QtDesigner/QDesignerLayoutDecorationExtension>
+#include <QtDesigner/default_extensionfactory.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+class QDesignerLayoutDecorationFactory: public QExtensionFactory
+{
+ Q_OBJECT
+ Q_INTERFACES(QAbstractExtensionFactory)
+public:
+ explicit QDesignerLayoutDecorationFactory(QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DEFAULT_LAYOUTDECORATION_H
diff --git a/tools/designer/src/components/formeditor/defaultbrushes.xml b/tools/designer/src/components/formeditor/defaultbrushes.xml
new file mode 100644
index 0000000..88035c3
--- /dev/null
+++ b/tools/designer/src/components/formeditor/defaultbrushes.xml
@@ -0,0 +1,542 @@
+<brushes>
+ <description name="French" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="1" coordinatemode="StretchToDeviceMode" endy="0" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.323" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.343" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.656" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.676" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="German" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.323" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.343" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.656" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.676" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Greek" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.09" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.105" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.205" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.22" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.32" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.335" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.435" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.45" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.55" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.565" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.665" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.68" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.78" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.795" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.895" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.91" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Italian" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="1" coordinatemode="StretchToDeviceMode" endy="0" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>60</red>
+ <green>160</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.323" >
+ <color alpha="255" >
+ <red>60</red>
+ <green>160</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.343" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.656" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.676" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Japanese" >
+ <brush brushstyle="RadialGradientPattern" >
+ <gradient focalx="0.5" focaly="0.5" radius="0.5" spread="PadSpread" type="RadialGradient" coordinatemode="StretchToDeviceMode" centralx="0.5" centraly="0.5" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.49" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.51" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Norwegian" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="1" coordinatemode="StretchToDeviceMode" endy="0" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.225" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.25" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.275" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.3" >
+ <color alpha="255" >
+ <red>5</red>
+ <green>0</green>
+ <blue>70</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.4" >
+ <color alpha="255" >
+ <red>5</red>
+ <green>0</green>
+ <blue>70</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.425" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.45" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.475" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Polish" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.475" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.525" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Spanish" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.24" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.26" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.74" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.76" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="black" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="blue" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="cyan" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="green" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="magenta" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="red" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="white" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="yellow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+</brushes>
diff --git a/tools/designer/src/components/formeditor/deviceprofiledialog.cpp b/tools/designer/src/components/formeditor/deviceprofiledialog.cpp
new file mode 100644
index 0000000..995bc3f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/deviceprofiledialog.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceprofiledialog.h"
+#include "ui_deviceprofiledialog.h"
+
+#include <abstractdialoggui_p.h>
+#include <deviceprofile_p.h>
+
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QFontDatabase>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+static const char *profileExtensionC = "qdp";
+
+static inline QString fileFilter()
+{
+ return qdesigner_internal::DeviceProfileDialog::tr("Device Profiles (*.%1)").arg(QLatin1String(profileExtensionC));
+}
+
+// Populate a combo with a sequence of integers, also set them as data.
+template <class IntIterator>
+ static void populateNumericCombo(IntIterator i1, IntIterator i2, QComboBox *cb)
+{
+ QString s;
+ cb->setEditable(false);
+ for ( ; i1 != i2 ; ++i1) {
+ const int n = *i1;
+ s.setNum(n);
+ cb->addItem(s, QVariant(n));
+ }
+}
+
+namespace qdesigner_internal {
+
+DeviceProfileDialog::DeviceProfileDialog(QDesignerDialogGuiInterface *dlgGui, QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::DeviceProfileDialog),
+ m_dlgGui(dlgGui)
+{
+ setModal(true);
+ m_ui->setupUi(this);
+
+ const QList<int> standardFontSizes = QFontDatabase::standardSizes();
+ populateNumericCombo(standardFontSizes.constBegin(), standardFontSizes.constEnd(), m_ui->m_systemFontSizeCombo);
+
+ // Styles
+ const QStringList styles = QStyleFactory::keys();
+ m_ui->m_styleCombo->addItem(tr("Default"), QVariant(QString()));
+ const QStringList::const_iterator cend = styles.constEnd();
+ for (QStringList::const_iterator it = styles.constBegin(); it != cend; ++it)
+ m_ui->m_styleCombo->addItem(*it, *it);
+
+ connect(m_ui->m_nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(nameChanged(QString)));
+ connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
+ // Note that Load/Save emit accepted() of the button box..
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Save), SIGNAL(clicked()), this, SLOT(save()));
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Open), SIGNAL(clicked()), this, SLOT(open()));
+}
+
+DeviceProfileDialog::~DeviceProfileDialog()
+{
+ delete m_ui;
+}
+
+DeviceProfile DeviceProfileDialog::deviceProfile() const
+{
+ DeviceProfile rc;
+ rc.setName(m_ui->m_nameLineEdit->text());
+ rc.setFontFamily(m_ui->m_systemFontComboBox->currentFont().family());
+ rc.setFontPointSize(m_ui->m_systemFontSizeCombo->itemData(m_ui->m_systemFontSizeCombo->currentIndex()).toInt());
+
+ int dpiX, dpiY;
+ m_ui->m_dpiChooser->getDPI(&dpiX, &dpiY);
+ rc.setDpiX(dpiX);
+ rc.setDpiY(dpiY);
+
+ rc.setStyle(m_ui->m_styleCombo->itemData(m_ui->m_styleCombo->currentIndex()).toString());
+
+ return rc;
+}
+
+void DeviceProfileDialog::setDeviceProfile(const DeviceProfile &s)
+{
+ m_ui->m_nameLineEdit->setText(s.name());
+ m_ui->m_systemFontComboBox->setCurrentFont(QFont(s.fontFamily()));
+ const int fontSizeIndex = m_ui->m_systemFontSizeCombo->findData(QVariant(s.fontPointSize()));
+ m_ui->m_systemFontSizeCombo->setCurrentIndex(fontSizeIndex != -1 ? fontSizeIndex : 0);
+ m_ui->m_dpiChooser->setDPI(s.dpiX(), s.dpiY());
+ const int styleIndex = m_ui->m_styleCombo->findData(s.style());
+ m_ui->m_styleCombo->setCurrentIndex(styleIndex != -1 ? styleIndex : 0);
+}
+
+void DeviceProfileDialog::setOkButtonEnabled(bool v)
+{
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(v);
+}
+
+bool DeviceProfileDialog::showDialog(const QStringList &existingNames)
+{
+ m_existingNames = existingNames;
+ m_ui->m_nameLineEdit->setFocus(Qt::OtherFocusReason);
+ nameChanged(m_ui->m_nameLineEdit->text());
+ return exec() == Accepted;
+}
+
+void DeviceProfileDialog::nameChanged(const QString &name)
+{
+ const bool invalid = name.isEmpty() || m_existingNames.indexOf(name) != -1;
+ setOkButtonEnabled(!invalid);
+}
+
+void DeviceProfileDialog::save()
+{
+ QString fn = m_dlgGui->getSaveFileName(this, tr("Save Profile"), QString(), fileFilter());
+ if (fn.isEmpty())
+ return;
+ if (QFileInfo(fn).completeSuffix().isEmpty()) {
+ fn += QLatin1Char('.');
+ fn += QLatin1String(profileExtensionC);
+ }
+
+ QFile file(fn);
+ if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) {
+ critical(tr("Save Profile - Error"), tr("Unable to open the file '%1' for writing: %2").arg(fn, file.errorString()));
+ return;
+ }
+ file.write(deviceProfile().toXml().toUtf8());
+}
+
+void DeviceProfileDialog::open()
+{
+ const QString fn = m_dlgGui->getOpenFileName(this, tr("Open profile"), QString(), fileFilter());
+ if (fn.isEmpty())
+ return;
+
+ QFile file(fn);
+ if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ critical(tr("Open Profile - Error"), tr("Unable to open the file '%1' for reading: %2").arg(fn, file.errorString()));
+ return;
+ }
+ QString errorMessage;
+ DeviceProfile newSettings;
+ if (!newSettings.fromXml(QString::fromUtf8(file.readAll()), &errorMessage)) {
+ critical(tr("Open Profile - Error"), tr("'%1' is not a valid profile: %2").arg(fn, errorMessage));
+ return;
+ }
+ setDeviceProfile(newSettings);
+}
+
+void DeviceProfileDialog::critical(const QString &title, const QString &msg)
+{
+ m_dlgGui->message(this, QDesignerDialogGuiInterface::OtherMessage, QMessageBox::Critical, title, msg);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/deviceprofiledialog.h b/tools/designer/src/components/formeditor/deviceprofiledialog.h
new file mode 100644
index 0000000..dafcd77
--- /dev/null
+++ b/tools/designer/src/components/formeditor/deviceprofiledialog.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SYSTEMSETTINGSDIALOG_H
+#define SYSTEMSETTINGSDIALOG_H
+
+#include <QtGui/QDialog>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class DeviceProfileDialog;
+}
+
+class QDesignerDialogGuiInterface;
+
+class QDialogButtonBox;
+
+namespace qdesigner_internal {
+
+class DeviceProfile;
+
+/* DeviceProfileDialog: Widget to edit system settings for embedded design */
+
+class DeviceProfileDialog : public QDialog
+{
+ Q_DISABLE_COPY(DeviceProfileDialog)
+ Q_OBJECT
+public:
+ explicit DeviceProfileDialog(QDesignerDialogGuiInterface *dlgGui, QWidget *parent = 0);
+ ~DeviceProfileDialog();
+
+ DeviceProfile deviceProfile() const;
+ void setDeviceProfile(const DeviceProfile &s);
+
+ bool showDialog(const QStringList &existingNames);
+
+private slots:
+ void setOkButtonEnabled(bool);
+ void nameChanged(const QString &name);
+ void save();
+ void open();
+
+private:
+ void critical(const QString &title, const QString &msg);
+ Ui::DeviceProfileDialog *m_ui;
+ QDesignerDialogGuiInterface *m_dlgGui;
+ QStringList m_existingNames;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // SYSTEMSETTINGSDIALOG_H
diff --git a/tools/designer/src/components/formeditor/deviceprofiledialog.ui b/tools/designer/src/components/formeditor/deviceprofiledialog.ui
new file mode 100644
index 0000000..3186c57
--- /dev/null
+++ b/tools/designer/src/components/formeditor/deviceprofiledialog.ui
@@ -0,0 +1,100 @@
+<ui version="4.0" >
+ <class>DeviceProfileDialog</class>
+ <widget class="QDialog" name="dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>348</width>
+ <height>209</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QWidget" native="1" name="SystemSettingsWidget" >
+ <layout class="QFormLayout" name="formLayout" >
+ <item row="1" column="0" >
+ <widget class="QLabel" name="m_systemFontFamilyLabel" >
+ <property name="text" >
+ <string>&amp;Family</string>
+ </property>
+ <property name="buddy" >
+ <cstring>m_systemFontComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QFontComboBox" name="m_systemFontComboBox" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="m_systemFontSizeLabel" >
+ <property name="text" >
+ <string>&amp;Point Size</string>
+ </property>
+ <property name="buddy" >
+ <cstring>m_systemFontSizeCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="m_systemFontSizeCombo" />
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="m_styleLabel" >
+ <property name="text" >
+ <string>Style</string>
+ </property>
+ <property name="buddy" >
+ <cstring>m_styleCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QComboBox" name="m_styleCombo" />
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="m_systemDPILabel" >
+ <property name="text" >
+ <string>Device DPI</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="qdesigner_internal::DPI_Chooser" native="1" name="m_dpiChooser" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="m_nameLabel" >
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="m_nameLineEdit" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Open|QDialogButtonBox::Save</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>qdesigner_internal::DPI_Chooser</class>
+ <extends>QWidget</extends>
+ <header>dpi_chooser.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/designer/src/components/formeditor/dpi_chooser.cpp b/tools/designer/src/components/formeditor/dpi_chooser.cpp
new file mode 100644
index 0000000..d766e31
--- /dev/null
+++ b/tools/designer/src/components/formeditor/dpi_chooser.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "dpi_chooser.h"
+
+#include <deviceprofile_p.h>
+
+#include <QtGui/QComboBox>
+#include <QtGui/QSpinBox>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QCheckBox>
+
+QT_BEGIN_NAMESPACE
+
+enum { minDPI = 50, maxDPI = 400 };
+
+namespace qdesigner_internal {
+
+// Entry struct for predefined values
+struct DPI_Entry {
+ int dpiX;
+ int dpiY;
+ const char *description;
+};
+
+const struct DPI_Entry dpiEntries[] = {
+ //: Embedded device standard screen resolution
+ { 96, 96, QT_TRANSLATE_NOOP("DPI_Chooser", "Standard (96 x 96)") },
+ //: Embedded device screen resolution
+ { 179, 185, QT_TRANSLATE_NOOP("DPI_Chooser", "Greenphone (179 x 185)") },
+ //: Embedded device high definition screen resolution
+ { 192, 192, QT_TRANSLATE_NOOP("DPI_Chooser", "High (192 x 192)") }
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(const struct qdesigner_internal::DPI_Entry*);
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------- DPI_Chooser
+
+DPI_Chooser::DPI_Chooser(QWidget *parent) :
+ QWidget(parent),
+ m_systemEntry(new DPI_Entry),
+ m_predefinedCombo(new QComboBox),
+ m_dpiXSpinBox(new QSpinBox),
+ m_dpiYSpinBox(new QSpinBox)
+{
+ // Predefined settings: System
+ DeviceProfile::systemResolution(&(m_systemEntry->dpiX), &(m_systemEntry->dpiY));
+ m_systemEntry->description = 0;
+ const struct DPI_Entry *systemEntry = m_systemEntry;
+ //: System resolution
+ m_predefinedCombo->addItem(tr("System (%1 x %2)").arg(m_systemEntry->dpiX).arg(m_systemEntry->dpiY), qVariantFromValue(systemEntry));
+ // Devices. Exclude the system values as not to duplicate the entries
+ const int predefinedCount = sizeof(dpiEntries)/sizeof(DPI_Entry);
+ const struct DPI_Entry *ecend = dpiEntries + predefinedCount;
+ for (const struct DPI_Entry *it = dpiEntries; it < ecend; ++it)
+ if (it->dpiX != m_systemEntry->dpiX || it->dpiY != m_systemEntry->dpiY)
+ m_predefinedCombo->addItem(tr(it->description), qVariantFromValue(it));
+ m_predefinedCombo->addItem(tr("User defined"));
+
+ setFocusProxy(m_predefinedCombo);
+ m_predefinedCombo->setEditable(false);
+ m_predefinedCombo->setCurrentIndex(0);
+ connect(m_predefinedCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(syncSpinBoxes()));
+ // top row with predefined settings
+ QVBoxLayout *vBoxLayout = new QVBoxLayout;
+ vBoxLayout->setMargin(0);
+ vBoxLayout->addWidget(m_predefinedCombo);
+ // Spin box row
+ QHBoxLayout *hBoxLayout = new QHBoxLayout;
+ hBoxLayout->setMargin(0);
+
+ m_dpiXSpinBox->setMinimum(minDPI);
+ m_dpiXSpinBox->setMaximum(maxDPI);
+ hBoxLayout->addWidget(m_dpiXSpinBox);
+ //: DPI X/Y separator
+ hBoxLayout->addWidget(new QLabel(tr(" x ")));
+
+ m_dpiYSpinBox->setMinimum(minDPI);
+ m_dpiYSpinBox->setMaximum(maxDPI);
+ hBoxLayout->addWidget(m_dpiYSpinBox);
+
+ hBoxLayout->addStretch();
+ vBoxLayout->addLayout(hBoxLayout);
+ setLayout(vBoxLayout);
+
+ syncSpinBoxes();
+}
+
+DPI_Chooser::~DPI_Chooser()
+{
+ delete m_systemEntry;
+}
+
+void DPI_Chooser::getDPI(int *dpiX, int *dpiY) const
+{
+ *dpiX = m_dpiXSpinBox->value();
+ *dpiY = m_dpiYSpinBox->value();
+}
+
+void DPI_Chooser::setDPI(int dpiX, int dpiY)
+{
+ // Default to system if it is something weird
+ const bool valid = dpiX >= minDPI && dpiX <= maxDPI && dpiY >= minDPI && dpiY <= maxDPI;
+ if (!valid) {
+ m_predefinedCombo->setCurrentIndex(0);
+ return;
+ }
+ // Try to find the values among the predefined settings
+ const int count = m_predefinedCombo->count();
+ int predefinedIndex = -1;
+ for (int i = 0; i < count; i++) {
+ const QVariant data = m_predefinedCombo->itemData(i);
+ if (data.type() != QVariant::Invalid) {
+ const struct DPI_Entry *entry = qvariant_cast<const struct DPI_Entry *>(data);
+ if (entry->dpiX == dpiX && entry->dpiY == dpiY) {
+ predefinedIndex = i;
+ break;
+ }
+ }
+ }
+ if (predefinedIndex != -1) {
+ m_predefinedCombo->setCurrentIndex(predefinedIndex); // triggers syncSpinBoxes()
+ } else {
+ setUserDefinedValues(dpiX, dpiY);
+ }
+}
+
+void DPI_Chooser::setUserDefinedValues(int dpiX, int dpiY)
+{
+ const bool blocked = m_predefinedCombo->blockSignals(true);
+ m_predefinedCombo->setCurrentIndex(m_predefinedCombo->count() - 1);
+ m_predefinedCombo->blockSignals(blocked);
+
+ m_dpiXSpinBox->setEnabled(true);
+ m_dpiYSpinBox->setEnabled(true);
+ m_dpiXSpinBox->setValue(dpiX);
+ m_dpiYSpinBox->setValue(dpiY);
+}
+
+void DPI_Chooser::syncSpinBoxes()
+{
+ const int predefIdx = m_predefinedCombo->currentIndex();
+ const QVariant data = m_predefinedCombo->itemData(predefIdx);
+
+ // Predefined mode in which spin boxes are disabled or user defined?
+ const bool userSetting = data.type() == QVariant::Invalid;
+ m_dpiXSpinBox->setEnabled(userSetting);
+ m_dpiYSpinBox->setEnabled(userSetting);
+
+ if (!userSetting) {
+ const struct DPI_Entry *entry = qvariant_cast<const struct DPI_Entry *>(data);
+ m_dpiXSpinBox->setValue(entry->dpiX);
+ m_dpiYSpinBox->setValue(entry->dpiY);
+ }
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/dpi_chooser.h b/tools/designer/src/components/formeditor/dpi_chooser.h
new file mode 100644
index 0000000..f8ca810
--- /dev/null
+++ b/tools/designer/src/components/formeditor/dpi_chooser.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DPICHOOSER_H
+#define DPICHOOSER_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QSpinBox;
+class QComboBox;
+
+namespace qdesigner_internal {
+
+struct DPI_Entry;
+
+/* Let the user choose a DPI settings */
+class DPI_Chooser : public QWidget {
+ Q_DISABLE_COPY(DPI_Chooser)
+ Q_OBJECT
+
+public:
+ explicit DPI_Chooser(QWidget *parent = 0);
+ ~DPI_Chooser();
+
+ void getDPI(int *dpiX, int *dpiY) const;
+ void setDPI(int dpiX, int dpiY);
+
+private slots:
+ void syncSpinBoxes();
+
+private:
+ void setUserDefinedValues(int dpiX, int dpiY);
+
+ struct DPI_Entry *m_systemEntry;
+ QComboBox *m_predefinedCombo;
+ QSpinBox *m_dpiXSpinBox;
+ QSpinBox *m_dpiYSpinBox;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // DPICHOOSER_H
diff --git a/tools/designer/src/components/formeditor/embeddedoptionspage.cpp b/tools/designer/src/components/formeditor/embeddedoptionspage.cpp
new file mode 100644
index 0000000..1a41985
--- /dev/null
+++ b/tools/designer/src/components/formeditor/embeddedoptionspage.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "embeddedoptionspage.h"
+#include "deviceprofiledialog.h"
+#include "widgetfactory_p.h"
+#include "formwindowmanager.h"
+
+#include <deviceprofile_p.h>
+#include <iconloader_p.h>
+#include <shared_settings_p.h>
+#include <abstractdialoggui_p.h>
+#include <formwindowbase_p.h>
+
+
+// SDK
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtGui/QLabel>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QComboBox>
+#include <QtGui/QToolButton>
+#include <QtGui/QMessageBox>
+#include <QtGui/QLabel>
+#include <QtGui/QGroupBox>
+
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+typedef QList<DeviceProfile> DeviceProfileList;
+
+enum { profileComboIndexOffset = 1 };
+
+// Sort by name. Used by template, do not make it static!
+bool deviceProfileLessThan(const DeviceProfile &d1, const DeviceProfile &d2)
+{
+ return d1.name().toLower() < d2.name().toLower();
+}
+
+static bool ask(QWidget *parent,
+ QDesignerDialogGuiInterface *dlgui,
+ const QString &title,
+ const QString &what)
+{
+ return dlgui->message(parent, QDesignerDialogGuiInterface::OtherMessage,
+ QMessageBox::Question, title, what,
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes;
+}
+
+// ------------ EmbeddedOptionsControlPrivate
+class EmbeddedOptionsControlPrivate {
+ Q_DISABLE_COPY(EmbeddedOptionsControlPrivate)
+public:
+ EmbeddedOptionsControlPrivate(QDesignerFormEditorInterface *core);
+ void init(EmbeddedOptionsControl *q);
+
+ bool isDirty() const { return m_dirty; }
+
+ void loadSettings();
+ void saveSettings();
+ void slotAdd();
+ void slotEdit();
+ void slotDelete();
+ void slotProfileIndexChanged(int);
+
+private:
+ QStringList existingProfileNames() const;
+ void sortAndPopulateProfileCombo();
+ void updateState();
+ void updateDescriptionLabel();
+
+ QDesignerFormEditorInterface *m_core;
+ QComboBox *m_profileCombo;
+ QToolButton *m_addButton;
+ QToolButton *m_editButton;
+ QToolButton *m_deleteButton;
+ QLabel *m_descriptionLabel;
+
+ DeviceProfileList m_sortedProfiles;
+ EmbeddedOptionsControl *m_q;
+ bool m_dirty;
+ QSet<QString> m_usedProfiles;
+};
+
+EmbeddedOptionsControlPrivate::EmbeddedOptionsControlPrivate(QDesignerFormEditorInterface *core) :
+ m_core(core),
+ m_profileCombo(new QComboBox),
+ m_addButton(new QToolButton),
+ m_editButton(new QToolButton),
+ m_deleteButton(new QToolButton),
+ m_descriptionLabel(new QLabel),
+ m_q(0),
+ m_dirty(false)
+{
+ m_descriptionLabel->setMinimumHeight(80);
+ // Determine used profiles to lock them
+ const QDesignerFormWindowManagerInterface *fwm = core->formWindowManager();
+ if (const int fwCount = fwm->formWindowCount()) {
+ for (int i = 0; i < fwCount; i++)
+ if (const FormWindowBase *fwb = qobject_cast<const FormWindowBase *>(fwm->formWindow(i))) {
+ const QString deviceProfileName = fwb->deviceProfileName();
+ if (!deviceProfileName.isEmpty())
+ m_usedProfiles.insert(deviceProfileName);
+ }
+ }
+}
+
+void EmbeddedOptionsControlPrivate::init(EmbeddedOptionsControl *q)
+{
+ m_q = q;
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ m_profileCombo->setMinimumWidth(200);
+ m_profileCombo->setEditable(false);
+ hLayout->addWidget(m_profileCombo);
+ m_profileCombo->addItem(EmbeddedOptionsControl::tr("None"));
+ EmbeddedOptionsControl::connect(m_profileCombo, SIGNAL(currentIndexChanged(int)), m_q, SLOT(slotProfileIndexChanged(int)));
+
+ m_addButton->setIcon(createIconSet(QString::fromUtf8("plus.png")));
+ m_addButton->setToolTip(EmbeddedOptionsControl::tr("Add a profile"));
+ EmbeddedOptionsControl::connect(m_addButton, SIGNAL(clicked()), m_q, SLOT(slotAdd()));
+ hLayout->addWidget(m_addButton);
+
+ EmbeddedOptionsControl::connect(m_editButton, SIGNAL(clicked()), m_q, SLOT(slotEdit()));
+ m_editButton->setIcon(createIconSet(QString::fromUtf8("edit.png")));
+ m_editButton->setToolTip(EmbeddedOptionsControl::tr("Edit the selected profile"));
+ hLayout->addWidget(m_editButton);
+
+ m_deleteButton->setIcon(createIconSet(QString::fromUtf8("minus.png")));
+ m_deleteButton->setToolTip(EmbeddedOptionsControl::tr("Delete the selected profile"));
+ EmbeddedOptionsControl::connect(m_deleteButton, SIGNAL(clicked()), m_q, SLOT(slotDelete()));
+ hLayout->addWidget(m_deleteButton);
+
+ hLayout->addStretch();
+ vLayout->addLayout(hLayout);
+ vLayout->addWidget(m_descriptionLabel);
+ m_q->setLayout(vLayout);
+}
+
+QStringList EmbeddedOptionsControlPrivate::existingProfileNames() const
+{
+ QStringList rc;
+ const DeviceProfileList::const_iterator dcend = m_sortedProfiles.constEnd();
+ for (DeviceProfileList::const_iterator it = m_sortedProfiles.constBegin(); it != dcend; ++it)
+ rc.push_back(it->name());
+ return rc;
+}
+
+void EmbeddedOptionsControlPrivate::slotAdd()
+{
+ DeviceProfileDialog dlg(m_core->dialogGui(), m_q);
+ dlg.setWindowTitle(EmbeddedOptionsControl::tr("Add Profile"));
+ // Create a new profile with a new, unique name
+ DeviceProfile settings;
+ settings.fromSystem();
+ dlg.setDeviceProfile(settings);
+
+ const QStringList names = existingProfileNames();
+ const QString newNamePrefix = EmbeddedOptionsControl::tr("New profile");
+ QString newName = newNamePrefix;
+ for (int i = 2; names.contains(newName); i++) {
+ newName = newNamePrefix;
+ newName += QString::number(i);
+ }
+
+ settings.setName(newName);
+ dlg.setDeviceProfile(settings);
+ if (dlg.showDialog(names)) {
+ const DeviceProfile newProfile = dlg.deviceProfile();
+ m_sortedProfiles.push_back(newProfile);
+ // Maintain sorted order
+ sortAndPopulateProfileCombo();
+ const int index = m_profileCombo->findText(newProfile.name());
+ m_profileCombo->setCurrentIndex(index);
+ m_dirty = true;
+ }
+}
+
+void EmbeddedOptionsControlPrivate::slotEdit()
+{
+ const int index = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ if (index < 0)
+ return;
+
+ // Edit the profile, compile a list of existing names
+ // excluding current one. re-insert if changed,
+ // re-sort if name changed.
+ const DeviceProfile oldProfile = m_sortedProfiles.at(index);
+ const QString oldName = oldProfile.name();
+ QStringList names = existingProfileNames();
+ names.removeAll(oldName);
+
+ DeviceProfileDialog dlg(m_core->dialogGui(), m_q);
+ dlg.setWindowTitle(EmbeddedOptionsControl::tr("Edit Profile"));
+ dlg.setDeviceProfile(oldProfile);
+ if (dlg.showDialog(names)) {
+ const DeviceProfile newProfile = dlg.deviceProfile();
+ if (newProfile != oldProfile) {
+ m_dirty = true;
+ m_sortedProfiles[index] = newProfile;
+ if (newProfile.name() != oldName) {
+ sortAndPopulateProfileCombo();
+ const int index = m_profileCombo->findText(newProfile.name());
+ m_profileCombo->setCurrentIndex(index);
+ } else {
+ updateDescriptionLabel();
+ }
+
+ }
+ }
+}
+
+void EmbeddedOptionsControlPrivate::slotDelete()
+{
+ const int index = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ if (index < 0)
+ return;
+ const QString name = m_sortedProfiles.at(index).name();
+ if (ask(m_q, m_core->dialogGui(),
+ EmbeddedOptionsControl::tr("Delete Profile"),
+ EmbeddedOptionsControl::tr("Would you like to delete the profile '%1'?").arg(name))) {
+ m_profileCombo->setCurrentIndex(0);
+ m_sortedProfiles.removeAt(index);
+ m_profileCombo->removeItem(index + profileComboIndexOffset);
+ m_dirty = true;
+ }
+}
+
+void EmbeddedOptionsControlPrivate::sortAndPopulateProfileCombo()
+{
+ // Clear items until only "None" is left
+ for (int i = m_profileCombo->count() - 1; i > 0; i--)
+ m_profileCombo->removeItem(i);
+ if (!m_sortedProfiles.empty()) {
+ qSort(m_sortedProfiles.begin(), m_sortedProfiles.end(), deviceProfileLessThan);
+ m_profileCombo->addItems(existingProfileNames());
+ }
+}
+
+void EmbeddedOptionsControlPrivate::loadSettings()
+{
+ const QDesignerSharedSettings settings(m_core);
+ m_sortedProfiles = settings.deviceProfiles();
+ sortAndPopulateProfileCombo();
+ // Index: 0 is "None"
+ const int settingsIndex = settings.currentDeviceProfileIndex();
+ const int profileIndex = settingsIndex >= 0 && settingsIndex < m_sortedProfiles.size() ? settingsIndex + profileComboIndexOffset : 0;
+ m_profileCombo->setCurrentIndex(profileIndex);
+ updateState();
+ m_dirty = false;
+}
+
+void EmbeddedOptionsControlPrivate::saveSettings()
+{
+ QDesignerSharedSettings settings(m_core);
+ settings.setDeviceProfiles(m_sortedProfiles);
+ // Index: 0 is "None"
+ settings.setCurrentDeviceProfileIndex(m_profileCombo->currentIndex() - profileComboIndexOffset);
+ m_dirty = false;
+}
+
+//: Format embedded device profile description
+static const char *descriptionFormat = QT_TRANSLATE_NOOP("EmbeddedOptionsControl",
+"<html>"
+"<table>"
+"<tr><td><b>Font</b></td><td>%1, %2</td></tr>"
+"<tr><td><b>Style</b></td><td>%3</td></tr>"
+"<tr><td><b>Resolution</b></td><td>%4 x %5</td></tr>"
+"</table>"
+"</html>");
+
+static inline QString description(const DeviceProfile& p)
+{
+ QString styleName = p.style();
+ if (styleName.isEmpty())
+ styleName = EmbeddedOptionsControl::tr("Default");
+ return EmbeddedOptionsControl::tr(descriptionFormat).
+ arg(p.fontFamily()).arg(p.fontPointSize()).arg(styleName).arg(p.dpiX()).arg(p.dpiY());
+}
+
+void EmbeddedOptionsControlPrivate::updateDescriptionLabel()
+{
+ const int profileIndex = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ if (profileIndex >= 0) {
+ m_descriptionLabel->setText(description(m_sortedProfiles.at(profileIndex)));
+ } else {
+ m_descriptionLabel->clear();
+ }
+}
+
+void EmbeddedOptionsControlPrivate::updateState()
+{
+ const int profileIndex = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ // Allow for changing/deleting only if it is not in use
+ bool modifyEnabled = false;
+ if (profileIndex >= 0)
+ modifyEnabled = !m_usedProfiles.contains(m_sortedProfiles.at(profileIndex).name());
+ m_editButton->setEnabled(modifyEnabled);
+ m_deleteButton->setEnabled(modifyEnabled);
+ updateDescriptionLabel();
+}
+
+void EmbeddedOptionsControlPrivate::slotProfileIndexChanged(int)
+{
+ updateState();
+ m_dirty = true;
+}
+
+// ------------- EmbeddedOptionsControl
+EmbeddedOptionsControl::EmbeddedOptionsControl(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_d(new EmbeddedOptionsControlPrivate(core))
+{
+ m_d->init(this);
+}
+
+EmbeddedOptionsControl::~EmbeddedOptionsControl()
+{
+ delete m_d;
+}
+
+void EmbeddedOptionsControl::slotAdd()
+{
+ m_d->slotAdd();
+}
+
+void EmbeddedOptionsControl::slotEdit()
+{
+ m_d->slotEdit();
+}
+
+void EmbeddedOptionsControl::slotDelete()
+{
+ m_d->slotDelete();
+}
+
+void EmbeddedOptionsControl::loadSettings()
+{
+ m_d->loadSettings();
+}
+
+void EmbeddedOptionsControl::saveSettings()
+{
+ m_d->saveSettings();
+}
+
+void EmbeddedOptionsControl::slotProfileIndexChanged(int i)
+{
+ m_d->slotProfileIndexChanged(i);
+}
+
+bool EmbeddedOptionsControl::isDirty() const
+{
+ return m_d->isDirty();
+}
+
+// EmbeddedOptionsPage:
+EmbeddedOptionsPage::EmbeddedOptionsPage(QDesignerFormEditorInterface *core) :
+ m_core(core)
+{
+}
+
+QString EmbeddedOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("EmbeddedOptionsPage", "Embedded Design");
+}
+
+QWidget *EmbeddedOptionsPage::createPage(QWidget *parent)
+{
+ QWidget *optionsWidget = new QWidget(parent);
+
+ QVBoxLayout *optionsVLayout = new QVBoxLayout();
+
+ //: EmbeddedOptionsControl group box"
+ QGroupBox *gb = new QGroupBox(QCoreApplication::translate("EmbeddedOptionsPage", "Device Profiles"));
+ QVBoxLayout *gbVLayout = new QVBoxLayout();
+ m_embeddedOptionsControl = new EmbeddedOptionsControl(m_core);
+ m_embeddedOptionsControl->loadSettings();
+ gbVLayout->addWidget(m_embeddedOptionsControl);
+ gb->setLayout(gbVLayout);
+ optionsVLayout->addWidget(gb);
+
+ optionsVLayout->addStretch(1);
+
+ // Outer layout to give it horizontal stretch
+ QHBoxLayout *optionsHLayout = new QHBoxLayout();
+ optionsHLayout->addLayout(optionsVLayout);
+ optionsHLayout->addStretch(1);
+ optionsWidget->setLayout(optionsHLayout);
+ return optionsWidget;
+}
+
+void EmbeddedOptionsPage::apply()
+{
+ if (!m_embeddedOptionsControl || !m_embeddedOptionsControl->isDirty())
+ return;
+
+ m_embeddedOptionsControl->saveSettings();
+ if (FormWindowManager *fw = qobject_cast<qdesigner_internal::FormWindowManager *>(m_core->formWindowManager()))
+ fw->deviceProfilesChanged();
+}
+
+void EmbeddedOptionsPage::finish()
+{
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/embeddedoptionspage.h b/tools/designer/src/components/formeditor/embeddedoptionspage.h
new file mode 100644
index 0000000..6b76d38
--- /dev/null
+++ b/tools/designer/src/components/formeditor/embeddedoptionspage.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EMBEDDEDOPTIONSPAGE_H
+#define EMBEDDEDOPTIONSPAGE_H
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class EmbeddedOptionsControlPrivate;
+
+/* EmbeddedOptions Control. Presents the user with a list of embedded
+ * device profiles he can modify/add/delete. */
+class EmbeddedOptionsControl : public QWidget {
+ Q_DISABLE_COPY(EmbeddedOptionsControl)
+ Q_OBJECT
+public:
+ explicit EmbeddedOptionsControl(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ ~EmbeddedOptionsControl();
+
+ bool isDirty() const;
+
+public slots:
+ void loadSettings();
+ void saveSettings();
+
+private slots:
+ void slotAdd();
+ void slotEdit();
+ void slotDelete();
+ void slotProfileIndexChanged(int);
+
+private:
+ EmbeddedOptionsControlPrivate *m_d;
+};
+
+// EmbeddedOptionsPage
+class EmbeddedOptionsPage : public QDesignerOptionsPageInterface
+{
+ Q_DISABLE_COPY(EmbeddedOptionsPage)
+public:
+ explicit EmbeddedOptionsPage(QDesignerFormEditorInterface *core);
+
+ QString name() const;
+ QWidget *createPage(QWidget *parent);
+ virtual void finish();
+ virtual void apply();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QPointer<EmbeddedOptionsControl> m_embeddedOptionsControl;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // EMBEDDEDOPTIONSPAGE_H
diff --git a/tools/designer/src/components/formeditor/formeditor.cpp b/tools/designer/src/components/formeditor/formeditor.cpp
new file mode 100644
index 0000000..b09ffab
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formeditor.h"
+#include "formeditor_optionspage.h"
+#include "embeddedoptionspage.h"
+#include "templateoptionspage.h"
+#include "metadatabase_p.h"
+#include "widgetdatabase_p.h"
+#include "widgetfactory_p.h"
+#include "formwindowmanager.h"
+#include "qmainwindow_container.h"
+#include "qworkspace_container.h"
+#include "qmdiarea_container.h"
+#include "qwizard_container.h"
+#include "default_container.h"
+#include "default_layoutdecoration.h"
+#include "default_actionprovider.h"
+#include "qlayoutwidget_propertysheet.h"
+#include "spacer_propertysheet.h"
+#include "line_propertysheet.h"
+#include "layout_propertysheet.h"
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_tabwidget_p.h"
+#include "qtbrushmanager.h"
+#include "brushmanagerproxy.h"
+#include "iconcache.h"
+#include "qtresourcemodel_p.h"
+#include "qdesigner_integration_p.h"
+#include "itemview_propertysheet.h"
+
+// sdk
+#include <QtDesigner/QExtensionManager>
+
+// shared
+#include <pluginmanager_p.h>
+#include <qdesigner_taskmenu_p.h>
+#include <qdesigner_membersheet_p.h>
+#include <qdesigner_promotion_p.h>
+#include <dialoggui_p.h>
+#include <qdesigner_introspection_p.h>
+#include <qdesigner_qsettings_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+FormEditor::FormEditor(QObject *parent)
+ : QDesignerFormEditorInterface(parent)
+{
+ setIntrospection(new QDesignerIntrospection);
+ setDialogGui(new DialogGui);
+ QDesignerPluginManager *pluginManager = new QDesignerPluginManager(this);
+ setPluginManager(pluginManager);
+
+ WidgetDataBase *widgetDatabase = new WidgetDataBase(this, this);
+ setWidgetDataBase(widgetDatabase);
+
+ MetaDataBase *metaDataBase = new MetaDataBase(this, this);
+ setMetaDataBase(metaDataBase);
+
+ WidgetFactory *widgetFactory = new WidgetFactory(this, this);
+ setWidgetFactory(widgetFactory);
+
+ FormWindowManager *formWindowManager = new FormWindowManager(this, this);
+ setFormManager(formWindowManager);
+ connect(formWindowManager, SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)), widgetFactory, SLOT(formWindowAdded(QDesignerFormWindowInterface*)));
+ connect(formWindowManager, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), widgetFactory, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+
+ QExtensionManager *mgr = new QExtensionManager(this);
+ const QString containerExtensionId = Q_TYPEID(QDesignerContainerExtension);
+
+ QDesignerStackedWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
+ QDesignerTabWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
+ QDesignerToolBoxContainerFactory::registerExtension(mgr, containerExtensionId);
+ QMainWindowContainerFactory::registerExtension(mgr, containerExtensionId);
+ QDockWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
+ QScrollAreaContainerFactory::registerExtension(mgr, containerExtensionId);
+ QWorkspaceContainerFactory::registerExtension(mgr, containerExtensionId);
+ QMdiAreaContainerFactory::registerExtension(mgr, containerExtensionId);
+ QWizardContainerFactory::registerExtension(mgr, containerExtensionId);
+
+ mgr->registerExtensions(new QDesignerLayoutDecorationFactory(mgr),
+ Q_TYPEID(QDesignerLayoutDecorationExtension));
+
+ const QString actionProviderExtensionId = Q_TYPEID(QDesignerActionProviderExtension);
+ QToolBarActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
+ QMenuBarActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
+ QMenuActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
+
+ QDesignerDefaultPropertySheetFactory::registerExtension(mgr);
+ QLayoutWidgetPropertySheetFactory::registerExtension(mgr);
+ SpacerPropertySheetFactory::registerExtension(mgr);
+ LinePropertySheetFactory::registerExtension(mgr);
+ LayoutPropertySheetFactory::registerExtension(mgr);
+ QStackedWidgetPropertySheetFactory::registerExtension(mgr);
+ QToolBoxWidgetPropertySheetFactory::registerExtension(mgr);
+ QTabWidgetPropertySheetFactory::registerExtension(mgr);
+ QMdiAreaPropertySheetFactory::registerExtension(mgr);
+ QWorkspacePropertySheetFactory::registerExtension(mgr);
+ QWizardPagePropertySheetFactory::registerExtension(mgr);
+ QWizardPropertySheetFactory::registerExtension(mgr);
+
+ QTreeViewPropertySheetFactory::registerExtension(mgr);
+ QTableViewPropertySheetFactory::registerExtension(mgr);
+
+ const QString internalTaskMenuId = QLatin1String("QDesignerInternalTaskMenuExtension");
+ QDesignerTaskMenuFactory::registerExtension(mgr, internalTaskMenuId);
+
+ mgr->registerExtensions(new QDesignerMemberSheetFactory(mgr),
+ Q_TYPEID(QDesignerMemberSheetExtension));
+
+ setExtensionManager(mgr);
+
+ setIconCache(new IconCache(this));
+
+ QtBrushManager *brushManager = new QtBrushManager(this);
+ setBrushManager(brushManager);
+
+ BrushManagerProxy *brushProxy = new BrushManagerProxy(this, this);
+ brushProxy->setBrushManager(brushManager);
+ setPromotion(new QDesignerPromotion(this));
+
+ QtResourceModel *resourceModel = new QtResourceModel(this);
+ setResourceModel(resourceModel);
+ connect(resourceModel, SIGNAL(qrcFileModifiedExternally(const QString &)),
+ this, SLOT(slotQrcFileChangedExternally(const QString &)));
+
+ QList<QDesignerOptionsPageInterface*> optionsPages;
+ optionsPages << new TemplateOptionsPage(this) << new FormEditorOptionsPage(this) << new EmbeddedOptionsPage(this);
+ setOptionsPages(optionsPages);
+
+ setSettingsManager(new QDesignerQSettings());
+}
+
+FormEditor::~FormEditor()
+{
+}
+
+void FormEditor::slotQrcFileChangedExternally(const QString &path)
+{
+ QDesignerIntegration *designerIntegration = qobject_cast<QDesignerIntegration *>(integration());
+ if (!designerIntegration)
+ return;
+
+ QDesignerIntegration::ResourceFileWatcherBehaviour behaviour = designerIntegration->resourceFileWatcherBehaviour();
+ if (behaviour == QDesignerIntegration::NoWatcher) {
+ return;
+ } else if (behaviour == QDesignerIntegration::PromptAndReload) {
+ QMessageBox::StandardButton button = dialogGui()->message(topLevel(), QDesignerDialogGuiInterface::FileChangedMessage, QMessageBox::Warning,
+ tr("Resource File Changed"),
+ tr("The file \"%1\" has changed outside Designer. Do you want to reload it?").arg(path),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+ if (button != QMessageBox::Yes)
+ return;
+ }
+
+ resourceModel()->reload(path);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formeditor.h b/tools/designer/src/components/formeditor/formeditor.h
new file mode 100644
index 0000000..2e0b819
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMEDITOR_H
+#define FORMEDITOR_H
+
+#include "formeditor_global.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT FormEditor: public QDesignerFormEditorInterface
+{
+ Q_OBJECT
+public:
+ FormEditor(QObject *parent = 0);
+ virtual ~FormEditor();
+public slots:
+ void slotQrcFileChangedExternally(const QString &path);
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMEDITOR_H
diff --git a/tools/designer/src/components/formeditor/formeditor.pri b/tools/designer/src/components/formeditor/formeditor.pri
new file mode 100644
index 0000000..bbe96d5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor.pri
@@ -0,0 +1,75 @@
+
+QT += xml
+
+INCLUDEPATH += $$PWD
+
+FORMS += $$PWD/deviceprofiledialog.ui \
+ $$PWD/formwindowsettings.ui \
+ $$PWD/templateoptionspage.ui
+
+HEADERS += $$PWD/qdesigner_resource.h \
+ $$PWD/formwindow.h \
+ $$PWD/formwindow_widgetstack.h \
+ $$PWD/formwindow_dnditem.h \
+ $$PWD/formwindowcursor.h \
+ $$PWD/widgetselection.h \
+ $$PWD/formwindowmanager.h \
+ $$PWD/formeditor.h \
+ $$PWD/formeditor_global.h \
+ $$PWD/qlayoutwidget_propertysheet.h \
+ $$PWD/layout_propertysheet.h \
+ $$PWD/spacer_propertysheet.h \
+ $$PWD/line_propertysheet.h \
+ $$PWD/default_container.h \
+ $$PWD/default_actionprovider.h \
+ $$PWD/qmainwindow_container.h \
+ $$PWD/qworkspace_container.h \
+ $$PWD/qmdiarea_container.h \
+ $$PWD/qwizard_container.h \
+ $$PWD/default_layoutdecoration.h \
+ $$PWD/qtbrushmanager.h \
+ $$PWD/brushmanagerproxy.h \
+ $$PWD/iconcache.h \
+ $$PWD/tool_widgeteditor.h \
+ $$PWD/formeditor_optionspage.h \
+ $$PWD/embeddedoptionspage.h \
+ $$PWD/formwindowsettings.h \
+ $$PWD/deviceprofiledialog.h \
+ $$PWD/dpi_chooser.h \
+ $$PWD/previewactiongroup.h \
+ $$PWD/itemview_propertysheet.h \
+ $$PWD/templateoptionspage.h
+
+SOURCES += $$PWD/qdesigner_resource.cpp \
+ $$PWD/formwindow.cpp \
+ $$PWD/formwindow_widgetstack.cpp \
+ $$PWD/formwindow_dnditem.cpp \
+ $$PWD/formwindowcursor.cpp \
+ $$PWD/widgetselection.cpp \
+ $$PWD/formwindowmanager.cpp \
+ $$PWD/formeditor.cpp \
+ $$PWD/qlayoutwidget_propertysheet.cpp \
+ $$PWD/layout_propertysheet.cpp \
+ $$PWD/spacer_propertysheet.cpp \
+ $$PWD/line_propertysheet.cpp \
+ $$PWD/qmainwindow_container.cpp \
+ $$PWD/qworkspace_container.cpp \
+ $$PWD/qmdiarea_container.cpp \
+ $$PWD/qwizard_container.cpp \
+ $$PWD/default_container.cpp \
+ $$PWD/default_layoutdecoration.cpp \
+ $$PWD/default_actionprovider.cpp \
+ $$PWD/tool_widgeteditor.cpp \
+ $$PWD/qtbrushmanager.cpp \
+ $$PWD/brushmanagerproxy.cpp \
+ $$PWD/iconcache.cpp \
+ $$PWD/formeditor_optionspage.cpp \
+ $$PWD/embeddedoptionspage.cpp \
+ $$PWD/formwindowsettings.cpp \
+ $$PWD/deviceprofiledialog.cpp \
+ $$PWD/dpi_chooser.cpp \
+ $$PWD/previewactiongroup.cpp \
+ $$PWD/itemview_propertysheet.cpp \
+ $$PWD/templateoptionspage.cpp
+
+RESOURCES += $$PWD/formeditor.qrc
diff --git a/tools/designer/src/components/formeditor/formeditor.qrc b/tools/designer/src/components/formeditor/formeditor.qrc
new file mode 100644
index 0000000..83cc9c7
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor.qrc
@@ -0,0 +1,173 @@
+<RCC>
+ <qresource prefix="/trolltech/formeditor">
+ <file>images/submenu.png</file>
+ <file>images/cursors/arrow.png</file>
+ <file>images/cursors/busy.png</file>
+ <file>images/cursors/closedhand.png</file>
+ <file>images/cursors/cross.png</file>
+ <file>images/cursors/hand.png</file>
+ <file>images/cursors/hsplit.png</file>
+ <file>images/cursors/ibeam.png</file>
+ <file>images/cursors/no.png</file>
+ <file>images/cursors/openhand.png</file>
+ <file>images/cursors/sizeall.png</file>
+ <file>images/cursors/sizeb.png</file>
+ <file>images/cursors/sizef.png</file>
+ <file>images/cursors/sizeh.png</file>
+ <file>images/cursors/sizev.png</file>
+ <file>images/cursors/uparrow.png</file>
+ <file>images/cursors/vsplit.png</file>
+ <file>images/cursors/wait.png</file>
+ <file>images/cursors/whatsthis.png</file>
+ <file>images/emptyicon.png</file>
+ <file>images/filenew-16.png</file>
+ <file>images/fileopen-16.png</file>
+ <file>images/editdelete-16.png</file>
+ <file>images/plus-16.png</file>
+ <file>images/minus-16.png</file>
+ <file>images/prefix-add.png</file>
+ <file>images/downplus.png</file>
+ <file>images/leveldown.png</file>
+ <file>images/levelup.png</file>
+ <file>images/mac/adjustsize.png</file>
+ <file>images/mac/widgettool.png</file>
+ <file>images/mac/signalslottool.png</file>
+ <file>images/mac/tabordertool.png</file>
+ <file>images/mac/buddytool.png</file>
+ <file>images/mac/editbreaklayout.png</file>
+ <file>images/mac/editcopy.png</file>
+ <file>images/mac/editcut.png</file>
+ <file>images/mac/editdelete.png</file>
+ <file>images/mac/editgrid.png</file>
+ <file>images/mac/editform.png</file>
+ <file>images/mac/edithlayout.png</file>
+ <file>images/mac/edithlayoutsplit.png</file>
+ <file>images/mac/editlower.png</file>
+ <file>images/mac/editpaste.png</file>
+ <file>images/mac/editraise.png</file>
+ <file>images/mac/editvlayout.png</file>
+ <file>images/mac/editvlayoutsplit.png</file>
+ <file>images/mac/filenew.png</file>
+ <file>images/mac/insertimage.png</file>
+ <file>images/mac/undo.png</file>
+ <file>images/mac/redo.png</file>
+ <file>images/mac/fileopen.png</file>
+ <file>images/mac/filesave.png</file>
+ <file>images/mac/resourceeditortool.png</file>
+ <file>images/mac/plus.png</file>
+ <file>images/mac/minus.png</file>
+ <file>images/mac/back.png</file>
+ <file>images/mac/forward.png</file>
+ <file>images/mac/down.png</file>
+ <file>images/mac/up.png</file>
+ <file>images/qtlogo.png</file>
+ <file>images/qt3logo.png</file>
+ <file>images/resetproperty.png</file>
+ <file>images/sort.png</file>
+ <file>images/edit.png</file>
+ <file>images/reload.png</file>
+ <file>images/configure.png</file>
+ <file>images/color.png</file>
+ <file>images/dropdownbutton.png</file>
+ <file>images/widgets/calendarwidget.png</file>
+ <file>images/widgets/checkbox.png</file>
+ <file>images/widgets/columnview.png</file>
+ <file>images/widgets/combobox.png</file>
+ <file>images/widgets/commandlinkbutton.png</file>
+ <file>images/widgets/dateedit.png</file>
+ <file>images/widgets/datetimeedit.png</file>
+ <file>images/widgets/dial.png</file>
+ <file>images/widgets/dialogbuttonbox.png</file>
+ <file>images/widgets/dockwidget.png</file>
+ <file>images/widgets/doublespinbox.png</file>
+ <file>images/widgets/fontcombobox.png</file>
+ <file>images/widgets/frame.png</file>
+ <file>images/widgets/graphicsview.png</file>
+ <file>images/widgets/groupbox.png</file>
+ <file>images/widgets/hscrollbar.png</file>
+ <file>images/widgets/hslider.png</file>
+ <file>images/widgets/hsplit.png</file>
+ <file>images/widgets/label.png</file>
+ <file>images/widgets/lcdnumber.png</file>
+ <file>images/widgets/line.png</file>
+ <file>images/widgets/lineedit.png</file>
+ <file>images/widgets/listbox.png</file>
+ <file>images/widgets/listview.png</file>
+ <file>images/widgets/mdiarea.png</file>
+ <file>images/widgets/plaintextedit.png</file>
+ <file>images/widgets/progress.png</file>
+ <file>images/widgets/pushbutton.png</file>
+ <file>images/widgets/radiobutton.png</file>
+ <file>images/widgets/scrollarea.png</file>
+ <file>images/widgets/spacer.png</file>
+ <file>images/widgets/spinbox.png</file>
+ <file>images/widgets/table.png</file>
+ <file>images/widgets/tabwidget.png</file>
+ <file>images/widgets/textedit.png</file>
+ <file>images/widgets/timeedit.png</file>
+ <file>images/widgets/toolbox.png</file>
+ <file>images/widgets/toolbutton.png</file>
+ <file>images/widgets/vline.png</file>
+ <file>images/widgets/vscrollbar.png</file>
+ <file>images/widgets/vslider.png</file>
+ <file>images/widgets/vspacer.png</file>
+ <file>images/widgets/widget.png</file>
+ <file>images/widgets/widget.png</file>
+ <file>images/widgets/widgetstack.png</file>
+ <file>images/widgets/wizard.png</file>
+ <file>images/win/adjustsize.png</file>
+ <file>images/win/widgettool.png</file>
+ <file>images/win/signalslottool.png</file>
+ <file>images/win/tabordertool.png</file>
+ <file>images/win/buddytool.png</file>
+ <file>images/win/editbreaklayout.png</file>
+ <file>images/win/editcopy.png</file>
+ <file>images/win/editcut.png</file>
+ <file>images/win/editdelete.png</file>
+ <file>images/win/editgrid.png</file>
+ <file>images/win/editform.png</file>
+ <file>images/win/edithlayout.png</file>
+ <file>images/win/edithlayoutsplit.png</file>
+ <file>images/win/editlower.png</file>
+ <file>images/win/editpaste.png</file>
+ <file>images/win/editraise.png</file>
+ <file>images/win/editvlayout.png</file>
+ <file>images/win/editvlayoutsplit.png</file>
+ <file>images/win/filenew.png</file>
+ <file>images/win/insertimage.png</file>
+ <file>images/win/undo.png</file>
+ <file>images/win/redo.png</file>
+ <file>images/win/fileopen.png</file>
+ <file>images/win/filesave.png</file>
+ <file>images/win/resourceeditortool.png</file>
+ <file>images/win/plus.png</file>
+ <file>images/win/minus.png</file>
+ <file>images/win/textanchor.png</file>
+ <file>images/win/textbold.png</file>
+ <file>images/win/textitalic.png</file>
+ <file>images/win/textunder.png</file>
+ <file>images/win/textleft.png</file>
+ <file>images/win/textcenter.png</file>
+ <file>images/win/textright.png</file>
+ <file>images/win/textjustify.png</file>
+ <file>images/win/textsuperscript.png</file>
+ <file>images/win/textsubscript.png</file>
+ <file>images/win/back.png</file>
+ <file>images/win/forward.png</file>
+ <file>images/win/down.png</file>
+ <file>images/win/up.png</file>
+ <file>images/mac/textanchor.png</file>
+ <file>images/mac/textbold.png</file>
+ <file>images/mac/textitalic.png</file>
+ <file>images/mac/textunder.png</file>
+ <file>images/mac/textleft.png</file>
+ <file>images/mac/textcenter.png</file>
+ <file>images/mac/textright.png</file>
+ <file>images/mac/textjustify.png</file>
+ <file>images/mac/textsuperscript.png</file>
+ <file>images/mac/textsubscript.png</file>
+ </qresource>
+ <qresource prefix="/trolltech/brushes">
+ <file>defaultbrushes.xml</file>
+ </qresource>
+</RCC>
diff --git a/tools/designer/src/components/formeditor/formeditor_global.h b/tools/designer/src/components/formeditor/formeditor_global.h
new file mode 100644
index 0000000..0195f1b
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMEDITOR_GLOBAL_H
+#define FORMEDITOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_FORMEDITOR_LIBRARY
+# define QT_FORMEDITOR_EXPORT
+#else
+# define QT_FORMEDITOR_EXPORT
+#endif
+#else
+#define QT_FORMEDITOR_EXPORT
+#endif
+
+#endif // FORMEDITOR_GLOBAL_H
diff --git a/tools/designer/src/components/formeditor/formeditor_optionspage.cpp b/tools/designer/src/components/formeditor/formeditor_optionspage.cpp
new file mode 100644
index 0000000..0b20531
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor_optionspage.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formeditor_optionspage.h"
+
+// shared
+#include "formwindowbase_p.h"
+#include "gridpanel_p.h"
+#include "grid_p.h"
+#include "previewconfigurationwidget_p.h"
+#include "shared_settings_p.h"
+#include "zoomwidget_p.h"
+
+// SDK
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtCore/QString>
+#include <QtCore/QCoreApplication>
+#include <QtGui/QGroupBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QComboBox>
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<int> IntList;
+
+namespace qdesigner_internal {
+
+// Zoom, currently for preview only
+class ZoomSettingsWidget : public QGroupBox {
+ Q_DISABLE_COPY(ZoomSettingsWidget)
+public:
+ explicit ZoomSettingsWidget(QWidget *parent = 0);
+
+ void fromSettings(const QDesignerSharedSettings &s);
+ void toSettings(QDesignerSharedSettings &s) const;
+
+private:
+ QComboBox *m_zoomCombo;
+};
+
+ZoomSettingsWidget::ZoomSettingsWidget(QWidget *parent) :
+ QGroupBox(parent),
+ m_zoomCombo(new QComboBox)
+{
+ m_zoomCombo->setEditable(false);
+ const IntList zoomValues = ZoomMenu::zoomValues();
+ const IntList::const_iterator cend = zoomValues.constEnd();
+ //: Zoom percentage
+ for (IntList::const_iterator it = zoomValues.constBegin(); it != cend; ++it)
+ m_zoomCombo->addItem(QCoreApplication::translate("FormEditorOptionsPage", "%1 %").arg(*it), QVariant(*it));
+
+ // Layout
+ setCheckable(true);
+ setTitle(QCoreApplication::translate("FormEditorOptionsPage", "Preview Zoom"));
+ QFormLayout *lt = new QFormLayout;
+ lt->addRow(QCoreApplication::translate("FormEditorOptionsPage", "Default Zoom"), m_zoomCombo);
+ setLayout(lt);
+}
+
+void ZoomSettingsWidget::fromSettings(const QDesignerSharedSettings &s)
+{
+ setChecked(s.zoomEnabled());
+ const int idx = m_zoomCombo->findData(QVariant(s.zoom()));
+ m_zoomCombo->setCurrentIndex(qMax(0, idx));
+}
+
+void ZoomSettingsWidget::toSettings(QDesignerSharedSettings &s) const
+{
+ s.setZoomEnabled(isChecked());
+ const int zoom = m_zoomCombo->itemData(m_zoomCombo->currentIndex()).toInt();
+ s.setZoom(zoom);
+}
+
+
+
+// FormEditorOptionsPage:
+FormEditorOptionsPage::FormEditorOptionsPage(QDesignerFormEditorInterface *core)
+ : m_core(core)
+{
+}
+
+QString FormEditorOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("FormEditorOptionsPage", "Forms");
+}
+
+QWidget *FormEditorOptionsPage::createPage(QWidget *parent)
+{
+ QWidget *optionsWidget = new QWidget(parent);
+
+ const QDesignerSharedSettings settings(m_core);
+ m_previewConf = new PreviewConfigurationWidget(m_core);
+ m_zoomSettingsWidget = new ZoomSettingsWidget;
+ m_zoomSettingsWidget->fromSettings(settings);
+
+ m_defaultGridConf = new GridPanel();
+ m_defaultGridConf->setTitle(QCoreApplication::translate("FormEditorOptionsPage", "Default Grid"));
+ m_defaultGridConf->setGrid(settings.defaultGrid());
+
+ QVBoxLayout *optionsVLayout = new QVBoxLayout();
+ optionsVLayout->addWidget(m_defaultGridConf);
+ optionsVLayout->addWidget(m_previewConf);
+ optionsVLayout->addWidget(m_zoomSettingsWidget);
+ optionsVLayout->addStretch(1);
+
+ // Outer layout to give it horizontal stretch
+ QHBoxLayout *optionsHLayout = new QHBoxLayout();
+ optionsHLayout->addLayout(optionsVLayout);
+ optionsHLayout->addStretch(1);
+ optionsWidget->setLayout(optionsHLayout);
+
+ return optionsWidget;
+}
+
+void FormEditorOptionsPage::apply()
+{
+ QDesignerSharedSettings settings(m_core);
+ if (m_defaultGridConf) {
+ const Grid defaultGrid = m_defaultGridConf->grid();
+ settings.setDefaultGrid(defaultGrid);
+
+ FormWindowBase::setDefaultDesignerGrid(defaultGrid);
+ // Update grid settings in all existing form windows
+ QDesignerFormWindowManagerInterface *fwm = m_core->formWindowManager();
+ if (const int numWindows = fwm->formWindowCount()) {
+ for (int i = 0; i < numWindows; i++)
+ if (qdesigner_internal::FormWindowBase *fwb
+ = qobject_cast<qdesigner_internal::FormWindowBase *>( fwm->formWindow(i)))
+ if (!fwb->hasFormGrid())
+ fwb->setDesignerGrid(defaultGrid);
+ }
+ }
+ if (m_previewConf) {
+ m_previewConf->saveState();
+ }
+
+ if (m_zoomSettingsWidget)
+ m_zoomSettingsWidget->toSettings(settings);
+}
+
+void FormEditorOptionsPage::finish()
+{
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formeditor_optionspage.h b/tools/designer/src/components/formeditor/formeditor_optionspage.h
new file mode 100644
index 0000000..4aeda6a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formeditor_optionspage.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMEDITOR_OPTIONSPAGE_H
+#define FORMEDITOR_OPTIONSPAGE_H
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class PreviewConfigurationWidget;
+class GridPanel;
+class ZoomSettingsWidget;
+
+class FormEditorOptionsPage : public QDesignerOptionsPageInterface
+{
+public:
+ explicit FormEditorOptionsPage(QDesignerFormEditorInterface *core);
+
+ QString name() const;
+ QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QPointer<PreviewConfigurationWidget> m_previewConf;
+ QPointer<GridPanel> m_defaultGridConf;
+ QPointer<ZoomSettingsWidget> m_zoomSettingsWidget;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMEDITOR_OPTIONSPAGE_H
diff --git a/tools/designer/src/components/formeditor/formwindow.cpp b/tools/designer/src/components/formeditor/formwindow.cpp
new file mode 100644
index 0000000..07d785a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindow.cpp
@@ -0,0 +1,2917 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindow.h"
+#include "formeditor.h"
+#include "formwindow_dnditem.h"
+#include "formwindow_widgetstack.h"
+#include "formwindowcursor.h"
+#include "formwindowmanager.h"
+#include "tool_widgeteditor.h"
+#include "widgetselection.h"
+#include "qtresourcemodel_p.h"
+#include "widgetfactory_p.h"
+
+// shared
+#include <metadatabase_p.h>
+#include <qdesigner_tabwidget_p.h>
+#include <qdesigner_toolbox_p.h>
+#include <qdesigner_stackedbox_p.h>
+#include <qdesigner_resource.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_command2_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <qdesigner_taskmenu_p.h>
+#include <qdesigner_widget_p.h>
+#include <qdesigner_utils_p.h>
+#include <qlayout_widget_p.h>
+#include <spacer_widget_p.h>
+#include <invisible_widget_p.h>
+#include <layoutinfo_p.h>
+#include <qdesigner_objectinspector_p.h>
+#include <connectionedit_p.h>
+#include <actionprovider_p.h>
+#include <ui4_p.h>
+#include <deviceprofile_p.h>
+#include <shared_settings_p.h>
+#include <grid_p.h>
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <abstractdialoggui_p.h>
+
+#include <QtCore/QtDebug>
+#include <QtCore/QBuffer>
+#include <QtCore/QTimer>
+#include <QtCore/QXmlStreamReader>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QClipboard>
+#include <QtGui/QUndoGroup>
+#include <QtGui/QScrollArea>
+#include <QtGui/QRubberBand>
+#include <QtGui/QApplication>
+#include <QtGui/QSplitter>
+#include <QtGui/QPainter>
+#include <QtGui/QGroupBox>
+#include <QtGui/QDockWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QButtonGroup>
+
+Q_DECLARE_METATYPE(QWidget*)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+class BlockSelection
+{
+public:
+ BlockSelection(qdesigner_internal::FormWindow *fw)
+ : m_formWindow(fw),
+ m_blocked(m_formWindow->blockSelectionChanged(true))
+ {
+ }
+
+ ~BlockSelection()
+ {
+ if (m_formWindow)
+ m_formWindow->blockSelectionChanged(m_blocked);
+ }
+
+private:
+ QPointer<qdesigner_internal::FormWindow> m_formWindow;
+ const bool m_blocked;
+};
+
+enum { debugFormWindow = 0 };
+}
+
+namespace qdesigner_internal {
+
+// ------------------------ FormWindow::Selection
+// Maintains a pool of WidgetSelections to be used for selected widgets.
+
+class FormWindow::Selection
+{
+public:
+ Selection();
+ ~Selection();
+
+ // Clear
+ void clear();
+
+ // Also clear out the pool. Call if reparenting of the main container occurs.
+ void clearSelectionPool();
+
+ void repaintSelection(QWidget *w);
+ void repaintSelection();
+
+ bool isWidgetSelected(QWidget *w) const;
+ QWidgetList selectedWidgets() const;
+
+ WidgetSelection *addWidget(FormWindow* fw, QWidget *w);
+ // remove widget, return new current widget or 0
+ QWidget* removeWidget(QWidget *w);
+
+ void raiseList(const QWidgetList& l);
+ void raiseWidget(QWidget *w);
+
+ void updateGeometry(QWidget *w);
+
+ void hide(QWidget *w);
+ void show(QWidget *w);
+
+private:
+
+ typedef QList<WidgetSelection *> SelectionPool;
+ SelectionPool m_selectionPool;
+
+ typedef QHash<QWidget *, WidgetSelection *> SelectionHash;
+ SelectionHash m_usedSelections;
+};
+
+FormWindow::Selection::Selection()
+{
+}
+
+FormWindow::Selection::~Selection()
+{
+ clearSelectionPool();
+}
+
+void FormWindow::Selection::clear()
+{
+ if (!m_usedSelections.empty()) {
+ const SelectionHash::iterator mend = m_usedSelections.end();
+ for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
+ it.value()->setWidget(0);
+ }
+ m_usedSelections.clear();
+ }
+}
+
+void FormWindow::Selection::clearSelectionPool()
+{
+ clear();
+ qDeleteAll(m_selectionPool);
+ m_selectionPool.clear();
+}
+
+WidgetSelection *FormWindow::Selection::addWidget(FormWindow* fw, QWidget *w)
+{
+ WidgetSelection *rc = m_usedSelections.value(w);
+ if (rc != 0) {
+ rc->show();
+ rc->updateActive();
+ return rc;
+ }
+ // find a free one in the pool
+ const SelectionPool::iterator pend = m_selectionPool.end();
+ for (SelectionPool::iterator it = m_selectionPool.begin(); it != pend; ++it) {
+ if (! (*it)->isUsed()) {
+ rc = *it;
+ break;
+ }
+ }
+
+ if (rc == 0) {
+ rc = new WidgetSelection(fw);
+ m_selectionPool.push_back(rc);
+ }
+
+ m_usedSelections.insert(w, rc);
+ rc->setWidget(w);
+ return rc;
+}
+
+QWidget* FormWindow::Selection::removeWidget(QWidget *w)
+{
+ WidgetSelection *s = m_usedSelections.value(w);
+ if (!s)
+ return w;
+
+ s->setWidget(0);
+ m_usedSelections.remove(w);
+
+ if (m_usedSelections.isEmpty())
+ return 0;
+
+ return (*m_usedSelections.begin())->widget();
+}
+
+void FormWindow::Selection::repaintSelection(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->update();
+}
+
+void FormWindow::Selection::repaintSelection()
+{
+ const SelectionHash::iterator mend = m_usedSelections.end();
+ for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
+ it.value()->update();
+ }
+}
+
+bool FormWindow::Selection::isWidgetSelected(QWidget *w) const{
+ return m_usedSelections.contains(w);
+}
+
+QWidgetList FormWindow::Selection::selectedWidgets() const
+{
+ return m_usedSelections.keys();
+}
+
+void FormWindow::Selection::raiseList(const QWidgetList& l)
+{
+ const SelectionHash::iterator mend = m_usedSelections.end();
+ for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
+ WidgetSelection *w = it.value();
+ if (l.contains(w->widget()))
+ w->show();
+ }
+}
+
+void FormWindow::Selection::raiseWidget(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->show();
+}
+
+void FormWindow::Selection::updateGeometry(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w)) {
+ s->updateGeometry();
+ }
+}
+
+void FormWindow::Selection::hide(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->hide();
+}
+
+void FormWindow::Selection::show(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->show();
+}
+
+// ------------------------ FormWindow
+FormWindow::FormWindow(FormEditor *core, QWidget *parent, Qt::WindowFlags flags) :
+ FormWindowBase(core, parent, flags),
+ m_mouseState(NoMouseState),
+ m_core(core),
+ m_selection(new Selection),
+ m_widgetStack(new FormWindowWidgetStack(this)),
+ m_contextMenuPosition(-1, -1)
+{
+ // Apply settings to formcontainer
+ deviceProfile().apply(core, m_widgetStack->formContainer(), qdesigner_internal::DeviceProfile::ApplyFormParent);
+
+ setLayout(m_widgetStack->layout());
+ init();
+
+ m_cursor = new FormWindowCursor(this, this);
+
+ core->formWindowManager()->addFormWindow(this);
+
+ setDirty(false);
+ setAcceptDrops(true);
+}
+
+FormWindow::~FormWindow()
+{
+ Q_ASSERT(core() != 0);
+ Q_ASSERT(core()->metaDataBase() != 0);
+ Q_ASSERT(core()->formWindowManager() != 0);
+
+ core()->formWindowManager()->removeFormWindow(this);
+ core()->metaDataBase()->remove(this);
+
+ QWidgetList l = widgets();
+ foreach (QWidget *w, l)
+ core()->metaDataBase()->remove(w);
+
+ m_widgetStack = 0;
+ m_rubberBand = 0;
+ if (resourceSet())
+ core()->resourceModel()->removeResourceSet(resourceSet());
+ delete m_selection;
+}
+
+QDesignerFormEditorInterface *FormWindow::core() const
+{
+ return m_core;
+}
+
+QDesignerFormWindowCursorInterface *FormWindow::cursor() const
+{
+ return m_cursor;
+}
+
+void FormWindow::updateWidgets()
+{
+ if (!m_mainContainer)
+ return;
+}
+
+int FormWindow::widgetDepth(const QWidget *w)
+{
+ int d = -1;
+ while (w && !w->isWindow()) {
+ d++;
+ w = w->parentWidget();
+ }
+
+ return d;
+}
+
+bool FormWindow::isChildOf(const QWidget *c, const QWidget *p)
+{
+ while (c) {
+ if (c == p)
+ return true;
+ c = c->parentWidget();
+ }
+ return false;
+}
+
+void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
+{
+#ifndef QT_NO_CURSOR
+ start->setCursor(c);
+ const QWidgetList widgets = qFindChildren<QWidget*>(start);
+ foreach (QWidget *widget, widgets) {
+ if (!qobject_cast<WidgetHandle*>(widget)) {
+ widget->setCursor(c);
+ }
+ }
+#endif
+}
+
+void FormWindow::init()
+{
+ if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
+ m_commandHistory = new QUndoStack(this);
+ manager->undoGroup()->addStack(m_commandHistory);
+ }
+
+ m_blockSelectionChanged = false;
+
+ m_defaultMargin = INT_MIN;
+ m_defaultSpacing = INT_MIN;
+
+ connect(m_widgetStack, SIGNAL(currentToolChanged(int)), this, SIGNAL(toolChanged(int)));
+
+ m_selectionChangedTimer = new QTimer(this);
+ m_selectionChangedTimer->setSingleShot(true);
+ connect(m_selectionChangedTimer, SIGNAL(timeout()), this, SLOT(selectionChangedTimerDone()));
+
+ m_checkSelectionTimer = new QTimer(this);
+ m_checkSelectionTimer->setSingleShot(true);
+ connect(m_checkSelectionTimer, SIGNAL(timeout()), this, SLOT(checkSelectionNow()));
+
+ m_geometryChangedTimer = new QTimer(this);
+ m_geometryChangedTimer->setSingleShot(true);
+ connect(m_geometryChangedTimer, SIGNAL(timeout()), this, SIGNAL(geometryChanged()));
+
+ m_rubberBand = 0;
+
+ setFocusPolicy(Qt::StrongFocus);
+
+ m_mainContainer = 0;
+ m_currentWidget = 0;
+
+ connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(updateDirty()));
+ connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SIGNAL(changed()));
+ connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(checkSelection()));
+
+ core()->metaDataBase()->add(this);
+
+ initializeCoreTools();
+
+ QAction *a = new QAction(this);
+ a->setText(tr("Edit contents"));
+ a->setShortcut(tr("F2"));
+ connect(a, SIGNAL(triggered()), this, SLOT(editContents()));
+ addAction(a);
+}
+
+QWidget *FormWindow::mainContainer() const
+{
+ return m_mainContainer;
+}
+
+
+void FormWindow::clearMainContainer()
+{
+ if (m_mainContainer) {
+ setCurrentTool(0);
+ m_widgetStack->setMainContainer(0);
+ core()->metaDataBase()->remove(m_mainContainer);
+ unmanageWidget(m_mainContainer);
+ delete m_mainContainer;
+ m_mainContainer = 0;
+ }
+}
+
+void FormWindow::setMainContainer(QWidget *w)
+{
+ if (w == m_mainContainer) {
+ // nothing to do
+ return;
+ }
+
+ clearMainContainer();
+
+ m_mainContainer = w;
+ const QSize sz = m_mainContainer->size();
+
+ m_widgetStack->setMainContainer(m_mainContainer);
+ m_widgetStack->setCurrentTool(m_widgetEditor);
+
+ setCurrentWidget(m_mainContainer);
+ manageWidget(m_mainContainer);
+
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), m_mainContainer)) {
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowTitle")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowIcon")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowModality")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowFilePath")), true);
+ // ### generalize
+ }
+
+ m_mainContainer->setFocusPolicy(Qt::StrongFocus);
+ m_mainContainer->resize(sz);
+
+ emit mainContainerChanged(m_mainContainer);
+}
+
+QWidget *FormWindow::findTargetContainer(QWidget *widget) const
+{
+ Q_ASSERT(widget);
+
+ while (QWidget *parentWidget = widget->parentWidget()) {
+ if (LayoutInfo::layoutType(m_core, parentWidget) == LayoutInfo::NoLayout && isManaged(widget))
+ return widget;
+
+ widget = parentWidget;
+ }
+
+ return mainContainer();
+}
+
+static inline void clearObjectInspectorSelection(const QDesignerFormEditorInterface *core)
+{
+ if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core->objectInspector()))
+ oi->clearSelection();
+}
+
+// Find a parent of a desired selection state
+static QWidget *findSelectedParent(QDesignerFormWindowInterface *fw, const QWidget *w, bool selected)
+{
+ const QDesignerFormWindowCursorInterface *cursor = fw->cursor();
+ QWidget *mainContainer = fw->mainContainer();
+ for (QWidget *p = w->parentWidget(); p && p != mainContainer; p = p->parentWidget())
+ if (fw->isManaged(p))
+ if (cursor->isWidgetSelected(p) == selected)
+ return p;
+ return 0;
+}
+
+// Mouse modifiers.
+
+enum MouseFlags { ToggleSelectionModifier = 0x1, CycleParentModifier=0x2, CopyDragModifier=0x4 };
+
+static inline unsigned mouseFlags(Qt::KeyboardModifiers mod)
+{
+ switch (mod) {
+ case Qt::ShiftModifier:
+ return CycleParentModifier;
+ break;
+#ifdef Q_WS_MAC
+ case Qt::AltModifier: // "Alt" or "option" key on Mac means copy
+ return CopyDragModifier;
+#endif
+ case Qt::ControlModifier:
+ return CopyDragModifier|ToggleSelectionModifier;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+// Handle the click selection: Do toggling/cycling
+// of parents according to the modifiers.
+void FormWindow::handleClickSelection(QWidget *managedWidget, unsigned mouseMode)
+{
+ const bool sameWidget = managedWidget == m_lastClickedWidget;
+ m_lastClickedWidget = managedWidget;
+
+ const bool selected = isWidgetSelected(managedWidget);
+ if (debugFormWindow)
+ qDebug() << "handleClickSelection" << managedWidget << " same=" << sameWidget << " mouse= " << mouseMode << " selected=" << selected;
+
+ // // toggle selection state of widget
+ if (mouseMode & ToggleSelectionModifier) {
+ selectWidget(managedWidget, !selected);
+ return;
+ }
+
+ QWidget *selectionCandidate = 0;
+ // Hierarchy cycling: If the same widget clicked again: Attempt to cycle
+ // trough the hierarchy. Find the next currently selected parent
+ if (sameWidget && (mouseMode & CycleParentModifier))
+ if (QWidget *currentlySelectedParent = selected ? managedWidget : findSelectedParent(this, managedWidget, true))
+ selectionCandidate = findSelectedParent(this, currentlySelectedParent, false);
+ // Not the same widget, list wrapped over or there was no unselected parent
+ if (!selectionCandidate && !selected)
+ selectionCandidate = managedWidget;
+
+ if (selectionCandidate)
+ selectSingleWidget(selectionCandidate);
+}
+
+void FormWindow::selectSingleWidget(QWidget *w)
+{
+ clearSelection(false);
+ selectWidget(w, true);
+ raiseChildSelections(w);
+}
+
+bool FormWindow::handleMousePressEvent(QWidget * widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ m_mouseState = NoMouseState;
+ m_startPos = QPoint();
+ e->accept();
+
+ BlockSelection blocker(this);
+
+ if (core()->formWindowManager()->activeFormWindow() != this)
+ core()->formWindowManager()->setActiveFormWindow(this);
+
+ const Qt::MouseButtons buttons = e->buttons();
+ if (buttons != Qt::LeftButton && buttons != Qt::MidButton)
+ return true;
+
+ m_startPos = mapFromGlobal(e->globalPos());
+
+ if (debugFormWindow)
+ qDebug() << "handleMousePressEvent:" << widget << ',' << managedWidget;
+
+ if (buttons == Qt::MidButton || isMainContainer(managedWidget) == true) { // press was on the formwindow
+ clearObjectInspectorSelection(m_core); // We might have a toolbar or non-widget selected in the object inspector.
+ clearSelection(false);
+
+ m_mouseState = MouseDrawRubber;
+ m_currRect = QRect();
+ startRectDraw(mapFromGlobal(e->globalPos()), this, Rubber);
+ return true;
+ }
+ if (buttons != Qt::LeftButton)
+ return true;
+
+ const unsigned mouseMode = mouseFlags(e->modifiers());
+
+ /* Normally, we want to be able to click /select-on-press to drag away
+ * the widget in the next step. However, in the case of a widget which
+ * itself or whose parent is selected, we defer the selection to the
+ * release event.
+ * This is to prevent children from being dragged away from layouts
+ * when their layouts are selected and one wants to move the layout.
+ * Note that toggle selection is only deferred if the widget is already
+ * selected, so, it is still possible to just Ctrl+Click and CopyDrag. */
+ const bool deferSelection = isWidgetSelected(managedWidget) || findSelectedParent(this, managedWidget, true);
+ if (deferSelection) {
+ m_mouseState = MouseDeferredSelection;
+ } else {
+ // Cycle the parent unless we explicitly want toggle
+ const unsigned effectiveMouseMode = (mouseMode & ToggleSelectionModifier) ? mouseMode : static_cast<unsigned>(CycleParentModifier);
+ handleClickSelection(managedWidget, effectiveMouseMode);
+ }
+ return true;
+}
+
+// We can drag widget in managed layouts except splitter.
+static bool canDragWidgetInLayout(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ bool managed;
+ const LayoutInfo::Type type = LayoutInfo::laidoutWidgetType(core ,w, &managed);
+ if (!managed)
+ return false;
+ switch (type) {
+ case LayoutInfo::NoLayout:
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e)
+{
+ e->accept();
+ if (m_startPos.isNull())
+ return true;
+
+ const QPoint pos = mapFromGlobal(e->globalPos());
+
+ switch (m_mouseState) {
+ case MouseDrawRubber: // Rubber band with left/middle mouse
+ continueRectDraw(pos, this, Rubber);
+ return true;
+ case MouseMoveDrag: // Spurious move event after drag started?
+ return true;
+ default:
+ break;
+ }
+
+ if (e->buttons() != Qt::LeftButton)
+ return true;
+
+ const bool canStartDrag = (m_startPos - pos).manhattanLength() > QApplication::startDragDistance();
+
+ if (canStartDrag == false) {
+ // nothing to do
+ return true;
+ }
+
+ m_mouseState = MouseMoveDrag;
+ const bool blocked = blockSelectionChanged(true);
+
+ QWidgetList sel = selectedWidgets();
+ simplifySelection(&sel);
+
+ QSet<QWidget*> widget_set;
+
+ foreach (QWidget *child, sel) { // Move parent layout or container?
+ QWidget *current = child;
+
+ bool done = false;
+ while (!isMainContainer(current) && !done) {
+ if (!isManaged(current)) {
+ current = current->parentWidget();
+ continue;
+ } else if (LayoutInfo::isWidgetLaidout(core(), current)) {
+ // Go up to parent of layout if shift pressed, else do that only for splitters
+ if (!canDragWidgetInLayout(core(), current)) {
+ current = current->parentWidget();
+ continue;
+ }
+ }
+ done = true;
+ }
+
+ if (current == mainContainer())
+ continue;
+
+ widget_set.insert(current);
+ }
+
+ sel = widget_set.toList();
+ QDesignerFormWindowCursorInterface *c = cursor();
+ QWidget *current = c->current();
+ if (sel.contains(current)) {
+ sel.removeAll(current);
+ sel.prepend(current);
+ }
+
+ QList<QDesignerDnDItemInterface*> item_list;
+ const QPoint globalPos = mapToGlobal(m_startPos);
+ const QDesignerDnDItemInterface::DropType dropType = (mouseFlags(e->modifiers()) & CopyDragModifier) ?
+ QDesignerDnDItemInterface::CopyDrop : QDesignerDnDItemInterface::MoveDrop;
+ foreach (QWidget *widget, sel) {
+ item_list.append(new FormWindowDnDItem(dropType, this, widget, globalPos));
+ if (dropType == QDesignerDnDItemInterface::MoveDrop) {
+ m_selection->hide(widget);
+ widget->hide();
+ }
+ }
+
+ blockSelectionChanged(blocked);
+
+ if (!sel.empty()) // reshow selection?
+ if (QDesignerMimeData::execDrag(item_list, core()->topLevel()) == Qt::IgnoreAction && dropType == QDesignerDnDItemInterface::MoveDrop)
+ foreach (QWidget *widget, sel)
+ m_selection->show(widget);
+
+ m_startPos = QPoint();
+
+ return true;
+}
+
+bool FormWindow::handleMouseReleaseEvent(QWidget *w, QWidget *mw, QMouseEvent *e)
+{
+ const MouseState oldState = m_mouseState;
+ m_mouseState = NoMouseState;
+
+ if (debugFormWindow)
+ qDebug() << "handleMouseeleaseEvent:" << w << ',' << mw << "state=" << oldState;
+
+ if (oldState == MouseDoubleClicked)
+ return true;
+
+ e->accept();
+
+ switch (oldState) {
+ case MouseDrawRubber: { // we were drawing a rubber selection
+ endRectDraw(); // get rid of the rectangle
+ const bool blocked = blockSelectionChanged(true);
+ selectWidgets(); // select widgets which intersect the rect
+ blockSelectionChanged(blocked);
+ }
+ break;
+ // Deferred select: Select the child here unless the parent was moved.
+ case MouseDeferredSelection:
+ handleClickSelection(mw, mouseFlags(e->modifiers()));
+ break;
+ default:
+ break;
+ }
+
+ m_startPos = QPoint();
+
+ /* Inform about selection changes (left/mid or context menu). Also triggers
+ * in the case of an empty rubber drag that cleared the selection in
+ * MousePressEvent. */
+ switch (e->button()) {
+ case Qt::LeftButton:
+ case Qt::MidButton:
+ case Qt::RightButton:
+ emitSelectionChanged();
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+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::startRectDraw(const QPoint &pos, QWidget *, RectType t)
+{
+ m_rectAnchor = (t == Insert) ? designerGrid().snapPoint(pos) : pos;
+
+ m_currRect = QRect(m_rectAnchor, QSize(0, 0));
+ if (!m_rubberBand)
+ m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
+ m_rubberBand->setGeometry(m_currRect);
+ m_rubberBand->show();
+}
+
+void FormWindow::continueRectDraw(const QPoint &pos, QWidget *, RectType t)
+{
+ const QPoint p2 = (t == Insert) ? designerGrid().snapPoint(pos) : pos;
+
+ QRect r(m_rectAnchor, p2);
+ r = r.normalized();
+
+ if (m_currRect == r)
+ return;
+
+ if (r.width() > 1 || r.height() > 1) {
+ m_currRect = r;
+ if (m_rubberBand)
+ m_rubberBand->setGeometry(m_currRect);
+ }
+}
+
+void FormWindow::endRectDraw()
+{
+ if (m_rubberBand) {
+ delete m_rubberBand;
+ m_rubberBand = 0;
+ }
+}
+
+QWidget *FormWindow::currentWidget() const
+{
+ return m_currentWidget;
+}
+
+bool FormWindow::setCurrentWidget(QWidget *currentWidget)
+{
+ if (debugFormWindow)
+ qDebug() << "setCurrentWidget:" << m_currentWidget << " --> " << currentWidget;
+ if (currentWidget == m_currentWidget)
+ return false;
+ // repaint the old widget unless it is the main window
+ if (m_currentWidget && m_currentWidget != mainContainer()) {
+ m_selection->repaintSelection(m_currentWidget);
+ }
+ // set new and repaint
+ m_currentWidget = currentWidget;
+ if (m_currentWidget && m_currentWidget != mainContainer()) {
+ m_selection->repaintSelection(m_currentWidget);
+ }
+ return true;
+}
+
+void FormWindow::selectWidget(QWidget* w, bool select)
+{
+ if (trySelectWidget(w, select))
+ emitSelectionChanged();
+}
+
+// Selects a widget and determines the new current one. Returns true if a change occurs.
+bool FormWindow::trySelectWidget(QWidget *w, bool select)
+{
+ if (debugFormWindow)
+ qDebug() << "trySelectWidget:" << w << select;
+ if (!isManaged(w) && !isCentralWidget(w))
+ return false;
+
+ if (!select && !isWidgetSelected(w))
+ return false;
+
+ if (!mainContainer())
+ return false;
+
+ if (isMainContainer(w) || isCentralWidget(w)) {
+ setCurrentWidget(mainContainer());
+ return true;
+ }
+
+ if (select) {
+ setCurrentWidget(w);
+ m_selection->addWidget(this, w);
+ } else {
+ QWidget *newCurrent = m_selection->removeWidget(w);
+ if (!newCurrent)
+ newCurrent = mainContainer();
+ setCurrentWidget(newCurrent);
+ }
+ return true;
+}
+
+void FormWindow::clearSelection(bool changePropertyDisplay)
+{
+ if (debugFormWindow)
+ qDebug() << "clearSelection(" << changePropertyDisplay << ')';
+ // At all events, we need a current widget.
+ m_selection->clear();
+ setCurrentWidget(mainContainer());
+
+ if (changePropertyDisplay)
+ emitSelectionChanged();
+}
+
+void FormWindow::emitSelectionChanged()
+{
+ if (m_blockSelectionChanged == true) {
+ // nothing to do
+ return;
+ }
+
+ m_selectionChangedTimer->start(0);
+}
+
+void FormWindow::selectionChangedTimerDone()
+{
+ emit selectionChanged();
+}
+
+bool FormWindow::isWidgetSelected(QWidget *w) const
+{
+ return m_selection->isWidgetSelected(w);
+}
+
+bool FormWindow::isMainContainer(const QWidget *w) const
+{
+ return w && (w == this || w == mainContainer());
+}
+
+void FormWindow::updateChildSelections(QWidget *w)
+{
+ const QWidgetList l = qFindChildren<QWidget*>(w);
+ if (!l.empty()) {
+ const QWidgetList::const_iterator lcend = l.constEnd();
+ for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it) {
+ QWidget *w = *it;
+ if (isManaged(w))
+ updateSelection(w);
+ }
+ }
+}
+
+void FormWindow::repaintSelection()
+{
+ m_selection->repaintSelection();
+}
+
+void FormWindow::raiseSelection(QWidget *w)
+{
+ m_selection->raiseWidget(w);
+}
+
+void FormWindow::updateSelection(QWidget *w)
+{
+ if (!w->isVisibleTo(this)) {
+ selectWidget(w, false);
+ } else {
+ m_selection->updateGeometry(w);
+ }
+}
+
+QWidget *FormWindow::designerWidget(QWidget *w) const
+{
+ while ((w && !isMainContainer(w) && !isManaged(w)) || isCentralWidget(w))
+ w = w->parentWidget();
+
+ return w;
+}
+
+bool FormWindow::isCentralWidget(QWidget *w) const
+{
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(mainContainer()))
+ return w == mainWindow->centralWidget();
+
+ return false;
+}
+
+void FormWindow::ensureUniqueObjectName(QObject *object)
+{
+ QString name = object->objectName();
+ if (name.isEmpty()) {
+ QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ if (QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(object)))
+ name = qdesigner_internal::qtify(item->name());
+ }
+ unify(object, name, true);
+ object->setObjectName(name);
+}
+
+template <class Iterator>
+static inline void insertNames(const QDesignerMetaDataBaseInterface *metaDataBase,
+ Iterator it, const Iterator &end,
+ QObject *excludedObject, QSet<QString> &nameSet)
+{
+ for ( ; it != end; ++it)
+ if (excludedObject != *it && metaDataBase->item(*it))
+ nameSet.insert((*it)->objectName());
+}
+
+static QSet<QString> languageKeywords()
+{
+ static QSet<QString> keywords;
+ if (keywords.isEmpty()) {
+ // C++ keywords
+ keywords.insert(QLatin1String("asm"));
+ keywords.insert(QLatin1String("auto"));
+ keywords.insert(QLatin1String("bool"));
+ keywords.insert(QLatin1String("break"));
+ keywords.insert(QLatin1String("case"));
+ keywords.insert(QLatin1String("catch"));
+ keywords.insert(QLatin1String("char"));
+ keywords.insert(QLatin1String("class"));
+ keywords.insert(QLatin1String("const"));
+ keywords.insert(QLatin1String("const_cast"));
+ keywords.insert(QLatin1String("continue"));
+ keywords.insert(QLatin1String("default"));
+ keywords.insert(QLatin1String("delete"));
+ keywords.insert(QLatin1String("do"));
+ keywords.insert(QLatin1String("double"));
+ keywords.insert(QLatin1String("dynamic_cast"));
+ keywords.insert(QLatin1String("else"));
+ keywords.insert(QLatin1String("enum"));
+ keywords.insert(QLatin1String("explicit"));
+ keywords.insert(QLatin1String("export"));
+ keywords.insert(QLatin1String("extern"));
+ keywords.insert(QLatin1String("false"));
+ keywords.insert(QLatin1String("float"));
+ keywords.insert(QLatin1String("for"));
+ keywords.insert(QLatin1String("friend"));
+ keywords.insert(QLatin1String("goto"));
+ keywords.insert(QLatin1String("if"));
+ keywords.insert(QLatin1String("inline"));
+ keywords.insert(QLatin1String("int"));
+ keywords.insert(QLatin1String("long"));
+ keywords.insert(QLatin1String("mutable"));
+ keywords.insert(QLatin1String("namespace"));
+ keywords.insert(QLatin1String("new"));
+ keywords.insert(QLatin1String("NULL"));
+ keywords.insert(QLatin1String("operator"));
+ keywords.insert(QLatin1String("private"));
+ keywords.insert(QLatin1String("protected"));
+ keywords.insert(QLatin1String("public"));
+ keywords.insert(QLatin1String("register"));
+ keywords.insert(QLatin1String("reinterpret_cast"));
+ keywords.insert(QLatin1String("return"));
+ keywords.insert(QLatin1String("short"));
+ keywords.insert(QLatin1String("signed"));
+ keywords.insert(QLatin1String("sizeof"));
+ keywords.insert(QLatin1String("static"));
+ keywords.insert(QLatin1String("static_cast"));
+ keywords.insert(QLatin1String("struct"));
+ keywords.insert(QLatin1String("switch"));
+ keywords.insert(QLatin1String("template"));
+ keywords.insert(QLatin1String("this"));
+ keywords.insert(QLatin1String("throw"));
+ keywords.insert(QLatin1String("true"));
+ keywords.insert(QLatin1String("try"));
+ keywords.insert(QLatin1String("typedef"));
+ keywords.insert(QLatin1String("typeid"));
+ keywords.insert(QLatin1String("typename"));
+ keywords.insert(QLatin1String("union"));
+ keywords.insert(QLatin1String("unsigned"));
+ keywords.insert(QLatin1String("using"));
+ keywords.insert(QLatin1String("virtual"));
+ keywords.insert(QLatin1String("void"));
+ keywords.insert(QLatin1String("volatile"));
+ keywords.insert(QLatin1String("wchar_t"));
+ keywords.insert(QLatin1String("while"));
+
+ // java keywords
+ keywords.insert(QLatin1String("abstract"));
+ keywords.insert(QLatin1String("assert"));
+ keywords.insert(QLatin1String("boolean"));
+ keywords.insert(QLatin1String("break"));
+ keywords.insert(QLatin1String("byte"));
+ keywords.insert(QLatin1String("case"));
+ keywords.insert(QLatin1String("catch"));
+ keywords.insert(QLatin1String("char"));
+ keywords.insert(QLatin1String("class"));
+ keywords.insert(QLatin1String("const"));
+ keywords.insert(QLatin1String("continue"));
+ keywords.insert(QLatin1String("default"));
+ keywords.insert(QLatin1String("do"));
+ keywords.insert(QLatin1String("double"));
+ keywords.insert(QLatin1String("else"));
+ keywords.insert(QLatin1String("enum"));
+ keywords.insert(QLatin1String("extends"));
+ keywords.insert(QLatin1String("false"));
+ keywords.insert(QLatin1String("final"));
+ keywords.insert(QLatin1String("finality"));
+ keywords.insert(QLatin1String("float"));
+ keywords.insert(QLatin1String("for"));
+ keywords.insert(QLatin1String("goto"));
+ keywords.insert(QLatin1String("if"));
+ keywords.insert(QLatin1String("implements"));
+ keywords.insert(QLatin1String("import"));
+ keywords.insert(QLatin1String("instanceof"));
+ keywords.insert(QLatin1String("int"));
+ keywords.insert(QLatin1String("interface"));
+ keywords.insert(QLatin1String("long"));
+ keywords.insert(QLatin1String("native"));
+ keywords.insert(QLatin1String("new"));
+ keywords.insert(QLatin1String("null"));
+ keywords.insert(QLatin1String("package"));
+ keywords.insert(QLatin1String("private"));
+ keywords.insert(QLatin1String("protected"));
+ keywords.insert(QLatin1String("public"));
+ keywords.insert(QLatin1String("return"));
+ keywords.insert(QLatin1String("short"));
+ keywords.insert(QLatin1String("static"));
+ keywords.insert(QLatin1String("strictfp"));
+ keywords.insert(QLatin1String("super"));
+ keywords.insert(QLatin1String("switch"));
+ keywords.insert(QLatin1String("synchronized"));
+ keywords.insert(QLatin1String("this"));
+ keywords.insert(QLatin1String("throw"));
+ keywords.insert(QLatin1String("throws"));
+ keywords.insert(QLatin1String("transient"));
+ keywords.insert(QLatin1String("true"));
+ keywords.insert(QLatin1String("try"));
+ keywords.insert(QLatin1String("void"));
+ keywords.insert(QLatin1String("volatile"));
+ keywords.insert(QLatin1String("while"));
+ }
+ return keywords;
+}
+
+bool FormWindow::unify(QObject *w, QString &s, bool changeIt)
+{
+ typedef QSet<QString> StringSet;
+
+ QWidget *main = mainContainer();
+ if (!main)
+ return true;
+
+ StringSet existingNames = languageKeywords();
+ // build a set of existing names of other widget excluding self
+ if (!(w->isWidgetType() && isMainContainer(qobject_cast<QWidget*>(w))))
+ existingNames.insert(main->objectName());
+
+ const QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
+ const QWidgetList widgetChildren = qFindChildren<QWidget*>(main);
+ if (!widgetChildren.empty())
+ insertNames(metaDataBase, widgetChildren.constBegin(), widgetChildren.constEnd(), w, existingNames);
+
+ const QList<QLayout *> layoutChildren = qFindChildren<QLayout*>(main);
+ if (!layoutChildren.empty())
+ insertNames(metaDataBase, layoutChildren.constBegin(), layoutChildren.constEnd(), w, existingNames);
+
+ const QList<QAction *> actionChildren = qFindChildren<QAction*>(main);
+ if (!actionChildren.empty())
+ insertNames(metaDataBase, actionChildren.constBegin(), actionChildren.constEnd(), w, existingNames);
+
+ const QList<QButtonGroup *> buttonGroupChildren = qFindChildren<QButtonGroup*>(main);
+ if (!buttonGroupChildren.empty())
+ insertNames(metaDataBase, buttonGroupChildren.constBegin(), buttonGroupChildren.constEnd(), w, existingNames);
+
+ const StringSet::const_iterator enEnd = existingNames.constEnd();
+ if (existingNames.constFind(s) == enEnd)
+ return true;
+ else
+ if (!changeIt)
+ return false;
+
+ // split 'name_number'
+ qlonglong num = 0;
+ qlonglong factor = 1;
+ int idx = s.length()-1;
+ const ushort zeroUnicode = QLatin1Char('0').unicode();
+ for ( ; idx > 0 && s.at(idx).isDigit(); --idx) {
+ num += (s.at(idx).unicode() - zeroUnicode) * factor;
+ factor *= 10;
+ }
+ // Position index past '_'.
+ const QChar underscore = QLatin1Char('_');
+ if (idx >= 0 && s.at(idx) == underscore) {
+ idx++;
+ } else {
+ num = 1;
+ s += underscore;
+ idx = s.length();
+ }
+ // try 'name_n', 'name_n+1'
+ for (num++ ; ;num++) {
+ s.truncate(idx);
+ s += QString::number(num);
+ if (existingNames.constFind(s) == enEnd)
+ break;
+ }
+ return false;
+}
+/* already_in_form is true when we are moving a widget from one parent to another inside the same
+ * form. All this means is that InsertWidgetCommand::undo() must not unmanage it. */
+
+void FormWindow::insertWidget(QWidget *w, const QRect &rect, QWidget *container, bool already_in_form)
+{
+ clearSelection(false);
+
+ beginCommand(tr("Insert widget '%1'").arg(WidgetFactory::classNameOf(m_core, w))); // ### use the WidgetDatabaseItem
+
+ /* Reparenting into a QSplitter automatically adjusts child's geometry. We create the geometry
+ * command before we push the reparent command, so that the geometry command has the original
+ * geometry of the widget. */
+ QRect r = rect;
+ Q_ASSERT(r.isValid());
+ SetPropertyCommand *geom_cmd = new SetPropertyCommand(this);
+ geom_cmd->init(w, QLatin1String("geometry"), r); // ### use rc.size()
+
+ if (w->parentWidget() != container) {
+ ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
+ cmd->init(w, container);
+ m_commandHistory->push(cmd);
+ }
+
+ m_commandHistory->push(geom_cmd);
+
+ InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
+ cmd->init(w, already_in_form);
+ m_commandHistory->push(cmd);
+
+ endCommand();
+
+ w->show();
+}
+
+QWidget *FormWindow::createWidget(DomUI *ui, const QRect &rc, QWidget *target)
+{
+ QWidget *container = findContainer(target, false);
+ if (!container)
+ return 0;
+ if (isMainContainer(container)) {
+ if (QMainWindow *mw = qobject_cast<QMainWindow*>(container)) {
+ Q_ASSERT(mw->centralWidget() != 0);
+ container = mw->centralWidget();
+ }
+ }
+ QDesignerResource resource(this);
+ const FormBuilderClipboard clipboard = resource.paste(ui, container);
+ if (clipboard.m_widgets.size() != 1) // multiple-paste from DomUI not supported yet
+ return 0;
+ QWidget *widget = clipboard.m_widgets.first();
+ insertWidget(widget, rc, container);
+ return widget;
+}
+
+#ifndef QT_NO_DEBUG
+static bool isDescendant(const QWidget *parent, const QWidget *child)
+{
+ for (; child != 0; child = child->parentWidget()) {
+ if (child == parent)
+ return true;
+ }
+ return false;
+}
+#endif
+
+void FormWindow::resizeWidget(QWidget *widget, const QRect &geometry)
+{
+ Q_ASSERT(isDescendant(this, widget));
+
+ QRect r = geometry;
+ if (m_lastIndex > m_commandHistory->index())
+ m_lastIndex = -1;
+ SetPropertyCommand *cmd = new SetPropertyCommand(this);
+ cmd->init(widget, QLatin1String("geometry"), r);
+ cmd->setText(tr("Resize"));
+ m_commandHistory->push(cmd);
+}
+
+void FormWindow::raiseChildSelections(QWidget *w)
+{
+ const QWidgetList l = qFindChildren<QWidget*>(w);
+ if (l.isEmpty())
+ return;
+ m_selection->raiseList(l);
+}
+
+QWidget *FormWindow::containerAt(const QPoint &pos, QWidget *notParentOf)
+{
+ QWidget *container = 0;
+ int depth = -1;
+ const QWidgetList selected = selectedWidgets();
+ if (rect().contains(mapFromGlobal(pos))) {
+ container = mainContainer();
+ depth = widgetDepth(container);
+ }
+
+ QListIterator<QWidget*> it(m_widgets);
+ while (it.hasNext()) {
+ QWidget *wit = it.next();
+ if (qobject_cast<QLayoutWidget*>(wit) || qobject_cast<QSplitter*>(wit))
+ continue;
+ if (!wit->isVisibleTo(this))
+ continue;
+ if (selected.indexOf(wit) != -1)
+ continue;
+ if (!core()->widgetDataBase()->isContainer(wit) &&
+ wit != mainContainer())
+ continue;
+
+ // the rectangles of all ancestors of the container must contain the insert position
+ QWidget *w = wit;
+ while (w && !w->isWindow()) {
+ if (!w->rect().contains((w->mapFromGlobal(pos))))
+ break;
+ w = w->parentWidget();
+ }
+ if (!(w == 0 || w->isWindow()))
+ continue; // we did not get through the full while loop
+
+ int wd = widgetDepth(wit);
+ if (wd == depth && container) {
+ if (wit->parentWidget()->children().indexOf(wit) >
+ container->parentWidget()->children().indexOf(container))
+ wd++;
+ }
+ if (wd > depth && !isChildOf(wit, notParentOf)) {
+ depth = wd;
+ container = wit;
+ }
+ }
+ return container;
+}
+
+QWidgetList FormWindow::selectedWidgets() const
+{
+ return m_selection->selectedWidgets();
+}
+
+void FormWindow::selectWidgets()
+{
+ bool selectionChanged = false;
+ const QWidgetList l = qFindChildren<QWidget*>(mainContainer());
+ QListIterator <QWidget*> it(l);
+ const QRect selRect(mapToGlobal(m_currRect.topLeft()), m_currRect.size());
+ while (it.hasNext()) {
+ QWidget *w = it.next();
+ if (w->isVisibleTo(this) && isManaged(w)) {
+ const QPoint p = w->mapToGlobal(QPoint(0,0));
+ const QRect r(p, w->size());
+ if (r.intersects(selRect) && !r.contains(selRect) && trySelectWidget(w, true))
+ selectionChanged = true;
+ }
+ }
+
+ if (selectionChanged)
+ emitSelectionChanged();
+}
+
+bool FormWindow::handleKeyPressEvent(QWidget *widget, QWidget *, QKeyEvent *e)
+{
+ if (qobject_cast<const FormWindow*>(widget) || qobject_cast<const QMenu*>(widget))
+ return false;
+
+ e->accept(); // we always accept!
+
+ switch (e->key()) {
+ default: break; // we don't care about the other keys
+
+ case Qt::Key_Delete:
+ case Qt::Key_Backspace:
+ if (e->modifiers() == Qt::NoModifier)
+ deleteWidgets();
+ break;
+
+ case Qt::Key_Tab:
+ if (e->modifiers() == Qt::NoModifier)
+ cursor()->movePosition(QDesignerFormWindowCursorInterface::Next);
+ break;
+
+ case Qt::Key_Backtab:
+ if (e->modifiers() == Qt::NoModifier)
+ cursor()->movePosition(QDesignerFormWindowCursorInterface::Prev);
+ break;
+
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ handleArrowKeyEvent(e->key(), e->modifiers());
+ break;
+ }
+
+ return true;
+}
+
+int FormWindow::getValue(const QRect &rect, int key, bool size) const
+{
+ if (size) {
+ if (key == Qt::Key_Left || key == Qt::Key_Right)
+ return rect.width();
+ return rect.height();
+ }
+ if (key == Qt::Key_Left || key == Qt::Key_Right)
+ return rect.x();
+ return rect.y();
+}
+
+int FormWindow::calcValue(int val, bool forward, bool snap, int snapOffset) const
+{
+ if (snap) {
+ const int rest = val % snapOffset;
+ if (rest) {
+ const int offset = forward ? snapOffset : 0;
+ const int newOffset = rest < 0 ? offset - snapOffset : offset;
+ return val + newOffset - rest;
+ }
+ return (forward ? val + snapOffset : val - snapOffset);
+ }
+ return (forward ? val + 1 : val - 1);
+}
+
+QRect FormWindow::applyValue(const QRect &rect, int val, int key, bool size) const
+{
+ QRect r = rect;
+ if (size) {
+ if (key == Qt::Key_Left || key == Qt::Key_Right)
+ r.setWidth(val);
+ else
+ r.setHeight(val);
+ } else {
+ if (key == Qt::Key_Left || key == Qt::Key_Right)
+ r.moveLeft(val);
+ else
+ r.moveTop(val);
+ }
+ return r;
+}
+
+void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
+{
+ bool startMacro = false;
+ const QDesignerFormWindowCursorInterface *c = cursor();
+ if (!c->hasSelection())
+ return;
+
+ QWidgetList selection;
+
+ // check if a laid out widget is selected
+ const int count = c->selectedWidgetCount();
+ for (int index = 0; index < count; ++index) {
+ QWidget *w = c->selectedWidget(index);
+ if (!LayoutInfo::isWidgetLaidout(m_core, w))
+ selection.append(w);
+ }
+
+ if (selection.isEmpty())
+ return;
+
+ QWidget *current = c->current();
+ if (!current || LayoutInfo::isWidgetLaidout(m_core, current)) {
+ current = selection.first();
+ }
+
+ const bool size = modifiers & Qt::ShiftModifier;
+
+ const bool snap = !(modifiers & Qt::ControlModifier);
+ const bool forward = (key == Qt::Key_Right || key == Qt::Key_Down);
+ const int snapPoint = (key == Qt::Key_Left || key == Qt::Key_Right) ? grid().x() : grid().y();
+
+ const int oldValue = getValue(current->geometry(), key, size);
+
+ const int newValue = calcValue(oldValue, forward, snap, snapPoint);
+
+ const int offset = newValue - oldValue;
+
+ const int selCount = selection.count();
+ // check if selection is the same as last time
+ if (selCount != m_moveSelection.count() ||
+ m_lastUndoIndex != m_commandHistory->index()) {
+ m_moveSelection.clear();
+ startMacro = true;
+ } else {
+ for (int index = 0; index < selCount; ++index) {
+ if (m_moveSelection[index]->object() != selection.at(index)) {
+ m_moveSelection.clear();
+ startMacro = true;
+ break;
+ }
+ }
+ }
+
+ if (startMacro)
+ beginCommand(tr("Key Move"));
+
+ for (int index = 0; index < selCount; ++index) {
+ QWidget *w = selection.at(index);
+ const QRect oldGeom = w->geometry();
+ const QRect geom = applyValue(oldGeom, getValue(oldGeom, key, size) + offset, key, size);
+
+ SetPropertyCommand *cmd = 0;
+
+ if (m_moveSelection.count() > index)
+ cmd = m_moveSelection[index];
+
+ if (!cmd) {
+ cmd = new SetPropertyCommand(this);
+ cmd->init(w, QLatin1String("geometry"), geom);
+ cmd->setText(tr("Key Move"));
+ m_commandHistory->push(cmd);
+
+ if (m_moveSelection.count() > index)
+ m_moveSelection.replace(index, cmd);
+ else
+ m_moveSelection.append(cmd);
+ } else {
+ cmd->setNewValue(geom);
+ cmd->redo();
+ }
+ }
+
+ if (startMacro) {
+ endCommand();
+ m_lastUndoIndex = m_commandHistory->index();
+ }
+}
+
+bool FormWindow::handleKeyReleaseEvent(QWidget *, QWidget *, QKeyEvent *e)
+{
+ e->accept();
+ return true;
+}
+
+void FormWindow::selectAll()
+{
+ bool selectionChanged = false;
+ foreach (QWidget *widget, m_widgets) {
+ if (widget->isVisibleTo(this) && trySelectWidget(widget, true))
+ selectionChanged = true;
+ }
+ if (selectionChanged)
+ emitSelectionChanged();
+}
+
+void FormWindow::createLayout(int type, QWidget *container)
+{
+ if (container) {
+ layoutContainer(container, type);
+ } else {
+ LayoutCommand *cmd = new LayoutCommand(this);
+ cmd->init(mainContainer(), selectedWidgets(), static_cast<LayoutInfo::Type>(type));
+ commandHistory()->push(cmd);
+ }
+}
+
+void FormWindow::morphLayout(QWidget *container, int newType)
+{
+ MorphLayoutCommand *cmd = new MorphLayoutCommand(this);
+ if (cmd->init(container, newType)) {
+ commandHistory()->push(cmd);
+ } else {
+ qDebug() << "** WARNING Unable to morph layout.";
+ delete cmd;
+ }
+}
+
+void FormWindow::deleteWidgets()
+{
+ QWidgetList selection = selectedWidgets();
+ simplifySelection(&selection);
+
+ deleteWidgetList(selection);
+}
+
+QString FormWindow::fileName() const
+{
+ return m_fileName;
+}
+
+void FormWindow::setFileName(const QString &fileName)
+{
+ if (m_fileName == fileName)
+ return;
+
+ m_fileName = fileName;
+ emit fileNameChanged(fileName);
+}
+
+QString FormWindow::contents() const
+{
+ QBuffer b;
+ if (!mainContainer() || !b.open(QIODevice::WriteOnly))
+ return QString();
+
+ QDesignerResource resource(const_cast<FormWindow*>(this));
+ resource.save(&b, mainContainer());
+
+ return QString::fromUtf8(b.buffer());
+}
+
+void FormWindow::copy()
+{
+ QBuffer b;
+ if (!b.open(QIODevice::WriteOnly))
+ return;
+
+ FormBuilderClipboard clipboard;
+ QDesignerResource resource(this);
+ resource.setSaveRelative(false);
+ clipboard.m_widgets = selectedWidgets();
+ simplifySelection(&clipboard.m_widgets);
+ resource.copy(&b, clipboard);
+
+ qApp->clipboard()->setText(QString::fromUtf8(b.buffer()), QClipboard::Clipboard);
+}
+
+void FormWindow::cut()
+{
+ copy();
+ deleteWidgets();
+}
+
+// for cases like QMainWindow (central widget is an inner container) or QStackedWidget (page is an inner container)
+QWidget *FormWindow::innerContainer(QWidget *outerContainer) const
+{
+ bool isContainer = m_core->widgetDataBase()->isContainer(outerContainer);
+ if (isContainer)
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), outerContainer))
+ return container->widget(container->currentIndex());
+ return outerContainer;
+}
+
+QWidget *FormWindow::containerForPaste() const
+{
+ QWidget *w = mainContainer();
+ if (!w)
+ return 0;
+ do {
+ // Try to find a close parent, for example a non-laid-out
+ // QFrame/QGroupBox when a widget within it is selected.
+ QWidgetList selection = selectedWidgets();
+ if (selection.empty())
+ break;
+ simplifySelection(&selection);
+
+ QWidget *containerOfW = findContainer(selection.first(), /* exclude layouts */ true);
+ if (!containerOfW || containerOfW == mainContainer())
+ break;
+ // No layouts, must be container
+ containerOfW = innerContainer(containerOfW);
+ if (LayoutInfo::layoutType(m_core, containerOfW) != LayoutInfo::NoLayout || !m_core->widgetDataBase()->isContainer(containerOfW))
+ break;
+ w = containerOfW;
+ } while (false);
+ // First check for layout (note that it does not cover QMainWindow
+ // and the like as the central widget has the layout).
+
+ w = innerContainer(w);
+ if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
+ return 0;
+ // Go up via container extension (also includes step from QMainWindow to its central widget)
+ w = m_core->widgetFactory()->containerOfWidget(w);
+ if (w == 0 || LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
+ return 0;
+
+ if (debugFormWindow)
+ qDebug() <<"containerForPaste() " << w;
+ return w;
+}
+
+void FormWindow::paste()
+{
+ paste(PasteAll);
+}
+
+// Construct DomUI from clipboard (paste) and determine number of widgets/actions.
+static inline DomUI *domUIFromClipboard(int *widgetCount, int *actionCount)
+{
+ *widgetCount = *actionCount = 0;
+ const QString clipboardText = qApp->clipboard()->text();
+ if (clipboardText.isEmpty() || clipboardText.indexOf(QLatin1Char('<')) == -1)
+ return 0;
+
+ QXmlStreamReader reader(clipboardText);
+ DomUI *ui = 0;
+ const QString uiElement = QLatin1String("ui");
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0 && !ui) {
+ ui = new DomUI();
+ ui->read(reader);
+ break;
+ } else {
+ reader.raiseError(QCoreApplication::translate("FormWindow", "Unexpected element <%1>").arg(reader.name().toString()));
+ }
+ }
+ }
+ if (reader.hasError()) {
+ delete ui;
+ ui = 0;
+ designerWarning(QCoreApplication::translate("FormWindow", "Error while pasting clipboard contents at line %1, column %2: %3").
+ arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
+ return 0;
+ }
+
+ if (const DomWidget *topLevel = ui->elementWidget()) {
+ *widgetCount = topLevel->elementWidget().size();
+ *actionCount = topLevel->elementAction().size();
+ }
+ if (*widgetCount == 0 && *actionCount == 0) {
+ delete ui;
+ return 0;
+ }
+ return ui;
+}
+
+static inline QString pasteCommandDescription(int widgetCount, int actionCount)
+{
+ if (widgetCount == 0)
+ return FormWindow::tr("Paste %n action(s)", 0, actionCount);
+ if (actionCount == 0)
+ return FormWindow::tr("Paste %n widget(s)", 0, widgetCount);
+ return FormWindow::tr("Paste (%1 widgets, %2 actions)").arg(widgetCount).arg(actionCount);
+}
+
+static void positionPastedWidgetsAtMousePosition(FormWindow *fw, const QPoint &contextMenuPosition, QWidget *parent, const QWidgetList &l)
+{
+ // Try to position pasted widgets at mouse position (current mouse position for Ctrl-V or position of context menu)
+ // if it fits. If it is completely outside, force it to 0,0
+ // If it fails, the old coordinates relative to the previous parent will be used.
+ QPoint currentPos = contextMenuPosition.x() >=0 ? parent->mapFrom(fw, contextMenuPosition) : parent->mapFromGlobal(QCursor::pos());
+ const Grid &grid = fw->designerGrid();
+ QPoint cursorPos = grid.snapPoint(currentPos);
+ const QRect parentGeometry = QRect(QPoint(0, 0), parent->size());
+ const bool outside = !parentGeometry.contains(cursorPos);
+ if (outside)
+ cursorPos = grid.snapPoint(QPoint(0, 0));
+ // Determine area of pasted widgets
+ QRect pasteArea;
+ const QWidgetList::const_iterator lcend = l.constEnd();
+ for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it)
+ pasteArea =pasteArea.isNull() ? (*it)->geometry() : pasteArea.united((*it)->geometry());
+
+ // Mouse on some child? (try to position bottomRight on a free spot to
+ // get the stacked-offset effect of Designer 4.3, that is, offset by grid if Ctrl-V is pressed continuously
+ do {
+ const QPoint bottomRight = cursorPos + QPoint(pasteArea.width(), pasteArea.height()) - QPoint(1, 1);
+ if (bottomRight.y() > parentGeometry.bottom() || parent->childAt(bottomRight) == 0)
+ break;
+ cursorPos += QPoint(grid.deltaX(), grid.deltaY());
+ } while (true);
+ // Move.
+ const QPoint offset = cursorPos - pasteArea.topLeft();
+ for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it)
+ (*it)->move((*it)->pos() + offset);
+}
+
+void FormWindow::paste(PasteMode pasteMode)
+{
+ // Avoid QDesignerResource constructing widgets that are not used as
+ // QDesignerResource manages the widgets it creates (creating havoc if one remains unused)
+ DomUI *ui = 0;
+ do {
+ int widgetCount;
+ int actionCount;
+ ui = domUIFromClipboard(&widgetCount, &actionCount);
+ if (!ui)
+ break;
+
+ // Check for actions
+ if (pasteMode == PasteActionsOnly)
+ if (widgetCount != 0 || actionCount == 0)
+ break;
+
+ // Check for widgets: need a container
+ QWidget *pasteContainer = widgetCount ? containerForPaste() : 0;
+ if (widgetCount && pasteContainer == 0) {
+
+ const QString message = tr("Cannot paste widgets. Designer could not find a container "
+ "without a layout to paste into.");
+ const QString infoMessage = tr("Break the layout of the "
+ "container you want to paste into, select this container "
+ "and then paste again.");
+ core()->dialogGui()->message(this, QDesignerDialogGuiInterface::FormEditorMessage, QMessageBox::Information,
+ tr("Paste error"), message, infoMessage, QMessageBox::Ok);
+ break;
+ }
+
+ QDesignerResource resource(this);
+ // Note that the widget factory must be able to locate the
+ // form window (us) via parent, otherwise, it will not able to construct QLayoutWidgets
+ // (It will then default to widgets) among other issues.
+ const FormBuilderClipboard clipboard = resource.paste(ui, pasteContainer, this);
+
+ clearSelection(false);
+ // Create command sequence
+ beginCommand(pasteCommandDescription(widgetCount, actionCount));
+
+ if (widgetCount) {
+ positionPastedWidgetsAtMousePosition(this, m_contextMenuPosition, pasteContainer, clipboard.m_widgets);
+ foreach (QWidget *w, clipboard.m_widgets) {
+ InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
+ cmd->init(w);
+ m_commandHistory->push(cmd);
+ selectWidget(w);
+ }
+ }
+
+ if (actionCount)
+ foreach (QAction *a, clipboard.m_actions) {
+ ensureUniqueObjectName(a);
+ AddActionCommand *cmd = new AddActionCommand(this);
+ cmd->init(a);
+ m_commandHistory->push(cmd);
+ }
+ endCommand();
+ } while (false);
+ delete ui;
+}
+
+// Draw a dotted frame around containers
+bool FormWindow::frameNeeded(QWidget *w) const
+{
+ if (!core()->widgetDataBase()->isContainer(w))
+ return false;
+ if (qobject_cast<QGroupBox *>(w))
+ return false;
+ if (qobject_cast<QToolBox *>(w))
+ return false;
+ if (qobject_cast<QTabWidget *>(w))
+ return false;
+ if (qobject_cast<QStackedWidget *>(w))
+ return false;
+ if (qobject_cast<QDockWidget *>(w))
+ return false;
+ if (qobject_cast<QDesignerWidget *>(w))
+ return false;
+ if (qobject_cast<QMainWindow *>(w))
+ return false;
+ if (qobject_cast<QDialog *>(w))
+ return false;
+ if (qobject_cast<QLayoutWidget *>(w))
+ return false;
+ return true;
+}
+
+bool FormWindow::eventFilter(QObject *watched, QEvent *event)
+{
+ const bool ret = FormWindowBase::eventFilter(watched, event);
+ if (event->type() != QEvent::Paint)
+ return ret;
+
+ Q_ASSERT(watched->isWidgetType());
+ QWidget *w = static_cast<QWidget *>(watched);
+ QPaintEvent *pe = static_cast<QPaintEvent*>(event);
+ const QRect widgetRect = w->rect();
+ const QRect paintRect = pe->rect();
+ // Does the paint rectangle touch the borders of the widget rectangle
+ if (paintRect.x() > widgetRect.x() && paintRect.y() > widgetRect.y() &&
+ paintRect.right() < widgetRect.right() && paintRect.bottom() < widgetRect.bottom())
+ return ret;
+ QPainter p(w);
+ const QPen pen(QColor(0, 0, 0, 32), 0, Qt::DotLine);
+ p.setPen(pen);
+ p.setBrush(QBrush(Qt::NoBrush));
+ p.drawRect(widgetRect.adjusted(0, 0, -1, -1));
+ return ret;
+}
+
+void FormWindow::manageWidget(QWidget *w)
+{
+ if (isManaged(w))
+ return;
+
+ Q_ASSERT(qobject_cast<QMenu*>(w) == 0);
+
+ if (w->hasFocus())
+ setFocus();
+
+ core()->metaDataBase()->add(w);
+
+ m_insertedWidgets.insert(w);
+ m_widgets.append(w);
+
+#ifndef QT_NO_CURSOR
+ setCursorToAll(Qt::ArrowCursor, w);
+#endif
+
+ emit changed();
+ emit widgetManaged(w);
+
+ if (frameNeeded(w))
+ w->installEventFilter(this);
+}
+
+void FormWindow::unmanageWidget(QWidget *w)
+{
+ if (!isManaged(w))
+ return;
+
+ m_selection->removeWidget(w);
+
+ emit aboutToUnmanageWidget(w);
+
+ if (w == m_currentWidget)
+ setCurrentWidget(mainContainer());
+
+ core()->metaDataBase()->remove(w);
+
+ m_insertedWidgets.remove(w);
+ m_widgets.removeAt(m_widgets.indexOf(w));
+
+ emit changed();
+ emit widgetUnmanaged(w);
+
+ if (frameNeeded(w))
+ w->removeEventFilter(this);
+}
+
+bool FormWindow::isManaged(QWidget *w) const
+{
+ return m_insertedWidgets.contains(w);
+}
+
+void FormWindow::breakLayout(QWidget *w)
+{
+ if (w == this)
+ w = mainContainer();
+ // Find the first-order managed child widgets
+ QWidgetList widgets;
+
+ const QObjectList children = w->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ const QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it)
+ if ( (*it)->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(*it);
+ if (mdb->item(w))
+ widgets.push_back(w);
+ }
+
+ BreakLayoutCommand *cmd = new BreakLayoutCommand(this);
+ cmd->init(widgets, w);
+ commandHistory()->push(cmd);
+ clearSelection(false);
+}
+
+void FormWindow::beginCommand(const QString &description)
+{
+ if (m_lastIndex > m_commandHistory->index())
+ m_lastIndex = -1;
+ m_commandHistory->beginMacro(description);
+}
+
+void FormWindow::endCommand()
+{
+ m_commandHistory->endMacro();
+}
+
+void FormWindow::raiseWidgets()
+{
+ QWidgetList widgets = selectedWidgets();
+ simplifySelection(&widgets);
+
+ if (widgets.isEmpty())
+ return;
+
+ beginCommand(tr("Raise widgets"));
+ foreach (QWidget *widget, widgets) {
+ RaiseWidgetCommand *cmd = new RaiseWidgetCommand(this);
+ cmd->init(widget);
+ m_commandHistory->push(cmd);
+ }
+ endCommand();
+}
+
+void FormWindow::lowerWidgets()
+{
+ QWidgetList widgets = selectedWidgets();
+ simplifySelection(&widgets);
+
+ if (widgets.isEmpty())
+ return;
+
+ beginCommand(tr("Lower widgets"));
+ foreach (QWidget *widget, widgets) {
+ LowerWidgetCommand *cmd = new LowerWidgetCommand(this);
+ cmd->init(widget);
+ m_commandHistory->push(cmd);
+ }
+ endCommand();
+}
+
+bool FormWindow::handleMouseButtonDblClickEvent(QWidget *w, QWidget *managedWidget, QMouseEvent *e)
+{
+ if (debugFormWindow)
+ qDebug() << "handleMouseButtonDblClickEvent:" << w << ',' << managedWidget << "state=" << m_mouseState;
+
+ e->accept();
+
+ // Might be out of sync due cycling of the parent selection
+ // In that case, do nothing
+ if (isWidgetSelected(managedWidget))
+ emit activated(managedWidget);
+
+ m_mouseState = MouseDoubleClicked;
+ return true;
+}
+
+
+QMenu *FormWindow::initializePopupMenu(QWidget *managedWidget)
+{
+ if (!isManaged(managedWidget) || currentTool())
+ return 0;
+
+ // Make sure the managedWidget is selected and current since
+ // the SetPropertyCommands must use the right reference
+ // object obtained from the property editor for the property group
+ // of a multiselection to be correct.
+ const bool selected = isWidgetSelected(managedWidget);
+ bool update = false;
+ if (selected == false) {
+ clearObjectInspectorSelection(m_core); // We might have a toolbar or non-widget selected in the object inspector.
+ clearSelection(false);
+ update = trySelectWidget(managedWidget, true);
+ raiseChildSelections(managedWidget); // raise selections and select widget
+ } else {
+ update = setCurrentWidget(managedWidget);
+ }
+
+ if (update) {
+ emitSelectionChanged();
+ QMetaObject::invokeMethod(core()->formWindowManager(), "slotUpdateActions");
+ }
+
+ QWidget *contextMenuWidget = 0;
+
+ if (isMainContainer(managedWidget)) { // press on a child widget
+ contextMenuWidget = mainContainer();
+ } else { // press on a child widget
+ // if widget is laid out, find the first non-laid out super-widget
+ QWidget *realWidget = managedWidget; // but store the original one
+ QMainWindow *mw = qobject_cast<QMainWindow*>(mainContainer());
+
+ if (mw && mw->centralWidget() == realWidget) {
+ contextMenuWidget = managedWidget;
+ } else {
+ contextMenuWidget = realWidget;
+ }
+ }
+
+ if (!contextMenuWidget)
+ return 0;
+
+ QMenu *contextMenu = createPopupMenu(contextMenuWidget);
+ if (!contextMenu)
+ return 0;
+
+ emit contextMenuRequested(contextMenu, contextMenuWidget);
+ return contextMenu;
+}
+
+bool FormWindow::handleContextMenu(QWidget *, QWidget *managedWidget, QContextMenuEvent *e)
+{
+ QMenu *contextMenu = initializePopupMenu(managedWidget);
+ if (!contextMenu)
+ return false;
+ const QPoint globalPos = e->globalPos();
+ m_contextMenuPosition = mapFromGlobal (globalPos);
+ contextMenu->exec(globalPos);
+ delete contextMenu;
+ e->accept();
+ m_contextMenuPosition = QPoint(-1, -1);
+ return true;
+}
+
+void FormWindow::setContents(QIODevice *dev)
+{
+ UpdateBlocker ub(this);
+ clearSelection();
+ m_selection->clearSelectionPool();
+ m_insertedWidgets.clear();
+ m_widgets.clear();
+ // The main container is cleared as otherwise
+ // the names of the newly loaded objects will be unified.
+ clearMainContainer();
+ emit changed();
+
+ QDesignerResource r(this);
+ QWidget *w = r.load(dev, formContainer());
+ setMainContainer(w);
+ emit changed();
+}
+
+void FormWindow::setContents(const QString &contents)
+{
+ QByteArray data = contents.toUtf8();
+ QBuffer b(&data);
+ if (b.open(QIODevice::ReadOnly))
+ setContents(&b);
+}
+
+void FormWindow::layoutContainer(QWidget *w, int type)
+{
+ if (w == this)
+ w = mainContainer();
+
+ w = core()->widgetFactory()->containerOfWidget(w);
+
+ const QObjectList l = w->children();
+ if (l.isEmpty())
+ return;
+ // find managed widget children
+ QWidgetList widgets;
+ const QObjectList::const_iterator ocend = l.constEnd();
+ for (QObjectList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it)
+ if ( (*it)->isWidgetType() ) {
+ QWidget *widget = static_cast<QWidget*>(*it);
+ if (widget->isVisibleTo(this) && isManaged(widget))
+ widgets.append(widget);
+ }
+
+ LayoutCommand *cmd = new LayoutCommand(this);
+ cmd->init(mainContainer(), widgets, static_cast<LayoutInfo::Type>(type), w);
+ clearSelection(false);
+ commandHistory()->push(cmd);
+}
+
+bool FormWindow::hasInsertedChildren(QWidget *widget) const // ### move
+{
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ widget = container->widget(container->currentIndex());
+ }
+
+ const QWidgetList l = widgets(widget);
+
+ foreach (QWidget *child, l) {
+ if (isManaged(child) && !LayoutInfo::isWidgetLaidout(core(), child) && child->isVisibleTo(const_cast<FormWindow*>(this)))
+ return true;
+ }
+
+ return false;
+}
+
+// "Select Ancestor" sub menu code
+void FormWindow::slotSelectWidget(QAction *a)
+{
+ if (QWidget *w = qvariant_cast<QWidget*>(a->data()))
+ selectSingleWidget(w);
+}
+
+static inline QString objectNameOf(const QWidget *w)
+{
+ if (const QLayoutWidget *lw = qobject_cast<const QLayoutWidget *>(w)) {
+ const QLayout *layout = lw->layout();
+ const QString rc = layout->objectName();
+ if (!rc.isEmpty())
+ return rc;
+ // Fall thru for 4.3 forms which have a name on the widget: Display the class name
+ return QString::fromUtf8(layout->metaObject()->className());
+ }
+ return w->objectName();
+}
+
+QAction *FormWindow::createSelectAncestorSubMenu(QWidget *w)
+{
+ // Find the managed, unselected parents
+ QWidgetList parents;
+ QWidget *mc = mainContainer();
+ for (QWidget *p = w->parentWidget(); p && p != mc; p = p->parentWidget())
+ if (isManaged(p) && !isWidgetSelected(p))
+ parents.push_back(p);
+ if (parents.empty())
+ return 0;
+ // Create a submenu listing the managed, unselected parents
+ QMenu *menu = new QMenu;
+ QActionGroup *ag = new QActionGroup(menu);
+ QObject::connect(ag, SIGNAL(triggered(QAction*)), this, SLOT(slotSelectWidget(QAction*)));
+ const int size = parents.size();
+ for (int i = 0; i < size; i++) {
+ QWidget *w = parents.at(i);
+ QAction *a = ag->addAction(objectNameOf(w));
+ a->setData(qVariantFromValue(w));
+ menu->addAction(a);
+ }
+ QAction *ma = new QAction(tr("Select Ancestor"), 0);
+ ma->setMenu(menu);
+ return ma;
+}
+
+QMenu *FormWindow::createPopupMenu(QWidget *w)
+{
+ QMenu *popup = createExtensionTaskMenu(this, w, true);
+ if (!popup)
+ popup = new QMenu;
+ // if w doesn't have a QDesignerTaskMenu as a child create one and make it a child.
+ // insert actions from QDesignerTaskMenu
+
+ QDesignerFormWindowManagerInterface *manager = core()->formWindowManager();
+ const bool isFormWindow = qobject_cast<const FormWindow*>(w);
+
+ // Check for special containers and obtain the page menu from them to add layout actions.
+ if (!isFormWindow) {
+ if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(w)) {
+ QStackedWidgetEventFilter::addStackedWidgetContextMenuActions(stackedWidget, popup);
+ } else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(w)) {
+ QTabWidgetEventFilter::addTabWidgetContextMenuActions(tabWidget, popup);
+ } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(w)) {
+ QToolBoxHelper::addToolBoxContextMenuActions(toolBox, popup);
+ }
+
+ popup->addAction(manager->actionCut());
+ popup->addAction(manager->actionCopy());
+ }
+
+ popup->addAction(manager->actionPaste());
+
+ if (QAction *selectAncestorAction = createSelectAncestorSubMenu(w))
+ popup->addAction(selectAncestorAction);
+ popup->addAction(manager->actionSelectAll());
+
+ if (!isFormWindow) {
+ popup->addAction(manager->actionDelete());
+ }
+
+ popup->addSeparator();
+ QMenu *layoutMenu = popup->addMenu(tr("Lay out"));
+ layoutMenu->addAction(manager->actionAdjustSize());
+ layoutMenu->addAction(manager->actionHorizontalLayout());
+ layoutMenu->addAction(manager->actionVerticalLayout());
+ layoutMenu->addAction(manager->actionGridLayout());
+ layoutMenu->addAction(manager->actionFormLayout());
+ if (!isFormWindow) {
+ layoutMenu->addAction(manager->actionSplitHorizontal());
+ layoutMenu->addAction(manager->actionSplitVertical());
+ }
+ layoutMenu->addAction(manager->actionBreakLayout());
+ layoutMenu->addAction(manager->actionSimplifyLayout());
+
+ return popup;
+}
+
+void FormWindow::resizeEvent(QResizeEvent *e)
+{
+ m_geometryChangedTimer->start(10);
+
+ QWidget::resizeEvent(e);
+}
+
+/*!
+ 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->isWindow() && !isMainContainer(i)) {
+ p = i->mapToParent(p);
+ i = i->parentWidget();
+ }
+
+ return mapFromGlobal(w->mapToGlobal(pos));
+}
+
+bool FormWindow::canBeBuddy(QWidget *w) const // ### rename me.
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), w)) {
+ const int index = sheet->indexOf(QLatin1String("focusPolicy"));
+ if (index != -1) {
+ bool ok = false;
+ const Qt::FocusPolicy q = static_cast<Qt::FocusPolicy>(Utils::valueOf(sheet->property(index), &ok));
+ return ok && q != Qt::NoFocus;
+ }
+ }
+
+ return false;
+}
+
+QWidget *FormWindow::findContainer(QWidget *w, bool excludeLayout) const
+{
+ if (!isChildOf(w, this)
+ || const_cast<const QWidget *>(w) == this)
+ return 0;
+
+ QDesignerWidgetFactoryInterface *widgetFactory = core()->widgetFactory();
+ QDesignerWidgetDataBaseInterface *widgetDataBase = core()->widgetDataBase();
+ QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
+
+ QWidget *container = 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
+ while (w) {
+ if (qobject_cast<InvisibleWidget*>(w) || !metaDataBase->item(w)) {
+ w = w->parentWidget();
+ continue;
+ }
+
+ const bool isContainer = widgetDataBase->isContainer(w, true) || w == mainContainer();
+
+ if (!isContainer || (excludeLayout && qobject_cast<QLayoutWidget*>(w))) { // ### skip QSplitter
+ w = w->parentWidget();
+ } else {
+ container = w;
+ break;
+ }
+ }
+ }
+
+ return container;
+}
+
+void FormWindow::simplifySelection(QWidgetList *sel) const
+{
+ if (sel->size() < 2)
+ return;
+ // Figure out which widgets should be removed from selection.
+ // We want to remove those whose parent widget is also in the
+ // selection (because the child widgets are contained by
+ // their parent, they shouldn't be in the selection --
+ // they are "implicitly" selected).
+ QWidget *mainC = mainContainer(); // Quick check for main container first
+ if (sel->contains(mainC)) {
+ sel->clear();
+ sel->push_back(mainC);
+ return;
+ }
+ typedef QVector<QWidget *> WidgetVector;
+ WidgetVector toBeRemoved;
+ toBeRemoved.reserve(sel->size());
+ const QWidgetList::const_iterator scend = sel->constEnd();
+ for (QWidgetList::const_iterator it = sel->constBegin(); it != scend; ++it) {
+ QWidget *child = *it;
+ for (QWidget *w = child; true ; ) { // Is any of the parents also selected?
+ QWidget *parent = w->parentWidget();
+ if (!parent || parent == mainC)
+ break;
+ if (sel->contains(parent)) {
+ toBeRemoved.append(child);
+ break;
+ }
+ w = parent;
+ }
+ }
+ // Now we can actually remove the widgets that were marked
+ // for removal in the previous pass.
+ if (!toBeRemoved.isEmpty()) {
+ const WidgetVector::const_iterator rcend = toBeRemoved.constEnd();
+ for (WidgetVector::const_iterator it = toBeRemoved.constBegin(); it != rcend; ++it)
+ sel->removeAll(*it);
+ }
+}
+
+FormWindow *FormWindow::findFormWindow(QWidget *w)
+{
+ return qobject_cast<FormWindow*>(QDesignerFormWindowInterface::findFormWindow(w));
+}
+
+bool FormWindow::isDirty() const
+{
+ return m_dirty;
+}
+
+void FormWindow::setDirty(bool dirty)
+{
+ m_dirty = dirty;
+
+ if (!m_dirty)
+ m_lastIndex = m_commandHistory->index();
+}
+
+void FormWindow::updateDirty()
+{
+ m_dirty = m_commandHistory->index() != m_lastIndex;
+}
+
+QWidget *FormWindow::containerAt(const QPoint &pos)
+{
+ QWidget *widget = widgetAt(pos);
+ return findContainer(widget, true);
+}
+
+static QWidget *childAt_SkipDropLine(QWidget *w, QPoint pos)
+{
+ const QObjectList child_list = w->children();
+ for (int i = child_list.size() - 1; i >= 0; --i) {
+ QObject *child_obj = child_list[i];
+ if (qobject_cast<WidgetHandle*>(child_obj) != 0)
+ continue;
+ QWidget *child = qobject_cast<QWidget*>(child_obj);
+ if (!child || child->isWindow() || !child->isVisible() ||
+ !child->geometry().contains(pos) || child->testAttribute(Qt::WA_TransparentForMouseEvents))
+ continue;
+ const QPoint childPos = child->mapFromParent(pos);
+ if (QWidget *res = childAt_SkipDropLine(child, childPos))
+ return res;
+ if (child->testAttribute(Qt::WA_MouseNoMask) || child->mask().contains(pos)
+ || child->mask().isEmpty())
+ return child;
+ }
+
+ return 0;
+}
+
+QWidget *FormWindow::widgetAt(const QPoint &pos)
+{
+ QWidget *w = childAt(pos);
+ if (qobject_cast<const WidgetHandle*>(w) != 0)
+ w = childAt_SkipDropLine(this, pos);
+ return (w == 0 || w == formContainer()) ? this : w;
+}
+
+void FormWindow::highlightWidget(QWidget *widget, const QPoint &pos, HighlightMode mode)
+{
+ Q_ASSERT(widget);
+
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*> (widget)) {
+ widget = mainWindow->centralWidget();
+ }
+
+ QWidget *container = findContainer(widget, false);
+
+ if (container == 0 || core()->metaDataBase()->item(container) == 0)
+ return;
+
+ if (QDesignerActionProviderExtension *g = qt_extension<QDesignerActionProviderExtension*>(core()->extensionManager(), container)) {
+ if (mode == Restore) {
+ g->adjustIndicator(QPoint());
+ } else {
+ const QPoint pt = widget->mapTo(container, pos);
+ g->adjustIndicator(pt);
+ }
+ } else if (QDesignerLayoutDecorationExtension *g = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), container)) {
+ if (mode == Restore) {
+ g->adjustIndicator(QPoint(), -1);
+ } else {
+ const QPoint pt = widget->mapTo(container, pos);
+ const int index = g->findItemAt(pt);
+ g->adjustIndicator(pt, index);
+ }
+ }
+
+ QMainWindow *mw = qobject_cast<QMainWindow*> (container);
+ if (container == mainContainer() || (mw && mw->centralWidget() && mw->centralWidget() == container))
+ return;
+
+ if (mode == Restore) {
+ const WidgetPaletteMap::iterator pit = m_palettesBeforeHighlight.find(container);
+ if (pit != m_palettesBeforeHighlight.end()) {
+ container->setPalette(pit.value().first);
+ container->setAutoFillBackground(pit.value().second);
+ m_palettesBeforeHighlight.erase(pit);
+ }
+ } else {
+ QPalette p = container->palette();
+ if (!m_palettesBeforeHighlight.contains(container)) {
+ PaletteAndFill paletteAndFill;
+ if (container->testAttribute(Qt::WA_SetPalette))
+ paletteAndFill.first = p;
+ paletteAndFill.second = container->autoFillBackground();
+ m_palettesBeforeHighlight.insert(container, paletteAndFill);
+ }
+
+ p.setColor(backgroundRole(), p.midlight().color());
+ container->setPalette(p);
+ container->setAutoFillBackground(true);
+ }
+}
+
+QWidgetList FormWindow::widgets(QWidget *widget) const
+{
+ const QObjectList children = widget->children();
+ if (children.empty())
+ return QWidgetList();
+ QWidgetList rc;
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it)
+ if ((*it)->isWidgetType()) {
+ QWidget *w = qobject_cast<QWidget*>(*it);
+ if (isManaged(w))
+ rc.push_back(w);
+ }
+ return rc;
+}
+
+int FormWindow::toolCount() const
+{
+ return m_widgetStack->count();
+}
+
+QDesignerFormWindowToolInterface *FormWindow::tool(int index) const
+{
+ return m_widgetStack->tool(index);
+}
+
+void FormWindow::registerTool(QDesignerFormWindowToolInterface *tool)
+{
+ Q_ASSERT(tool != 0);
+
+ m_widgetStack->addTool(tool);
+
+ if (m_mainContainer)
+ m_mainContainer->update();
+}
+
+void FormWindow::setCurrentTool(int index)
+{
+ m_widgetStack->setCurrentTool(index);
+}
+
+int FormWindow::currentTool() const
+{
+ return m_widgetStack->currentIndex();
+}
+
+bool FormWindow::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ if (m_widgetStack == 0)
+ return false;
+
+ QDesignerFormWindowToolInterface *tool = m_widgetStack->currentTool();
+ if (tool == 0)
+ return false;
+
+ return tool->handleEvent(widget, managedWidget, event);
+}
+
+void FormWindow::initializeCoreTools()
+{
+ m_widgetEditor = new WidgetEditorTool(this);
+ registerTool(m_widgetEditor);
+}
+
+void FormWindow::checkSelection()
+{
+ m_checkSelectionTimer->start(0);
+}
+
+void FormWindow::checkSelectionNow()
+{
+ m_checkSelectionTimer->stop();
+
+ foreach (QWidget *widget, selectedWidgets()) {
+ updateSelection(widget);
+
+ if (LayoutInfo::layoutType(core(), widget) != LayoutInfo::NoLayout)
+ updateChildSelections(widget);
+ }
+}
+
+QString FormWindow::author() const
+{
+ return m_author;
+}
+
+QString FormWindow::comment() const
+{
+ return m_comment;
+}
+
+void FormWindow::setAuthor(const QString &author)
+{
+ m_author = author;
+}
+
+void FormWindow::setComment(const QString &comment)
+{
+ m_comment = comment;
+}
+
+void FormWindow::editWidgets()
+{
+ m_widgetEditor->action()->trigger();
+}
+
+QStringList FormWindow::resourceFiles() const
+{
+ return m_resourceFiles;
+}
+
+void FormWindow::addResourceFile(const QString &path)
+{
+ if (!m_resourceFiles.contains(path)) {
+ m_resourceFiles.append(path);
+ setDirty(true);
+ emit resourceFilesChanged();
+ }
+}
+
+void FormWindow::removeResourceFile(const QString &path)
+{
+ if (m_resourceFiles.removeAll(path) > 0) {
+ setDirty(true);
+ emit resourceFilesChanged();
+ }
+}
+
+bool FormWindow::blockSelectionChanged(bool b)
+{
+ const bool blocked = m_blockSelectionChanged;
+ m_blockSelectionChanged = b;
+ return blocked;
+}
+
+void FormWindow::editContents()
+{
+ const QWidgetList sel = selectedWidgets();
+ if (sel.count() == 1) {
+ QWidget *widget = sel.first();
+
+ if (QAction *a = preferredEditAction(core(), widget))
+ a->trigger();
+ }
+}
+
+void FormWindow::dragWidgetWithinForm(QWidget *widget, const QRect &targetGeometry, QWidget *targetContainer)
+{
+ const bool fromLayout = canDragWidgetInLayout(core(), widget);
+ const QDesignerLayoutDecorationExtension *targetDeco = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), targetContainer);
+ const bool toLayout = targetDeco != 0;
+
+ if (fromLayout) {
+ // Drag from Layout: We need to delete the widget properly to store the layout state
+ // Do not simplify the layout when dragging onto a layout
+ // as this might invalidate the insertion position if it is the same layout
+ DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
+ unsigned deleteFlags = DeleteWidgetCommand::DoNotUnmanage;
+ if (toLayout)
+ deleteFlags |= DeleteWidgetCommand::DoNotSimplifyLayout;
+ cmd->init(widget, deleteFlags);
+ commandHistory()->push(cmd);
+ }
+
+ if (toLayout) {
+ // Drag from form to layout: just insert. Do not manage
+ insertWidget(widget, targetGeometry, targetContainer, true);
+ } else {
+ // into container without layout
+ if (targetContainer != widget->parent()) { // different parent
+ ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
+ cmd->init(widget, targetContainer );
+ commandHistory()->push(cmd);
+ }
+ resizeWidget(widget, targetGeometry);
+ selectWidget(widget, true);
+ widget->show();
+ }
+}
+
+static Qt::DockWidgetArea detectDropArea(QMainWindow *mainWindow, const QRect &area, const QPoint &drop)
+{
+ QPoint offset = area.topLeft();
+ QRect rect = area;
+ rect.moveTopLeft(QPoint(0, 0));
+ QPoint point = drop - offset;
+ const int x = point.x();
+ const int y = point.y();
+ const int w = rect.width();
+ const int h = rect.height();
+
+ if (rect.contains(point)) {
+ bool topRight = false;
+ bool topLeft = false;
+ if (w * y < h * x) // top and right, oterwise bottom and left
+ topRight = true;
+ if (w * y < h * (w - x)) // top and left, otherwise bottom and right
+ topLeft = true;
+
+ if (topRight && topLeft)
+ return Qt::TopDockWidgetArea;
+ else if (topRight && !topLeft)
+ return Qt::RightDockWidgetArea;
+ else if (!topRight && topLeft)
+ return Qt::LeftDockWidgetArea;
+ return Qt::BottomDockWidgetArea;
+ }
+
+ if (x < 0) {
+ if (y < 0)
+ return mainWindow->corner(Qt::TopLeftCorner);
+ else if (y > h)
+ return mainWindow->corner(Qt::BottomLeftCorner);
+ else
+ return Qt::LeftDockWidgetArea;
+ } else if (x > w) {
+ if (y < 0)
+ return mainWindow->corner(Qt::TopRightCorner);
+ else if (y > h)
+ return mainWindow->corner(Qt::BottomRightCorner);
+ else
+ return Qt::RightDockWidgetArea;
+ } else {
+ if (y < 0)
+ return Qt::TopDockWidgetArea;
+ else
+ return Qt::BottomDockWidgetArea;
+ }
+ return Qt::LeftDockWidgetArea;
+}
+
+bool FormWindow::dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &global_mouse_pos)
+{
+ DomUI *dom_ui = item->domUi();
+
+ QMainWindow *mw = qobject_cast<QMainWindow *>(mainContainer());
+ if (!mw)
+ return false;
+
+ QDesignerResource resource(this);
+ const FormBuilderClipboard clipboard = resource.paste(dom_ui, mw);
+ if (clipboard.m_widgets.size() != 1) // multiple-paste from DomUI not supported yet
+ return false;
+
+ QWidget *centralWidget = mw->centralWidget();
+ QPoint localPos = centralWidget->mapFromGlobal(global_mouse_pos);
+ const QRect centralWidgetAreaRect = centralWidget->rect();
+ Qt::DockWidgetArea area = detectDropArea(mw, centralWidgetAreaRect, localPos);
+
+ beginCommand(tr("Drop widget"));
+
+ clearSelection(false);
+ highlightWidget(mw, QPoint(0, 0), FormWindow::Restore);
+
+ QWidget *widget = clipboard.m_widgets.first();
+
+ insertWidget(widget, QRect(0, 0, 1, 1), mw);
+
+ selectWidget(widget, true);
+ mw->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector
+
+ core()->formWindowManager()->setActiveFormWindow(this);
+ mainContainer()->activateWindow();
+
+ QDesignerPropertySheetExtension *propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m_core->extensionManager()->extension(widget, Q_TYPEID(QDesignerPropertySheetExtension)));
+ if (propertySheet) {
+ const QString dockWidgetAreaName = QLatin1String("dockWidgetArea");
+ PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(propertySheet->property(propertySheet->indexOf(dockWidgetAreaName)));
+ e.value = area;
+ QVariant v;
+ qVariantSetValue(v, e);
+ SetPropertyCommand *cmd = new SetPropertyCommand(this);
+ cmd->init(widget, dockWidgetAreaName, v);
+ m_commandHistory->push(cmd);
+ }
+
+ endCommand();
+ return true;
+}
+
+bool FormWindow::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
+ const QPoint &global_mouse_pos)
+{
+
+ QWidget *parent = target;
+ if (parent == 0)
+ parent = mainContainer();
+ // You can only drop stuff onto the central widget of a QMainWindow
+ // ### generalize to use container extension
+ if (QMainWindow *main_win = qobject_cast<QMainWindow*>(target)) {
+ if (!main_win->centralWidget()) {
+ designerWarning(tr("A QMainWindow-based form does not contain a central widget."));
+ return false;
+ }
+ const QPoint main_win_pos = main_win->mapFromGlobal(global_mouse_pos);
+ const QRect central_wgt_geo = main_win->centralWidget()->geometry();
+ if (!central_wgt_geo.contains(main_win_pos))
+ return false;
+ }
+
+ QWidget *container = findContainer(parent, false);
+ if (container == 0)
+ return false;
+
+ beginCommand(tr("Drop widget"));
+
+ clearSelection(false);
+ highlightWidget(target, target->mapFromGlobal(global_mouse_pos), FormWindow::Restore);
+
+ QPoint offset;
+ QDesignerDnDItemInterface *current = 0;
+ QDesignerFormWindowCursorInterface *c = cursor();
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ QWidget *w = item->widget();
+ if (!current)
+ current = item;
+ if (c->current() == w) {
+ current = item;
+ break;
+ }
+ }
+ if (current) {
+ QRect geom = current->decoration()->geometry();
+ QPoint topLeft = container->mapFromGlobal(geom.topLeft());
+ offset = designerGrid().snapPoint(topLeft) - topLeft;
+ }
+
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ DomUI *dom_ui = item->domUi();
+ QRect geometry = item->decoration()->geometry();
+ Q_ASSERT(dom_ui != 0);
+
+ geometry.moveTopLeft(container->mapFromGlobal(geometry.topLeft()) + offset);
+ if (item->type() == QDesignerDnDItemInterface::CopyDrop) { // from widget box or CTRL + mouse move
+ QWidget *widget = createWidget(dom_ui, geometry, parent);
+ if (!widget) {
+ endCommand();
+ return false;
+ }
+ selectWidget(widget, true);
+ mainContainer()->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector
+ } else { // same form move
+ QWidget *widget = item->widget();
+ Q_ASSERT(widget != 0);
+ QDesignerFormWindowInterface *dest = findFormWindow(widget);
+ if (dest == this) {
+ dragWidgetWithinForm(widget, geometry, container);
+ } else { // from other form
+ FormWindow *source = qobject_cast<FormWindow*>(item->source());
+ Q_ASSERT(source != 0);
+
+ source->deleteWidgetList(QWidgetList() << widget);
+ QWidget *new_widget = createWidget(dom_ui, geometry, parent);
+
+ selectWidget(new_widget, true);
+ }
+ }
+ }
+
+ core()->formWindowManager()->setActiveFormWindow(this);
+ mainContainer()->activateWindow();
+ endCommand();
+ return true;
+}
+
+QDir FormWindow::absoluteDir() const
+{
+ if (fileName().isEmpty())
+ return QDir::current();
+
+ return QFileInfo(fileName()).absoluteDir();
+}
+
+void FormWindow::layoutDefault(int *margin, int *spacing)
+{
+ *margin = m_defaultMargin;
+ *spacing = m_defaultSpacing;
+}
+
+void FormWindow::setLayoutDefault(int margin, int spacing)
+{
+ m_defaultMargin = margin;
+ m_defaultSpacing = spacing;
+}
+
+void FormWindow::layoutFunction(QString *margin, QString *spacing)
+{
+ *margin = m_marginFunction;
+ *spacing = m_spacingFunction;
+}
+
+void FormWindow::setLayoutFunction(const QString &margin, const QString &spacing)
+{
+ m_marginFunction = margin;
+ m_spacingFunction = spacing;
+}
+
+QString FormWindow::pixmapFunction() const
+{
+ return m_pixmapFunction;
+}
+
+void FormWindow::setPixmapFunction(const QString &pixmapFunction)
+{
+ m_pixmapFunction = pixmapFunction;
+}
+
+QStringList FormWindow::includeHints() const
+{
+ return m_includeHints;
+}
+
+void FormWindow::setIncludeHints(const QStringList &includeHints)
+{
+ m_includeHints = includeHints;
+}
+
+QString FormWindow::exportMacro() const
+{
+ return m_exportMacro;
+}
+
+void FormWindow::setExportMacro(const QString &exportMacro)
+{
+ m_exportMacro = exportMacro;
+}
+
+QEditorFormBuilder *FormWindow::createFormBuilder()
+{
+ return new QDesignerResource(this);
+}
+
+QWidget *FormWindow::formContainer() const
+{
+ return m_widgetStack->formContainer();
+}
+
+} // namespace
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindow.h b/tools/designer/src/components/formeditor/formwindow.h
new file mode 100644
index 0000000..7e50ca2
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindow.h
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOW_H
+#define FORMWINDOW_H
+
+#include "formeditor_global.h"
+#include <formwindowbase_p.h>
+
+// Qt
+#include <QtCore/QHash>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerDnDItemInterface;
+class QDesignerTaskMenuExtension;
+class DomConnections;
+
+class QWidget;
+class QAction;
+class QLabel;
+class QTimer;
+class QAction;
+class QMenu;
+class QUndoStack;
+class QRubberBand;
+
+namespace qdesigner_internal {
+
+class FormEditor;
+class FormWindowCursor;
+class WidgetEditorTool;
+class FormWindowWidgetStack;
+class FormWindowManager;
+class FormWindowDnDItem;
+class SetPropertyCommand;
+
+class QT_FORMEDITOR_EXPORT FormWindow: public FormWindowBase
+{
+ Q_OBJECT
+
+public:
+ explicit FormWindow(FormEditor *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~FormWindow();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual QDesignerFormWindowCursorInterface *cursor() const;
+
+ // Overwritten: FormWindowBase
+ virtual QWidget *formContainer() const;
+
+ virtual int toolCount() const;
+ virtual int currentTool() const;
+ virtual void setCurrentTool(int index);
+ virtual QDesignerFormWindowToolInterface *tool(int index) const;
+ virtual void registerTool(QDesignerFormWindowToolInterface *tool);
+
+ virtual QString author() const;
+ virtual void setAuthor(const QString &author);
+
+ virtual QString comment() const;
+ virtual void setComment(const QString &comment);
+
+ virtual void layoutDefault(int *margin, int *spacing);
+ virtual void setLayoutDefault(int margin, int spacing);
+
+ virtual void layoutFunction(QString *margin, QString *spacing);
+ virtual void setLayoutFunction(const QString &margin, const QString &spacing);
+
+ virtual QString pixmapFunction() const;
+ virtual void setPixmapFunction(const QString &pixmapFunction);
+
+ virtual QString exportMacro() const;
+ virtual void setExportMacro(const QString &exportMacro);
+
+ virtual QStringList includeHints() const;
+ virtual void setIncludeHints(const QStringList &includeHints);
+
+ virtual QString fileName() const;
+ virtual void setFileName(const QString &fileName);
+
+ virtual QString contents() const;
+ virtual void setContents(const QString &contents);
+ virtual void setContents(QIODevice *dev);
+
+ virtual QDir absoluteDir() const;
+
+ virtual void simplifySelection(QWidgetList *sel) const;
+
+ virtual void ensureUniqueObjectName(QObject *object);
+
+ virtual QWidget *mainContainer() const;
+ void setMainContainer(QWidget *mainContainer);
+ bool isMainContainer(const QWidget *w) const;
+
+ QWidget *currentWidget() const;
+
+ bool hasInsertedChildren(QWidget *w) const;
+
+ QList<QWidget *> selectedWidgets() const;
+ void clearSelection(bool changePropertyDisplay=true);
+ bool isWidgetSelected(QWidget *w) const;
+ void selectWidget(QWidget *w, bool select=true);
+
+ void selectWidgets();
+ void repaintSelection();
+ void updateSelection(QWidget *w);
+ void updateChildSelections(QWidget *w);
+ void raiseChildSelections(QWidget *w);
+ void raiseSelection(QWidget *w);
+
+ inline const QList<QWidget *>& widgets() const { return m_widgets; }
+ inline int widgetCount() const { return m_widgets.count(); }
+ inline QWidget *widgetAt(int index) const { return m_widgets.at(index); }
+
+ QList<QWidget *> widgets(QWidget *widget) const;
+
+ QWidget *createWidget(DomUI *ui, const QRect &rect, QWidget *target);
+
+ bool isManaged(QWidget *w) const;
+
+ void manageWidget(QWidget *w);
+ void unmanageWidget(QWidget *w);
+
+ inline QUndoStack *commandHistory() const
+ { return m_commandHistory; }
+
+ void beginCommand(const QString &description);
+ void endCommand();
+
+ virtual bool blockSelectionChanged(bool blocked);
+ virtual void emitSelectionChanged();
+
+ bool unify(QObject *w, QString &s, bool changeIt);
+
+ bool isDirty() const;
+ void setDirty(bool dirty);
+
+ static FormWindow *findFormWindow(QWidget *w);
+
+ virtual QWidget *containerAt(const QPoint &pos);
+ virtual QWidget *widgetAt(const QPoint &pos);
+ virtual void highlightWidget(QWidget *w, const QPoint &pos,
+ HighlightMode mode = Highlight);
+
+ void updateOrderIndicators();
+
+ bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+ QStringList resourceFiles() const;
+ void addResourceFile(const QString &path);
+ void removeResourceFile(const QString &path);
+
+ void resizeWidget(QWidget *widget, const QRect &geometry);
+
+ bool dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &global_mouse_pos);
+ bool dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
+ const QPoint &global_mouse_pos);
+
+ virtual QWidget *findContainer(QWidget *w, bool excludeLayout) const;
+ // for WidgetSelection only.
+ QWidget *designerWidget(QWidget *w) const;
+
+ // Initialize and return a popup menu for a managed widget
+ QMenu *initializePopupMenu(QWidget *managedWidget);
+
+ virtual void paste(PasteMode pasteMode);
+ virtual QEditorFormBuilder *createFormBuilder();
+
+ bool eventFilter(QObject *watched, QEvent *event);
+
+signals:
+ void contextMenuRequested(QMenu *menu, QWidget *widget);
+
+public slots:
+ void deleteWidgets();
+ void raiseWidgets();
+ void lowerWidgets();
+ void copy();
+ void cut();
+ void paste();
+ void selectAll();
+
+ void createLayout(int type, QWidget *container = 0);
+ void morphLayout(QWidget *container, int newType);
+ void breakLayout(QWidget *w);
+
+ void editContents();
+
+protected:
+ virtual QMenu *createPopupMenu(QWidget *w);
+ virtual void resizeEvent(QResizeEvent *e);
+
+ void insertWidget(QWidget *w, const QRect &rect, QWidget *target, bool already_in_form = false);
+
+private slots:
+ void selectionChangedTimerDone();
+ void updateDirty();
+ void checkSelection();
+ void checkSelectionNow();
+ void slotSelectWidget(QAction *);
+
+private:
+ enum MouseState {
+ NoMouseState,
+ // Double click received
+ MouseDoubleClicked,
+ // Drawing selection rubber band rectangle
+ MouseDrawRubber,
+ // Started a move operation
+ MouseMoveDrag,
+ // Click on a widget whose parent is selected. Defer selection to release
+ MouseDeferredSelection
+ };
+ MouseState m_mouseState;
+ QPointer<QWidget> m_lastClickedWidget;
+
+ void init();
+ void initializeCoreTools();
+
+ int getValue(const QRect &rect, int key, bool size) const;
+ int calcValue(int val, bool forward, bool snap, int snapOffset) const;
+ QRect applyValue(const QRect &rect, int val, int key, bool size) const;
+ void handleClickSelection(QWidget *managedWidget, unsigned mouseFlags);
+
+ bool frameNeeded(QWidget *w) const;
+
+ enum RectType { Insert, Rubber };
+
+ void startRectDraw(const QPoint &global, QWidget *, RectType t);
+ void continueRectDraw(const QPoint &global, QWidget *, RectType t);
+ void endRectDraw();
+
+ QWidget *containerAt(const QPoint &pos, QWidget *notParentOf);
+
+ void checkPreviewGeometry(QRect &r);
+
+ void finishContextMenu(QWidget *w, QWidget *menuParent, QContextMenuEvent *e);
+
+ bool handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e);
+ bool handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+ bool handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+
+ bool isCentralWidget(QWidget *w) const;
+
+ bool setCurrentWidget(QWidget *currentWidget);
+ bool trySelectWidget(QWidget *w, bool select);
+
+ void dragWidgetWithinForm(QWidget *widget, const QRect &targetGeometry, QWidget *targetContainer);
+
+ void setCursorToAll(const QCursor &c, QWidget *start);
+
+ QPoint mapToForm(const QWidget *w, const QPoint &pos) const;
+ bool canBeBuddy(QWidget *w) const;
+
+ QWidget *findTargetContainer(QWidget *widget) const;
+
+ void clearMainContainer();
+
+ static int widgetDepth(const QWidget *w);
+ static bool isChildOf(const QWidget *c, const QWidget *p);
+
+ void editWidgets();
+
+ void updateWidgets();
+
+ void handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers);
+
+ void layoutSelection(int type);
+ void layoutContainer(QWidget *w, int type);
+
+private:
+ QWidget *innerContainer(QWidget *outerContainer) const;
+ QWidget *containerForPaste() const;
+ QAction *createSelectAncestorSubMenu(QWidget *w);
+ void selectSingleWidget(QWidget *w);
+
+ FormEditor *m_core;
+ FormWindowCursor *m_cursor;
+ QWidget *m_mainContainer;
+ QWidget *m_currentWidget;
+
+ bool m_blockSelectionChanged;
+
+ QPoint m_rectAnchor;
+ QRect m_currRect;
+
+ QWidgetList m_widgets;
+ QSet<QWidget*> m_insertedWidgets;
+
+ class Selection;
+ Selection *m_selection;
+
+ QPoint m_startPos;
+
+ QUndoStack *m_commandHistory;
+
+ QString m_fileName;
+
+ typedef QPair<QPalette ,bool> PaletteAndFill;
+ typedef QMap<QWidget*, PaletteAndFill> WidgetPaletteMap;
+ WidgetPaletteMap m_palettesBeforeHighlight;
+
+ QRubberBand *m_rubberBand;
+
+ QTimer *m_selectionChangedTimer;
+ QTimer *m_checkSelectionTimer;
+ QTimer *m_geometryChangedTimer;
+
+ int m_dirty;
+ int m_lastIndex;
+
+ FormWindowWidgetStack *m_widgetStack;
+ WidgetEditorTool *m_widgetEditor;
+
+ QStringList m_resourceFiles;
+
+ QString m_comment;
+ QString m_author;
+ QString m_pixmapFunction;
+ int m_defaultMargin, m_defaultSpacing;
+ QString m_marginFunction, m_spacingFunction;
+ QString m_exportMacro;
+ QStringList m_includeHints;
+
+ QList<SetPropertyCommand*> m_moveSelection;
+ int m_lastUndoIndex;
+ QPoint m_contextMenuPosition;
+
+private:
+ friend class WidgetEditorTool;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOW_H
diff --git a/tools/designer/src/components/formeditor/formwindow_dnditem.cpp b/tools/designer/src/components/formeditor/formwindow_dnditem.cpp
new file mode 100644
index 0000000..3af5343
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindow_dnditem.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindow_dnditem.h"
+#include "formwindow.h"
+
+#include <ui4_p.h>
+#include <qdesigner_resource.h>
+#include <qtresourcemodel_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QLabel>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+static QWidget *decorationFromWidget(QWidget *w)
+{
+ QLabel *label = new QLabel(0, Qt::ToolTip);
+ QPixmap pm = QPixmap::grabWidget(w);
+ label->setPixmap(pm);
+ label->resize(pm.size());
+
+ return label;
+}
+
+static DomUI *widgetToDom(QWidget *widget, FormWindow *form)
+{
+ QDesignerResource builder(form);
+ builder.setSaveRelative(false);
+ return builder.copy(FormBuilderClipboard(widget));
+}
+
+FormWindowDnDItem::FormWindowDnDItem(QDesignerDnDItemInterface::DropType type, FormWindow *form,
+ QWidget *widget, const QPoint &global_mouse_pos)
+ : QDesignerDnDItem(type, form)
+{
+ QWidget *decoration = decorationFromWidget(widget);
+ QPoint pos = widget->mapToGlobal(QPoint(0, 0));
+ decoration->move(pos);
+
+ init(0, widget, decoration, global_mouse_pos);
+}
+
+DomUI *FormWindowDnDItem::domUi() const
+{
+ DomUI *result = QDesignerDnDItem::domUi();
+ if (result != 0)
+ return result;
+ FormWindow *form = qobject_cast<FormWindow*>(source());
+ if (widget() == 0 || form == 0)
+ return 0;
+
+ QtResourceModel *resourceModel = form->core()->resourceModel();
+ QtResourceSet *currentResourceSet = resourceModel->currentResourceSet();
+ /* Short:
+ * We need to activate the original resourceSet associated with a form
+ * to properly generate the dom resource includes.
+ * Long:
+ * widgetToDom() calls copy() on QDesignerResource. It generates the
+ * Dom structure. In order to create DomResources properly we need to
+ * have the associated ResourceSet active (QDesignerResource::saveResources()
+ * queries the resource model for a qrc path for the given resource file:
+ * qrcFile = m_core->resourceModel()->qrcPath(ri->text());
+ * This works only when the resource file comes from the active
+ * resourceSet */
+ resourceModel->setCurrentResourceSet(form->resourceSet());
+
+ result = widgetToDom(widget(), form);
+ const_cast<FormWindowDnDItem*>(this)->setDomUi(result);
+ resourceModel->setCurrentResourceSet(currentResourceSet);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindow_dnditem.h b/tools/designer/src/components/formeditor/formwindow_dnditem.h
new file mode 100644
index 0000000..c6e7479
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindow_dnditem.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOW_DNDITEM_H
+#define FORMWINDOW_DNDITEM_H
+
+#include <qdesigner_dnditem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class FormWindow;
+
+class FormWindowDnDItem : public QDesignerDnDItem
+{
+public:
+ FormWindowDnDItem(QDesignerDnDItemInterface::DropType type, FormWindow *form,
+ QWidget *widget, const QPoint &global_mouse_pos);
+ virtual DomUI *domUi() const;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOW_DNDITEM_H
diff --git a/tools/designer/src/components/formeditor/formwindow_widgetstack.cpp b/tools/designer/src/components/formeditor/formwindow_widgetstack.cpp
new file mode 100644
index 0000000..7270628
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindow_widgetstack.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindow_widgetstack.h"
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+#include <QtGui/QWidget>
+#include <QtGui/qevent.h>
+#include <QtGui/QAction>
+#include <QtGui/QStackedLayout>
+#include <QtGui/QVBoxLayout>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+FormWindowWidgetStack::FormWindowWidgetStack(QObject *parent) :
+ QObject(parent),
+ m_formContainer(new QWidget),
+ m_formContainerLayout(new QVBoxLayout),
+ m_layout(new QStackedLayout)
+{
+ m_layout->setMargin(0);
+ m_layout->setSpacing(0);
+ m_layout->setStackingMode(QStackedLayout::StackAll);
+
+ m_formContainerLayout->setMargin(0);
+ m_formContainer->setObjectName(QLatin1String("formContainer"));
+ m_formContainer->setLayout(m_formContainerLayout);
+ // System settings might have different background colors, autofill them
+ // (affects for example mainwindow status bars)
+ m_formContainer->setAutoFillBackground(true);
+}
+
+FormWindowWidgetStack::~FormWindowWidgetStack()
+{
+}
+
+int FormWindowWidgetStack::count() const
+{
+ return m_tools.count();
+}
+
+QDesignerFormWindowToolInterface *FormWindowWidgetStack::currentTool() const
+{
+ return tool(currentIndex());
+}
+
+void FormWindowWidgetStack::setCurrentTool(int index)
+{
+ const int cnt = count();
+ if (index < 0 || index >= cnt) {
+ qDebug("FormWindowWidgetStack::setCurrentTool(): invalid index: %d", index);
+ return;
+ }
+
+ const int cur = currentIndex();
+ if (index == cur)
+ return;
+
+ if (cur != -1)
+ m_tools.at(cur)->deactivated();
+
+
+ m_layout->setCurrentIndex(index);
+ // Show the widget editor and the current tool
+ for (int i = 0; i < cnt; i++)
+ m_tools.at(i)->editor()->setVisible(i == 0 || i == index);
+
+ QDesignerFormWindowToolInterface *tool = m_tools.at(index);
+ tool->activated();
+
+ emit currentToolChanged(index);
+}
+
+void FormWindowWidgetStack::setSenderAsCurrentTool()
+{
+ QDesignerFormWindowToolInterface *tool = 0;
+ QAction *action = qobject_cast<QAction*>(sender());
+ if (action == 0) {
+ qDebug("FormWindowWidgetStack::setSenderAsCurrentTool(): sender is not a QAction");
+ return;
+ }
+
+ foreach (QDesignerFormWindowToolInterface *t, m_tools) {
+ if (action == t->action()) {
+ tool = t;
+ break;
+ }
+ }
+
+ if (tool == 0) {
+ qDebug("FormWindowWidgetStack::setSenderAsCurrentTool(): unknown tool");
+ return;
+ }
+
+ setCurrentTool(tool);
+}
+
+int FormWindowWidgetStack::indexOf(QDesignerFormWindowToolInterface *tool) const
+{
+ return m_tools.indexOf(tool);
+}
+
+void FormWindowWidgetStack::setCurrentTool(QDesignerFormWindowToolInterface *tool)
+{
+ int index = indexOf(tool);
+ if (index == -1) {
+ qDebug("FormWindowWidgetStack::setCurrentTool(): unknown tool");
+ return;
+ }
+
+ setCurrentTool(index);
+}
+
+void FormWindowWidgetStack::setMainContainer(QWidget *w)
+{
+ // This code is triggered once by the formwindow and
+ // by integrations doing "revert to saved". Anything changing?
+ const int previousCount = m_formContainerLayout->count();
+ QWidget *previousMainContainer = previousCount ? m_formContainerLayout->itemAt(0)->widget() : static_cast<QWidget*>(0);
+ if (previousMainContainer == w)
+ return;
+ // Swap
+ if (previousCount)
+ delete m_formContainerLayout->takeAt(0);
+ if (w)
+ m_formContainerLayout->addWidget(w);
+}
+
+void FormWindowWidgetStack::addTool(QDesignerFormWindowToolInterface *tool)
+{
+ if (QWidget *w = tool->editor()) {
+ w->setVisible(m_layout->count() == 0); // Initially only form editor is visible
+ m_layout->addWidget(w);
+ } else {
+ // The form editor might not have a tool initially, use dummy. Assert on anything else
+ Q_ASSERT(m_tools.empty());
+ m_layout->addWidget(m_formContainer);
+ }
+
+ m_tools.append(tool);
+
+ connect(tool->action(), SIGNAL(triggered()), this, SLOT(setSenderAsCurrentTool()));
+}
+
+QDesignerFormWindowToolInterface *FormWindowWidgetStack::tool(int index) const
+{
+ if (index < 0 || index >= count())
+ return 0;
+
+ return m_tools.at(index);
+}
+
+int FormWindowWidgetStack::currentIndex() const
+{
+ return m_layout->currentIndex();
+}
+
+QWidget *FormWindowWidgetStack::defaultEditor() const
+{
+ if (m_tools.isEmpty())
+ return 0;
+
+ return m_tools.at(0)->editor();
+}
+
+QLayout *FormWindowWidgetStack::layout() const
+{
+ return m_layout;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindow_widgetstack.h b/tools/designer/src/components/formeditor/formwindow_widgetstack.h
new file mode 100644
index 0000000..92323c5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindow_widgetstack.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOW_WIDGETSTACK_H
+#define FORMWINDOW_WIDGETSTACK_H
+
+#include "formeditor_global.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowToolInterface;
+
+class QStackedLayout;
+class QVBoxLayout;
+class QWidget;
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT FormWindowWidgetStack: public QObject
+{
+ Q_OBJECT
+public:
+ FormWindowWidgetStack(QObject *parent = 0);
+ virtual ~FormWindowWidgetStack();
+
+ QLayout *layout() const;
+
+ int count() const;
+ QDesignerFormWindowToolInterface *tool(int index) const;
+ QDesignerFormWindowToolInterface *currentTool() const;
+ int currentIndex() const;
+ int indexOf(QDesignerFormWindowToolInterface *tool) const;
+
+ void setMainContainer(QWidget *w = 0);
+
+ // Return the widget containing the form which can be used to apply embedded design settings to.
+ // These settings should not affect the other editing tools.
+ QWidget *formContainer() const { return m_formContainer; }
+
+signals:
+ void currentToolChanged(int index);
+
+public slots:
+ void addTool(QDesignerFormWindowToolInterface *tool);
+ void setCurrentTool(QDesignerFormWindowToolInterface *tool);
+ void setCurrentTool(int index);
+ void setSenderAsCurrentTool();
+
+protected:
+ QWidget *defaultEditor() const;
+
+private:
+ QList<QDesignerFormWindowToolInterface*> m_tools;
+ QWidget *m_formContainer;
+ QVBoxLayout *m_formContainerLayout;
+ QStackedLayout *m_layout;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOW_WIDGETSTACK_H
diff --git a/tools/designer/src/components/formeditor/formwindowcursor.cpp b/tools/designer/src/components/formeditor/formwindowcursor.cpp
new file mode 100644
index 0000000..fb30885
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowcursor.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindowcursor.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/propertysheet.h>
+#include <QtDesigner/QExtensionManager>
+#include <qdesigner_propertycommand_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+FormWindowCursor::FormWindowCursor(FormWindow *fw, QObject *parent)
+ : QObject(parent),
+ m_formWindow(fw)
+{
+ update();
+ connect(fw, SIGNAL(changed()), this, SLOT(update()));
+}
+
+FormWindowCursor::~FormWindowCursor()
+{
+}
+
+QDesignerFormWindowInterface *FormWindowCursor::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool FormWindowCursor::movePosition(MoveOperation op, MoveMode mode)
+{
+ if (widgetCount() == 0)
+ return false;
+
+ int iterator = position();
+
+ if (mode == MoveAnchor)
+ m_formWindow->clearSelection(false);
+
+ switch (op) {
+ case Next:
+ ++iterator;
+ if (iterator >= widgetCount())
+ iterator = 0;
+
+ m_formWindow->selectWidget(m_formWindow->widgetAt(iterator), true);
+ return true;
+
+ case Prev:
+ --iterator;
+ if (iterator < 0)
+ iterator = widgetCount() - 1;
+
+ if (iterator < 0)
+ return false;
+
+ m_formWindow->selectWidget(m_formWindow->widgetAt(iterator), true);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+int FormWindowCursor::position() const
+{
+ const int index = m_formWindow->widgets().indexOf(current());
+ return index == -1 ? 0 : index;
+}
+
+void FormWindowCursor::setPosition(int pos, MoveMode mode)
+{
+ if (!widgetCount())
+ return;
+
+ if (mode == MoveAnchor)
+ m_formWindow->clearSelection(false);
+
+ if (pos >= widgetCount())
+ pos = 0;
+
+ m_formWindow->selectWidget(m_formWindow->widgetAt(pos), true);
+}
+
+QWidget *FormWindowCursor::current() const
+{
+ return m_formWindow->currentWidget();
+}
+
+bool FormWindowCursor::hasSelection() const
+{
+ return !m_formWindow->selectedWidgets().isEmpty();
+}
+
+int FormWindowCursor::selectedWidgetCount() const
+{
+ int N = m_formWindow->selectedWidgets().count();
+ return N ? N : 1;
+}
+
+QWidget *FormWindowCursor::selectedWidget(int index) const
+{
+ return hasSelection()
+ ? m_formWindow->selectedWidgets().at(index)
+ : m_formWindow->mainContainer();
+}
+
+void FormWindowCursor::update()
+{
+ // ### todo
+}
+
+int FormWindowCursor::widgetCount() const
+{
+ return m_formWindow->widgetCount();
+}
+
+QWidget *FormWindowCursor::widget(int index) const
+{
+ return m_formWindow->widgetAt(index);
+}
+
+void FormWindowCursor::setProperty(const QString &name, const QVariant &value)
+{
+
+ // build selection
+ const int N = selectedWidgetCount();
+ Q_ASSERT(N);
+
+ SetPropertyCommand::ObjectList selection;
+ for (int i=0; i<N; ++i)
+ selection.push_back(selectedWidget(i));
+
+
+ SetPropertyCommand* setPropertyCommand = new SetPropertyCommand(m_formWindow);
+ if (setPropertyCommand->init(selection, name, value, current())) {
+ m_formWindow->commandHistory()->push(setPropertyCommand);
+ } else {
+ delete setPropertyCommand;
+ qDebug() << "Unable to set property " << name << '.';
+ }
+}
+
+void FormWindowCursor::setWidgetProperty(QWidget *widget, const QString &name, const QVariant &value)
+{
+ SetPropertyCommand *cmd = new SetPropertyCommand(m_formWindow);
+ if (cmd->init(widget, name, value)) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "Unable to set property " << name << '.';
+ }
+}
+
+void FormWindowCursor::resetWidgetProperty(QWidget *widget, const QString &name)
+{
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(m_formWindow);
+ if (cmd->init(widget, name)) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "Unable to reset property " << name << '.';
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindowcursor.h b/tools/designer/src/components/formeditor/formwindowcursor.h
new file mode 100644
index 0000000..7167432
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowcursor.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOWCURSOR_H
+#define FORMWINDOWCURSOR_H
+
+#include "formeditor_global.h"
+#include "formwindow.h"
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT FormWindowCursor: public QObject, public QDesignerFormWindowCursorInterface
+{
+ Q_OBJECT
+public:
+ explicit FormWindowCursor(FormWindow *fw, QObject *parent = 0);
+ virtual ~FormWindowCursor();
+
+ virtual QDesignerFormWindowInterface *formWindow() const;
+
+ virtual bool movePosition(MoveOperation op, MoveMode mode);
+
+ virtual int position() const;
+ virtual void setPosition(int pos, MoveMode mode);
+
+ virtual QWidget *current() const;
+
+ virtual int widgetCount() const;
+ virtual QWidget *widget(int index) const;
+
+ virtual bool hasSelection() const;
+ virtual int selectedWidgetCount() const;
+ virtual QWidget *selectedWidget(int index) const;
+
+ virtual void setProperty(const QString &name, const QVariant &value);
+ virtual void setWidgetProperty(QWidget *widget, const QString &name, const QVariant &value);
+ virtual void resetWidgetProperty(QWidget *widget, const QString &name);
+
+public slots:
+ void update();
+
+private:
+ FormWindow *m_formWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWCURSOR_H
diff --git a/tools/designer/src/components/formeditor/formwindowmanager.cpp b/tools/designer/src/components/formeditor/formwindowmanager.cpp
new file mode 100644
index 0000000..ea8d128
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowmanager.cpp
@@ -0,0 +1,1016 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// components/formeditor
+#include "formwindowmanager.h"
+#include "formwindow_dnditem.h"
+#include "formwindow.h"
+#include "formeditor.h"
+#include "widgetselection.h"
+#include "previewactiongroup.h"
+#include "formwindowsettings.h"
+
+// shared
+#include <widgetdatabase_p.h>
+#include <iconloader_p.h>
+#include <connectionedit_p.h>
+#include <qtresourcemodel_p.h>
+#include <qdesigner_dnditem_p.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_command2_p.h>
+#include <layoutinfo_p.h>
+#include <qlayout_widget_p.h>
+#include <qdesigner_objectinspector_p.h>
+#include <actioneditor_p.h>
+#include <shared_settings_p.h>
+#include <previewmanager_p.h>
+#include <abstractdialoggui_p.h>
+#include <widgetfactory_p.h>
+#include <spacer_widget_p.h>
+
+// SDK
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerIntegrationInterface>
+
+#include <QtGui/QUndoGroup>
+#include <QtGui/QAction>
+#include <QtGui/QSplitter>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QApplication>
+#include <QtGui/QSizeGrip>
+#include <QtGui/QClipboard>
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QMessageBox>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { debugFWM = 0 };
+}
+
+static inline QString whatsThisFrom(const QString &str) { /// ### implement me!
+ return str;
+}
+
+// find the first child of w in a sequence
+template <class Iterator>
+static inline Iterator findFirstChildOf(Iterator it,Iterator end, const QWidget *w)
+{
+ for (;it != end; ++it) {
+ if (w->isAncestorOf(*it))
+ return it;
+ }
+ return it;
+}
+
+namespace qdesigner_internal {
+
+FormWindowManager::FormWindowManager(QDesignerFormEditorInterface *core, QObject *parent) :
+ QDesignerFormWindowManager(parent),
+ m_core(core),
+ m_activeFormWindow(0),
+ m_previewManager(new PreviewManager(PreviewManager::SingleFormNonModalPreview, this)),
+ m_createLayoutContext(LayoutContainer),
+ m_morphLayoutContainer(0),
+ m_actionGroupPreviewInStyle(0),
+ m_actionShowFormWindowSettingsDialog(0)
+{
+ setupActions();
+ qApp->installEventFilter(this);
+}
+
+FormWindowManager::~FormWindowManager()
+{
+ qDeleteAll(m_formWindows);
+}
+
+QDesignerFormEditorInterface *FormWindowManager::core() const
+{
+ return m_core;
+}
+
+QDesignerFormWindowInterface *FormWindowManager::activeFormWindow() const
+{
+ return m_activeFormWindow;
+}
+
+int FormWindowManager::formWindowCount() const
+{
+ return m_formWindows.size();
+}
+
+QDesignerFormWindowInterface *FormWindowManager::formWindow(int index) const
+{
+ return m_formWindows.at(index);
+}
+
+bool FormWindowManager::eventFilter(QObject *o, QEvent *e)
+{
+ if (!o->isWidgetType())
+ return false;
+
+ // If we don't have an active form, we only listen for WindowActivate to speed up integrations
+ const QEvent::Type eventType = e->type();
+ if (m_activeFormWindow == 0 && eventType != QEvent::WindowActivate)
+ return false;
+
+ switch (eventType) { // Uninteresting events
+ case QEvent::Create:
+ case QEvent::Destroy:
+ case QEvent::AccessibilityDescription:
+ case QEvent::AccessibilityHelp:
+ case QEvent::AccessibilityPrepare:
+ case QEvent::ActionAdded:
+ case QEvent::ActionChanged:
+ case QEvent::ActionRemoved:
+ case QEvent::ChildAdded:
+ case QEvent::ChildPolished:
+ case QEvent::ChildRemoved:
+ case QEvent::Clipboard:
+ case QEvent::ContentsRectChange:
+ case QEvent::DeferredDelete:
+ case QEvent::FileOpen:
+ case QEvent::LanguageChange:
+ case QEvent::MetaCall:
+ case QEvent::ModifiedChange:
+ case QEvent::Paint:
+ case QEvent::PaletteChange:
+ case QEvent::ParentAboutToChange:
+ case QEvent::ParentChange:
+ case QEvent::Polish:
+ case QEvent::PolishRequest:
+ case QEvent::QueryWhatsThis:
+ case QEvent::StatusTip:
+ case QEvent::StyleChange:
+ case QEvent::Timer:
+ case QEvent::ToolBarChange:
+ case QEvent::ToolTip:
+ case QEvent::WhatsThis:
+ case QEvent::WhatsThisClicked:
+ case QEvent::DynamicPropertyChange:
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ return false;
+ default:
+ break;
+ }
+
+ QWidget *widget = static_cast<QWidget*>(o);
+
+ if (qobject_cast<WidgetHandle*>(widget)) { // ### remove me
+ return false;
+ }
+
+ FormWindow *fw = FormWindow::findFormWindow(widget);
+ if (fw == 0) {
+ return false;
+ }
+
+ if (QWidget *managedWidget = findManagedWidget(fw, widget)) {
+ // Prevent MDI and QWorkspace subwindows from being closed by clicking at the title bar
+ if (managedWidget != widget && eventType == QEvent::Close) {
+ e->ignore();
+ return true;
+ }
+ switch (eventType) {
+
+ case QEvent::WindowActivate: {
+ if (fw->parentWidget()->isWindow() && fw->isMainContainer(managedWidget) && activeFormWindow() != fw) {
+ setActiveFormWindow(fw);
+ }
+ } break;
+
+ case QEvent::WindowDeactivate: {
+ if (o == fw && o == activeFormWindow())
+ fw->repaintSelection();
+ } break;
+
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Escape) {
+ ke->accept();
+ return true;
+ }
+ }
+ // don't break...
+ // Embedded Design: Drop on different form: Make sure the right form
+ // window/device is active before having the widget created by the factory
+ case QEvent::Drop:
+ if (activeFormWindow() != fw)
+ setActiveFormWindow(fw);
+ // don't break...
+ default: {
+ if (fw->handleEvent(widget, managedWidget, e)) {
+ return true;
+ }
+ } break;
+
+ } // end switch
+ }
+
+ return false;
+}
+
+void FormWindowManager::addFormWindow(QDesignerFormWindowInterface *w)
+{
+ FormWindow *formWindow = qobject_cast<FormWindow*>(w);
+ if (!formWindow || m_formWindows.contains(formWindow))
+ return;
+
+ connect(formWindow, SIGNAL(selectionChanged()), this, SLOT(slotUpdateActions()));
+ connect(formWindow->commandHistory(), SIGNAL(indexChanged(int)), this, SLOT(slotUpdateActions()));
+ connect(formWindow, SIGNAL(toolChanged(int)), this, SLOT(slotUpdateActions()));
+
+ if (ActionEditor *ae = qobject_cast<ActionEditor *>(m_core->actionEditor()))
+ connect(w, SIGNAL(mainContainerChanged(QWidget*)), ae, SLOT(mainContainerChanged()));
+ if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(m_core->objectInspector()))
+ connect(w, SIGNAL(mainContainerChanged(QWidget*)), oi, SLOT(mainContainerChanged()));
+
+ m_formWindows.append(formWindow);
+ emit formWindowAdded(formWindow);
+}
+
+void FormWindowManager::removeFormWindow(QDesignerFormWindowInterface *w)
+{
+ FormWindow *formWindow = qobject_cast<FormWindow*>(w);
+
+ int idx = m_formWindows.indexOf(formWindow);
+ if (!formWindow || idx == -1)
+ return;
+
+ formWindow->disconnect(this);
+ m_formWindows.removeAt(idx);
+ emit formWindowRemoved(formWindow);
+
+ if (formWindow == m_activeFormWindow)
+ setActiveFormWindow(0);
+
+ if (m_formWindows.size() == 0
+ && m_core->widgetBox()) {
+ // Make sure that widget box is enabled by default
+ m_core->widgetBox()->setEnabled(true);
+ }
+
+}
+
+void FormWindowManager::setActiveFormWindow(QDesignerFormWindowInterface *w)
+{
+ FormWindow *formWindow = qobject_cast<FormWindow*>(w);
+
+ if (formWindow == m_activeFormWindow)
+ return;
+
+ FormWindow *old = m_activeFormWindow;
+
+ m_activeFormWindow = formWindow;
+
+ QtResourceSet *resourceSet = 0;
+ if (formWindow)
+ resourceSet = formWindow->resourceSet();
+ m_core->resourceModel()->setCurrentResourceSet(resourceSet);
+
+ slotUpdateActions();
+
+ if (m_activeFormWindow) {
+ m_activeFormWindow->repaintSelection();
+ if (old)
+ old->repaintSelection();
+ }
+
+ emit activeFormWindowChanged(m_activeFormWindow);
+
+ if (m_activeFormWindow) {
+ m_activeFormWindow->emitSelectionChanged();
+ m_activeFormWindow->commandHistory()->setActive();
+ // Trigger setActiveSubWindow on mdi area unless we are in toplevel mode
+ QMdiSubWindow *mdiSubWindow = 0;
+ if (QWidget *formwindow = m_activeFormWindow->parentWidget()) {
+ mdiSubWindow = qobject_cast<QMdiSubWindow *>(formwindow->parentWidget());
+ }
+ if (mdiSubWindow) {
+ for (QWidget *parent = mdiSubWindow->parentWidget(); parent; parent = parent->parentWidget()) {
+ if (QMdiArea *mdiArea = qobject_cast<QMdiArea*>(parent)) {
+ mdiArea->setActiveSubWindow(mdiSubWindow);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void FormWindowManager::closeAllPreviews()
+{
+ m_previewManager->closeAllPreviews();
+}
+
+QWidget *FormWindowManager::findManagedWidget(FormWindow *fw, QWidget *w)
+{
+ while (w && w != fw) {
+ if (fw->isManaged(w))
+ break;
+ w = w->parentWidget();
+ }
+ return w;
+}
+
+void FormWindowManager::setupActions()
+{
+ m_actionCut = new QAction(createIconSet(QLatin1String("editcut.png")), tr("Cu&t"), this);
+ m_actionCut->setObjectName(QLatin1String("__qt_cut_action"));
+ m_actionCut->setShortcut(QKeySequence::Cut);
+ m_actionCut->setStatusTip(tr("Cuts the selected widgets and puts them on the clipboard"));
+ m_actionCut->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Cut")));
+ connect(m_actionCut, SIGNAL(triggered()), this, SLOT(slotActionCutActivated()));
+ m_actionCut->setEnabled(false);
+
+ m_actionCopy = new QAction(createIconSet(QLatin1String("editcopy.png")), tr("&Copy"), this);
+ m_actionCopy->setObjectName(QLatin1String("__qt_copy_action"));
+ m_actionCopy->setShortcut(QKeySequence::Copy);
+ m_actionCopy->setStatusTip(tr("Copies the selected widgets to the clipboard"));
+ m_actionCopy->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Copy")));
+ connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(slotActionCopyActivated()));
+ m_actionCopy->setEnabled(false);
+
+ m_actionPaste = new QAction(createIconSet(QLatin1String("editpaste.png")), tr("&Paste"), this);
+ m_actionPaste->setObjectName(QLatin1String("__qt_paste_action"));
+ m_actionPaste->setShortcut(QKeySequence::Paste);
+ m_actionPaste->setStatusTip(tr("Pastes the clipboard's contents"));
+ m_actionPaste->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Paste")));
+ connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(slotActionPasteActivated()));
+ m_actionPaste->setEnabled(false);
+
+ m_actionDelete = new QAction(tr("&Delete"), this);
+ m_actionDelete->setObjectName(QLatin1String("__qt_delete_action"));
+ m_actionDelete->setStatusTip(tr("Deletes the selected widgets"));
+ m_actionDelete->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Delete")));
+ connect(m_actionDelete, SIGNAL(triggered()), this, SLOT(slotActionDeleteActivated()));
+ m_actionDelete->setEnabled(false);
+
+ m_actionSelectAll = new QAction(tr("Select &All"), this);
+ m_actionSelectAll->setObjectName(QLatin1String("__qt_select_all_action"));
+ m_actionSelectAll->setShortcut(QKeySequence::SelectAll);
+ m_actionSelectAll->setStatusTip(tr("Selects all widgets"));
+ m_actionSelectAll->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Select All")));
+ connect(m_actionSelectAll, SIGNAL(triggered()), this, SLOT(slotActionSelectAllActivated()));
+ m_actionSelectAll->setEnabled(false);
+
+ m_actionRaise = new QAction(createIconSet(QLatin1String("editraise.png")), tr("Bring to &Front"), this);
+ m_actionRaise->setObjectName(QLatin1String("__qt_raise_action"));
+ m_actionRaise->setShortcut(Qt::CTRL + Qt::Key_L);
+ m_actionRaise->setStatusTip(tr("Raises the selected widgets"));
+ m_actionRaise->setWhatsThis(tr("Raises the selected widgets"));
+ connect(m_actionRaise, SIGNAL(triggered()), this, SLOT(slotActionRaiseActivated()));
+ m_actionRaise->setEnabled(false);
+
+ m_actionLower = new QAction(createIconSet(QLatin1String("editlower.png")), tr("Send to &Back"), this);
+ m_actionLower->setObjectName(QLatin1String("__qt_lower_action"));
+ m_actionLower->setShortcut(Qt::CTRL + Qt::Key_K);
+ m_actionLower->setStatusTip(tr("Lowers the selected widgets"));
+ m_actionLower->setWhatsThis(tr("Lowers the selected widgets"));
+ connect(m_actionLower, SIGNAL(triggered()), this, SLOT(slotActionLowerActivated()));
+ m_actionLower->setEnabled(false);
+
+ m_actionAdjustSize = new QAction(createIconSet(QLatin1String("adjustsize.png")), tr("Adjust &Size"), this);
+ m_actionAdjustSize->setObjectName(QLatin1String("__qt_adjust_size_action"));
+ m_actionAdjustSize->setShortcut(Qt::CTRL + Qt::Key_J);
+ m_actionAdjustSize->setStatusTip(tr("Adjusts the size of the selected widget"));
+ m_actionAdjustSize->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Adjust Size")));
+ connect(m_actionAdjustSize, SIGNAL(triggered()), this, SLOT(slotActionAdjustSizeActivated()));
+ m_actionAdjustSize->setEnabled(false);
+
+
+ m_actionHorizontalLayout = new QAction(createIconSet(QLatin1String("edithlayout.png")), tr("Lay Out &Horizontally"), this);
+ m_actionHorizontalLayout->setObjectName(QLatin1String("__qt_horizontal_layout_action"));
+ m_actionHorizontalLayout->setShortcut(Qt::CTRL + Qt::Key_1);
+ m_actionHorizontalLayout->setStatusTip(tr("Lays out the selected widgets horizontally"));
+ m_actionHorizontalLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Horizontally")));
+ m_actionHorizontalLayout->setData(LayoutInfo::HBox);
+ m_actionHorizontalLayout->setEnabled(false);
+ connect(m_actionHorizontalLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionVerticalLayout = new QAction(createIconSet(QLatin1String("editvlayout.png")), tr("Lay Out &Vertically"), this);
+ m_actionVerticalLayout->setObjectName(QLatin1String("__qt_vertical_layout_action"));
+ m_actionVerticalLayout->setShortcut(Qt::CTRL + Qt::Key_2);
+ m_actionVerticalLayout->setStatusTip(tr("Lays out the selected widgets vertically"));
+ m_actionVerticalLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Vertically")));
+ m_actionVerticalLayout->setData(LayoutInfo::VBox);
+ m_actionVerticalLayout->setEnabled(false);
+ connect(m_actionVerticalLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ QAction *actionFormLayout = new QAction(createIconSet(QLatin1String("editform.png")), tr("Lay Out in a &Form Layout"), this);
+ actionFormLayout->setObjectName(QLatin1String("__qt_form_layout_action"));
+ actionFormLayout->setShortcut(Qt::CTRL + Qt::Key_6);
+ actionFormLayout->setStatusTip(tr("Lays out the selected widgets in a form layout"));
+ actionFormLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out in a Form")));
+ actionFormLayout->setData(LayoutInfo::Form);
+ actionFormLayout->setEnabled(false);
+ setActionFormLayout(actionFormLayout);
+ connect(actionFormLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionGridLayout = new QAction(createIconSet(QLatin1String("editgrid.png")), tr("Lay Out in a &Grid"), this);
+ m_actionGridLayout->setObjectName(QLatin1String("__qt_grid_layout_action"));
+ m_actionGridLayout->setShortcut(Qt::CTRL + Qt::Key_5);
+ m_actionGridLayout->setStatusTip(tr("Lays out the selected widgets in a grid"));
+ m_actionGridLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out in a Grid")));
+ m_actionGridLayout->setData(LayoutInfo::Grid);
+ m_actionGridLayout->setEnabled(false);
+ connect(m_actionGridLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionSplitHorizontal = new QAction(createIconSet(QLatin1String("edithlayoutsplit.png")),
+ tr("Lay Out Horizontally in S&plitter"), this);
+ m_actionSplitHorizontal->setObjectName(QLatin1String("__qt_split_horizontal_action"));
+ m_actionSplitHorizontal->setShortcut(Qt::CTRL + Qt::Key_3);
+ m_actionSplitHorizontal->setStatusTip(tr("Lays out the selected widgets horizontally in a splitter"));
+ m_actionSplitHorizontal->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Horizontally in Splitter")));
+ m_actionSplitHorizontal->setData(LayoutInfo::HSplitter);
+ m_actionSplitHorizontal->setEnabled(false);
+ connect(m_actionSplitHorizontal, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionSplitVertical = new QAction(createIconSet(QLatin1String("editvlayoutsplit.png")),
+ tr("Lay Out Vertically in Sp&litter"), this);
+ m_actionSplitVertical->setObjectName(QLatin1String("__qt_split_vertical_action"));
+ m_actionSplitVertical->setShortcut(Qt::CTRL + Qt::Key_4);
+ m_actionSplitVertical->setStatusTip(tr("Lays out the selected widgets vertically in a splitter"));
+ m_actionSplitVertical->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Vertically in Splitter")));
+ connect(m_actionSplitVertical, SIGNAL(triggered()), this, SLOT(createLayout()));
+ m_actionSplitVertical->setData(LayoutInfo::VSplitter);
+
+ m_actionSplitVertical->setEnabled(false);
+
+ m_actionBreakLayout = new QAction(createIconSet(QLatin1String("editbreaklayout.png")), tr("&Break Layout"), this);
+ m_actionBreakLayout->setObjectName(QLatin1String("__qt_break_layout_action"));
+ m_actionBreakLayout->setShortcut(Qt::CTRL + Qt::Key_0);
+ m_actionBreakLayout->setStatusTip(tr("Breaks the selected layout"));
+ m_actionBreakLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Break Layout")));
+ connect(m_actionBreakLayout, SIGNAL(triggered()), this, SLOT(slotActionBreakLayoutActivated()));
+ m_actionBreakLayout->setEnabled(false);
+
+ QAction *simplifyLayoutAction = new QAction(tr("Si&mplify Grid Layout"), this);
+ simplifyLayoutAction->setObjectName(QLatin1String("__qt_simplify_layout_action"));
+ simplifyLayoutAction->setStatusTip(tr("Removes empty columns and rows"));
+ simplifyLayoutAction->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Simplify Layout")));
+ connect(simplifyLayoutAction, SIGNAL(triggered()), this, SLOT(slotActionSimplifyLayoutActivated()));
+ simplifyLayoutAction->setEnabled(false);
+ setActionSimplifyLayout(simplifyLayoutAction);
+
+ m_actionDefaultPreview = new QAction(tr("&Preview..."), this);
+ m_actionDefaultPreview->setObjectName(QLatin1String("__qt_default_preview_action"));
+ m_actionDefaultPreview->setStatusTip(tr("Preview current form"));
+ m_actionDefaultPreview->setWhatsThis(whatsThisFrom(QLatin1String("Form|Preview")));
+ connect(m_actionDefaultPreview, SIGNAL(triggered()),
+ this, SLOT(slotActionDefaultPreviewActivated()));
+
+ m_undoGroup = new QUndoGroup(this);
+
+ m_actionUndo = m_undoGroup->createUndoAction(this);
+ m_actionUndo->setEnabled(false);
+ m_actionUndo->setIcon(createIconSet(QLatin1String("undo.png")));
+ m_actionRedo = m_undoGroup->createRedoAction(this);
+ m_actionRedo->setEnabled(false);
+ m_actionRedo->setIcon(createIconSet(QLatin1String("redo.png")));
+
+ m_actionShowFormWindowSettingsDialog = new QAction(tr("Form &Settings..."), this);
+ m_actionShowFormWindowSettingsDialog->setObjectName(QLatin1String("__qt_form_settings_action"));
+ connect(m_actionShowFormWindowSettingsDialog, SIGNAL(triggered()), this, SLOT(slotActionShowFormWindowSettingsDialog()));
+ m_actionShowFormWindowSettingsDialog->setEnabled(false);
+}
+
+void FormWindowManager::slotActionCutActivated()
+{
+ m_activeFormWindow->cut();
+}
+
+void FormWindowManager::slotActionCopyActivated()
+{
+ m_activeFormWindow->copy();
+ slotUpdateActions();
+}
+
+void FormWindowManager::slotActionPasteActivated()
+{
+ m_activeFormWindow->paste();
+}
+
+void FormWindowManager::slotActionDeleteActivated()
+{
+ m_activeFormWindow->deleteWidgets();
+}
+
+void FormWindowManager::slotActionLowerActivated()
+{
+ m_activeFormWindow->lowerWidgets();
+}
+
+void FormWindowManager::slotActionRaiseActivated()
+{
+ m_activeFormWindow->raiseWidgets();
+}
+
+static inline QWidget *findLayoutContainer(const FormWindow *fw)
+{
+ QList<QWidget*> l(fw->selectedWidgets());
+ fw->simplifySelection(&l);
+ return l.empty() ? fw->mainContainer() : l.front();
+}
+
+void FormWindowManager::createLayout()
+{
+ QAction *a = qobject_cast<QAction *>(sender());
+ if (!a)
+ return;
+ const int type = a->data().toInt();
+ switch (m_createLayoutContext) {
+ case LayoutContainer:
+ // Cannot create a splitter on a container
+ if (type != LayoutInfo::HSplitter && type != LayoutInfo::VSplitter)
+ m_activeFormWindow->createLayout(type, findLayoutContainer(m_activeFormWindow));
+ break;
+ case LayoutSelection:
+ m_activeFormWindow->createLayout(type);
+ break;
+ case MorphLayout:
+ m_activeFormWindow->morphLayout(m_morphLayoutContainer, type);
+ break;
+ }
+}
+
+void FormWindowManager::slotActionBreakLayoutActivated()
+{
+ const QList<QWidget *> layouts = layoutsToBeBroken();
+ if (layouts.isEmpty())
+ return;
+
+ if (debugFWM) {
+ qDebug() << "slotActionBreakLayoutActivated: " << layouts.size();
+ foreach (QWidget *w, layouts) {
+ qDebug() << w;
+ }
+ }
+
+ m_activeFormWindow->beginCommand(tr("Break Layout"));
+ foreach (QWidget *layout, layouts) {
+ m_activeFormWindow->breakLayout(layout);
+ }
+ m_activeFormWindow->endCommand();
+}
+
+void FormWindowManager::slotActionSimplifyLayoutActivated()
+{
+ Q_ASSERT(m_activeFormWindow != 0);
+ QWidgetList selectedWidgets = m_activeFormWindow->selectedWidgets();
+ m_activeFormWindow->simplifySelection(&selectedWidgets);
+ if (selectedWidgets.size() != 1)
+ return;
+ SimplifyLayoutCommand *cmd = new SimplifyLayoutCommand(m_activeFormWindow);
+ if (cmd->init(selectedWidgets.front())) {
+ m_activeFormWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ }
+}
+
+void FormWindowManager::slotActionAdjustSizeActivated()
+{
+ Q_ASSERT(m_activeFormWindow != 0);
+
+ m_activeFormWindow->beginCommand(tr("Adjust Size"));
+
+ QList<QWidget*> selectedWidgets = m_activeFormWindow->selectedWidgets();
+ m_activeFormWindow->simplifySelection(&selectedWidgets);
+
+ if (selectedWidgets.isEmpty()) {
+ Q_ASSERT(m_activeFormWindow->mainContainer() != 0);
+ selectedWidgets.append(m_activeFormWindow->mainContainer());
+ }
+
+ // Always count the main container as unlaid-out
+ foreach (QWidget *widget, selectedWidgets) {
+ bool unlaidout = LayoutInfo::layoutType(core(), widget->parentWidget()) == LayoutInfo::NoLayout;
+ bool isMainContainer = m_activeFormWindow->isMainContainer(widget);
+
+ if (unlaidout || isMainContainer) {
+ AdjustWidgetSizeCommand *cmd = new AdjustWidgetSizeCommand(m_activeFormWindow);
+ cmd->init(widget);
+ m_activeFormWindow->commandHistory()->push(cmd);
+ }
+ }
+
+ m_activeFormWindow->endCommand();
+}
+
+void FormWindowManager::slotActionSelectAllActivated()
+{
+ m_activeFormWindow->selectAll();
+}
+
+void FormWindowManager::slotActionDefaultPreviewActivated()
+{
+ slotActionGroupPreviewInStyle(QString(), -1);
+}
+
+void FormWindowManager::slotActionGroupPreviewInStyle(const QString &style, int deviceProfileIndex)
+{
+ QDesignerFormWindowInterface *fw = activeFormWindow();
+ if (!fw)
+ return;
+
+ QString errorMessage;
+ if (!m_previewManager->showPreview(fw, style, deviceProfileIndex, &errorMessage)) {
+ const QString title = tr("Could not create form preview", "Title of warning message box");
+ core()->dialogGui()->message(fw, QDesignerDialogGuiInterface::FormEditorMessage, QMessageBox::Warning,
+ title, errorMessage);
+ }
+}
+
+// The user might click on a layout child or the actual layout container.
+QWidgetList FormWindowManager::layoutsToBeBroken(QWidget *w) const
+{
+ if (!w)
+ return QList<QWidget *>();
+
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: " << w;
+
+ QWidget *parent = w->parentWidget();
+ if (m_activeFormWindow->isMainContainer(w))
+ parent = 0;
+
+ QWidget *widget = core()->widgetFactory()->containerOfWidget(w);
+
+ // maybe we want to remove following block
+ const QDesignerWidgetDataBaseInterface *db = m_core->widgetDataBase();
+ const QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(widget));
+ if (!item) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Don't have an item, recursing for parent";
+ return layoutsToBeBroken(parent);
+ }
+
+ const bool layoutContainer = (item->isContainer() || m_activeFormWindow->isMainContainer(widget));
+
+ if (!layoutContainer) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Not a container, recursing for parent";
+ return layoutsToBeBroken(parent);
+ }
+
+ QLayout *widgetLayout = widget->layout();
+ QLayout *managedLayout = LayoutInfo::managedLayout(m_core, widgetLayout);
+ if (!managedLayout) {
+ if (qobject_cast<const QSplitter *>(widget)) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Splitter special";
+ QList<QWidget *> list = layoutsToBeBroken(parent);
+ list.append(widget);
+ return list;
+ }
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Is a container but doesn't have a managed layout (has an internal layout), returning 0";
+ return QList<QWidget *>();
+ }
+
+ if (managedLayout) {
+ QList<QWidget *> list;
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Is a container and has a layout";
+ if (qobject_cast<const QLayoutWidget *>(widget)) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: red layout special case";
+ list = layoutsToBeBroken(parent);
+ }
+ list.append(widget);
+ return list;
+ }
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Is a container but doesn't have a layout at all, returning 0";
+ return QList<QWidget *>();
+
+}
+
+QMap<QWidget *, bool> FormWindowManager::getUnsortedLayoutsToBeBroken(bool firstOnly) const
+{
+ // Return a set of layouts to be broken.
+ QMap<QWidget *, bool> layouts;
+
+ QList<QWidget *> selection = m_activeFormWindow->selectedWidgets();
+ if (selection.isEmpty() && m_activeFormWindow->mainContainer())
+ selection.append(m_activeFormWindow->mainContainer());
+
+ const QList<QWidget *>::const_iterator scend = selection.constEnd();
+ for (QList<QWidget *>::const_iterator sit = selection.constBegin(); sit != scend; ++sit) {
+ // find all layouts
+ const QList<QWidget *> list = layoutsToBeBroken(*sit);
+ if (!list.empty()) {
+ const QList<QWidget *>::const_iterator lbcend = list.constEnd();
+ for (QList<QWidget *>::const_iterator lbit = list.constBegin(); lbit != lbcend; ++lbit) {
+ layouts.insert(*lbit, true);
+ }
+ if (firstOnly)
+ return layouts;
+ }
+ }
+ return layouts;
+}
+
+bool FormWindowManager::hasLayoutsToBeBroken() const
+{
+ // Quick check for layouts to be broken
+ return !getUnsortedLayoutsToBeBroken(true).isEmpty();
+}
+
+QWidgetList FormWindowManager::layoutsToBeBroken() const
+{
+ // Get all layouts. This is a list of all 'red' layouts (QLayoutWidgets)
+ // up to the first 'real' widget with a layout in hierarchy order.
+ QMap<QWidget *, bool> unsortedLayouts = getUnsortedLayoutsToBeBroken(false);
+ // Sort in order of hierarchy
+ QList<QWidget *> orderedLayoutList;
+ const QMap<QWidget *, bool>::const_iterator lscend = unsortedLayouts.constEnd();
+ for (QMap<QWidget *, bool>::const_iterator itLay = unsortedLayouts.constBegin(); itLay != lscend; ++itLay) {
+ QWidget *wToBeInserted = itLay.key();
+ if (!orderedLayoutList.contains(wToBeInserted)) {
+ // try to find first child, use as insertion position, else append
+ const QList<QWidget *>::iterator firstChildPos = findFirstChildOf(orderedLayoutList.begin(), orderedLayoutList.end(), wToBeInserted);
+ if (firstChildPos == orderedLayoutList.end()) {
+ orderedLayoutList.push_back(wToBeInserted);
+ } else {
+ orderedLayoutList.insert(firstChildPos, wToBeInserted);
+ }
+ }
+ }
+ return orderedLayoutList;
+}
+
+static inline bool hasManagedLayoutItems(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ if (const QLayout *ml = LayoutInfo::managedLayout(core, w)) {
+ // Try to find managed items, ignore dummy grid spacers
+ const int count = ml->count();
+ for (int i = 0; i < count; i++)
+ if (!LayoutInfo::isEmptyItem(ml->itemAt(i)))
+ return true;
+ }
+ return false;
+}
+
+void FormWindowManager::slotUpdateActions()
+{
+ m_createLayoutContext = LayoutSelection;
+ m_morphLayoutContainer = 0;
+ bool canMorphIntoVBoxLayout = false;
+ bool canMorphIntoHBoxLayout = false;
+ bool canMorphIntoGridLayout = false;
+ bool canMorphIntoFormLayout = false;
+ int selectedWidgetCount = 0;
+ int laidoutWidgetCount = 0;
+ int unlaidoutWidgetCount = 0;
+ bool pasteAvailable = false;
+ bool layoutAvailable = false;
+ bool breakAvailable = false;
+ bool simplifyAvailable = false;
+ bool layoutContainer = false;
+ bool canChangeZOrder = true;
+
+ do {
+ if (m_activeFormWindow == 0 || m_activeFormWindow->currentTool() != 0)
+ break;
+
+ breakAvailable = hasLayoutsToBeBroken();
+
+ QWidgetList simplifiedSelection = m_activeFormWindow->selectedWidgets();
+
+ selectedWidgetCount = simplifiedSelection.count();
+ pasteAvailable = qApp->clipboard()->mimeData() && qApp->clipboard()->mimeData()->hasText();
+
+ m_activeFormWindow->simplifySelection(&simplifiedSelection);
+ QWidget *mainContainer = m_activeFormWindow->mainContainer();
+ if (simplifiedSelection.isEmpty() && mainContainer)
+ simplifiedSelection.append(mainContainer);
+
+ // Always count the main container as unlaid-out
+ const QWidgetList::const_iterator cend = simplifiedSelection.constEnd();
+ for (QWidgetList::const_iterator it = simplifiedSelection.constBegin(); it != cend; ++it) {
+ if (*it != mainContainer && LayoutInfo::isWidgetLaidout(m_core, *it)) {
+ ++laidoutWidgetCount;
+ } else {
+ ++unlaidoutWidgetCount;
+ }
+ if (qobject_cast<const QLayoutWidget *>(*it) || qobject_cast<const Spacer *>(*it))
+ canChangeZOrder = false;
+ }
+
+ // Figure out layouts: Looking at a group of dangling widgets
+ if (simplifiedSelection.count() != 1) {
+ layoutAvailable = unlaidoutWidgetCount > 1;
+ //breakAvailable = false;
+ break;
+ }
+ // Manipulate layout of a single widget
+ m_createLayoutContext = LayoutSelection;
+ QWidget *widget = core()->widgetFactory()->containerOfWidget(simplifiedSelection.first());
+ if (widget == 0) // We are looking at a page-based container with 0 pages
+ break;
+
+ const QDesignerWidgetDataBaseInterface *db = m_core->widgetDataBase();
+ const QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(widget));
+ if (!item)
+ break;
+
+ QLayout *widgetLayout = LayoutInfo::internalLayout(widget);
+ QLayout *managedLayout = LayoutInfo::managedLayout(m_core, widgetLayout);
+ // We don't touch a layout createds by a custom widget
+ if (widgetLayout && !managedLayout)
+ break;
+
+ layoutContainer = (item->isContainer() || m_activeFormWindow->isMainContainer(widget));
+
+ layoutAvailable = layoutContainer && m_activeFormWindow->hasInsertedChildren(widget) && managedLayout == 0;
+ simplifyAvailable = SimplifyLayoutCommand::canSimplify(m_core, widget);
+ if (layoutAvailable) {
+ m_createLayoutContext = LayoutContainer;
+ } else {
+ /* Cannot create a layout, have some layouts to be broken and
+ * exactly one, non-empty layout with selected: check the morph layout options
+ * (Note that there might be > 1 layouts to broken if the selection
+ * is a red layout, however, we want the inner-most layout here). */
+ if (breakAvailable && simplifiedSelection.size() == 1
+ && hasManagedLayoutItems(m_core, widget)) {
+ int type;
+ m_morphLayoutContainer = widget; // Was: page of first selected
+ m_createLayoutContext = MorphLayout;
+ if (MorphLayoutCommand::canMorph(m_activeFormWindow, m_morphLayoutContainer, &type)) {
+ canMorphIntoVBoxLayout = type != LayoutInfo::VBox;
+ canMorphIntoHBoxLayout = type != LayoutInfo::HBox;
+ canMorphIntoGridLayout = type != LayoutInfo::Grid;
+ canMorphIntoFormLayout = type != LayoutInfo::Form;
+ }
+ }
+ }
+ } while(false);
+
+ m_actionCut->setEnabled(selectedWidgetCount > 0);
+ m_actionCopy->setEnabled(selectedWidgetCount > 0);
+ m_actionDelete->setEnabled(selectedWidgetCount > 0);
+ m_actionLower->setEnabled(canChangeZOrder && selectedWidgetCount > 0);
+ m_actionRaise->setEnabled(canChangeZOrder && selectedWidgetCount > 0);
+
+ m_actionPaste->setEnabled(pasteAvailable);
+
+ m_actionSelectAll->setEnabled(m_activeFormWindow != 0);
+
+ m_actionAdjustSize->setEnabled(unlaidoutWidgetCount > 0);
+
+ m_actionHorizontalLayout->setEnabled(layoutAvailable || canMorphIntoHBoxLayout);
+ m_actionVerticalLayout->setEnabled(layoutAvailable || canMorphIntoVBoxLayout);
+ m_actionSplitHorizontal->setEnabled(layoutAvailable && !layoutContainer);
+ m_actionSplitVertical->setEnabled(layoutAvailable && !layoutContainer);
+ actionFormLayout()->setEnabled(layoutAvailable || canMorphIntoFormLayout);
+ m_actionGridLayout->setEnabled(layoutAvailable || canMorphIntoGridLayout);
+
+ m_actionBreakLayout->setEnabled(breakAvailable);
+ actionSimplifyLayout()->setEnabled(simplifyAvailable);
+ m_actionShowFormWindowSettingsDialog->setEnabled(m_activeFormWindow != 0);
+}
+
+QDesignerFormWindowInterface *FormWindowManager::createFormWindow(QWidget *parentWidget, Qt::WindowFlags flags)
+{
+ FormWindow *formWindow = new FormWindow(qobject_cast<FormEditor*>(core()), parentWidget, flags);
+ formWindow->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
+ addFormWindow(formWindow);
+ return formWindow;
+}
+
+QPixmap FormWindowManager::createPreviewPixmap(QString *errorMessage)
+{
+ QPixmap pixmap;
+ QDesignerFormWindowInterface *fw = activeFormWindow();
+ if (!fw)
+ return pixmap;
+
+ pixmap = m_previewManager->createPreviewPixmap(fw, QString(), errorMessage);
+ return pixmap;
+}
+
+QAction *FormWindowManager::actionUndo() const
+{
+ return m_actionUndo;
+}
+
+QAction *FormWindowManager::actionRedo() const
+{
+ return m_actionRedo;
+}
+
+QActionGroup *FormWindowManager::actionGroupPreviewInStyle() const
+{
+ if (m_actionGroupPreviewInStyle == 0) {
+ // Wish we could make the 'this' pointer mutable ;-)
+ QObject *parent = const_cast<FormWindowManager*>(this);
+ m_actionGroupPreviewInStyle = new PreviewActionGroup(m_core, parent);
+ connect(m_actionGroupPreviewInStyle, SIGNAL(preview(QString,int)),
+ this, SLOT(slotActionGroupPreviewInStyle(QString,int)));
+ }
+ return m_actionGroupPreviewInStyle;
+}
+
+void FormWindowManager::deviceProfilesChanged()
+{
+ if (m_actionGroupPreviewInStyle)
+ m_actionGroupPreviewInStyle->updateDeviceProfiles();
+}
+
+// DnD stuff
+
+void FormWindowManager::dragItems(const QList<QDesignerDnDItemInterface*> &item_list)
+{
+ QDesignerMimeData::execDrag(item_list, m_core->topLevel());
+}
+
+QUndoGroup *FormWindowManager::undoGroup() const
+{
+ return m_undoGroup;
+}
+
+QAction *FormWindowManager::actionShowFormWindowSettingsDialog() const
+{
+ return m_actionShowFormWindowSettingsDialog;
+}
+
+void FormWindowManager::slotActionShowFormWindowSettingsDialog()
+{
+ QDesignerFormWindowInterface *fw = activeFormWindow();
+ if (!fw)
+ return;
+
+ QDialog *settingsDialog = 0;
+ const bool wasDirty = fw->isDirty();
+
+ // Ask the language extension for a dialog. If not, create our own
+ if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*>(m_core->extensionManager(), m_core))
+ settingsDialog = lang->createFormWindowSettingsDialog(fw, /*parent=*/ 0);
+
+ if (!settingsDialog)
+ settingsDialog = new FormWindowSettings(fw);
+
+ QString title = QFileInfo(fw->fileName()).fileName();
+ if (title.isEmpty()) // Grab the title from the outer window if no filename
+ if (const QWidget *window = m_core->integration()->containerWindow(fw))
+ title = window->windowTitle();
+
+ settingsDialog->setWindowTitle(tr("Form Settings - %1").arg(title));
+ if (settingsDialog->exec())
+ if (fw->isDirty() != wasDirty)
+ emit formWindowSettingsChanged(fw);
+
+ delete settingsDialog;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindowmanager.h b/tools/designer/src/components/formeditor/formwindowmanager.h
new file mode 100644
index 0000000..d81ec2d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowmanager.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOWMANAGER_H
+#define FORMWINDOWMANAGER_H
+
+#include "formeditor_global.h"
+
+#include <QtDesigner/private/qdesigner_formwindowmanager_p.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QActionGroup;
+class QUndoGroup;
+class QDesignerFormEditorInterface;
+class QDesignerWidgetBoxInterface;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+class PreviewManager;
+class PreviewActionGroup;
+
+class QT_FORMEDITOR_EXPORT FormWindowManager
+ : public QDesignerFormWindowManager
+{
+ Q_OBJECT
+public:
+ explicit FormWindowManager(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ virtual ~FormWindowManager();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ inline QAction *actionCut() const { return m_actionCut; }
+ inline QAction *actionCopy() const { return m_actionCopy; }
+ inline QAction *actionPaste() const { return m_actionPaste; }
+ inline QAction *actionDelete() const { return m_actionDelete; }
+ inline QAction *actionSelectAll() const { return m_actionSelectAll; }
+ inline QAction *actionLower() const { return m_actionLower; }
+ inline QAction *actionRaise() const { return m_actionRaise; }
+ QAction *actionUndo() const;
+ QAction *actionRedo() const;
+
+ inline QAction *actionHorizontalLayout() const { return m_actionHorizontalLayout; }
+ inline QAction *actionVerticalLayout() const { return m_actionVerticalLayout; }
+ inline QAction *actionSplitHorizontal() const { return m_actionSplitHorizontal; }
+ inline QAction *actionSplitVertical() const { return m_actionSplitVertical; }
+ inline QAction *actionGridLayout() const { return m_actionGridLayout; }
+ inline QAction *actionBreakLayout() const { return m_actionBreakLayout; }
+ inline QAction *actionAdjustSize() const { return m_actionAdjustSize; }
+
+ inline QAction *actionDefaultPreview() const { return m_actionDefaultPreview; }
+ QActionGroup *actionGroupPreviewInStyle() const;
+ virtual QAction *actionShowFormWindowSettingsDialog() const;
+
+ QDesignerFormWindowInterface *activeFormWindow() const;
+
+ int formWindowCount() const;
+ QDesignerFormWindowInterface *formWindow(int index) const;
+
+ QDesignerFormWindowInterface *createFormWindow(QWidget *parentWidget = 0, Qt::WindowFlags flags = 0);
+
+ QPixmap createPreviewPixmap(QString *errorMessage);
+
+ bool eventFilter(QObject *o, QEvent *e);
+
+ void dragItems(const QList<QDesignerDnDItemInterface*> &item_list);
+
+ QUndoGroup *undoGroup() const;
+
+ virtual PreviewManager *previewManager() const { return m_previewManager; }
+
+public slots:
+ void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+ void setActiveFormWindow(QDesignerFormWindowInterface *formWindow);
+ void closeAllPreviews();
+ void deviceProfilesChanged();
+
+private slots:
+ void slotActionCutActivated();
+ void slotActionCopyActivated();
+ void slotActionPasteActivated();
+ void slotActionDeleteActivated();
+ void slotActionSelectAllActivated();
+ void slotActionLowerActivated();
+ void slotActionRaiseActivated();
+ void createLayout();
+ void slotActionBreakLayoutActivated();
+ void slotActionAdjustSizeActivated();
+ void slotActionSimplifyLayoutActivated();
+ void slotActionDefaultPreviewActivated();
+ void slotActionGroupPreviewInStyle(const QString &style, int deviceProfileIndex);
+ void slotActionShowFormWindowSettingsDialog();
+
+ void slotUpdateActions();
+
+private:
+ void setupActions();
+ FormWindow *findFormWindow(QWidget *w);
+ QWidget *findManagedWidget(FormWindow *fw, QWidget *w);
+
+ void setCurrentUndoStack(QUndoStack *stack);
+
+private:
+ enum CreateLayoutContext { LayoutContainer, LayoutSelection, MorphLayout };
+
+ QDesignerFormEditorInterface *m_core;
+ FormWindow *m_activeFormWindow;
+ QList<FormWindow*> m_formWindows;
+
+ PreviewManager *m_previewManager;
+
+ /* Context of the layout actions and base for morphing layouts. Determined
+ * in slotUpdateActions() and used later on in the action slots. */
+ CreateLayoutContext m_createLayoutContext;
+ QWidget *m_morphLayoutContainer;
+
+ // edit actions
+ QAction *m_actionCut;
+ QAction *m_actionCopy;
+ QAction *m_actionPaste;
+ QAction *m_actionSelectAll;
+ QAction *m_actionDelete;
+ QAction *m_actionLower;
+ QAction *m_actionRaise;
+ // layout actions
+ QAction *m_actionHorizontalLayout;
+ QAction *m_actionVerticalLayout;
+ QAction *m_actionSplitHorizontal;
+ QAction *m_actionSplitVertical;
+ QAction *m_actionGridLayout;
+ QAction *m_actionBreakLayout;
+ QAction *m_actionAdjustSize;
+ // preview actions
+ QAction *m_actionDefaultPreview;
+ mutable PreviewActionGroup *m_actionGroupPreviewInStyle;
+ QAction *m_actionShowFormWindowSettingsDialog;
+
+ QAction *m_actionUndo;
+ QAction *m_actionRedo;
+
+ QMap<QWidget *,bool> getUnsortedLayoutsToBeBroken(bool firstOnly) const;
+ bool hasLayoutsToBeBroken() const;
+ QWidgetList layoutsToBeBroken(QWidget *w) const;
+ QWidgetList layoutsToBeBroken() const;
+
+ QUndoGroup *m_undoGroup;
+
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWMANAGER_H
diff --git a/tools/designer/src/components/formeditor/formwindowsettings.cpp b/tools/designer/src/components/formeditor/formwindowsettings.cpp
new file mode 100644
index 0000000..1f6d5dd
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowsettings.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindowsettings.h"
+#include "ui_formwindowsettings.h"
+
+#include <formwindowbase_p.h>
+#include <grid_p.h>
+
+#include <QtGui/QStyle>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Data structure containing form dialog data providing comparison
+struct FormWindowData {
+ FormWindowData();
+
+ bool equals(const FormWindowData&) const;
+
+ void fromFormWindow(FormWindowBase* fw);
+ void applyToFormWindow(FormWindowBase* fw) const;
+
+ bool layoutDefaultEnabled;
+ int defaultMargin;
+ int defaultSpacing;
+
+ bool layoutFunctionsEnabled;
+ QString marginFunction;
+ QString spacingFunction;
+
+ QString pixFunction;
+
+ QString author;
+
+ QStringList includeHints;
+
+ bool hasFormGrid;
+ Grid grid;
+};
+
+inline bool operator==(const FormWindowData &fd1, const FormWindowData &fd2) { return fd1.equals(fd2); }
+inline bool operator!=(const FormWindowData &fd1, const FormWindowData &fd2) { return !fd1.equals(fd2); }
+
+QDebug operator<<(QDebug str, const FormWindowData &d)
+{
+ str.nospace() << "LayoutDefault=" << d.layoutDefaultEnabled << ',' << d.defaultMargin
+ << ',' << d.defaultSpacing << " LayoutFunctions=" << d.layoutFunctionsEnabled << ','
+ << d.marginFunction << ',' << d.spacingFunction << " PixFunction="
+ << d.pixFunction << " Author=" << d.author << " Hints=" << d.includeHints
+ << " Grid=" << d.hasFormGrid << d.grid.deltaX() << d.grid.deltaY() << '\n';
+ return str;
+}
+
+FormWindowData::FormWindowData() :
+ layoutDefaultEnabled(false),
+ defaultMargin(0),
+ defaultSpacing(0),
+ layoutFunctionsEnabled(false),
+ hasFormGrid(false)
+{
+}
+
+bool FormWindowData::equals(const FormWindowData &rhs) const
+{
+ return layoutDefaultEnabled == rhs.layoutDefaultEnabled &&
+ defaultMargin == rhs.defaultMargin &&
+ defaultSpacing == rhs.defaultSpacing &&
+ layoutFunctionsEnabled == rhs.layoutFunctionsEnabled &&
+ marginFunction == rhs.marginFunction &&
+ spacingFunction == rhs.spacingFunction &&
+ pixFunction == rhs.pixFunction &&
+ author == rhs.author &&
+ includeHints == rhs.includeHints &&
+ hasFormGrid == rhs.hasFormGrid &&
+ grid == rhs.grid;
+}
+
+void FormWindowData::fromFormWindow(FormWindowBase* fw)
+{
+ defaultMargin = defaultSpacing = INT_MIN;
+ fw->layoutDefault(&defaultMargin, &defaultSpacing);
+
+ QStyle *style = fw->formContainer()->style();
+ layoutDefaultEnabled = defaultMargin != INT_MIN || defaultMargin != INT_MIN;
+ if (defaultMargin == INT_MIN)
+ defaultMargin = style->pixelMetric(QStyle::PM_DefaultChildMargin, 0);
+ if (defaultSpacing == INT_MIN)
+ defaultSpacing = style->pixelMetric(QStyle::PM_DefaultLayoutSpacing, 0);
+
+
+ marginFunction.clear();
+ spacingFunction.clear();
+ fw->layoutFunction(&marginFunction, &spacingFunction);
+ layoutFunctionsEnabled = !marginFunction.isEmpty() || !spacingFunction.isEmpty();
+
+ pixFunction = fw->pixmapFunction();
+
+ author = fw->author();
+
+ includeHints = fw->includeHints();
+ includeHints.removeAll(QString());
+
+ hasFormGrid = fw->hasFormGrid();
+ grid = hasFormGrid ? fw->designerGrid() : FormWindowBase::defaultDesignerGrid();
+}
+
+void FormWindowData::applyToFormWindow(FormWindowBase* fw) const
+{
+ fw->setAuthor(author);
+ fw->setPixmapFunction(pixFunction);
+
+ if (layoutDefaultEnabled) {
+ fw->setLayoutDefault(defaultMargin, defaultSpacing);
+ } else {
+ fw->setLayoutDefault(INT_MIN, INT_MIN);
+ }
+
+ if (layoutFunctionsEnabled) {
+ fw->setLayoutFunction(marginFunction, spacingFunction);
+ } else {
+ fw->setLayoutFunction(QString(), QString());
+ }
+
+ fw->setIncludeHints(includeHints);
+
+ const bool hadFormGrid = fw->hasFormGrid();
+ fw->setHasFormGrid(hasFormGrid);
+ if (hasFormGrid || hadFormGrid != hasFormGrid)
+ fw->setDesignerGrid(hasFormGrid ? grid : FormWindowBase::defaultDesignerGrid());
+}
+
+// -------------------------- FormWindowSettings
+
+FormWindowSettings::FormWindowSettings(QDesignerFormWindowInterface *parent) :
+ QDialog(parent),
+ m_ui(new ::Ui::FormWindowSettings),
+ m_formWindow(qobject_cast<FormWindowBase*>(parent)),
+ m_oldData(new FormWindowData)
+{
+ Q_ASSERT(m_formWindow);
+
+ m_ui->setupUi(this);
+ m_ui->gridPanel->setCheckable(true);
+ m_ui->gridPanel->setResetButtonVisible(false);
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QString deviceProfileName = m_formWindow->deviceProfileName();
+ if (deviceProfileName.isEmpty())
+ deviceProfileName = tr("None");
+ m_ui->deviceProfileLabel->setText(tr("Device Profile: %1").arg(deviceProfileName));
+
+ m_oldData->fromFormWindow(m_formWindow);
+ setData(*m_oldData);
+}
+
+FormWindowSettings::~FormWindowSettings()
+{
+ delete m_oldData;
+ delete m_ui;
+}
+
+FormWindowData FormWindowSettings::data() const
+{
+ FormWindowData rc;
+ rc.author = m_ui->authorLineEdit->text();
+
+ if (m_ui->pixmapFunctionGroupBox->isChecked()) {
+ rc.pixFunction = m_ui->pixmapFunctionLineEdit->text();
+ } else {
+ rc.pixFunction.clear();
+ }
+
+ rc.layoutDefaultEnabled = m_ui->layoutDefaultGroupBox->isChecked();
+ rc.defaultMargin = m_ui->defaultMarginSpinBox->value();
+ rc.defaultSpacing = m_ui->defaultSpacingSpinBox->value();
+
+ rc.layoutFunctionsEnabled = m_ui->layoutFunctionGroupBox->isChecked();
+ rc.marginFunction = m_ui->marginFunctionLineEdit->text();
+ rc.spacingFunction = m_ui->spacingFunctionLineEdit->text();
+
+ const QString hints = m_ui->includeHintsTextEdit->toPlainText();
+ if (!hints.isEmpty()) {
+ rc.includeHints = hints.split(QString(QLatin1Char('\n')));
+ // Purge out any lines consisting of blanks only
+ const QRegExp blankLine = QRegExp(QLatin1String("^\\s*$"));
+ Q_ASSERT(blankLine.isValid());
+ for (QStringList::iterator it = rc.includeHints.begin(); it != rc.includeHints.end(); )
+ if (blankLine.exactMatch(*it)) {
+ it = rc.includeHints.erase(it);
+ } else {
+ ++it;
+ }
+ rc.includeHints.removeAll(QString());
+ }
+
+ rc.hasFormGrid = m_ui->gridPanel->isChecked();
+ rc.grid = m_ui->gridPanel->grid();
+ return rc;
+}
+
+void FormWindowSettings::setData(const FormWindowData &data)
+{
+ m_ui->layoutDefaultGroupBox->setChecked(data.layoutDefaultEnabled);
+ m_ui->defaultMarginSpinBox->setValue(data.defaultMargin);
+ m_ui->defaultSpacingSpinBox->setValue(data.defaultSpacing);
+
+ m_ui->layoutFunctionGroupBox->setChecked(data.layoutFunctionsEnabled);
+ m_ui->marginFunctionLineEdit->setText(data.marginFunction);
+ m_ui->spacingFunctionLineEdit->setText(data.spacingFunction);
+
+ m_ui->pixmapFunctionLineEdit->setText(data.pixFunction);
+ m_ui->pixmapFunctionGroupBox->setChecked(!data.pixFunction.isEmpty());
+
+ m_ui->authorLineEdit->setText(data.author);
+
+ if (data.includeHints.empty()) {
+ m_ui->includeHintsTextEdit->clear();
+ } else {
+ m_ui->includeHintsTextEdit->setText(data.includeHints.join(QLatin1String("\n")));
+ }
+
+ m_ui->gridPanel->setChecked(data.hasFormGrid);
+ m_ui->gridPanel->setGrid(data.grid);
+}
+
+void FormWindowSettings::accept()
+{
+ // Anything changed? -> Apply and set dirty
+ const FormWindowData newData = data();
+ if (newData != *m_oldData) {
+ newData.applyToFormWindow(m_formWindow);
+ m_formWindow->setDirty(true);
+ }
+
+ QDialog::accept();
+}
+}
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindowsettings.h b/tools/designer/src/components/formeditor/formwindowsettings.h
new file mode 100644
index 0000000..4289f42
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowsettings.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOWSETTINGS_H
+#define FORMWINDOWSETTINGS_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class FormWindowSettings;
+}
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+struct FormWindowData;
+class FormWindowBase;
+
+/* Dialog to edit the settings of a QDesignerFormWindowInterface.
+ * It sets the dirty flag on the form window if something was changed. */
+
+class FormWindowSettings: public QDialog
+{
+ Q_DISABLE_COPY(FormWindowSettings)
+ Q_OBJECT
+public:
+ explicit FormWindowSettings(QDesignerFormWindowInterface *formWindow);
+ virtual ~FormWindowSettings();
+
+ virtual void accept();
+
+private:
+ FormWindowData data() const;
+ void setData(const FormWindowData&);
+
+ Ui::FormWindowSettings *m_ui;
+ FormWindowBase *m_formWindow;
+ FormWindowData *m_oldData;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWSETTINGS_H
diff --git a/tools/designer/src/components/formeditor/formwindowsettings.ui b/tools/designer/src/components/formeditor/formwindowsettings.ui
new file mode 100644
index 0000000..4e56365
--- /dev/null
+++ b/tools/designer/src/components/formeditor/formwindowsettings.ui
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>FormWindowSettings</class>
+ <widget class="QDialog" name="FormWindowSettings">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>470</width>
+ <height>466</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form Settings</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="3" column="0" colspan="2">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="layoutDefaultGroupBox">
+ <property name="title">
+ <string>Layout &amp;Default</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&amp;Spacing:</string>
+ </property>
+ <property name="buddy">
+ <cstring>defaultSpacingSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&amp;Margin:</string>
+ </property>
+ <property name="buddy">
+ <cstring>defaultMarginSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="defaultSpacingSpinBox"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="defaultMarginSpinBox"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="layoutFunctionGroupBox">
+ <property name="title">
+ <string>&amp;Layout Function</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="spacingFunctionLineEdit"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="marginFunctionLineEdit"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Ma&amp;rgin:</string>
+ </property>
+ <property name="buddy">
+ <cstring>marginFunctionLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3_2">
+ <property name="text">
+ <string>Spa&amp;cing:</string>
+ </property>
+ <property name="buddy">
+ <cstring>spacingFunctionLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="pixmapFunctionGroupBox">
+ <property name="title">
+ <string>&amp;Pixmap Function</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="pixmapFunctionLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="1">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>111</width>
+ <height>115</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="7" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" rowspan="2">
+ <widget class="QGroupBox" name="includeHintsGroupBox">
+ <property name="title">
+ <string>&amp;Include Hints</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="includeHintsTextEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="qdesigner_internal::GridPanel" name="gridPanel">
+ <property name="title">
+ <string>Grid</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="embeddedGroupBox">
+ <property name="title">
+ <string>Embedded Design</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="deviceProfileLabel">
+ <property name="text">
+ <string notr="true">TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="pixmapFunctionGroupBox_2">
+ <property name="title">
+ <string>&amp;Author</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="authorLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>qdesigner_internal::GridPanel</class>
+ <extends>QGroupBox</extends>
+ <header location="global">gridpanel_p.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>authorLineEdit</tabstop>
+ <tabstop>defaultMarginSpinBox</tabstop>
+ <tabstop>defaultSpacingSpinBox</tabstop>
+ <tabstop>marginFunctionLineEdit</tabstop>
+ <tabstop>spacingFunctionLineEdit</tabstop>
+ <tabstop>pixmapFunctionLineEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>FormWindowSettings</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>294</x>
+ <y>442</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>150</x>
+ <y>459</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>FormWindowSettings</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>373</x>
+ <y>444</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>357</x>
+ <y>461</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/designer/src/components/formeditor/iconcache.cpp b/tools/designer/src/components/formeditor/iconcache.cpp
new file mode 100644
index 0000000..a256bf8
--- /dev/null
+++ b/tools/designer/src/components/formeditor/iconcache.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "iconcache.h"
+#include <QtGui/QPixmap>
+#include <QtGui/QIcon>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+IconCache::IconCache(QObject *parent)
+ : QDesignerIconCacheInterface(parent)
+{
+}
+
+QIcon IconCache::nameToIcon(const QString &path, const QString &resourcePath)
+{
+ Q_UNUSED(path)
+ Q_UNUSED(resourcePath)
+ qWarning() << "IconCache::nameToIcon(): IconCache is obsoleted";
+ return QIcon();
+}
+
+QString IconCache::iconToFilePath(const QIcon &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::iconToFilePath(): IconCache is obsoleted";
+ return QString();
+}
+
+QString IconCache::iconToQrcPath(const QIcon &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::iconToQrcPath(): IconCache is obsoleted";
+ return QString();
+}
+
+QPixmap IconCache::nameToPixmap(const QString &path, const QString &resourcePath)
+{
+ Q_UNUSED(path)
+ Q_UNUSED(resourcePath)
+ qWarning() << "IconCache::nameToPixmap(): IconCache is obsoleted";
+ return QPixmap();
+}
+
+QString IconCache::pixmapToFilePath(const QPixmap &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::pixmapToFilePath(): IconCache is obsoleted";
+ return QString();
+}
+
+QString IconCache::pixmapToQrcPath(const QPixmap &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::pixmapToQrcPath(): IconCache is obsoleted";
+ return QString();
+}
+
+QList<QPixmap> IconCache::pixmapList() const
+{
+ qWarning() << "IconCache::pixmapList(): IconCache is obsoleted";
+ return QList<QPixmap>();
+}
+
+QList<QIcon> IconCache::iconList() const
+{
+ qWarning() << "IconCache::iconList(): IconCache is obsoleted";
+ return QList<QIcon>();
+}
+
+QString IconCache::resolveQrcPath(const QString &filePath, const QString &qrcPath, const QString &wd) const
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(qrcPath)
+ Q_UNUSED(wd)
+ qWarning() << "IconCache::resolveQrcPath(): IconCache is obsoleted";
+ return QString();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/iconcache.h b/tools/designer/src/components/formeditor/iconcache.h
new file mode 100644
index 0000000..24d36e2
--- /dev/null
+++ b/tools/designer/src/components/formeditor/iconcache.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ICONCACHE_H
+#define ICONCACHE_H
+
+#include "formeditor_global.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT IconCache : public QDesignerIconCacheInterface
+{
+ Q_OBJECT
+public:
+ explicit IconCache(QObject *parent);
+
+ virtual QIcon nameToIcon(const QString &path, const QString &resourcePath = QString());
+ virtual QString iconToFilePath(const QIcon &pm) const;
+ virtual QString iconToQrcPath(const QIcon &pm) const;
+ virtual QPixmap nameToPixmap(const QString &path, const QString &resourcePath = QString());
+ virtual QString pixmapToFilePath(const QPixmap &pm) const;
+ virtual QString pixmapToQrcPath(const QPixmap &pm) const;
+
+ virtual QList<QPixmap> pixmapList() const;
+ virtual QList<QIcon> iconList() const;
+
+ virtual QString resolveQrcPath(const QString &filePath, const QString &qrcPath, const QString &workingDirectory = QString()) const;
+
+private:
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ICONCACHE_H
diff --git a/tools/designer/src/components/formeditor/images/color.png b/tools/designer/src/components/formeditor/images/color.png
new file mode 100644
index 0000000..54b7ebc
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/color.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/configure.png b/tools/designer/src/components/formeditor/images/configure.png
new file mode 100644
index 0000000..d9f2fd8
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/configure.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/arrow.png b/tools/designer/src/components/formeditor/images/cursors/arrow.png
new file mode 100644
index 0000000..a69ef4e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/arrow.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/busy.png b/tools/designer/src/components/formeditor/images/cursors/busy.png
new file mode 100644
index 0000000..53717e4
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/busy.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/closedhand.png b/tools/designer/src/components/formeditor/images/cursors/closedhand.png
new file mode 100644
index 0000000..b78dd1d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/closedhand.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/cross.png b/tools/designer/src/components/formeditor/images/cursors/cross.png
new file mode 100644
index 0000000..fe38e74
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/cross.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/hand.png b/tools/designer/src/components/formeditor/images/cursors/hand.png
new file mode 100644
index 0000000..d2004ae
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/hand.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/hsplit.png b/tools/designer/src/components/formeditor/images/cursors/hsplit.png
new file mode 100644
index 0000000..a5667e3
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/hsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/ibeam.png b/tools/designer/src/components/formeditor/images/cursors/ibeam.png
new file mode 100644
index 0000000..097fc5f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/ibeam.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/no.png b/tools/designer/src/components/formeditor/images/cursors/no.png
new file mode 100644
index 0000000..2b08c4e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/no.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/openhand.png b/tools/designer/src/components/formeditor/images/cursors/openhand.png
new file mode 100644
index 0000000..9181c85
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/openhand.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/sizeall.png b/tools/designer/src/components/formeditor/images/cursors/sizeall.png
new file mode 100644
index 0000000..69f13eb
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/sizeall.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/sizeb.png b/tools/designer/src/components/formeditor/images/cursors/sizeb.png
new file mode 100644
index 0000000..3b127a0
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/sizeb.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/sizef.png b/tools/designer/src/components/formeditor/images/cursors/sizef.png
new file mode 100644
index 0000000..f37d7b9
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/sizef.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/sizeh.png b/tools/designer/src/components/formeditor/images/cursors/sizeh.png
new file mode 100644
index 0000000..a9f40cb
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/sizeh.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/sizev.png b/tools/designer/src/components/formeditor/images/cursors/sizev.png
new file mode 100644
index 0000000..1edbab2
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/sizev.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/uparrow.png b/tools/designer/src/components/formeditor/images/cursors/uparrow.png
new file mode 100644
index 0000000..d3e70ef
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/uparrow.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/vsplit.png b/tools/designer/src/components/formeditor/images/cursors/vsplit.png
new file mode 100644
index 0000000..1beda25
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/vsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/wait.png b/tools/designer/src/components/formeditor/images/cursors/wait.png
new file mode 100644
index 0000000..69056c4
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/wait.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/cursors/whatsthis.png b/tools/designer/src/components/formeditor/images/cursors/whatsthis.png
new file mode 100644
index 0000000..b47601c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cursors/whatsthis.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/downplus.png b/tools/designer/src/components/formeditor/images/downplus.png
new file mode 100644
index 0000000..1e384a7
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/downplus.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/dropdownbutton.png b/tools/designer/src/components/formeditor/images/dropdownbutton.png
new file mode 100644
index 0000000..5dd9649
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/dropdownbutton.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/edit.png b/tools/designer/src/components/formeditor/images/edit.png
new file mode 100644
index 0000000..a5e49ad
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/edit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/editdelete-16.png b/tools/designer/src/components/formeditor/images/editdelete-16.png
new file mode 100644
index 0000000..ef5c799
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/editdelete-16.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/emptyicon.png b/tools/designer/src/components/formeditor/images/emptyicon.png
new file mode 100644
index 0000000..897220e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/emptyicon.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/filenew-16.png b/tools/designer/src/components/formeditor/images/filenew-16.png
new file mode 100644
index 0000000..eefb3c5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/filenew-16.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/fileopen-16.png b/tools/designer/src/components/formeditor/images/fileopen-16.png
new file mode 100644
index 0000000..d832c62
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/fileopen-16.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/leveldown.png b/tools/designer/src/components/formeditor/images/leveldown.png
new file mode 100644
index 0000000..742b7fb
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/leveldown.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/levelup.png b/tools/designer/src/components/formeditor/images/levelup.png
new file mode 100644
index 0000000..48b3e89
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/levelup.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/adjustsize.png b/tools/designer/src/components/formeditor/images/mac/adjustsize.png
new file mode 100644
index 0000000..c4d884c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/adjustsize.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/back.png b/tools/designer/src/components/formeditor/images/mac/back.png
new file mode 100644
index 0000000..e58177f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/back.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/buddytool.png b/tools/designer/src/components/formeditor/images/mac/buddytool.png
new file mode 100644
index 0000000..2a42870
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/buddytool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/down.png b/tools/designer/src/components/formeditor/images/mac/down.png
new file mode 100644
index 0000000..29d1d44
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/down.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editbreaklayout.png b/tools/designer/src/components/formeditor/images/mac/editbreaklayout.png
new file mode 100644
index 0000000..dc00559
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editbreaklayout.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editcopy.png b/tools/designer/src/components/formeditor/images/mac/editcopy.png
new file mode 100644
index 0000000..f551364
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editcopy.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editcut.png b/tools/designer/src/components/formeditor/images/mac/editcut.png
new file mode 100644
index 0000000..a784fd5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editcut.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editdelete.png b/tools/designer/src/components/formeditor/images/mac/editdelete.png
new file mode 100644
index 0000000..201b31c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editdelete.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editform.png b/tools/designer/src/components/formeditor/images/mac/editform.png
new file mode 100644
index 0000000..4fc2e40
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editform.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editgrid.png b/tools/designer/src/components/formeditor/images/mac/editgrid.png
new file mode 100644
index 0000000..bba4a69
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editgrid.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/edithlayout.png b/tools/designer/src/components/formeditor/images/mac/edithlayout.png
new file mode 100644
index 0000000..ec880bb
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/edithlayout.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/edithlayoutsplit.png b/tools/designer/src/components/formeditor/images/mac/edithlayoutsplit.png
new file mode 100644
index 0000000..227d011
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/edithlayoutsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editlower.png b/tools/designer/src/components/formeditor/images/mac/editlower.png
new file mode 100644
index 0000000..347806f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editlower.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editpaste.png b/tools/designer/src/components/formeditor/images/mac/editpaste.png
new file mode 100644
index 0000000..64c0b2d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editpaste.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editraise.png b/tools/designer/src/components/formeditor/images/mac/editraise.png
new file mode 100644
index 0000000..09cbbd7
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editraise.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editvlayout.png b/tools/designer/src/components/formeditor/images/mac/editvlayout.png
new file mode 100644
index 0000000..63b26cd
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editvlayout.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/editvlayoutsplit.png b/tools/designer/src/components/formeditor/images/mac/editvlayoutsplit.png
new file mode 100644
index 0000000..5a02c94
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/editvlayoutsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/filenew.png b/tools/designer/src/components/formeditor/images/mac/filenew.png
new file mode 100644
index 0000000..9dcba42
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/filenew.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/fileopen.png b/tools/designer/src/components/formeditor/images/mac/fileopen.png
new file mode 100644
index 0000000..c12bcd5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/fileopen.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/filesave.png b/tools/designer/src/components/formeditor/images/mac/filesave.png
new file mode 100644
index 0000000..b41ecf5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/filesave.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/forward.png b/tools/designer/src/components/formeditor/images/mac/forward.png
new file mode 100644
index 0000000..34b91f0
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/forward.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/insertimage.png b/tools/designer/src/components/formeditor/images/mac/insertimage.png
new file mode 100644
index 0000000..b8673e1
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/insertimage.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/minus.png b/tools/designer/src/components/formeditor/images/mac/minus.png
new file mode 100644
index 0000000..8d2eaed
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/minus.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/plus.png b/tools/designer/src/components/formeditor/images/mac/plus.png
new file mode 100644
index 0000000..1ee4542
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/plus.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/redo.png b/tools/designer/src/components/formeditor/images/mac/redo.png
new file mode 100644
index 0000000..8875bf2
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/redo.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/resetproperty.png b/tools/designer/src/components/formeditor/images/mac/resetproperty.png
new file mode 100644
index 0000000..9048252
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/resetproperty.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/resourceeditortool.png b/tools/designer/src/components/formeditor/images/mac/resourceeditortool.png
new file mode 100644
index 0000000..7ef511c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/resourceeditortool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/signalslottool.png b/tools/designer/src/components/formeditor/images/mac/signalslottool.png
new file mode 100644
index 0000000..71c9b07
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/signalslottool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/tabordertool.png b/tools/designer/src/components/formeditor/images/mac/tabordertool.png
new file mode 100644
index 0000000..f54faf9
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/tabordertool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textanchor.png b/tools/designer/src/components/formeditor/images/mac/textanchor.png
new file mode 100644
index 0000000..baa9dda
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textanchor.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textbold.png b/tools/designer/src/components/formeditor/images/mac/textbold.png
new file mode 100644
index 0000000..38400bd
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textbold.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textcenter.png b/tools/designer/src/components/formeditor/images/mac/textcenter.png
new file mode 100644
index 0000000..2ef5b2e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textcenter.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textitalic.png b/tools/designer/src/components/formeditor/images/mac/textitalic.png
new file mode 100644
index 0000000..0170ee2
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textitalic.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textjustify.png b/tools/designer/src/components/formeditor/images/mac/textjustify.png
new file mode 100644
index 0000000..39cd6c1
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textjustify.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textleft.png b/tools/designer/src/components/formeditor/images/mac/textleft.png
new file mode 100644
index 0000000..83a66d5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textleft.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textright.png b/tools/designer/src/components/formeditor/images/mac/textright.png
new file mode 100644
index 0000000..e7c0464
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textright.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textsubscript.png b/tools/designer/src/components/formeditor/images/mac/textsubscript.png
new file mode 100644
index 0000000..ff431f3
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textsubscript.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textsuperscript.png b/tools/designer/src/components/formeditor/images/mac/textsuperscript.png
new file mode 100644
index 0000000..cb67a33
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textsuperscript.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/textunder.png b/tools/designer/src/components/formeditor/images/mac/textunder.png
new file mode 100644
index 0000000..968bac5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/textunder.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/undo.png b/tools/designer/src/components/formeditor/images/mac/undo.png
new file mode 100644
index 0000000..a3bd5e0
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/undo.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/up.png b/tools/designer/src/components/formeditor/images/mac/up.png
new file mode 100644
index 0000000..e437312
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/up.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/mac/widgettool.png b/tools/designer/src/components/formeditor/images/mac/widgettool.png
new file mode 100644
index 0000000..e1aa353
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/mac/widgettool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/minus-16.png b/tools/designer/src/components/formeditor/images/minus-16.png
new file mode 100644
index 0000000..745b445
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/minus-16.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/plus-16.png b/tools/designer/src/components/formeditor/images/plus-16.png
new file mode 100644
index 0000000..ef43788
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/plus-16.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/prefix-add.png b/tools/designer/src/components/formeditor/images/prefix-add.png
new file mode 100644
index 0000000..cfbb053
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/prefix-add.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/qt3logo.png b/tools/designer/src/components/formeditor/images/qt3logo.png
new file mode 100644
index 0000000..7202850
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/qt3logo.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/qtlogo.png b/tools/designer/src/components/formeditor/images/qtlogo.png
new file mode 100644
index 0000000..038fa2c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/qtlogo.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/reload.png b/tools/designer/src/components/formeditor/images/reload.png
new file mode 100644
index 0000000..18c752e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/reload.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/resetproperty.png b/tools/designer/src/components/formeditor/images/resetproperty.png
new file mode 100644
index 0000000..9048252
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/resetproperty.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/sort.png b/tools/designer/src/components/formeditor/images/sort.png
new file mode 100644
index 0000000..883bfa9
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/sort.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/submenu.png b/tools/designer/src/components/formeditor/images/submenu.png
new file mode 100644
index 0000000..3deb28e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/submenu.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/calendarwidget.png b/tools/designer/src/components/formeditor/images/widgets/calendarwidget.png
new file mode 100644
index 0000000..26737b8
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/calendarwidget.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/checkbox.png b/tools/designer/src/components/formeditor/images/widgets/checkbox.png
new file mode 100644
index 0000000..ab6f53e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/checkbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/columnview.png b/tools/designer/src/components/formeditor/images/widgets/columnview.png
new file mode 100644
index 0000000..4132ee6
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/columnview.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/combobox.png b/tools/designer/src/components/formeditor/images/widgets/combobox.png
new file mode 100644
index 0000000..bf3ed79
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/combobox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/commandlinkbutton.png b/tools/designer/src/components/formeditor/images/widgets/commandlinkbutton.png
new file mode 100644
index 0000000..6bbd84a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/commandlinkbutton.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/dateedit.png b/tools/designer/src/components/formeditor/images/widgets/dateedit.png
new file mode 100644
index 0000000..6827fa7
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/dateedit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/datetimeedit.png b/tools/designer/src/components/formeditor/images/widgets/datetimeedit.png
new file mode 100644
index 0000000..7d8e6fe
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/datetimeedit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/dial.png b/tools/designer/src/components/formeditor/images/widgets/dial.png
new file mode 100644
index 0000000..050d1db
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/dial.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/dialogbuttonbox.png b/tools/designer/src/components/formeditor/images/widgets/dialogbuttonbox.png
new file mode 100644
index 0000000..b1f89fb
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/dialogbuttonbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/dockwidget.png b/tools/designer/src/components/formeditor/images/widgets/dockwidget.png
new file mode 100644
index 0000000..9eee04f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/dockwidget.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/doublespinbox.png b/tools/designer/src/components/formeditor/images/widgets/doublespinbox.png
new file mode 100644
index 0000000..5686ac8
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/doublespinbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/fontcombobox.png b/tools/designer/src/components/formeditor/images/widgets/fontcombobox.png
new file mode 100644
index 0000000..6848f15
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/fontcombobox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/frame.png b/tools/designer/src/components/formeditor/images/widgets/frame.png
new file mode 100644
index 0000000..68f5da0
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/frame.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/graphicsview.png b/tools/designer/src/components/formeditor/images/widgets/graphicsview.png
new file mode 100644
index 0000000..93fe760
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/graphicsview.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/groupbox.png b/tools/designer/src/components/formeditor/images/widgets/groupbox.png
new file mode 100644
index 0000000..4025b4d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/groupbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/groupboxcollapsible.png b/tools/designer/src/components/formeditor/images/widgets/groupboxcollapsible.png
new file mode 100644
index 0000000..62fd1ad
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/groupboxcollapsible.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/hscrollbar.png b/tools/designer/src/components/formeditor/images/widgets/hscrollbar.png
new file mode 100644
index 0000000..466c58d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/hscrollbar.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/hslider.png b/tools/designer/src/components/formeditor/images/widgets/hslider.png
new file mode 100644
index 0000000..525bd1c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/hslider.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/hsplit.png b/tools/designer/src/components/formeditor/images/widgets/hsplit.png
new file mode 100644
index 0000000..1ea8f2a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/hsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/label.png b/tools/designer/src/components/formeditor/images/widgets/label.png
new file mode 100644
index 0000000..5d7d7b4
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/label.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/lcdnumber.png b/tools/designer/src/components/formeditor/images/widgets/lcdnumber.png
new file mode 100644
index 0000000..c3cac18
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/lcdnumber.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/line.png b/tools/designer/src/components/formeditor/images/widgets/line.png
new file mode 100644
index 0000000..5c64dfb
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/line.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/lineedit.png b/tools/designer/src/components/formeditor/images/widgets/lineedit.png
new file mode 100644
index 0000000..75fc890
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/lineedit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/listbox.png b/tools/designer/src/components/formeditor/images/widgets/listbox.png
new file mode 100644
index 0000000..367e67f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/listbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/listview.png b/tools/designer/src/components/formeditor/images/widgets/listview.png
new file mode 100644
index 0000000..d1308d5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/listview.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/mdiarea.png b/tools/designer/src/components/formeditor/images/widgets/mdiarea.png
new file mode 100644
index 0000000..7783dd5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/mdiarea.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/plaintextedit.png b/tools/designer/src/components/formeditor/images/widgets/plaintextedit.png
new file mode 100644
index 0000000..077bf16
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/plaintextedit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/progress.png b/tools/designer/src/components/formeditor/images/widgets/progress.png
new file mode 100644
index 0000000..44ae094
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/progress.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/pushbutton.png b/tools/designer/src/components/formeditor/images/widgets/pushbutton.png
new file mode 100644
index 0000000..61f779c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/pushbutton.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/radiobutton.png b/tools/designer/src/components/formeditor/images/widgets/radiobutton.png
new file mode 100644
index 0000000..10c1d8c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/radiobutton.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/scrollarea.png b/tools/designer/src/components/formeditor/images/widgets/scrollarea.png
new file mode 100644
index 0000000..651ea24
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/scrollarea.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/spacer.png b/tools/designer/src/components/formeditor/images/widgets/spacer.png
new file mode 100644
index 0000000..8a0931b
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/spacer.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/spinbox.png b/tools/designer/src/components/formeditor/images/widgets/spinbox.png
new file mode 100644
index 0000000..cdd9fe1
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/spinbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/tabbar.png b/tools/designer/src/components/formeditor/images/widgets/tabbar.png
new file mode 100644
index 0000000..d5d3783
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/tabbar.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/table.png b/tools/designer/src/components/formeditor/images/widgets/table.png
new file mode 100644
index 0000000..4bbd9c2
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/table.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/tabwidget.png b/tools/designer/src/components/formeditor/images/widgets/tabwidget.png
new file mode 100644
index 0000000..1254bb6
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/tabwidget.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/textedit.png b/tools/designer/src/components/formeditor/images/widgets/textedit.png
new file mode 100644
index 0000000..32e897d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/textedit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/timeedit.png b/tools/designer/src/components/formeditor/images/widgets/timeedit.png
new file mode 100644
index 0000000..c66d91b
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/timeedit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/toolbox.png b/tools/designer/src/components/formeditor/images/widgets/toolbox.png
new file mode 100644
index 0000000..2ab71dc
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/toolbox.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/toolbutton.png b/tools/designer/src/components/formeditor/images/widgets/toolbutton.png
new file mode 100644
index 0000000..0bff069
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/toolbutton.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/vline.png b/tools/designer/src/components/formeditor/images/widgets/vline.png
new file mode 100644
index 0000000..35a7300
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/vline.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/vscrollbar.png b/tools/designer/src/components/formeditor/images/widgets/vscrollbar.png
new file mode 100644
index 0000000..28b7c40
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/vscrollbar.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/vslider.png b/tools/designer/src/components/formeditor/images/widgets/vslider.png
new file mode 100644
index 0000000..59f06ba
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/vslider.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/vspacer.png b/tools/designer/src/components/formeditor/images/widgets/vspacer.png
new file mode 100644
index 0000000..ce5e8bd
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/vspacer.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/widget.png b/tools/designer/src/components/formeditor/images/widgets/widget.png
new file mode 100644
index 0000000..1cf960e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/widget.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/widgetstack.png b/tools/designer/src/components/formeditor/images/widgets/widgetstack.png
new file mode 100644
index 0000000..2c6964e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/widgetstack.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/widgets/wizard.png b/tools/designer/src/components/formeditor/images/widgets/wizard.png
new file mode 100644
index 0000000..7c0e107
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/widgets/wizard.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/adjustsize.png b/tools/designer/src/components/formeditor/images/win/adjustsize.png
new file mode 100644
index 0000000..3cda333
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/adjustsize.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/back.png b/tools/designer/src/components/formeditor/images/win/back.png
new file mode 100644
index 0000000..e58177f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/back.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/buddytool.png b/tools/designer/src/components/formeditor/images/win/buddytool.png
new file mode 100644
index 0000000..4cd968b
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/buddytool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/down.png b/tools/designer/src/components/formeditor/images/win/down.png
new file mode 100644
index 0000000..29d1d44
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/down.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editbreaklayout.png b/tools/designer/src/components/formeditor/images/win/editbreaklayout.png
new file mode 100644
index 0000000..07c5fae
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editbreaklayout.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editcopy.png b/tools/designer/src/components/formeditor/images/win/editcopy.png
new file mode 100644
index 0000000..1121b47
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editcopy.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editcut.png b/tools/designer/src/components/formeditor/images/win/editcut.png
new file mode 100644
index 0000000..4b6c82c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editcut.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editdelete.png b/tools/designer/src/components/formeditor/images/win/editdelete.png
new file mode 100644
index 0000000..5a42514
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editdelete.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editform.png b/tools/designer/src/components/formeditor/images/win/editform.png
new file mode 100644
index 0000000..452fcd8
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editform.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editgrid.png b/tools/designer/src/components/formeditor/images/win/editgrid.png
new file mode 100644
index 0000000..789bf7d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editgrid.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/edithlayout.png b/tools/designer/src/components/formeditor/images/win/edithlayout.png
new file mode 100644
index 0000000..4dd3f0c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/edithlayout.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/edithlayoutsplit.png b/tools/designer/src/components/formeditor/images/win/edithlayoutsplit.png
new file mode 100644
index 0000000..2dcc690
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/edithlayoutsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editlower.png b/tools/designer/src/components/formeditor/images/win/editlower.png
new file mode 100644
index 0000000..ba63094
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editlower.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editpaste.png b/tools/designer/src/components/formeditor/images/win/editpaste.png
new file mode 100644
index 0000000..ffab15a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editpaste.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editraise.png b/tools/designer/src/components/formeditor/images/win/editraise.png
new file mode 100644
index 0000000..bb8362c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editraise.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editvlayout.png b/tools/designer/src/components/formeditor/images/win/editvlayout.png
new file mode 100644
index 0000000..7ad28fd
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editvlayout.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/editvlayoutsplit.png b/tools/designer/src/components/formeditor/images/win/editvlayoutsplit.png
new file mode 100644
index 0000000..720e18b
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/editvlayoutsplit.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/filenew.png b/tools/designer/src/components/formeditor/images/win/filenew.png
new file mode 100644
index 0000000..af5d122
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/filenew.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/fileopen.png b/tools/designer/src/components/formeditor/images/win/fileopen.png
new file mode 100644
index 0000000..fc6f17e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/fileopen.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/filesave.png b/tools/designer/src/components/formeditor/images/win/filesave.png
new file mode 100644
index 0000000..8feec99
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/filesave.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/forward.png b/tools/designer/src/components/formeditor/images/win/forward.png
new file mode 100644
index 0000000..34b91f0
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/forward.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/insertimage.png b/tools/designer/src/components/formeditor/images/win/insertimage.png
new file mode 100644
index 0000000..cfab637
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/insertimage.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/minus.png b/tools/designer/src/components/formeditor/images/win/minus.png
new file mode 100644
index 0000000..c0dc274
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/minus.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/plus.png b/tools/designer/src/components/formeditor/images/win/plus.png
new file mode 100644
index 0000000..ecf0589
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/plus.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/redo.png b/tools/designer/src/components/formeditor/images/win/redo.png
new file mode 100644
index 0000000..686ad14
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/redo.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/resourceeditortool.png b/tools/designer/src/components/formeditor/images/win/resourceeditortool.png
new file mode 100644
index 0000000..cc9cb58
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/resourceeditortool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/signalslottool.png b/tools/designer/src/components/formeditor/images/win/signalslottool.png
new file mode 100644
index 0000000..e80fd1c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/signalslottool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/tabordertool.png b/tools/designer/src/components/formeditor/images/win/tabordertool.png
new file mode 100644
index 0000000..7e6e2de
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/tabordertool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textanchor.png b/tools/designer/src/components/formeditor/images/win/textanchor.png
new file mode 100644
index 0000000..1911ab0
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textanchor.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textbold.png b/tools/designer/src/components/formeditor/images/win/textbold.png
new file mode 100644
index 0000000..9cbc713
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textbold.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textcenter.png b/tools/designer/src/components/formeditor/images/win/textcenter.png
new file mode 100644
index 0000000..11efb4b
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textcenter.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textitalic.png b/tools/designer/src/components/formeditor/images/win/textitalic.png
new file mode 100644
index 0000000..b30ce14
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textitalic.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textjustify.png b/tools/designer/src/components/formeditor/images/win/textjustify.png
new file mode 100644
index 0000000..9de0c88
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textjustify.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textleft.png b/tools/designer/src/components/formeditor/images/win/textleft.png
new file mode 100644
index 0000000..16f80bc
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textleft.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textright.png b/tools/designer/src/components/formeditor/images/win/textright.png
new file mode 100644
index 0000000..16872df
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textright.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textsubscript.png b/tools/designer/src/components/formeditor/images/win/textsubscript.png
new file mode 100644
index 0000000..d86347d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textsubscript.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textsuperscript.png b/tools/designer/src/components/formeditor/images/win/textsuperscript.png
new file mode 100644
index 0000000..9109965
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textsuperscript.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/textunder.png b/tools/designer/src/components/formeditor/images/win/textunder.png
new file mode 100644
index 0000000..c72eff5
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/textunder.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/undo.png b/tools/designer/src/components/formeditor/images/win/undo.png
new file mode 100644
index 0000000..c3b8c513
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/undo.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/up.png b/tools/designer/src/components/formeditor/images/win/up.png
new file mode 100644
index 0000000..e437312
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/up.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/images/win/widgettool.png b/tools/designer/src/components/formeditor/images/win/widgettool.png
new file mode 100644
index 0000000..a52224e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/win/widgettool.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/itemview_propertysheet.cpp b/tools/designer/src/components/formeditor/itemview_propertysheet.cpp
new file mode 100644
index 0000000..609ce84
--- /dev/null
+++ b/tools/designer/src/components/formeditor/itemview_propertysheet.cpp
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "itemview_propertysheet.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QHeaderView>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+struct Property {
+ Property() : m_sheet(0),m_id(-1) {}
+ Property(QDesignerPropertySheetExtension *sheet, int id)
+ : m_sheet(sheet), m_id(id) {}
+ bool operator==(const Property &p) { return m_sheet == p.m_sheet && m_id == p.m_id; }
+ uint qHash() {
+ return ((int)(m_sheet-(QDesignerPropertySheetExtension*)(0))) & m_id;
+ }
+
+ QDesignerPropertySheetExtension *m_sheet;
+ int m_id;
+};
+
+class ItemViewPropertySheetPrivate {
+
+public:
+ ItemViewPropertySheetPrivate(QHeaderView *horizontalHeader,
+ QHeaderView *verticalHeader,
+ QObject *parent);
+
+ inline void createMapping(int fakeId, QHeaderView *header, const QString &headerName);
+ inline QStringList realPropertyNames();
+ inline QString fakePropertyName(const QString &prefix, const QString &realName);
+
+ QDesignerFormEditorInterface *m_core;
+
+ // Maps index of fake property
+ // to index of real property in respective sheet
+ QHash<int, Property> m_propertyIdMap;
+
+ // Maps name of fake property
+ // to name of real property
+ QHash<QString, QString> m_propertyNameMap;
+
+private:
+ static QDesignerFormEditorInterface *formEditorForObject(QObject *o);
+
+ QHeaderView *m_hHeader;
+ QHeaderView *m_vHeader;
+ QHash<QHeaderView *, QDesignerPropertySheetExtension *> m_propertySheet;
+ QStringList m_realPropertyNames;
+};
+
+// Name of the fake group
+static const char *headerGroup = "Header";
+
+// Name of the real properties
+static const char *visibleProperty = "visible";
+static const char *cascadingSectionResizesProperty = "cascadingSectionResizes";
+static const char *defaultSectionSizeProperty = "defaultSectionSize";
+static const char *highlightSectionsProperty = "highlightSections";
+static const char *minimumSectionSizeProperty = "minimumSectionSize";
+static const char *showSortIndicatorProperty = "showSortIndicator";
+static const char *stretchLastSectionProperty = "stretchLastSection";
+} // namespace qdesigner_internal
+
+using namespace qdesigner_internal;
+
+
+/***************** ItemViewPropertySheetPrivate *********************/
+
+ItemViewPropertySheetPrivate::ItemViewPropertySheetPrivate(QHeaderView *horizontalHeader,
+ QHeaderView *verticalHeader,
+ QObject *parent)
+ : m_core(formEditorForObject(parent)),
+ m_hHeader(horizontalHeader),
+ m_vHeader(verticalHeader)
+{
+ if (horizontalHeader)
+ m_propertySheet.insert(horizontalHeader,
+ qt_extension<QDesignerPropertySheetExtension*>
+ (m_core->extensionManager(), horizontalHeader));
+ if (verticalHeader)
+ m_propertySheet.insert(verticalHeader,
+ qt_extension<QDesignerPropertySheetExtension*>
+ (m_core->extensionManager(), verticalHeader));
+}
+
+// Find the form editor in the hierarchy.
+// We know that the parent of the sheet is the extension manager
+// whose parent is the core.
+QDesignerFormEditorInterface *ItemViewPropertySheetPrivate::formEditorForObject(QObject *o)
+{
+ do {
+ if (QDesignerFormEditorInterface* core = qobject_cast<QDesignerFormEditorInterface*>(o))
+ return core;
+ o = o->parent();
+ } while(o);
+ Q_ASSERT(o);
+ return 0;
+}
+
+void ItemViewPropertySheetPrivate::createMapping(int fakeId, QHeaderView *header,
+ const QString &headerName)
+{
+ const int realPropertyId = m_propertySheet.value(header)->indexOf(headerName);
+ QDesignerPropertySheetExtension *propertySheet = m_propertySheet.value(header);
+ m_propertyIdMap.insert(fakeId, Property(propertySheet, realPropertyId));
+}
+
+QStringList ItemViewPropertySheetPrivate::realPropertyNames()
+{
+ if (m_realPropertyNames.isEmpty())
+ m_realPropertyNames
+ << QLatin1String(visibleProperty)
+ << QLatin1String(cascadingSectionResizesProperty)
+ << QLatin1String(defaultSectionSizeProperty)
+ << QLatin1String(highlightSectionsProperty)
+ << QLatin1String(minimumSectionSizeProperty)
+ << QLatin1String(showSortIndicatorProperty)
+ << QLatin1String(stretchLastSectionProperty);
+ return m_realPropertyNames;
+}
+
+QString ItemViewPropertySheetPrivate::fakePropertyName(const QString &prefix,
+ const QString &realName)
+{
+ // prefix = "header", realPropertyName = "isVisible" returns "headerIsVisible"
+ QString fakeName = prefix + realName.at(0).toUpper() + realName.mid(1);
+ m_propertyNameMap.insert(fakeName, realName);
+ return fakeName;
+}
+
+/***************** ItemViewPropertySheet *********************/
+
+/*!
+ \class qdesigner_internal::ItemViewPropertySheet
+
+ \brief
+ Adds header fake properties to QTreeView and QTableView objects
+
+ QHeaderView objects are currently not shown in the object inspector.
+ This class adds some fake properties to the property sheet
+ of QTreeView and QTableView objects that nevertheless allow the manipulation
+ of the headers attached to the item view object.
+
+ Currently the defaultAlignment property is not shown because the property sheet
+ would only show integers, instead of the Qt::Alignment enumeration.
+
+ The fake properties here need special handling in QDesignerResource, uiloader and uic.
+ */
+
+ItemViewPropertySheet::ItemViewPropertySheet(QTreeView *treeViewObject, QObject *parent)
+ : QDesignerPropertySheet(treeViewObject, parent),
+ d(new ItemViewPropertySheetPrivate(treeViewObject->header(), 0, parent))
+{
+ QHeaderView *hHeader = treeViewObject->header();
+
+ foreach (const QString &realPropertyName, d->realPropertyNames()) {
+ const QString fakePropertyName
+ = d->fakePropertyName(QLatin1String("header"), realPropertyName);
+ d->createMapping(createFakeProperty(fakePropertyName, 0), hHeader, realPropertyName);
+ }
+
+ foreach (int id, d->m_propertyIdMap.keys()) {
+ setAttribute(id, true);
+ setPropertyGroup(id, QLatin1String(headerGroup));
+ }
+}
+
+
+ItemViewPropertySheet::ItemViewPropertySheet(QTableView *tableViewObject, QObject *parent)
+ : QDesignerPropertySheet(tableViewObject, parent),
+ d(new ItemViewPropertySheetPrivate(tableViewObject->horizontalHeader(),
+ tableViewObject->verticalHeader(), parent))
+{
+ QHeaderView *hHeader = tableViewObject->horizontalHeader();
+ QHeaderView *vHeader = tableViewObject->verticalHeader();
+
+ foreach (const QString &realPropertyName, d->realPropertyNames()) {
+ const QString fakePropertyName
+ = d->fakePropertyName(QLatin1String("horizontalHeader"), realPropertyName);
+ d->createMapping(createFakeProperty(fakePropertyName, 0), hHeader, realPropertyName);
+ }
+ foreach (const QString &realPropertyName, d->realPropertyNames()) {
+ const QString fakePropertyName
+ = d->fakePropertyName(QLatin1String("verticalHeader"), realPropertyName);
+ d->createMapping(createFakeProperty(fakePropertyName, 0), vHeader, realPropertyName);
+ }
+
+ foreach (int id, d->m_propertyIdMap.keys()) {
+ setAttribute(id, true);
+ setPropertyGroup(id, QLatin1String(headerGroup));
+ }
+}
+
+ItemViewPropertySheet::~ItemViewPropertySheet()
+{
+ delete d;
+}
+
+/*!
+ Returns the mapping of fake property names to real property names
+ */
+QHash<QString,QString> ItemViewPropertySheet::propertyNameMap() const
+{
+ return d->m_propertyNameMap;
+}
+
+QVariant ItemViewPropertySheet::property(int index) const
+{
+ if (d->m_propertyIdMap.contains(index)) {
+ Property realProperty = d->m_propertyIdMap.value(index);
+ return realProperty.m_sheet->property(realProperty.m_id);
+ } else {
+ return QDesignerPropertySheet::property(index);
+ }
+}
+
+void ItemViewPropertySheet::setProperty(int index, const QVariant &value)
+{
+ if (d->m_propertyIdMap.contains(index)) {
+ Property realProperty = d->m_propertyIdMap.value(index);
+ realProperty.m_sheet->setProperty(realProperty.m_id, value);
+ } else {
+ QDesignerPropertySheet::setProperty(index, value);
+ }
+}
+
+void ItemViewPropertySheet::setChanged(int index, bool changed)
+{
+ if (d->m_propertyIdMap.contains(index)) {
+ Property realProperty = d->m_propertyIdMap.value(index);
+ realProperty.m_sheet->setChanged(realProperty.m_id, changed);
+ }
+ QDesignerPropertySheet::setChanged(index, changed);
+}
+
+bool ItemViewPropertySheet::reset(int index)
+{
+ if (d->m_propertyIdMap.contains(index)) {
+ Property realProperty = d->m_propertyIdMap.value(index);
+ return realProperty.m_sheet->reset(realProperty.m_id);
+ } else {
+ return QDesignerPropertySheet::reset(index);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/itemview_propertysheet.h b/tools/designer/src/components/formeditor/itemview_propertysheet.h
new file mode 100644
index 0000000..e4c80dd
--- /dev/null
+++ b/tools/designer/src/components/formeditor/itemview_propertysheet.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMVIEW_PROPERTYSHEET_H
+#define ITEMVIEW_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QTreeView>
+#include <QtGui/QTableView>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class ItemViewPropertySheetPrivate;
+
+class ItemViewPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit ItemViewPropertySheet(QTreeView *treeViewObject, QObject *parent = 0);
+ explicit ItemViewPropertySheet(QTableView *tableViewObject, QObject *parent = 0);
+ ~ItemViewPropertySheet();
+
+ QHash<QString,QString> propertyNameMap() const;
+
+ // QDesignerPropertySheet
+ QVariant property(int index) const;
+ void setProperty(int index, const QVariant &value);
+
+ void setChanged(int index, bool changed);
+
+ bool reset(int index);
+
+private:
+ ItemViewPropertySheetPrivate *d;
+};
+
+typedef QDesignerPropertySheetFactory<QTreeView, ItemViewPropertySheet>
+ QTreeViewPropertySheetFactory;
+typedef QDesignerPropertySheetFactory<QTableView, ItemViewPropertySheet>
+ QTableViewPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ITEMVIEW_PROPERTYSHEET_H
diff --git a/tools/designer/src/components/formeditor/layout_propertysheet.cpp b/tools/designer/src/components/formeditor/layout_propertysheet.cpp
new file mode 100644
index 0000000..a304c6a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/layout_propertysheet.cpp
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "layout_propertysheet.h"
+
+// sdk
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+// shared
+#include <ui4_p.h>
+#include <qlayout_widget_p.h>
+#include <formbuilderextra_p.h>
+
+#include <QtGui/QFormLayout>
+
+#include <QtCore/QHash>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+#include <QtCore/QByteArray>
+#include <QtCore/QRegExp> // Remove once there is an editor for lists
+
+QT_BEGIN_NAMESPACE
+
+#define USE_LAYOUT_SIZE_CONSTRAINT
+
+static const char *leftMargin = "leftMargin";
+static const char *topMargin = "topMargin";
+static const char *rightMargin = "rightMargin";
+static const char *bottomMargin = "bottomMargin";
+static const char *horizontalSpacing = "horizontalSpacing";
+static const char *verticalSpacing = "verticalSpacing";
+static const char *spacing = "spacing";
+static const char *margin = "margin";
+static const char *sizeConstraint = "sizeConstraint";
+static const char *boxStretchPropertyC = "stretch";
+static const char *gridRowStretchPropertyC = "rowStretch";
+static const char *gridColumnStretchPropertyC = "columnStretch";
+static const char *gridRowMinimumHeightPropertyC = "rowMinimumHeight";
+static const char *gridColumnMinimumWidthPropertyC = "columnMinimumWidth";
+
+namespace {
+ enum LayoutPropertyType {
+ LayoutPropertyNone,
+ LayoutPropertyMargin, // Deprecated
+ LayoutPropertyLeftMargin,
+ LayoutPropertyTopMargin,
+ LayoutPropertyRightMargin,
+ LayoutPropertyBottomMargin,
+ LayoutPropertySpacing,
+ LayoutPropertyHorizontalSpacing,
+ LayoutPropertyVerticalSpacing,
+ LayoutPropertySizeConstraint,
+ LayoutPropertyBoxStretch,
+ LayoutPropertyGridRowStretch,
+ LayoutPropertyGridColumnStretch,
+ LayoutPropertyGridRowMinimumHeight,
+ LayoutPropertyGridColumnMinimumWidth
+ };
+}
+
+// Check for a comma-separated list of integers. Used for
+// per-cell stretch properties and grid per row/column properties.
+// As it works now, they are passed as QByteArray strings. The
+// property sheet refuses all invalid values. This could be
+// replaced by lists once the property editor can handle them.
+
+static bool isIntegerList(const QString &s)
+{
+ // Check for empty string or comma-separated list of integers
+ static const QRegExp re(QLatin1String("[0-9]+(,[0-9]+)+"));
+ Q_ASSERT(re.isValid());
+ return s.isEmpty() || re.exactMatch(s);
+}
+
+// Quick lookup by name
+static LayoutPropertyType layoutPropertyType(const QString &name)
+{
+ static QHash<QString, LayoutPropertyType> namePropertyMap;
+ if (namePropertyMap.empty()) {
+ namePropertyMap.insert(QLatin1String(leftMargin), LayoutPropertyLeftMargin);
+ namePropertyMap.insert(QLatin1String(topMargin), LayoutPropertyTopMargin);
+ namePropertyMap.insert(QLatin1String(rightMargin), LayoutPropertyRightMargin);
+ namePropertyMap.insert(QLatin1String(bottomMargin), LayoutPropertyBottomMargin);
+ namePropertyMap.insert(QLatin1String(horizontalSpacing), LayoutPropertyHorizontalSpacing);
+ namePropertyMap.insert(QLatin1String(verticalSpacing), LayoutPropertyVerticalSpacing);
+ namePropertyMap.insert(QLatin1String(spacing), LayoutPropertySpacing);
+ namePropertyMap.insert(QLatin1String(margin), LayoutPropertyMargin);
+ namePropertyMap.insert(QLatin1String(sizeConstraint), LayoutPropertySizeConstraint);
+ namePropertyMap.insert(QLatin1String(boxStretchPropertyC ), LayoutPropertyBoxStretch);
+ namePropertyMap.insert(QLatin1String(gridRowStretchPropertyC), LayoutPropertyGridRowStretch);
+ namePropertyMap.insert(QLatin1String(gridColumnStretchPropertyC), LayoutPropertyGridColumnStretch);
+ namePropertyMap.insert(QLatin1String(gridRowMinimumHeightPropertyC), LayoutPropertyGridRowMinimumHeight);
+ namePropertyMap.insert(QLatin1String(gridColumnMinimumWidthPropertyC), LayoutPropertyGridColumnMinimumWidth);
+ }
+ return namePropertyMap.value(name, LayoutPropertyNone);
+}
+
+// return the layout margin if it is margin
+static int getLayoutMargin(const QLayout *l, LayoutPropertyType type)
+{
+ int left, top, right, bottom;
+ l->getContentsMargins(&left, &top, &right, &bottom);
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ return left;
+ case LayoutPropertyTopMargin:
+ return top;
+ case LayoutPropertyRightMargin:
+ return right;
+ case LayoutPropertyBottomMargin:
+ return bottom;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ return 0;
+}
+
+// return the layout margin if it is margin
+static void setLayoutMargin(QLayout *l, LayoutPropertyType type, int margin)
+{
+ int left, top, right, bottom;
+ l->getContentsMargins(&left, &top, &right, &bottom);
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ left = margin;
+ break;
+ case LayoutPropertyTopMargin:
+ top = margin;
+ break;
+ case LayoutPropertyRightMargin:
+ right = margin;
+ break;
+ case LayoutPropertyBottomMargin:
+ bottom = margin;
+ break;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ l->setContentsMargins(left, top, right, bottom);
+}
+
+namespace qdesigner_internal {
+
+// ---------- LayoutPropertySheet: This sheet is never visible in
+// the property editor. Rather, the sheet pulled for QLayoutWidget
+// forwards all properties to it. Some properties (grid spacings) must be handled
+// manually, as they are QDOC_PROPERTY only and not visible to introspection. Ditto
+// for the 4 margins.
+
+LayoutPropertySheet::LayoutPropertySheet(QLayout *l, QObject *parent)
+ : QDesignerPropertySheet(l, parent), m_layout(l)
+{
+ const QString layoutGroup = QLatin1String("Layout");
+ int pindex = createFakeProperty(QLatin1String(leftMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(topMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(rightMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(bottomMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ const int visibleMask = LayoutProperties::visibleProperties(m_layout);
+ if (visibleMask & LayoutProperties::HorizSpacingProperty) {
+ pindex = createFakeProperty(QLatin1String(horizontalSpacing), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(verticalSpacing), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ setAttribute(indexOf(QLatin1String(spacing)), true);
+ }
+
+ setAttribute(indexOf(QLatin1String(margin)), true);
+ // Stretch
+ if (visibleMask & LayoutProperties::BoxStretchProperty) {
+ pindex = createFakeProperty(QLatin1String(boxStretchPropertyC), QByteArray());
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ } else {
+ // Add the grid per-row/column stretch and size limits
+ if (visibleMask & LayoutProperties::GridColumnStretchProperty) {
+ const QByteArray empty;
+ pindex = createFakeProperty(QLatin1String(gridRowStretchPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ pindex = createFakeProperty(QLatin1String(gridColumnStretchPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ pindex = createFakeProperty(QLatin1String(gridRowMinimumHeightPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ pindex = createFakeProperty(QLatin1String(gridColumnMinimumWidthPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ }
+ }
+#ifdef USE_LAYOUT_SIZE_CONSTRAINT
+ // SizeConstraint cannot possibly be handled as a real property
+ // as it affects the layout parent widget and thus
+ // conflicts with Designer's special layout widget.
+ // It will take effect on the preview only.
+ pindex = createFakeProperty(QLatin1String(sizeConstraint));
+ setPropertyGroup(pindex, layoutGroup);
+#endif
+}
+
+LayoutPropertySheet::~LayoutPropertySheet()
+{
+}
+
+void LayoutPropertySheet::setProperty(int index, const QVariant &value)
+{
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ if (QLayoutWidget *lw = qobject_cast<QLayoutWidget *>(m_layout->parent())) {
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ lw->setLayoutLeftMargin(value.toInt());
+ return;
+ case LayoutPropertyTopMargin:
+ lw->setLayoutTopMargin(value.toInt());
+ return;
+ case LayoutPropertyRightMargin:
+ lw->setLayoutRightMargin(value.toInt());
+ return;
+ case LayoutPropertyBottomMargin:
+ lw->setLayoutBottomMargin(value.toInt());
+ return;
+ case LayoutPropertyMargin: {
+ const int v = value.toInt();
+ lw->setLayoutLeftMargin(v);
+ lw->setLayoutTopMargin(v);
+ lw->setLayoutRightMargin(v);
+ lw->setLayoutBottomMargin(v);
+ }
+ return;
+ default:
+ break;
+ }
+ }
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ case LayoutPropertyTopMargin:
+ case LayoutPropertyRightMargin:
+ case LayoutPropertyBottomMargin:
+ setLayoutMargin(m_layout, type, value.toInt());
+ return;
+ case LayoutPropertyHorizontalSpacing:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ grid->setHorizontalSpacing(value.toInt());
+ return;
+ }
+ if (QFormLayout *form = qobject_cast<QFormLayout *>(m_layout)) {
+ form->setHorizontalSpacing(value.toInt());
+ return;
+ }
+ break;
+ case LayoutPropertyVerticalSpacing:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ grid->setVerticalSpacing(value.toInt());
+ return;
+ }
+ if (QFormLayout *form = qobject_cast<QFormLayout *>(m_layout)) {
+ form->setVerticalSpacing(value.toInt());
+ return;
+ }
+ break;
+ case LayoutPropertyBoxStretch:
+ // TODO: Remove the regexp check once a proper editor for integer
+ // lists is in place?
+ if (QBoxLayout *box = qobject_cast<QBoxLayout *>(m_layout)) {
+ const QString stretch = value.toString();
+ if (isIntegerList(stretch))
+ QFormBuilderExtra::setBoxLayoutStretch(value.toString(), box);
+ }
+ break;
+ case LayoutPropertyGridRowStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString stretch = value.toString();
+ if (isIntegerList(stretch))
+ QFormBuilderExtra::setGridLayoutRowStretch(stretch, grid);
+ }
+ break;
+ case LayoutPropertyGridColumnStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString stretch = value.toString();
+ if (isIntegerList(stretch))
+ QFormBuilderExtra::setGridLayoutColumnStretch(value.toString(), grid);
+ }
+ break;
+ case LayoutPropertyGridRowMinimumHeight:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString minSize = value.toString();
+ if (isIntegerList(minSize))
+ QFormBuilderExtra::setGridLayoutRowMinimumHeight(minSize, grid);
+ }
+ break;
+ case LayoutPropertyGridColumnMinimumWidth:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString minSize = value.toString();
+ if (isIntegerList(minSize))
+ QFormBuilderExtra::setGridLayoutColumnMinimumWidth(minSize, grid);
+ }
+ break;
+ default:
+ break;
+ }
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+QVariant LayoutPropertySheet::property(int index) const
+{
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ if (const QLayoutWidget *lw = qobject_cast<QLayoutWidget *>(m_layout->parent())) {
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ return lw->layoutLeftMargin();
+ case LayoutPropertyTopMargin:
+ return lw->layoutTopMargin();
+ case LayoutPropertyRightMargin:
+ return lw->layoutRightMargin();
+ case LayoutPropertyBottomMargin:
+ return lw->layoutBottomMargin();
+ default:
+ break;
+ }
+ }
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ case LayoutPropertyTopMargin:
+ case LayoutPropertyRightMargin:
+ case LayoutPropertyBottomMargin:
+ return getLayoutMargin(m_layout, type);
+ case LayoutPropertyHorizontalSpacing:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return grid->horizontalSpacing();
+ if (const QFormLayout *form = qobject_cast<QFormLayout *>(m_layout))
+ return form->horizontalSpacing();
+ break;
+ case LayoutPropertyVerticalSpacing:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return grid->verticalSpacing();
+ if (const QFormLayout *form = qobject_cast<QFormLayout *>(m_layout))
+ return form->verticalSpacing();
+ case LayoutPropertyBoxStretch:
+ if (const QBoxLayout *box = qobject_cast<QBoxLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::boxLayoutStretch(box).toUtf8()));
+ break;
+ case LayoutPropertyGridRowStretch:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutRowStretch(grid).toUtf8()));
+ break;
+ case LayoutPropertyGridColumnStretch:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutColumnStretch(grid).toUtf8()));
+ break;
+ case LayoutPropertyGridRowMinimumHeight:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutRowMinimumHeight(grid).toUtf8()));
+ break;
+ case LayoutPropertyGridColumnMinimumWidth:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutColumnMinimumWidth(grid).toUtf8()));
+ break;
+ default:
+ break;
+ }
+ return QDesignerPropertySheet::property(index);
+}
+
+bool LayoutPropertySheet::reset(int index)
+{
+ int left, top, right, bottom;
+ m_layout->getContentsMargins(&left, &top, &right, &bottom);
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ bool rc = true;
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ m_layout->setContentsMargins(-1, top, right, bottom);
+ break;
+ case LayoutPropertyTopMargin:
+ m_layout->setContentsMargins(left, -1, right, bottom);
+ break;
+ case LayoutPropertyRightMargin:
+ m_layout->setContentsMargins(left, top, -1, bottom);
+ break;
+ case LayoutPropertyBottomMargin:
+ m_layout->setContentsMargins(left, top, right, -1);
+ break;
+ case LayoutPropertyBoxStretch:
+ if (QBoxLayout *box = qobject_cast<QBoxLayout *>(m_layout))
+ QFormBuilderExtra::clearBoxLayoutStretch(box);
+ break;
+ case LayoutPropertyGridRowStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutRowStretch(grid);
+ break;
+ case LayoutPropertyGridColumnStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutColumnStretch(grid);
+ break;
+ case LayoutPropertyGridRowMinimumHeight:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutRowMinimumHeight(grid);
+ break;
+ case LayoutPropertyGridColumnMinimumWidth:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutColumnMinimumWidth(grid);
+ break;
+ default:
+ rc = QDesignerPropertySheet::reset(index);
+ break;
+ }
+ return rc;
+}
+
+void LayoutPropertySheet::setChanged(int index, bool changed)
+{
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ switch (type) {
+ case LayoutPropertySpacing:
+ if (LayoutProperties::visibleProperties(m_layout) & LayoutProperties::HorizSpacingProperty) {
+ setChanged(indexOf(QLatin1String(horizontalSpacing)), changed);
+ setChanged(indexOf(QLatin1String(verticalSpacing)), changed);
+ }
+ break;
+ case LayoutPropertyMargin:
+ setChanged(indexOf(QLatin1String(leftMargin)), changed);
+ setChanged(indexOf(QLatin1String(topMargin)), changed);
+ setChanged(indexOf(QLatin1String(rightMargin)), changed);
+ setChanged(indexOf(QLatin1String(bottomMargin)), changed);
+ break;
+ default:
+ break;
+ }
+ QDesignerPropertySheet::setChanged(index, changed);
+}
+
+void LayoutPropertySheet::stretchAttributesToDom(QDesignerFormEditorInterface *core, QLayout *lt, DomLayout *domLayout)
+{
+ // Check if the respective stretch properties of the layout are changed.
+ // If so, set them to the DOM
+ const int visibleMask = LayoutProperties::visibleProperties(lt);
+ if (!(visibleMask & (LayoutProperties::BoxStretchProperty|LayoutProperties::GridColumnStretchProperty|LayoutProperties::GridRowStretchProperty)))
+ return;
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), lt);
+ Q_ASSERT(sheet);
+
+ // Stretch
+ if (visibleMask & LayoutProperties::BoxStretchProperty) {
+ const int index = sheet->indexOf(QLatin1String(boxStretchPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeStretch(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridColumnStretchProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridColumnStretchPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeColumnStretch(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridRowStretchProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridRowStretchPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeRowStretch(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridRowMinimumHeightProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridRowMinimumHeightPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeRowMinimumHeight(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridColumnMinimumWidthProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridColumnMinimumWidthPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeColumnMinimumWidth(sheet->property(index).toString());
+ }
+}
+
+void LayoutPropertySheet::markChangedStretchProperties(QDesignerFormEditorInterface *core, QLayout *lt, const DomLayout *domLayout)
+{
+ // While the actual values are applied by the form builder, we still need
+ // to mark them as 'changed'.
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), lt);
+ Q_ASSERT(sheet);
+ if (!domLayout->attributeStretch().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(boxStretchPropertyC)), true);
+ if (!domLayout->attributeRowStretch().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridRowStretchPropertyC)), true);
+ if (!domLayout->attributeColumnStretch().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridColumnStretchPropertyC)), true);
+ if (!domLayout->attributeColumnMinimumWidth().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridColumnMinimumWidthPropertyC)), true);
+ if (!domLayout->attributeRowMinimumHeight().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridRowMinimumHeightPropertyC)), true);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/layout_propertysheet.h b/tools/designer/src/components/formeditor/layout_propertysheet.h
new file mode 100644
index 0000000..bb2b785
--- /dev/null
+++ b/tools/designer/src/components/formeditor/layout_propertysheet.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LAYOUT_PROPERTYSHEET_H
+#define LAYOUT_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class DomLayout;
+
+namespace qdesigner_internal {
+
+class LayoutPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit LayoutPropertySheet(QLayout *object, QObject *parent = 0);
+ virtual ~LayoutPropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual QVariant property(int index) const;
+ virtual bool reset(int index);
+ void setChanged(int index, bool changed);
+
+ static void stretchAttributesToDom(QDesignerFormEditorInterface *core, QLayout *lt, DomLayout *domLayout);
+ static void markChangedStretchProperties(QDesignerFormEditorInterface *core, QLayout *lt, const DomLayout *domLayout);
+
+private:
+ QLayout *m_layout;
+};
+
+typedef QDesignerPropertySheetFactory<QLayout, LayoutPropertySheet> LayoutPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LAYOUT_PROPERTYSHEET_H
diff --git a/tools/designer/src/components/formeditor/line_propertysheet.cpp b/tools/designer/src/components/formeditor/line_propertysheet.cpp
new file mode 100644
index 0000000..d13779e
--- /dev/null
+++ b/tools/designer/src/components/formeditor/line_propertysheet.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "line_propertysheet.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaProperty>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+LinePropertySheet::LinePropertySheet(Line *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent)
+{
+ clearFakeProperties();
+}
+
+LinePropertySheet::~LinePropertySheet()
+{
+}
+
+bool LinePropertySheet::isVisible(int index) const
+{
+ const QString name = propertyName(index);
+
+ if (name == QLatin1String("frameShape"))
+ return false;
+ return QDesignerPropertySheet::isVisible(index);
+}
+
+void LinePropertySheet::setProperty(int index, const QVariant &value)
+{
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+QString LinePropertySheet::propertyGroup(int index) const
+{
+ return QDesignerPropertySheet::propertyGroup(index);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/line_propertysheet.h b/tools/designer/src/components/formeditor/line_propertysheet.h
new file mode 100644
index 0000000..5149cac
--- /dev/null
+++ b/tools/designer/src/components/formeditor/line_propertysheet.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LINE_PROPERTYSHEET_H
+#define LINE_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <qdesigner_widget_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class LinePropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit LinePropertySheet(Line *object, QObject *parent = 0);
+ virtual ~LinePropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool isVisible(int index) const;
+ virtual QString propertyGroup(int index) const;
+};
+
+typedef QDesignerPropertySheetFactory<Line, LinePropertySheet> LinePropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LINE_PROPERTYSHEET_H
diff --git a/tools/designer/src/components/formeditor/previewactiongroup.cpp b/tools/designer/src/components/formeditor/previewactiongroup.cpp
new file mode 100644
index 0000000..aa52872
--- /dev/null
+++ b/tools/designer/src/components/formeditor/previewactiongroup.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewactiongroup.h"
+
+#include <deviceprofile_p.h>
+#include <shared_settings_p.h>
+
+#include <QtGui/QStyleFactory>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+enum { MaxDeviceActions = 20 };
+
+namespace qdesigner_internal {
+
+PreviewActionGroup::PreviewActionGroup(QDesignerFormEditorInterface *core, QObject *parent) :
+ QActionGroup(parent),
+ m_core(core)
+{
+ /* Create a list of up to MaxDeviceActions invisible actions to be
+ * populated with device profiles (actiondata: index) followed by the
+ * standard style actions (actiondata: style name). */
+ connect(this, SIGNAL(triggered(QAction*)), this, SLOT(slotTriggered(QAction*)));
+ setExclusive(true);
+
+ const QString objNamePostfix = QLatin1String("_action");
+ // Create invisible actions for devices. Set index as action data.
+ QString objNamePrefix = QLatin1String("__qt_designer_device_");
+ for (int i = 0; i < MaxDeviceActions; i++) {
+ QAction *a = new QAction(this);
+ QString objName = objNamePrefix;
+ objName += QString::number(i);
+ objName += objNamePostfix;
+ a->setObjectName(objName);
+ a->setVisible(false);
+ a->setData(i);
+ addAction(a);
+ }
+ // Create separator at index MaxDeviceActions
+ QAction *sep = new QAction(this);
+ sep->setObjectName(QLatin1String("__qt_designer_deviceseparator"));
+ sep->setSeparator(true);
+ sep->setVisible(false);
+ addAction(sep);
+ // Populate devices
+ updateDeviceProfiles();
+
+ // Add style actions
+ const QStringList styles = QStyleFactory::keys();
+ const QStringList::const_iterator cend = styles.constEnd();
+ // Make sure ObjectName is unique in case toolbar solution is used.
+ objNamePrefix = QLatin1String("__qt_designer_style_");
+ // Create styles. Set style name string as action data.
+ for (QStringList::const_iterator it = styles.constBegin(); it != cend ;++it) {
+ QAction *a = new QAction(tr("%1 Style").arg(*it), this);
+ QString objName = objNamePrefix;
+ objName += *it;
+ objName += objNamePostfix;
+ a->setObjectName(objName);
+ a->setData(*it);
+ addAction(a);
+ }
+}
+
+void PreviewActionGroup::updateDeviceProfiles()
+{
+ typedef QList<DeviceProfile> DeviceProfileList;
+ typedef QList<QAction *> ActionList;
+
+ const QDesignerSharedSettings settings(m_core);
+ const DeviceProfileList profiles = settings.deviceProfiles();
+ const ActionList al = actions();
+ // Separator?
+ const bool hasProfiles = !profiles.empty();
+ al.at(MaxDeviceActions)->setVisible(hasProfiles);
+ int index = 0;
+ if (hasProfiles) {
+ // Make actions visible
+ const int maxIndex = qMin(static_cast<int>(MaxDeviceActions), profiles.size());
+ for (; index < maxIndex; index++) {
+ const QString name = profiles.at(index).name();
+ al.at(index)->setText(name);
+ al.at(index)->setVisible(true);
+ }
+ }
+ // Hide rest
+ for ( ; index < MaxDeviceActions; index++)
+ al.at(index)->setVisible(false);
+}
+
+void PreviewActionGroup::slotTriggered(QAction *a)
+{
+ // Device or style according to data.
+ const QVariant data = a->data();
+ switch (data.type()) {
+ case QVariant::String:
+ emit preview(data.toString(), -1);
+ break;
+ case QVariant::Int:
+ emit preview(QString(), data.toInt());
+ break;
+ default:
+ break;
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/previewactiongroup.h b/tools/designer/src/components/formeditor/previewactiongroup.h
new file mode 100644
index 0000000..851f554
--- /dev/null
+++ b/tools/designer/src/components/formeditor/previewactiongroup.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PREVIEWACTIONGROUP_H
+#define PREVIEWACTIONGROUP_H
+
+#include <QtGui/QActionGroup>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+/* PreviewActionGroup: To be used as a submenu for 'Preview in...'
+ * Offers a menu of styles and device profiles. */
+
+class PreviewActionGroup : public QActionGroup
+{
+ Q_DISABLE_COPY(PreviewActionGroup)
+ Q_OBJECT
+public:
+ explicit PreviewActionGroup(QDesignerFormEditorInterface *core, QObject *parent = 0);
+
+signals:
+ void preview(const QString &style, int deviceProfileIndex);
+
+public slots:
+ void updateDeviceProfiles();
+
+private slots:
+ void slotTriggered(QAction *);
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // PREVIEWACTIONGROUP_H
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
new file mode 100644
index 0000000..75a53b7
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -0,0 +1,2665 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_resource.h"
+#include "formwindow.h"
+#include "dynamicpropertysheet.h"
+#include "qdesigner_tabwidget_p.h"
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_toolbar_p.h"
+#include "qdesigner_dockwidget_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_menubar_p.h"
+#include "qdesigner_membersheet_p.h"
+#include "qtresourcemodel_p.h"
+#include "qmdiarea_container.h"
+#include "qwizard_container.h"
+#include "itemview_propertysheet.h"
+#include "layout_propertysheet.h"
+
+#include <ui4_p.h>
+#include <formbuilderextra_p.h>
+#include <resourcebuilder_p.h>
+#include <textbuilder_p.h>
+#include <qdesigner_widgetitem_p.h>
+
+// shared
+#include <widgetdatabase_p.h>
+#include <metadatabase_p.h>
+#include <layout_p.h>
+#include <layoutinfo_p.h>
+#include <spacer_widget_p.h>
+#include <pluginmanager_p.h>
+#include <widgetfactory_p.h>
+#include <abstractlanguage.h>
+#include <abstractintrospection_p.h>
+
+#include <qlayout_widget_p.h>
+#include <qdesigner_utils_p.h>
+#include <ui4_p.h>
+
+// sdk
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <abstractdialoggui_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+#include <QtGui/QLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QToolBar>
+#include <QtGui/QTabBar>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QApplication>
+#include <QtGui/QMainWindow>
+#include <QtGui/QSplitter>
+#include <QtGui/QMdiArea>
+#include <QtGui/QWorkspace>
+#include <QtGui/QMenuBar>
+#include <QtGui/QFileDialog>
+#include <QtGui/QHeaderView>
+#include <QtGui/QTreeView>
+#include <QtGui/QTableView>
+#include <QtGui/QWizardPage>
+#include <private/qlayoutengine_p.h>
+
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QMetaProperty>
+#include <QtCore/qdebug.h>
+#include <QtCore/QXmlStreamWriter>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ typedef QList<DomProperty*> DomPropertyList;
+}
+
+static const char *currentUiVersion = "4.0";
+static const char *clipboardObjectName = "__qt_fake_top_level";
+
+#define OLD_RESOURCE_FORMAT // Support pre 4.4 format.
+
+namespace qdesigner_internal {
+
+// -------------------- QDesignerResourceBuilder: A resource builder that works on the property sheet icon types.
+class QDesignerResourceBuilder : public QResourceBuilder
+{
+public:
+ QDesignerResourceBuilder(QDesignerFormEditorInterface *core, DesignerPixmapCache *pixmapCache, DesignerIconCache *iconCache);
+
+ void setPixmapCache(DesignerPixmapCache *pixmapCache) { m_pixmapCache = pixmapCache; }
+ void setIconCache(DesignerIconCache *iconCache) { m_iconCache = iconCache; }
+ bool isSaveRelative() const { return m_saveRelative; }
+ void setSaveRelative(bool relative) { m_saveRelative = relative; }
+ QStringList usedQrcFiles() const { return m_usedQrcFiles.keys(); }
+#ifdef OLD_RESOURCE_FORMAT
+ QStringList loadedQrcFiles() const { return m_loadedQrcFiles.keys(); } // needed only for loading old resource attribute of <iconset> tag.
+#endif
+
+ virtual QVariant loadResource(const QDir &workingDirectory, const DomProperty *icon) const;
+
+ virtual QVariant toNativeValue(const QVariant &value) const;
+
+ virtual DomProperty *saveResource(const QDir &workingDirectory, const QVariant &value) const;
+
+ virtual bool isResourceType(const QVariant &value) const;
+private:
+
+ QDesignerFormEditorInterface *m_core;
+ DesignerPixmapCache *m_pixmapCache;
+ DesignerIconCache *m_iconCache;
+ bool m_saveRelative;
+ mutable QMap<QString, bool> m_usedQrcFiles;
+ mutable QMap<QString, bool> m_loadedQrcFiles;
+};
+
+QDesignerResourceBuilder::QDesignerResourceBuilder(QDesignerFormEditorInterface *core, DesignerPixmapCache *pixmapCache, DesignerIconCache *iconCache) :
+ m_core(core),
+ m_pixmapCache(pixmapCache),
+ m_iconCache(iconCache),
+ m_saveRelative(true)
+{
+}
+
+static inline void setIconPixmap(QIcon::Mode m, QIcon::State s, const QDir &workingDirectory, const QString &v, PropertySheetIconValue &icon)
+{
+ icon.setPixmap(m, s, PropertySheetPixmapValue(QFileInfo(workingDirectory, v).absoluteFilePath()));
+}
+
+QVariant QDesignerResourceBuilder::loadResource(const QDir &workingDirectory, const DomProperty *property) const
+{
+ switch (property->kind()) {
+ case DomProperty::Pixmap: {
+ PropertySheetPixmapValue pixmap;
+ DomResourcePixmap *dp = property->elementPixmap();
+ if (!dp->text().isEmpty()) {
+ pixmap.setPath(QFileInfo(workingDirectory, dp->text()).absoluteFilePath());
+#ifdef OLD_RESOURCE_FORMAT
+ if (dp->hasAttributeResource())
+ m_loadedQrcFiles.insert(QFileInfo(workingDirectory, dp->attributeResource()).absoluteFilePath(), false);
+#endif
+ }
+ return qVariantFromValue(pixmap);
+ }
+
+ case DomProperty::IconSet: {
+ PropertySheetIconValue icon;
+ DomResourceIcon *di = property->elementIconSet();
+ if (const int flags = iconStateFlags(di)) { // new, post 4.4 format
+ if (flags & NormalOff)
+ setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->elementNormalOff()->text(), icon);
+ if (flags & NormalOn)
+ setIconPixmap(QIcon::Normal, QIcon::On, workingDirectory, di->elementNormalOn()->text(), icon);
+ if (flags & DisabledOff)
+ setIconPixmap(QIcon::Disabled, QIcon::Off, workingDirectory, di->elementDisabledOff()->text(), icon);
+ if (flags & DisabledOn)
+ setIconPixmap(QIcon::Disabled, QIcon::On, workingDirectory, di->elementDisabledOn()->text(), icon);
+ if (flags & ActiveOff)
+ setIconPixmap(QIcon::Active, QIcon::Off, workingDirectory, di->elementActiveOff()->text(), icon);
+ if (flags & ActiveOn)
+ setIconPixmap(QIcon::Active, QIcon::On, workingDirectory, di->elementActiveOn()->text(), icon);
+ if (flags & SelectedOff)
+ setIconPixmap(QIcon::Selected, QIcon::Off, workingDirectory, di->elementSelectedOff()->text(), icon);
+ if (flags & SelectedOn)
+ setIconPixmap(QIcon::Selected, QIcon::On, workingDirectory, di->elementSelectedOn()->text(), icon);
+ } else {
+#ifdef OLD_RESOURCE_FORMAT
+ setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->text(), icon);
+ if (di->hasAttributeResource())
+ m_loadedQrcFiles.insert(QFileInfo(workingDirectory, di->attributeResource()).absoluteFilePath(), false);
+#endif
+ }
+ return qVariantFromValue(icon);
+ }
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QVariant QDesignerResourceBuilder::toNativeValue(const QVariant &value) const
+{
+ if (qVariantCanConvert<PropertySheetPixmapValue>(value)) {
+ if (m_pixmapCache)
+ return m_pixmapCache->pixmap(qVariantValue<PropertySheetPixmapValue>(value));
+ } else if (qVariantCanConvert<PropertySheetIconValue>(value)) {
+ if (m_iconCache)
+ return m_iconCache->icon(qVariantValue<PropertySheetIconValue>(value));
+ }
+ return value;
+}
+
+DomProperty *QDesignerResourceBuilder::saveResource(const QDir &workingDirectory, const QVariant &value) const
+{
+ DomProperty *p = new DomProperty;
+ if (qVariantCanConvert<PropertySheetPixmapValue>(value)) {
+ const PropertySheetPixmapValue pix = qvariant_cast<PropertySheetPixmapValue>(value);
+ DomResourcePixmap *rp = new DomResourcePixmap;
+ const QString pixPath = pix.path();
+ switch (pix.pixmapSource(m_core)) {
+ case PropertySheetPixmapValue::LanguageResourcePixmap:
+ rp->setText(pixPath);
+ break;
+ case PropertySheetPixmapValue::ResourcePixmap: {
+ rp->setText(pixPath);
+ const QString qrcFile = m_core->resourceModel()->qrcPath(pixPath);
+ if (!qrcFile.isEmpty()) {
+ m_usedQrcFiles.insert(qrcFile, false);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Add qrc path
+ rp->setAttributeResource(workingDirectory.relativeFilePath(qrcFile));
+#endif
+ }
+ }
+ break;
+ case PropertySheetPixmapValue::FilePixmap:
+ rp->setText(m_saveRelative ? workingDirectory.relativeFilePath(pixPath) : pixPath);
+ break;
+ }
+ p->setElementPixmap(rp);
+ return p;
+ } else if (qVariantCanConvert<PropertySheetIconValue>(value)) {
+ const PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(value);
+ const QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> pixmaps = icon.paths();
+ if (!pixmaps.isEmpty()) {
+ DomResourceIcon *ri = new DomResourceIcon;
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> itPix(pixmaps);
+ while (itPix.hasNext()) {
+ const QIcon::Mode mode = itPix.next().key().first;
+ const QIcon::State state = itPix.key().second;
+ DomResourcePixmap *rp = new DomResourcePixmap;
+ const PropertySheetPixmapValue pix = itPix.value();
+ const PropertySheetPixmapValue::PixmapSource ps = pix.pixmapSource(m_core);
+ const QString pixPath = pix.path();
+ rp->setText(ps == PropertySheetPixmapValue::FilePixmap && m_saveRelative ? workingDirectory.relativeFilePath(pixPath) : pixPath);
+ if (state == QIcon::Off) {
+ switch (mode) {
+ case QIcon::Normal:
+ ri->setElementNormalOff(rp);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Set Normal off as text/path in old format.
+ ri->setText(rp->text());
+#endif
+ if (ps == PropertySheetPixmapValue::ResourcePixmap) {
+ // Be sure that ri->text() file comes from active resourceSet (i.e. make appropriate
+ // resourceSet active before calling this method).
+ const QString qrcFile = m_core->resourceModel()->qrcPath(ri->text());
+ if (!qrcFile.isEmpty()) {
+ m_usedQrcFiles.insert(qrcFile, false);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Set Normal off as text/path in old format.
+ ri->setAttributeResource(workingDirectory.relativeFilePath(qrcFile));
+#endif
+ }
+ }
+ break;
+ case QIcon::Disabled: ri->setElementDisabledOff(rp); break;
+ case QIcon::Active: ri->setElementActiveOff(rp); break;
+ case QIcon::Selected: ri->setElementSelectedOff(rp); break;
+ }
+ } else {
+ switch (mode) {
+ case QIcon::Normal: ri->setElementNormalOn(rp); break;
+ case QIcon::Disabled: ri->setElementDisabledOn(rp); break;
+ case QIcon::Active: ri->setElementActiveOn(rp); break;
+ case QIcon::Selected: ri->setElementSelectedOn(rp); break;
+ }
+ }
+ }
+ p->setElementIconSet(ri);
+ return p;
+ }
+ }
+ delete p;
+ return 0;
+}
+
+bool QDesignerResourceBuilder::isResourceType(const QVariant &value) const
+{
+ if (qVariantCanConvert<PropertySheetPixmapValue>(value) || qVariantCanConvert<PropertySheetIconValue>(value))
+ return true;
+ return false;
+}
+// ------------------------- QDesignerTextBuilder
+class QDesignerTextBuilder : public QTextBuilder
+{
+public:
+ QDesignerTextBuilder() {}
+
+ virtual QVariant loadText(const DomProperty *icon) const;
+
+ virtual QVariant toNativeValue(const QVariant &value) const;
+
+ virtual DomProperty *saveText(const QVariant &value) const;
+};
+
+QVariant QDesignerTextBuilder::loadText(const DomProperty *text) const
+{
+ const DomString *str = text->elementString();
+ PropertySheetStringValue strVal(str->text());
+ if (str->hasAttributeComment()) {
+ strVal.setDisambiguation(str->attributeComment());
+ }
+ if (str->hasAttributeExtraComment()) {
+ strVal.setComment(str->attributeExtraComment());
+ }
+ if (str->hasAttributeNotr()) {
+ const QString notr = str->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ strVal.setTranslatable(translatable);
+ }
+ return qVariantFromValue(strVal);
+}
+
+QVariant QDesignerTextBuilder::toNativeValue(const QVariant &value) const
+{
+ if (qVariantCanConvert<PropertySheetStringValue>(value))
+ return qVariantFromValue(qVariantValue<PropertySheetStringValue>(value).value());
+ return value;
+}
+
+DomProperty *QDesignerTextBuilder::saveText(const QVariant &value) const
+{
+ if (!qVariantCanConvert<PropertySheetStringValue>(value) && !qVariantCanConvert<QString>(value))
+ return 0;
+
+ DomProperty *property = new DomProperty();
+ DomString *domStr = new DomString();
+
+ if (qVariantCanConvert<PropertySheetStringValue>(value)) {
+ PropertySheetStringValue str = qVariantValue<PropertySheetStringValue>(value);
+
+ domStr->setText(str.value());
+
+ const QString property_comment = str.disambiguation();
+ if (!property_comment.isEmpty())
+ domStr->setAttributeComment(property_comment);
+ const QString property_extraComment = str.comment();
+ if (!property_extraComment.isEmpty())
+ domStr->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = str.translatable();
+ if (!property_translatable)
+ domStr->setAttributeNotr(QLatin1String("true"));
+ } else {
+ domStr->setText(value.toString());
+ }
+
+ property->setElementString(domStr);
+ return property;
+}
+
+QDesignerResource::QDesignerResource(FormWindow *formWindow) :
+ QEditorFormBuilder(formWindow->core()),
+ m_formWindow(formWindow),
+ m_topLevelSpacerCount(0),
+ m_copyWidget(false),
+ m_selected(0),
+ m_resourceBuilder(new QDesignerResourceBuilder(m_formWindow->core(), m_formWindow->pixmapCache(), m_formWindow->iconCache()))
+{
+ setWorkingDirectory(formWindow->absoluteDir());
+ setResourceBuilder(m_resourceBuilder);
+ setTextBuilder(new QDesignerTextBuilder());
+
+ // ### generalise
+ const QString designerWidget = QLatin1String("QDesignerWidget");
+ const QString layoutWidget = QLatin1String("QLayoutWidget");
+ const QString widget = QLatin1String("QWidget");
+ m_internal_to_qt.insert(layoutWidget, widget);
+ m_internal_to_qt.insert(designerWidget, widget);
+ m_internal_to_qt.insert(QLatin1String("QDesignerDialog"), QLatin1String("QDialog"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerMenuBar"), QLatin1String("QMenuBar"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerMenu"), QLatin1String("QMenu"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerDockWidget"), QLatin1String("QDockWidget"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerQ3WidgetStack"), QLatin1String("Q3WidgetStack"));
+
+ // invert
+ QHash<QString, QString>::const_iterator cend = m_internal_to_qt.constEnd();
+ for (QHash<QString, QString>::const_iterator it = m_internal_to_qt.constBegin();it != cend; ++it ) {
+ if (it.value() != designerWidget && it.value() != layoutWidget)
+ m_qt_to_internal.insert(it.value(), it.key());
+
+ }
+}
+
+QDesignerResource::~QDesignerResource()
+{
+}
+
+static inline QString messageBoxTitle()
+{
+ return QApplication::translate("Designer", "Qt Designer");
+}
+
+void QDesignerResource::save(QIODevice *dev, QWidget *widget)
+{
+ m_topLevelSpacerCount = 0;
+
+ QAbstractFormBuilder::save(dev, widget);
+
+ if (QSimpleResource::warningsEnabled() && m_topLevelSpacerCount != 0) {
+ const QString message = QApplication::translate("Designer", "This file contains top level spacers.<br>"
+ "They have <b>NOT</b> been saved into the form.");
+ const QString infoMessage = QApplication::translate("Designer", "Perhaps you forgot to create a layout?");
+
+ core()->dialogGui()->message(widget->window(), QDesignerDialogGuiInterface::TopLevelSpacerMessage,
+ QMessageBox::Warning, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ }
+}
+
+void QDesignerResource::saveDom(DomUI *ui, QWidget *widget)
+{
+ QAbstractFormBuilder::saveDom(ui, widget);
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ Q_ASSERT(sheet != 0);
+
+ const QVariant classVar = sheet->property(sheet->indexOf(QLatin1String("objectName")));
+ QString classStr;
+ if (classVar.canConvert(QVariant::String))
+ classStr = classVar.toString();
+ else
+ classStr = qVariantValue<PropertySheetStringValue>(classVar).value();
+ ui->setElementClass(classStr);
+
+ for (int index = 0; index < m_formWindow->toolCount(); ++index) {
+ QDesignerFormWindowToolInterface *tool = m_formWindow->tool(index);
+ Q_ASSERT(tool != 0);
+ tool->saveToDom(ui, widget);
+ }
+
+ const QString author = m_formWindow->author();
+ if (!author.isEmpty()) {
+ ui->setElementAuthor(author);
+ }
+
+ const QString comment = m_formWindow->comment();
+ if (!comment.isEmpty()) {
+ ui->setElementComment(comment);
+ }
+
+ const QString exportMacro = m_formWindow->exportMacro();
+ if (!exportMacro.isEmpty()) {
+ ui->setElementExportMacro(exportMacro);
+ }
+
+ const QVariantMap designerFormData = m_formWindow->formData();
+ if (!designerFormData.empty()) {
+ DomPropertyList domPropertyList;
+ const QVariantMap::const_iterator cend = designerFormData.constEnd();
+ for (QVariantMap::const_iterator it = designerFormData.constBegin(); it != cend; ++it) {
+ if (DomProperty *prop = variantToDomProperty(this, widget->metaObject(), it.key(), it.value()))
+ domPropertyList += prop;
+ }
+ if (!domPropertyList.empty()) {
+ DomDesignerData* domDesignerFormData = new DomDesignerData;
+ domDesignerFormData->setElementProperty(domPropertyList);
+ ui->setElementDesignerdata(domDesignerFormData);
+ }
+ }
+
+ if (!m_formWindow->includeHints().isEmpty()) {
+ const QString local = QLatin1String("local");
+ const QString global = QLatin1String("global");
+ QList<DomInclude*> ui_includes;
+ foreach (QString includeHint, m_formWindow->includeHints()) {
+ if (includeHint.isEmpty())
+ continue;
+ DomInclude *incl = new DomInclude;
+ const QString location = includeHint.at(0) == QLatin1Char('<') ? global : local;
+ includeHint.remove(QLatin1Char('"'));
+ includeHint.remove(QLatin1Char('<'));
+ includeHint.remove(QLatin1Char('>'));
+ incl->setAttributeLocation(location);
+ incl->setText(includeHint);
+ ui_includes.append(incl);
+ }
+
+ DomIncludes *includes = new DomIncludes;
+ includes->setElementInclude(ui_includes);
+ ui->setElementIncludes(includes);
+ }
+
+ int defaultMargin = INT_MIN, defaultSpacing = INT_MIN;
+ m_formWindow->layoutDefault(&defaultMargin, &defaultSpacing);
+
+ if (defaultMargin != INT_MIN || defaultSpacing != INT_MIN) {
+ DomLayoutDefault *def = new DomLayoutDefault;
+ if (defaultMargin != INT_MIN)
+ def->setAttributeMargin(defaultMargin);
+ if (defaultSpacing != INT_MIN)
+ def->setAttributeSpacing(defaultSpacing);
+ ui->setElementLayoutDefault(def);
+ }
+
+ QString marginFunction, spacingFunction;
+ m_formWindow->layoutFunction(&marginFunction, &spacingFunction);
+ if (!marginFunction.isEmpty() || !spacingFunction.isEmpty()) {
+ DomLayoutFunction *def = new DomLayoutFunction;
+
+ if (!marginFunction.isEmpty())
+ def->setAttributeMargin(marginFunction);
+ if (!spacingFunction.isEmpty())
+ def->setAttributeSpacing(spacingFunction);
+ ui->setElementLayoutFunction(def);
+ }
+
+ QString pixFunction = m_formWindow->pixmapFunction();
+ if (!pixFunction.isEmpty()) {
+ ui->setElementPixmapFunction(pixFunction);
+ }
+
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core()))
+ extra->saveUiExtraInfo(ui);
+
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ const MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(m_formWindow->mainContainer());
+ const QStringList fakeSlots = item->fakeSlots();
+ const QStringList fakeSignals =item->fakeSignals();
+ if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ DomSlots *domSlots = new DomSlots();
+ domSlots->setElementSlot(fakeSlots);
+ domSlots->setElementSignal(fakeSignals);
+ ui->setElementSlots(domSlots);
+ }
+ }
+}
+
+namespace {
+ enum LoadPreCheck { LoadPreCheckFailed, LoadPreCheckVersion3, LoadPreCheckVersionMismatch, LoadPreCheckOk };
+ // Pair of major, minor
+ typedef QPair<int, int> UiVersion;
+}
+
+static UiVersion uiVersion(const QString &attr)
+{
+ const QStringList versions = attr.split(QLatin1Char('.'));
+ if (versions.empty())
+ return UiVersion(-1, -1);
+
+ bool ok = false;
+ UiVersion rc(versions.at(0).toInt(&ok), 0);
+
+ if (!ok)
+ return UiVersion(-1, -1);
+
+ if (versions.size() > 1) {
+ const int minorVersion = versions.at(1).toInt(&ok);
+ if (ok)
+ rc.second = minorVersion;
+ }
+ return rc;
+}
+
+// Read version and language attributes of an <UI> element.
+static bool readUiAttributes(QIODevice *dev, QString *errorMessage,
+ QString *version,
+ QString *language)
+{
+ const QString uiElement = QLatin1String("ui");
+ const QString versionAttribute = QLatin1String("version");
+ const QString languageAttribute = QLatin1String("language");
+ QXmlStreamReader reader(dev);
+ // Read up to first element
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ const QStringRef tag = reader.name();
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) {
+ const QXmlStreamAttributes attributes = reader.attributes();
+ if (attributes.hasAttribute(versionAttribute))
+ *version = attributes.value(versionAttribute).toString();
+ if (attributes.hasAttribute(languageAttribute))
+ *language = attributes.value(languageAttribute).toString();
+ return true;
+ } else {
+ *errorMessage = QCoreApplication::translate("Designer", "Invalid ui file: The root element <ui> is missing.");
+ return false;
+
+ }
+ }
+ }
+ *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the ui file at line %1, column %2: %3")
+ .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString());
+ return false;
+}
+
+// While loading a file, check language, version and extra extension
+static LoadPreCheck loadPrecheck(QDesignerFormEditorInterface *core,
+ QIODevice *dev,
+ QString *errorMessage, QString *versionString)
+{
+ QString language;
+ // Read attributes of <ui> and rewind
+ if (!readUiAttributes(dev, errorMessage, versionString, &language)) {
+ // XML error: Mimick the behaviour occurring if an XML error is
+ // detected later on, report to warning log and have embedding
+ // application display a dialog.
+ designerWarning(*errorMessage);
+ errorMessage->clear();
+ return LoadPreCheckFailed;
+ }
+ dev->seek(0);
+
+ // Check language unless extension present (Jambi)
+ if (!language.isEmpty() && !qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core)) {
+ if (language.toLower() != QLatin1String("c++")) {
+ // Jambi?!
+ *errorMessage = QApplication::translate("Designer", "This file cannot be read because it was created using %1.").arg(language);
+ return LoadPreCheckFailed;
+ }
+ }
+
+ // Version
+ if (!versionString->isEmpty()) {
+ const UiVersion version = uiVersion(*versionString);
+ switch (version.first) {
+ case 3:
+ return LoadPreCheckVersion3;
+ case 4:
+ break;
+ default:
+ *errorMessage = QApplication::translate("Designer", "This file was created using Designer from Qt-%1 and cannot be read.").arg(*versionString);
+ return LoadPreCheckVersionMismatch;
+ }
+ }
+ return LoadPreCheckOk;
+}
+
+QWidget *QDesignerResource::load(QIODevice *dev, QWidget *parentWidget)
+{
+ // Run loadPreCheck for version and language
+ QString errorMessage;
+ QString version;
+ switch (loadPrecheck(core(), dev, &errorMessage, &version)) {
+ case LoadPreCheckFailed:
+ case LoadPreCheckVersionMismatch:
+ if (!errorMessage.isEmpty())
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), errorMessage, QMessageBox::Ok);
+ return 0;
+ case LoadPreCheckVersion3: {
+ QWidget *w = 0;
+ QByteArray ba;
+ if (runUIC( m_formWindow->fileName(), UIC_ConvertV3, ba, errorMessage)) {
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::ReadOnly);
+ w = load(&buffer, parentWidget);
+ if (w) {
+ // Force the form to pop up a save file dialog
+ m_formWindow->setFileName(QString());
+ } else {
+ errorMessage = QApplication::translate("Designer", "The converted file could not be read.");
+ }
+ }
+ if (w) {
+ const QString message = QApplication::translate("Designer",
+ "This file was created using Designer from Qt-%1 and"
+ " will be converted to a new form by Qt Designer.").arg(version);
+ const QString infoMessage = QApplication::translate("Designer",
+ "The old form has not been touched, but you will have to save the form"
+ " under a new name.");
+
+ core()->dialogGui()->message(parentWidget->window(),
+ QDesignerDialogGuiInterface::UiVersionMismatchMessage,
+ QMessageBox::Information, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ return w;
+ }
+
+ const QString message = QApplication::translate("Designer",
+ "This file was created using Designer from Qt-%1 and "
+ "could not be read:\n%2").arg(version).arg(errorMessage);
+ const QString infoMessage = QApplication::translate("Designer",
+ "Please run it through <b>uic3&nbsp;-convert</b> to convert "
+ "it to Qt-4's ui format.");
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ return 0;
+ }
+
+ case LoadPreCheckOk:
+ break;
+ }
+ return QEditorFormBuilder::load(dev, parentWidget);
+}
+
+bool QDesignerResource::saveRelative() const
+{
+ return m_resourceBuilder->isSaveRelative();
+}
+
+void QDesignerResource::setSaveRelative(bool relative)
+{
+ m_resourceBuilder->setSaveRelative(relative);
+}
+
+static bool addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals)
+{
+ if (!domSlots)
+ return false;
+
+ bool rc = false;
+ foreach (const QString &fakeSlot, domSlots->elementSlot())
+ if (fakeSlots.indexOf(fakeSlot) == -1) {
+ fakeSlots += fakeSlot;
+ rc = true;
+ }
+
+ foreach (const QString &fakeSignal, domSlots->elementSignal())
+ if (fakeSignals.indexOf(fakeSignal) == -1) {
+ fakeSignals += fakeSignal;
+ rc = true;
+ }
+ return rc;
+}
+
+QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
+{
+ // Load extra info extension. This is used by Jambi for preventing
+ // C++ ui files from being loaded
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core())) {
+ if (!extra->loadUiExtraInfo(ui)) {
+ const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load.");
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), errorMessage, QMessageBox::Ok);
+ return 0;
+ }
+ }
+
+ qdesigner_internal::WidgetFactory *factory = qobject_cast<qdesigner_internal::WidgetFactory*>(core()->widgetFactory());
+ Q_ASSERT(factory != 0);
+
+ QDesignerFormWindowInterface *previousFormWindow = factory->currentFormWindow(m_formWindow);
+
+ m_isMainWidget = true;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ QWidget *mainWidget = QAbstractFormBuilder::create(ui, parentWidget);
+
+ if (mainWidget && m_formWindow) {
+ m_formWindow->setAuthor(ui->elementAuthor());
+ m_formWindow->setComment(ui->elementComment());
+ m_formWindow->setExportMacro(ui->elementExportMacro());
+
+ // Designer data
+ QVariantMap designerFormData;
+ if (ui->hasElementDesignerdata()) {
+ const DomPropertyList domPropertyList = ui->elementDesignerdata()->elementProperty();
+ const DomPropertyList::const_iterator cend = domPropertyList.constEnd();
+ for (DomPropertyList::const_iterator it = domPropertyList.constBegin(); it != cend; ++it) {
+ const QVariant vprop = domPropertyToVariant(this, mainWidget->metaObject(), *it);
+ if (vprop.type() != QVariant::Invalid)
+ designerFormData.insert((*it)->attributeName(), vprop);
+ }
+ }
+ m_formWindow->setFormData(designerFormData);
+
+ m_formWindow->setPixmapFunction(ui->elementPixmapFunction());
+
+ if (DomLayoutDefault *def = ui->elementLayoutDefault()) {
+ m_formWindow->setLayoutDefault(def->attributeMargin(), def->attributeSpacing());
+ }
+
+ if (DomLayoutFunction *fun = ui->elementLayoutFunction()) {
+ m_formWindow->setLayoutFunction(fun->attributeMargin(), fun->attributeSpacing());
+ }
+
+ if (DomIncludes *includes = ui->elementIncludes()) {
+ const QString global = QLatin1String("global");
+ QStringList includeHints;
+ foreach (DomInclude *incl, includes->elementInclude()) {
+ QString text = incl->text();
+
+ if (text.isEmpty())
+ continue;
+
+ if (incl->hasAttributeLocation() && incl->attributeLocation() == global ) {
+ text = text.prepend(QLatin1Char('<')).append(QLatin1Char('>'));
+ } else {
+ text = text.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
+ }
+
+ includeHints.append(text);
+ }
+
+ m_formWindow->setIncludeHints(includeHints);
+ }
+
+ // Register all button groups the form builder adds as children of the main container for them to be found
+ // in the signal slot editor
+ const QObjectList mchildren = mainWidget->children();
+ if (!mchildren.empty()) {
+ QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
+ const QObjectList::const_iterator cend = mchildren.constEnd();
+ for (QObjectList::const_iterator it = mchildren.constBegin(); it != cend; ++it)
+ if (QButtonGroup *bg = qobject_cast<QButtonGroup*>(*it))
+ mdb->add(bg);
+ }
+ // Load tools
+ for (int index = 0; index < m_formWindow->toolCount(); ++index) {
+ QDesignerFormWindowToolInterface *tool = m_formWindow->tool(index);
+ Q_ASSERT(tool != 0);
+ tool->loadFromDom(ui, mainWidget);
+ }
+ }
+
+ factory->currentFormWindow(previousFormWindow);
+
+ if (const DomSlots *domSlots = ui->elementSlots()) {
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ QStringList fakeSlots;
+ QStringList fakeSignals;
+ if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
+ MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(mainWidget);
+ item->setFakeSlots(fakeSlots);
+ item->setFakeSignals(fakeSignals);
+ }
+ }
+ }
+ if (mainWidget) {
+ // Initialize the mainwindow geometry. Has it been explicitly specified?
+ bool hasExplicitGeometry = false;
+ const QList<DomProperty *> properties = ui->elementWidget()->elementProperty();
+ if (!properties.empty()) {
+ const QString geometry = QLatin1String("geometry");
+ foreach (const DomProperty *p, properties)
+ if (p->attributeName() == geometry) {
+ hasExplicitGeometry = true;
+ break;
+ }
+ }
+ if (hasExplicitGeometry) {
+ // Geometry was specified explicitly: Verify that smartMinSize is respected
+ // (changed fonts, label wrapping policies, etc). This does not happen automatically in docked mode.
+ const QSize size = mainWidget->size();
+ const QSize minSize = size.expandedTo(qSmartMinSize(mainWidget));
+ if (minSize != size)
+ mainWidget->resize(minSize);
+ } else {
+ // No explicit Geometry: perform an adjustSize() to resize the form correctly before embedding it into a container
+ // (which might otherwise squeeze the form)
+ mainWidget->adjustSize();
+ }
+ // Some integration wizards create forms with main containers
+ // based on derived classes of QWidget and load them into Designer
+ // without the plugin existing. This will trigger the auto-promotion
+ // mechanism of Designer, which will set container=false for
+ // QWidgets. For the main container, force container=true and warn.
+ const QDesignerWidgetDataBaseInterface *wdb = core()->widgetDataBase();
+ const int wdbIndex = wdb->indexOfObject(mainWidget);
+ if (wdbIndex != -1) {
+ QDesignerWidgetDataBaseItemInterface *item = wdb->item(wdbIndex);
+ // Promoted main container that is not of container type
+ if (item->isPromoted() && !item->isContainer()) {
+ item->setContainer(true);
+ qWarning("** WARNING The form's main container is an unknown custom widget '%s'."
+ " Defaulting to a promoted instance of '%s', assuming container.",
+ item->name().toUtf8().constData(), item->extends().toUtf8().constData());
+ }
+ }
+ }
+ return mainWidget;
+}
+
+QWidget *QDesignerResource::create(DomWidget *ui_widget, QWidget *parentWidget)
+{
+ const QString className = ui_widget->attributeClass();
+ if (!m_isMainWidget && className == QLatin1String("QWidget") && ui_widget->elementLayout().size() &&
+ !ui_widget->hasAttributeNative()) {
+ // ### check if elementLayout.size() == 1
+
+ QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget);
+
+ if (container == 0) {
+ // generate a QLayoutWidget iff the parent is not an QDesignerContainerExtension.
+ ui_widget->setAttributeClass(QLatin1String("QLayoutWidget"));
+ }
+ }
+
+ // save the actions
+ const QList<DomActionRef*> actionRefs = ui_widget->elementAddAction();
+ ui_widget->setElementAddAction(QList<DomActionRef*>());
+
+ QWidget *w = QAbstractFormBuilder::create(ui_widget, parentWidget);
+
+ // restore the actions
+ ui_widget->setElementAddAction(actionRefs);
+
+ if (w == 0)
+ return 0;
+
+ // ### generalize using the extension manager
+ QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(w);
+ QDesignerMenuBar *menuBar = qobject_cast<QDesignerMenuBar*>(w);
+
+ if (menu) {
+ menu->interactive(false);
+ menu->hide();
+ } else if (menuBar) {
+ menuBar->interactive(false);
+ }
+
+ foreach (DomActionRef *ui_action_ref, actionRefs) {
+ const QString name = ui_action_ref->attributeName();
+ if (name == QLatin1String("separator")) {
+ QAction *sep = new QAction(w);
+ sep->setSeparator(true);
+ w->addAction(sep);
+ addMenuAction(sep);
+ } else if (QAction *a = m_actions.value(name)) {
+ w->addAction(a);
+ } else if (QActionGroup *g = m_actionGroups.value(name)) {
+ w->addActions(g->actions());
+ } else if (QMenu *menu = qFindChild<QMenu*>(w, name)) {
+ w->addAction(menu->menuAction());
+ addMenuAction(menu->menuAction());
+ }
+ }
+
+ if (menu) {
+ menu->interactive(true);
+ menu->adjustSpecialActions();
+ } else if (menuBar) {
+ menuBar->interactive(true);
+ menuBar->adjustSpecialActions();
+ }
+
+ ui_widget->setAttributeClass(className); // fix the class name
+ applyExtensionDataFromDOM(this, core(), ui_widget, w, true);
+
+ // store user-defined scripts
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ const QString designerSource = QLatin1String("designer");
+ const DomScripts domScripts = ui_widget->elementScript();
+ if (!domScripts.empty()) {
+ foreach (const DomScript *script, domScripts) {
+ if (script->hasAttributeSource() && script->attributeSource() == designerSource) {
+ metaDataBase->metaDataBaseItem(w)->setScript(script->text());
+ }
+ }
+ }
+ }
+
+ return w;
+}
+
+QLayout *QDesignerResource::create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget)
+{
+ QLayout *l = QAbstractFormBuilder::create(ui_layout, layout, parentWidget);
+
+ if (QGridLayout *gridLayout = qobject_cast<QGridLayout*>(l)) {
+ QLayoutSupport::createEmptyCells(gridLayout);
+ } else {
+ if (QFormLayout *formLayout = qobject_cast<QFormLayout*>(l))
+ QLayoutSupport::createEmptyCells(formLayout);
+ }
+ // While the actual values are applied by the form builder, we still need
+ // to mark them as 'changed'.
+ LayoutPropertySheet::markChangedStretchProperties(core(), l, ui_layout);
+ return l;
+}
+
+QLayoutItem *QDesignerResource::create(DomLayoutItem *ui_layoutItem, QLayout *layout, QWidget *parentWidget)
+{
+ if (ui_layoutItem->kind() == DomLayoutItem::Spacer) {
+ const DomSpacer *domSpacer = ui_layoutItem->elementSpacer();
+ const QHash<QString, DomProperty*> properties = propertyMap(domSpacer->elementProperty());
+ Spacer *spacer = static_cast<Spacer*>(core()->widgetFactory()->createWidget(QLatin1String("Spacer"), parentWidget));
+ if (domSpacer->hasAttributeName())
+ changeObjectName(spacer, domSpacer->attributeName());
+ core()->metaDataBase()->add(spacer);
+
+ spacer->setInteractiveMode(false);
+ applyProperties(spacer, ui_layoutItem->elementSpacer()->elementProperty());
+ spacer->setInteractiveMode(true);
+
+ if (m_formWindow) {
+ m_formWindow->manageWidget(spacer);
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), spacer))
+ sheet->setChanged(sheet->indexOf(QLatin1String("orientation")), true);
+ }
+
+ return new QWidgetItem(spacer);
+ } else if (ui_layoutItem->kind() == DomLayoutItem::Layout && parentWidget) {
+ DomLayout *ui_layout = ui_layoutItem->elementLayout();
+ QLayoutWidget *layoutWidget = new QLayoutWidget(m_formWindow, parentWidget);
+ core()->metaDataBase()->add(layoutWidget);
+ if (m_formWindow)
+ m_formWindow->manageWidget(layoutWidget);
+ (void) create(ui_layout, 0, layoutWidget);
+ return new QWidgetItem(layoutWidget);
+ }
+ return QAbstractFormBuilder::create(ui_layoutItem, layout, parentWidget);
+}
+
+void QDesignerResource::changeObjectName(QObject *o, QString objName)
+{
+ m_formWindow->unify(o, objName, true);
+ o->setObjectName(objName);
+
+}
+
+/* If the property is a enum or flag value, retrieve
+ * the existing enum/flag via property sheet and use it to convert */
+
+static bool readDomEnumerationValue(const DomProperty *p,
+ const QDesignerPropertySheetExtension* sheet, int index,
+ QVariant &v)
+{
+ switch (p->kind()) {
+ case DomProperty::Set: {
+ const QVariant sheetValue = sheet->property(index);
+ if (qVariantCanConvert<PropertySheetFlagValue>(sheetValue)) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(sheetValue);
+ bool ok = false;
+ v = f.metaFlags.parseFlags(p->elementSet(), &ok);
+ if (!ok)
+ designerWarning(f.metaFlags.messageParseFailed(p->elementSet()));
+ return true;
+ }
+ }
+ break;
+ case DomProperty::Enum: {
+ const QVariant sheetValue = sheet->property(index);
+ if (qVariantCanConvert<PropertySheetEnumValue>(sheetValue)) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(sheetValue);
+ bool ok = false;
+ v = e.metaEnum.parseEnum(p->elementEnum(), &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageParseFailed(p->elementEnum()));
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QDesignerResource::applyProperties(QObject *o, const QList<DomProperty*> &properties)
+{
+ if (properties.empty())
+ return;
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
+ if (!sheet)
+ return;
+
+ QFormBuilderExtra *formBuilderExtra = QFormBuilderExtra::instance(this);
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), o);
+ const bool dynamicPropertiesAllowed = dynamicSheet && dynamicSheet->dynamicPropertiesAllowed();
+
+ const QString objectNameProperty = QLatin1String("objectName");
+ const DomPropertyList::const_iterator cend = properties.constEnd();
+ for (DomPropertyList::const_iterator it = properties.constBegin(); it != cend; ++it) {
+ const DomProperty *p = *it;
+ const QString propertyName = p->attributeName();
+ const int index = sheet->indexOf(propertyName);
+ QVariant v;
+ if (!readDomEnumerationValue(p, sheet, index, v))
+ v = toVariant(o->metaObject(), *it);
+
+ if (p->kind() == DomProperty::String) {
+ if (index != -1 && sheet->property(index).userType() == qMetaTypeId<PropertySheetKeySequenceValue>()) {
+ const DomString *key = p->elementString();
+ PropertySheetKeySequenceValue keyVal(QKeySequence(key->text()));
+ if (key->hasAttributeComment())
+ keyVal.setDisambiguation(key->attributeComment());
+ if (key->hasAttributeExtraComment())
+ keyVal.setComment(key->attributeExtraComment());
+ if (key->hasAttributeNotr()) {
+ const QString notr = key->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ keyVal.setTranslatable(translatable);
+ }
+ v = qVariantFromValue(keyVal);
+ } else {
+ const DomString *str = p->elementString();
+ PropertySheetStringValue strVal(v.toString());
+ if (str->hasAttributeComment())
+ strVal.setDisambiguation(str->attributeComment());
+ if (str->hasAttributeExtraComment())
+ strVal.setComment(str->attributeExtraComment());
+ if (str->hasAttributeNotr()) {
+ const QString notr = str->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ strVal.setTranslatable(translatable);
+ }
+ v = qVariantFromValue(strVal);
+ }
+ }
+
+ formBuilderExtra->applyPropertyInternally(o, propertyName, v);
+ if (index != -1) {
+ sheet->setProperty(index, v);
+ sheet->setChanged(index, true);
+ } else if (dynamicPropertiesAllowed) {
+ QVariant defaultValue = QVariant(v.type());
+ bool isDefault = (v == defaultValue);
+ if (qVariantCanConvert<PropertySheetIconValue>(v)) {
+ defaultValue = QVariant(QVariant::Icon);
+ isDefault = (qVariantValue<PropertySheetIconValue>(v) == PropertySheetIconValue());
+ } else if (qVariantCanConvert<PropertySheetPixmapValue>(v)) {
+ defaultValue = QVariant(QVariant::Pixmap);
+ isDefault = (qVariantValue<PropertySheetPixmapValue>(v) == PropertySheetPixmapValue());
+ } else if (qVariantCanConvert<PropertySheetStringValue>(v)) {
+ defaultValue = QVariant(QVariant::String);
+ isDefault = (qVariantValue<PropertySheetStringValue>(v) == PropertySheetStringValue());
+ } else if (qVariantCanConvert<PropertySheetKeySequenceValue>(v)) {
+ defaultValue = QVariant(QVariant::KeySequence);
+ isDefault = (qVariantValue<PropertySheetKeySequenceValue>(v) == PropertySheetKeySequenceValue());
+ }
+ if (defaultValue.type() != QVariant::UserType) {
+ const int idx = dynamicSheet->addDynamicProperty(p->attributeName(), defaultValue);
+ if (idx != -1) {
+ sheet->setProperty(idx, v);
+ sheet->setChanged(idx, !isDefault);
+ }
+ }
+ }
+
+ if (propertyName == objectNameProperty)
+ changeObjectName(o, o->objectName());
+ }
+}
+
+QWidget *QDesignerResource::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &_name)
+{
+ QString name = _name;
+ QString className = widgetName;
+ if (m_isMainWidget)
+ m_isMainWidget = false;
+
+ QWidget *w = core()->widgetFactory()->createWidget(className, parentWidget);
+ if (!w)
+ return 0;
+
+ if (name.isEmpty()) {
+ QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ if (QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(w)))
+ name = qtify(item->name());
+ }
+
+ changeObjectName(w, name);
+
+ QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget);
+ if (!qobject_cast<QMenu*>(w) && (!parentWidget || !container)) {
+ m_formWindow->manageWidget(w);
+ if (parentWidget) {
+ QList<QWidget *> list = qVariantValue<QWidgetList>(parentWidget->property("_q_widgetOrder"));
+ list.append(w);
+ parentWidget->setProperty("_q_widgetOrder", qVariantFromValue(list));
+ QList<QWidget *> zOrder = qVariantValue<QWidgetList>(parentWidget->property("_q_zOrder"));
+ zOrder.append(w);
+ parentWidget->setProperty("_q_zOrder", qVariantFromValue(list));
+ }
+ } else {
+ core()->metaDataBase()->add(w);
+ }
+
+ w->setWindowFlags(w->windowFlags() & ~Qt::Window);
+ // Make sure it is non-modal (for example, KDialog calls setModal(true) in the constructor).
+ w->setWindowModality(Qt::NonModal);
+
+ return w;
+}
+
+QLayout *QDesignerResource::createLayout(const QString &layoutName, QObject *parent, const QString &name)
+{
+ QWidget *layoutBase = 0;
+ QLayout *layout = qobject_cast<QLayout*>(parent);
+
+ if (parent->isWidgetType())
+ layoutBase = static_cast<QWidget*>(parent);
+ else {
+ Q_ASSERT( layout != 0 );
+ layoutBase = layout->parentWidget();
+ }
+
+ LayoutInfo::Type layoutType = LayoutInfo::layoutType(layoutName);
+ if (layoutType == LayoutInfo::NoLayout) {
+ designerWarning(QCoreApplication::translate("QDesignerResource", "The layout type '%1' is not supported, defaulting to grid.").arg(layoutName));
+ layoutType = LayoutInfo::Grid;
+ }
+ QLayout *lay = core()->widgetFactory()->createLayout(layoutBase, layout, layoutType);
+ if (lay != 0)
+ changeObjectName(lay, name);
+
+ return lay;
+}
+
+// save
+DomWidget *QDesignerResource::createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive)
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(widget);
+ if (!item)
+ return 0;
+
+ if (qobject_cast<Spacer*>(widget) && m_copyWidget == false) {
+ ++m_topLevelSpacerCount;
+ return 0;
+ }
+
+ const QDesignerWidgetDataBaseInterface *wdb = core()->widgetDataBase();
+ QDesignerWidgetDataBaseItemInterface *widgetInfo = 0;
+ const int widgetInfoIndex = wdb->indexOfObject(widget, false);
+ if (widgetInfoIndex != -1) {
+ widgetInfo = wdb->item(widgetInfoIndex);
+ // Recursively add all dependent custom widgets
+ QDesignerWidgetDataBaseItemInterface *customInfo = widgetInfo;
+ while (customInfo && customInfo->isCustom()) {
+ m_usedCustomWidgets.insert(customInfo, true);
+ const QString extends = customInfo->extends();
+ if (extends == customInfo->name()) {
+ break; // There are faulty files around that have name==extends
+ } else {
+ const int extendsIndex = wdb->indexOfClassName(customInfo->extends());
+ customInfo = extendsIndex != -1 ? wdb->item(extendsIndex) : static_cast<QDesignerWidgetDataBaseItemInterface *>(0);
+ }
+ }
+ }
+
+ DomWidget *w = 0;
+
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(widget))
+ w = saveWidget(tabWidget, ui_parentWidget);
+ else if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(widget))
+ w = saveWidget(stackedWidget, ui_parentWidget);
+ else if (QToolBox *toolBox = qobject_cast<QToolBox*>(widget))
+ w = saveWidget(toolBox, ui_parentWidget);
+ else if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget))
+ w = saveWidget(toolBar, ui_parentWidget);
+ else if (QDesignerDockWidget *dockWidget = qobject_cast<QDesignerDockWidget*>(widget))
+ w = saveWidget(dockWidget, ui_parentWidget);
+ else if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget))
+ w = saveWidget(widget, container, ui_parentWidget);
+ else if (QTreeView *treeView = qobject_cast<QTreeView*>(widget))
+ w = saveWidget(treeView, ui_parentWidget);
+ else if (QTableView *tableView = qobject_cast<QTableView*>(widget))
+ w = saveWidget(tableView, ui_parentWidget);
+ else if (QWizardPage *wizardPage = qobject_cast<QWizardPage*>(widget))
+ w = saveWidget(wizardPage, ui_parentWidget);
+ else
+ w = QAbstractFormBuilder::createDom(widget, ui_parentWidget, recursive);
+
+ Q_ASSERT( w != 0 );
+
+ if (!qobject_cast<QLayoutWidget*>(widget) && w->attributeClass() == QLatin1String("QWidget")) {
+ w->setAttributeNative(true);
+ }
+
+ const QString className = w->attributeClass();
+ if (m_internal_to_qt.contains(className))
+ w->setAttributeClass(m_internal_to_qt.value(className));
+
+ w->setAttributeName(widget->objectName());
+
+ if (isPromoted( core(), widget)) { // is promoted?
+ Q_ASSERT(widgetInfo != 0);
+
+ w->setAttributeName(widget->objectName());
+ w->setAttributeClass(widgetInfo->name());
+
+ QList<DomProperty*> prop_list = w->elementProperty();
+ foreach (DomProperty *prop, prop_list) {
+ if (prop->attributeName() == QLatin1String("geometry")) {
+ if (DomRect *rect = prop->elementRect()) {
+ rect->setElementX(widget->x());
+ rect->setElementY(widget->y());
+ }
+ break;
+ }
+ }
+ } else if (widgetInfo != 0 && m_usedCustomWidgets.contains(widgetInfo)) {
+ if (widgetInfo->name() != w->attributeClass())
+ w->setAttributeClass(widgetInfo->name());
+ }
+ addExtensionDataToDOM(this, core(), w, widget);
+
+ addUserDefinedScripts(widget, w);
+ return w;
+}
+
+DomLayout *QDesignerResource::createDom(QLayout *layout, DomLayout *ui_parentLayout, DomWidget *ui_parentWidget)
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(layout);
+
+ if (item == 0) {
+ layout = qFindChild<QLayout*>(layout);
+ // refresh the meta database item
+ item = core()->metaDataBase()->item(layout);
+ }
+
+ if (item == 0) {
+ // nothing to do.
+ return 0;
+ }
+
+ if (qobject_cast<QSplitter*>(layout->parentWidget()) != 0) {
+ // nothing to do.
+ return 0;
+ }
+
+ m_chain.push(layout);
+
+ DomLayout *l = QAbstractFormBuilder::createDom(layout, ui_parentLayout, ui_parentWidget);
+ Q_ASSERT(l != 0);
+ LayoutPropertySheet::stretchAttributesToDom(core(), layout, l);
+
+ m_chain.pop();
+
+ return l;
+}
+
+DomLayoutItem *QDesignerResource::createDom(QLayoutItem *item, DomLayout *ui_layout, DomWidget *ui_parentWidget)
+{
+ DomLayoutItem *ui_item = 0;
+
+ if (Spacer *s = qobject_cast<Spacer*>(item->widget())) {
+ if (!core()->metaDataBase()->item(s))
+ return 0;
+
+ DomSpacer *spacer = new DomSpacer();
+ const QString objectName = s->objectName();
+ if (!objectName.isEmpty())
+ spacer->setAttributeName(objectName);
+ const QList<DomProperty*> properties = computeProperties(item->widget());
+ // ### filter the properties
+ spacer->setElementProperty(properties);
+
+ ui_item = new DomLayoutItem();
+ ui_item->setElementSpacer(spacer);
+ m_laidout.insert(item->widget(), true);
+ } else if (QLayoutWidget *layoutWidget = qobject_cast<QLayoutWidget*>(item->widget())) {
+ // Do not save a QLayoutWidget if it is within a layout (else it is saved as "QWidget"
+ Q_ASSERT(layoutWidget->layout());
+ DomLayout *l = createDom(layoutWidget->layout(), ui_layout, ui_parentWidget);
+ ui_item = new DomLayoutItem();
+ ui_item->setElementLayout(l);
+ m_laidout.insert(item->widget(), true);
+ } else if (!item->spacerItem()) { // we use spacer as fake item in the Designer
+ ui_item = QAbstractFormBuilder::createDom(item, ui_layout, ui_parentWidget);
+ } else {
+ return 0;
+ }
+
+ if (m_chain.size() && item->widget()) {
+ if (QGridLayout *grid = qobject_cast<QGridLayout*>(m_chain.top())) {
+ const int index = Utils::indexOfWidget(grid, item->widget());
+
+ int row, column, rowspan, colspan;
+ grid->getItemPosition(index, &row, &column, &rowspan, &colspan);
+ ui_item->setAttributeRow(row);
+ ui_item->setAttributeColumn(column);
+
+ if (colspan != 1)
+ ui_item->setAttributeColSpan(colspan);
+
+ if (rowspan != 1)
+ ui_item->setAttributeRowSpan(rowspan);
+ } else {
+ if (QFormLayout *form = qobject_cast<QFormLayout*>(m_chain.top())) {
+ const int index = Utils::indexOfWidget(form, item->widget());
+ int row, column, colspan;
+ getFormLayoutItemPosition(form, index, &row, &column, 0, &colspan);
+ ui_item->setAttributeRow(row);
+ ui_item->setAttributeColumn(column);
+ if (colspan != 1)
+ ui_item->setAttributeColSpan(colspan);
+ }
+ }
+ }
+
+ return ui_item;
+}
+
+static void addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item)
+{
+ const DomSlots *domSlots = domCustomWidget->elementSlots();
+ if (!domSlots)
+ return;
+
+ // Merge in new slots, signals
+ QStringList fakeSlots = item->fakeSlots();
+ QStringList fakeSignals = item->fakeSignals();
+ if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
+ item->setFakeSlots(fakeSlots);
+ item->setFakeSignals(fakeSignals);
+ }
+}
+
+void QDesignerResource::addCustomWidgetsToWidgetDatabase(DomCustomWidgetList& custom_widget_list)
+{
+ // Perform one iteration of adding the custom widgets to the database,
+ // looking up the base class and inheriting its data.
+ // Remove the succeeded custom widgets from the list.
+ // Classes whose base class could not be found are left in the list.
+ QDesignerWidgetDataBaseInterface *db = m_formWindow->core()->widgetDataBase();
+ for (int i=0; i < custom_widget_list.size(); ) {
+ bool classInserted = false;
+ DomCustomWidget *custom_widget = custom_widget_list[i];
+ const QString customClassName = custom_widget->elementClass();
+ const QString base_class = custom_widget->elementExtends();
+ QString includeFile;
+ IncludeType includeType = IncludeLocal;
+ if (const DomHeader *header = custom_widget->elementHeader()) {
+ includeFile = header->text();
+ if (header->hasAttributeLocation() && header->attributeLocation() == QLatin1String("global"))
+ includeType = IncludeGlobal;
+ }
+ const bool domIsContainer = custom_widget->elementContainer();
+ // Append a new item
+ if (base_class.isEmpty()) {
+ WidgetDataBaseItem *item = new WidgetDataBaseItem(customClassName);
+ item->setPromoted(false);
+ item->setGroup(QApplication::translate("Designer", "Custom Widgets"));
+ item->setIncludeFile(buildIncludeFile(includeFile, includeType));
+ item->setContainer(domIsContainer);
+ item->setCustom(true);
+ addFakeMethodsToWidgetDataBase(custom_widget, item);
+ db->append(item);
+ custom_widget_list.removeAt(i);
+ classInserted = true;
+ } else {
+ // Create a new entry cloned from base class. Note that this will ignore existing
+ // classes, eg, plugin custom widgets.
+ QDesignerWidgetDataBaseItemInterface *item =
+ appendDerived(db, customClassName, QApplication::translate("Designer", "Promoted Widgets"),
+ base_class,
+ buildIncludeFile(includeFile, includeType),
+ true,true);
+ // Ok, base class found.
+ if (item) {
+ // Hack to accommodate for old UI-files in which "contains" is not set properly:
+ // Apply "contains" from DOM only if true (else, eg classes from QFrame might not accept
+ // dropping child widgets on them as container=false). This also allows for
+ // QWidget-derived stacked pages.
+ if (domIsContainer)
+ item->setContainer(domIsContainer);
+
+ addFakeMethodsToWidgetDataBase(custom_widget, static_cast<WidgetDataBaseItem*>(item));
+ custom_widget_list.removeAt(i);
+ classInserted = true;
+ }
+ }
+ // Skip failed item.
+ if (!classInserted)
+ i++;
+ }
+
+}
+void QDesignerResource::createCustomWidgets(DomCustomWidgets *dom_custom_widgets)
+{
+ if (dom_custom_widgets == 0)
+ return;
+ DomCustomWidgetList custom_widget_list = dom_custom_widgets->elementCustomWidget();
+ // Attempt to insert each item derived from its base class.
+ // This should at most require two iterations in the event that the classes are out of order
+ // (derived first, max depth: promoted custom plugin = 2)
+ for (int iteration = 0; iteration < 2; iteration++) {
+ addCustomWidgetsToWidgetDatabase(custom_widget_list);
+ if (custom_widget_list.empty())
+ return;
+ }
+ // Oops, there are classes left whose base class could not be found.
+ // Default them to QWidget with warnings.
+ const QString fallBackBaseClass = QLatin1String("QWidget");
+ for (int i=0; i < custom_widget_list.size(); i++ ) {
+ DomCustomWidget *custom_widget = custom_widget_list[i];
+ const QString customClassName = custom_widget->elementClass();
+ const QString base_class = custom_widget->elementExtends();
+ qDebug() << "** WARNING The base class " << base_class << " of the custom widget class " << customClassName
+ << " could not be found. Defaulting to " << fallBackBaseClass << '.';
+ custom_widget->setElementExtends(fallBackBaseClass);
+ }
+ // One more pass.
+ addCustomWidgetsToWidgetDatabase(custom_widget_list);
+ Q_ASSERT(custom_widget_list.empty());
+}
+
+DomTabStops *QDesignerResource::saveTabStops()
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(m_formWindow);
+ Q_ASSERT(item);
+
+ QStringList tabStops;
+ foreach (QWidget *widget, item->tabOrder()) {
+ if (m_formWindow->mainContainer()->isAncestorOf(widget))
+ tabStops.append(widget->objectName());
+ }
+
+ if (tabStops.count()) {
+ DomTabStops *dom = new DomTabStops;
+ dom->setElementTabStop(tabStops);
+ return dom;
+ }
+
+ return 0;
+}
+
+void QDesignerResource::applyTabStops(QWidget *widget, DomTabStops *tabStops)
+{
+ if (!tabStops)
+ return;
+
+ QList<QWidget*> tabOrder;
+ foreach (QString widgetName, tabStops->elementTabStop()) {
+ if (QWidget *w = qFindChild<QWidget*>(widget, widgetName)) {
+ tabOrder.append(w);
+ }
+ }
+
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(m_formWindow);
+ Q_ASSERT(item);
+ item->setTabOrder(tabOrder);
+}
+
+/* Unmanaged container pages occur when someone adds a page in a custom widget
+ * constructor. They don't have a meta DB entry which causes createDom
+ * to return 0. */
+inline QString msgUnmanagedPage(QDesignerFormEditorInterface *core,
+ QWidget *container, int index, QWidget *page)
+{
+ return QCoreApplication::translate("QDesignerResource",
+"The container extension of the widget '%1' (%2) returned a widget not managed by Designer '%3' (%4) when queried for page #%5.\n"
+"Container pages should only be added by specifying them in XML returned by the domXml() method of the custom widget.").
+ arg(container->objectName(), WidgetFactory::classNameOf(core, container),
+ page->objectName(), WidgetFactory::classNameOf(core, page)).
+ arg(index);
+}
+
+DomWidget *QDesignerResource::saveWidget(QWidget *widget, QDesignerContainerExtension *container, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ if (DomWidget *ui_page = createDom(page, ui_widget)) {
+ ui_widget_list.append(ui_page);
+ } else {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ }
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QStackedWidget *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+ if (DomWidget *ui_page = createDom(page, ui_widget)) {
+ ui_widget_list.append(ui_page);
+ } else {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ }
+ }
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QToolBar *toolBar, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(toolBar, ui_parentWidget, false);
+ if (const QMainWindow *mainWindow = qobject_cast<QMainWindow*>(toolBar->parentWidget())) {
+ const bool toolBarBreak = mainWindow->toolBarBreak(toolBar);
+ const Qt::ToolBarArea area = mainWindow->toolBarArea(toolBar);
+
+ QList<DomProperty*> attributes = ui_widget->elementAttribute();
+
+ DomProperty *attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("toolBarArea"));
+ attr->setElementEnum(QLatin1String(toolBarAreaMetaEnum().valueToKey(area)));
+ attributes << attr;
+
+ attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("toolBarBreak"));
+ attr->setElementBool(toolBarBreak ? QLatin1String("true") : QLatin1String("false"));
+ attributes << attr;
+ ui_widget->setElementAttribute(attributes);
+ }
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QDesignerDockWidget *dockWidget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(dockWidget, ui_parentWidget, true);
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(dockWidget->parentWidget())) {
+ const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(dockWidget);
+ DomProperty *attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("dockWidgetArea"));
+ attr->setElementNumber(int(area));
+ ui_widget->setElementAttribute(ui_widget->elementAttribute() << attr);
+ }
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QTreeView *treeView, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(treeView, ui_parentWidget, true);
+
+ QDesignerPropertySheetExtension *sheet
+ = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), treeView);
+ ItemViewPropertySheet *itemViewSheet = static_cast<ItemViewPropertySheet*>(sheet);
+
+ if (itemViewSheet) {
+ QHash<QString,QString> nameMap = itemViewSheet->propertyNameMap();
+ foreach (const QString &fakeName, nameMap.keys()) {
+ int index = itemViewSheet->indexOf(fakeName);
+ if (sheet->isChanged(index)) {
+ DomProperty *domAttr = createProperty(treeView->header(), nameMap.value(fakeName),
+ itemViewSheet->property(index));
+ domAttr->setAttributeName(fakeName);
+ ui_widget->setElementAttribute(ui_widget->elementAttribute() << domAttr);
+ }
+ }
+ }
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QTableView *tableView, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(tableView, ui_parentWidget, true);
+
+ QDesignerPropertySheetExtension *sheet
+ = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), tableView);
+ ItemViewPropertySheet *itemViewSheet = static_cast<ItemViewPropertySheet*>(sheet);
+
+ if (itemViewSheet) {
+ QHash<QString,QString> nameMap = itemViewSheet->propertyNameMap();
+ foreach (const QString &fakeName, nameMap.keys()) {
+ int index = itemViewSheet->indexOf(fakeName);
+ if (sheet->isChanged(index)) {
+ DomProperty *domAttr;
+ if (fakeName.startsWith(QLatin1String("horizontal"))) {
+ domAttr = createProperty(tableView->horizontalHeader(), nameMap.value(fakeName),
+ itemViewSheet->property(index));
+ } else {
+ domAttr = createProperty(tableView->verticalHeader(), nameMap.value(fakeName),
+ itemViewSheet->property(index));
+ }
+ domAttr->setAttributeName(fakeName);
+ ui_widget->setElementAttribute(ui_widget->elementAttribute() << domAttr);
+ }
+ }
+ }
+
+ return ui_widget;
+}
+
+static void saveStringProperty(DomProperty *property, const PropertySheetStringValue &value)
+{
+ DomString *str = new DomString();
+ str->setText(value.value());
+
+ const QString property_comment = value.disambiguation();
+ if (!property_comment.isEmpty())
+ str->setAttributeComment(property_comment);
+ const QString property_extraComment = value.comment();
+ if (!property_extraComment.isEmpty())
+ str->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = value.translatable();
+ if (!property_translatable)
+ str->setAttributeNotr(QLatin1String("true"));
+
+ property->setElementString(str);
+}
+
+static void saveKeySequenceProperty(DomProperty *property, const PropertySheetKeySequenceValue &value)
+{
+ DomString *str = new DomString();
+ str->setText(value.value().toString());
+
+ const QString property_comment = value.disambiguation();
+ if (!property_comment.isEmpty())
+ str->setAttributeComment(property_comment);
+ const QString property_extraComment = value.comment();
+ if (!property_extraComment.isEmpty())
+ str->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = value.translatable();
+ if (!property_translatable)
+ str->setAttributeNotr(QLatin1String("true"));
+
+ property->setElementString(str);
+}
+
+DomWidget *QDesignerResource::saveWidget(QTabWidget *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int current = widget->currentIndex();
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ DomWidget *ui_page = createDom(page, ui_widget);
+ if (!ui_page) {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ continue;
+ }
+ QList<DomProperty*> ui_attribute_list;
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+ // attribute `icon'
+ widget->setCurrentIndex(i);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ PropertySheetIconValue icon = qVariantValue<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String("currentTabIcon"))));
+ DomProperty *p = resourceBuilder()->saveResource(workingDirectory(), qVariantFromValue(icon));
+ if (p) {
+ p->setAttributeName(strings.iconAttribute);
+ ui_attribute_list.append(p);
+ }
+ // attribute `title'
+ p = textBuilder()->saveText(sheet->property(sheet->indexOf(QLatin1String("currentTabText"))));
+ if (p) {
+ p->setAttributeName(strings.titleAttribute);
+ ui_attribute_list.append(p);
+ }
+
+ // attribute `toolTip'
+ QVariant v = sheet->property(sheet->indexOf(QLatin1String("currentTabToolTip")));
+ if (!qVariantValue<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.toolTipAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ // attribute `whatsThis'
+ v = sheet->property(sheet->indexOf(QLatin1String("currentTabWhatsThis")));
+ if (!qVariantValue<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.whatsThisAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ ui_page->setElementAttribute(ui_attribute_list);
+
+ ui_widget_list.append(ui_page);
+ }
+ widget->setCurrentIndex(current);
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QToolBox *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int current = widget->currentIndex();
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ DomWidget *ui_page = createDom(page, ui_widget);
+ if (!ui_page) {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ continue;
+ }
+
+ // attribute `label'
+ QList<DomProperty*> ui_attribute_list;
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ // attribute `icon'
+ widget->setCurrentIndex(i);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ PropertySheetIconValue icon = qVariantValue<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String("currentItemIcon"))));
+ DomProperty *p = resourceBuilder()->saveResource(workingDirectory(), qVariantFromValue(icon));
+ if (p) {
+ p->setAttributeName(strings.iconAttribute);
+ ui_attribute_list.append(p);
+ }
+ p = textBuilder()->saveText(sheet->property(sheet->indexOf(QLatin1String("currentItemText"))));
+ if (p) {
+ p->setAttributeName(strings.labelAttribute);
+ ui_attribute_list.append(p);
+ }
+
+ // attribute `toolTip'
+ QVariant v = sheet->property(sheet->indexOf(QLatin1String("currentItemToolTip")));
+ if (!qVariantValue<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.toolTipAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ ui_page->setElementAttribute(ui_attribute_list);
+
+ ui_widget_list.append(ui_page);
+ }
+ widget->setCurrentIndex(current);
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QWizardPage *wizardPage, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(wizardPage, ui_parentWidget, true);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), wizardPage);
+ // Save the page id (string) attribute, append to existing attributes
+ const QString pageIdPropertyName = QLatin1String(QWizardPagePropertySheet::pageIdProperty);
+ const int pageIdIndex = sheet->indexOf(pageIdPropertyName);
+ if (pageIdIndex != -1 && sheet->isChanged(pageIdIndex)) {
+ DomProperty *property = variantToDomProperty(this, wizardPage->metaObject(), pageIdPropertyName, sheet->property(pageIdIndex));
+ Q_ASSERT(property);
+ property->elementString()->setAttributeNotr(QLatin1String("true"));
+ DomPropertyList attributes = ui_widget->elementAttribute();
+ attributes.push_back(property);
+ ui_widget->setElementAttribute(attributes);
+ }
+ return ui_widget;
+}
+
+// Do not save the 'currentTabName' properties of containers
+static inline bool checkContainerProperty(const QWidget *w, const QString &propertyName)
+{
+ if (qobject_cast<const QToolBox *>(w))
+ return QToolBoxWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QTabWidget *>(w))
+ return QTabWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QStackedWidget *>(w))
+ return QStackedWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QMdiArea *>(w) || qobject_cast<const QWorkspace *>(w))
+ return QMdiAreaPropertySheet::checkProperty(propertyName);
+ return true;
+}
+
+bool QDesignerResource::checkProperty(QObject *obj, const QString &prop) const
+{
+ const QDesignerMetaObjectInterface *meta = core()->introspection()->metaObject(obj);
+
+ const int pindex = meta->indexOfProperty(prop);
+ if (pindex != -1 && !(meta->property(pindex)->attributes(obj) & QDesignerMetaPropertyInterface::StoredAttribute))
+ return false;
+
+ if (prop == QLatin1String("objectName") || prop == QLatin1String("spacerName")) // ### don't store the property objectName
+ return false;
+
+ QWidget *check_widget = 0;
+ if (obj->isWidgetType())
+ check_widget = static_cast<QWidget*>(obj);
+
+ if (check_widget && prop == QLatin1String("geometry")) {
+ if (check_widget == m_formWindow->mainContainer())
+ return true; // Save although maincontainer is technically laid-out by embedding container
+ if (m_selected && m_selected == check_widget)
+ return true;
+
+ return !LayoutInfo::isWidgetLaidout(core(), check_widget);
+ }
+
+ if (check_widget && !checkContainerProperty(check_widget, prop))
+ return false;
+
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), obj)) {
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), obj);
+ const int pindex = sheet->indexOf(prop);
+ if (sheet->isAttribute(pindex))
+ return false;
+
+ if (!dynamicSheet || !dynamicSheet->isDynamicProperty(pindex))
+ return sheet->isChanged(pindex);
+ if (!sheet->isVisible(pindex))
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
+bool QDesignerResource::addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout)
+{
+ if (item->widget() == 0) {
+ return false;
+ }
+
+ QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
+ QBoxLayout *box = qobject_cast<QBoxLayout*>(layout);
+
+ if (grid != 0) {
+ const int rowSpan = ui_item->hasAttributeRowSpan() ? ui_item->attributeRowSpan() : 1;
+ const int colSpan = ui_item->hasAttributeColSpan() ? ui_item->attributeColSpan() : 1;
+ grid->addWidget(item->widget(), ui_item->attributeRow(), ui_item->attributeColumn(), rowSpan, colSpan, item->alignment());
+ return true;
+ } else if (box != 0) {
+ box->addItem(item);
+ return true;
+ }
+
+ return QAbstractFormBuilder::addItem(ui_item, item, layout);
+}
+
+bool QDesignerResource::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ core()->metaDataBase()->add(widget); // ensure the widget is in the meta database
+
+ if (! QAbstractFormBuilder::addItem(ui_widget, widget, parentWidget) || qobject_cast<QMainWindow*> (parentWidget)) {
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget))
+ container->addWidget(widget);
+ }
+
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) {
+ const int tabIndex = tabWidget->count() - 1;
+ const int current = tabWidget->currentIndex();
+
+ tabWidget->setCurrentIndex(tabIndex);
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), parentWidget);
+ if (DomProperty *picon = attributes.value(strings.iconAttribute)) {
+ QVariant v = resourceBuilder()->loadResource(workingDirectory(), picon);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabIcon")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.titleAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabText")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.toolTipAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabToolTip")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.whatsThisAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabWhatsThis")), v);
+ }
+ tabWidget->setCurrentIndex(current);
+ } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) {
+ const int itemIndex = toolBox->count() - 1;
+ const int current = toolBox->currentIndex();
+
+ toolBox->setCurrentIndex(itemIndex);
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), parentWidget);
+ if (DomProperty *picon = attributes.value(strings.iconAttribute)) {
+ QVariant v = resourceBuilder()->loadResource(workingDirectory(), picon);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemIcon")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.labelAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemText")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.toolTipAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemToolTip")), v);
+ }
+ toolBox->setCurrentIndex(current);
+ }
+
+ return true;
+}
+
+bool QDesignerResource::copy(QIODevice *dev, const FormBuilderClipboard &selection)
+{
+ m_copyWidget = true;
+
+ DomUI *ui = copy(selection);
+
+ m_laidout.clear();
+ m_copyWidget = false;
+
+ if (!ui)
+ return false;
+
+ QXmlStreamWriter writer(dev);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ ui->write(writer);
+ writer.writeEndDocument();
+ delete ui;
+ return true;
+}
+
+DomUI *QDesignerResource::copy(const FormBuilderClipboard &selection)
+{
+ if (selection.empty())
+ return 0;
+
+ m_copyWidget = true;
+
+ DomWidget *ui_widget = new DomWidget();
+ ui_widget->setAttributeName(QLatin1String(clipboardObjectName));
+ bool hasItems = false;
+ // Widgets
+ if (!selection.m_widgets.empty()) {
+ QList<DomWidget*> ui_widget_list;
+ const int size = selection.m_widgets.size();
+ for (int i=0; i< size; ++i) {
+ QWidget *w = selection.m_widgets.at(i);
+ m_selected = w;
+ DomWidget *ui_child = createDom(w, ui_widget);
+ m_selected = 0;
+ if (ui_child)
+ ui_widget_list.append(ui_child);
+ }
+ if (!ui_widget_list.empty()) {
+ ui_widget->setElementWidget(ui_widget_list);
+ hasItems = true;
+ }
+ }
+ // actions
+ if (!selection.m_actions.empty()) {
+ QList<DomAction*> domActions;
+ foreach(QAction* action, selection.m_actions)
+ if (DomAction *domAction = createDom(action))
+ domActions += domAction;
+ if (!domActions.empty()) {
+ ui_widget-> setElementAction(domActions);
+ hasItems = true;
+ }
+ }
+
+ m_laidout.clear();
+ m_copyWidget = false;
+
+ if (!hasItems) {
+ delete ui_widget;
+ return 0;
+ }
+ // UI
+ DomUI *ui = new DomUI();
+ ui->setAttributeVersion(QLatin1String(currentUiVersion));
+ ui->setElementWidget(ui_widget);
+ ui->setElementResources(saveResources(m_resourceBuilder->usedQrcFiles()));
+ if (DomCustomWidgets *cws = saveCustomWidgets())
+ ui->setElementCustomWidgets(cws);
+ return ui;
+}
+
+FormBuilderClipboard QDesignerResource::paste(DomUI *ui, QWidget *widgetParent, QObject *actionParent)
+{
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ const int saved = m_isMainWidget;
+ m_isMainWidget = false;
+
+ FormBuilderClipboard rc;
+
+ // Widgets
+ const DomWidget *topLevel = ui->elementWidget();
+ initialize(ui);
+ const QList<DomWidget*> domWidgets = topLevel->elementWidget();
+ if (!domWidgets.empty()) {
+ const QPoint offset = m_formWindow->grid();
+ foreach (DomWidget* domWidget, domWidgets) {
+ if (QWidget *w = create(domWidget, widgetParent)) {
+ w->move(w->pos() + offset);
+ // ### change the init properties of w
+ rc.m_widgets.append(w);
+ }
+ }
+ }
+ const QList<DomAction*> domActions = topLevel->elementAction();
+ if (!domActions.empty())
+ foreach (DomAction *domAction, domActions)
+ if (QAction *a = create(domAction, actionParent))
+ rc.m_actions .append(a);
+
+ m_isMainWidget = saved;
+
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core()))
+ extra->loadUiExtraInfo(ui);
+
+ createResources(ui->elementResources());
+
+ return rc;
+}
+
+FormBuilderClipboard QDesignerResource::paste(QIODevice *dev, QWidget *widgetParent, QObject *actionParent)
+{
+ DomUI ui;
+ QXmlStreamReader reader(dev);
+ bool uiInitialized = false;
+
+ const QString uiElement = QLatin1String("ui");
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive)) {
+ ui.read(reader);
+ uiInitialized = true;
+ } else {
+ //: Parsing clipboard contents
+ reader.raiseError(QCoreApplication::translate("QDesignerResource", "Unexpected element <%1>").arg(reader.name().toString()));
+ }
+ }
+ }
+ if (reader.hasError()) {
+ //: Parsing clipboard contents
+ designerWarning(QCoreApplication::translate("QDesignerResource", "Error while pasting clipboard contents at line %1, column %2: %3")
+ .arg(reader.lineNumber()).arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ uiInitialized = false;
+ } else if (uiInitialized == false) {
+ //: Parsing clipboard contents
+ designerWarning(QCoreApplication::translate("QDesignerResource", "Error while pasting clipboard contents: The root element <ui> is missing."));
+ }
+
+ if (!uiInitialized)
+ return FormBuilderClipboard();
+
+ FormBuilderClipboard clipBoard = paste(&ui, widgetParent, actionParent);
+
+ return clipBoard;
+}
+
+void QDesignerResource::layoutInfo(DomLayout *layout, QObject *parent, int *margin, int *spacing)
+{
+ QAbstractFormBuilder::layoutInfo(layout, parent, margin, spacing);
+}
+
+DomCustomWidgets *QDesignerResource::saveCustomWidgets()
+{
+ if (m_usedCustomWidgets.isEmpty())
+ return 0;
+
+ // We would like the list to be in order of the widget database indexes
+ // to ensure that base classes come first (nice optics)
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ QDesignerWidgetDataBaseInterface *db = core->widgetDataBase();
+ const bool isInternalWidgetDataBase = qobject_cast<const WidgetDataBase *>(db);
+ typedef QMap<int,DomCustomWidget*> OrderedDBIndexDomCustomWidgetMap;
+ OrderedDBIndexDomCustomWidgetMap orderedMap;
+
+ const QString global = QLatin1String("global");
+ foreach (QDesignerWidgetDataBaseItemInterface *item, m_usedCustomWidgets.keys()) {
+ const QString name = item->name();
+ DomCustomWidget *custom_widget = new DomCustomWidget;
+
+ custom_widget->setElementClass(name);
+ if (item->isContainer())
+ custom_widget->setElementContainer(item->isContainer());
+
+ if (!item->includeFile().isEmpty()) {
+ DomHeader *header = new DomHeader;
+ const IncludeSpecification spec = includeSpecification(item->includeFile());
+ header->setText(spec.first);
+ if (spec.second == IncludeGlobal) {
+ header->setAttributeLocation(global);
+ }
+ custom_widget->setElementHeader(header);
+ custom_widget->setElementExtends(item->extends());
+ }
+
+ if (isInternalWidgetDataBase) {
+ WidgetDataBaseItem *internalItem = static_cast<WidgetDataBaseItem *>(item);
+ const QStringList fakeSlots = internalItem->fakeSlots();
+ const QStringList fakeSignals = internalItem->fakeSignals();
+ if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ DomSlots *domSlots = new DomSlots();
+ domSlots->setElementSlot(fakeSlots);
+ domSlots->setElementSignal(fakeSignals);
+ custom_widget->setElementSlots(domSlots);
+ }
+ const QString addPageMethod = internalItem->addPageMethod();
+ if (!addPageMethod.isEmpty())
+ custom_widget->setElementAddPageMethod(addPageMethod);
+ }
+
+ // Look up static per-class scripts of designer
+ if (DomScript *domScript = createScript(customWidgetScript(core, name), ScriptCustomWidgetPlugin))
+ custom_widget->setElementScript(domScript);
+
+ orderedMap.insert(db->indexOfClassName(name), custom_widget);
+ }
+
+ DomCustomWidgets *customWidgets = new DomCustomWidgets;
+ customWidgets->setElementCustomWidget(orderedMap.values());
+ return customWidgets;
+}
+
+bool QDesignerResource::canCompressMargins(QObject *object) const
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ if (qobject_cast<QLayout *>(object)) {
+ const int l = sheet->property(sheet->indexOf(QLatin1String("leftMargin"))).toInt();
+ const int t = sheet->property(sheet->indexOf(QLatin1String("topMargin"))).toInt();
+ const int r = sheet->property(sheet->indexOf(QLatin1String("rightMargin"))).toInt();
+ const int b = sheet->property(sheet->indexOf(QLatin1String("bottomMargin"))).toInt();
+ if (l == t && l == r && l == b)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QDesignerResource::canCompressSpacings(QObject *object) const
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ if (qobject_cast<QGridLayout *>(object)) {
+ const int h = sheet->property(sheet->indexOf(QLatin1String("horizontalSpacing"))).toInt();
+ const int v = sheet->property(sheet->indexOf(QLatin1String("verticalSpacing"))).toInt();
+ if (h == v)
+ return true;
+ }
+ }
+ return false;
+}
+
+QList<DomProperty*> QDesignerResource::computeProperties(QObject *object)
+{
+ QList<DomProperty*> properties;
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), object);
+ const int count = sheet->count();
+ QList<DomProperty *> marginProperties;
+ QList<DomProperty *> spacingProperties;
+ const bool compressMargins = canCompressMargins(object);
+ const bool compressSpacings = canCompressSpacings(object);
+ for (int index = 0; index < count; ++index) {
+ if (!sheet->isChanged(index) && (!dynamicSheet || !dynamicSheet->isDynamicProperty(index)))
+ continue;
+
+ const QString propertyName = sheet->propertyName(index);
+ // Suppress windowModality in legacy forms that have it set on child widgets
+ if (propertyName == QLatin1String("windowModality") && !sheet->isVisible(index))
+ continue;
+
+ const QVariant value = sheet->property(index);
+ if (DomProperty *p = createProperty(object, propertyName, value)) {
+ if (compressMargins && (propertyName == QLatin1String("leftMargin")
+ || propertyName == QLatin1String("rightMargin")
+ || propertyName == QLatin1String("topMargin")
+ || propertyName == QLatin1String("bottomMargin"))) {
+ marginProperties.append(p);
+ } else if (compressSpacings && (propertyName == QLatin1String("horizontalSpacing")
+ || propertyName == QLatin1String("verticalSpacing"))) {
+ spacingProperties.append(p);
+ } else {
+ properties.append(p);
+ }
+ }
+ }
+ if (compressMargins) {
+ if (marginProperties.count() == 4) { // if we have 3 it means one is reset so we can't compress
+ DomProperty *marginProperty = marginProperties.at(0);
+ marginProperty->setAttributeName(QLatin1String("margin"));
+ properties.append(marginProperty);
+ delete marginProperties.at(1);
+ delete marginProperties.at(2);
+ delete marginProperties.at(3);
+ } else {
+ properties += marginProperties;
+ }
+ }
+ if (compressSpacings) {
+ if (spacingProperties.count() == 2) {
+ DomProperty *spacingProperty = spacingProperties.at(0);
+ spacingProperty->setAttributeName(QLatin1String("spacing"));
+ properties.append(spacingProperty);
+ delete spacingProperties.at(1);
+ } else {
+ properties += spacingProperties;
+ }
+ }
+ }
+ return properties;
+}
+
+DomProperty *QDesignerResource::applyProperStdSetAttribute(QObject *object, const QString &propertyName, DomProperty *property)
+{
+ if (!property)
+ return 0;
+
+ QExtensionManager *mgr = core()->extensionManager();
+ if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(mgr, object)) {
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(mgr, object);
+ const QDesignerPropertySheet *designerSheet = qobject_cast<QDesignerPropertySheet*>(core()->extensionManager()->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
+ const int index = sheet->indexOf(propertyName);
+ if ((dynamicSheet && dynamicSheet->isDynamicProperty(index)) || (designerSheet && designerSheet->isDefaultDynamicProperty(index)))
+ property->setAttributeStdset(0);
+ }
+ return property;
+}
+
+// Optimistic check for a standard setter function
+static inline bool hasSetter(QDesignerFormEditorInterface *core, QObject *object, const QString &propertyName)
+{
+ const QDesignerMetaObjectInterface *meta = core->introspection()->metaObject(object);
+ const int pindex = meta->indexOfProperty(propertyName);
+ if (pindex == -1)
+ return true;
+ return meta->property(pindex)->hasSetter();
+}
+
+DomProperty *QDesignerResource::createProperty(QObject *object, const QString &propertyName, const QVariant &value)
+{
+ if (!checkProperty(object, propertyName)) {
+ return 0;
+ }
+
+ if (qVariantCanConvert<PropertySheetFlagValue>(value)) {
+ const PropertySheetFlagValue f = qVariantValue<PropertySheetFlagValue>(value);
+ const QString flagString = f.metaFlags.toString(f.value, DesignerMetaFlags::FullyQualified);
+ if (flagString.isEmpty())
+ return 0;
+
+ DomProperty *p = new DomProperty;
+ // check if we have a standard cpp set function
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+ p->setAttributeName(propertyName);
+ p->setElementSet(flagString);
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (qVariantCanConvert<PropertySheetEnumValue>(value)) {
+ const PropertySheetEnumValue e = qVariantValue<PropertySheetEnumValue>(value);
+ bool ok;
+ const QString id = e.metaEnum.toString(e.value, DesignerMetaEnum::FullyQualified, &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageToStringFailed(e.value));
+ if (id.isEmpty())
+ return 0;
+
+ DomProperty *p = new DomProperty;
+ // check if we have a standard cpp set function
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+ p->setAttributeName(propertyName);
+ p->setElementEnum(id);
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (qVariantCanConvert<PropertySheetStringValue>(value)) {
+ const PropertySheetStringValue strVal = qVariantValue<PropertySheetStringValue>(value);
+ DomProperty *p = new DomProperty;
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+
+ p->setAttributeName(propertyName);
+
+ saveStringProperty(p, strVal);
+
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (qVariantCanConvert<PropertySheetKeySequenceValue>(value)) {
+ const PropertySheetKeySequenceValue keyVal = qVariantValue<PropertySheetKeySequenceValue>(value);
+ DomProperty *p = new DomProperty;
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+
+ p->setAttributeName(propertyName);
+
+ saveKeySequenceProperty(p, keyVal);
+
+ return applyProperStdSetAttribute(object, propertyName, p);
+ }
+
+ return applyProperStdSetAttribute(object, propertyName, QAbstractFormBuilder::createProperty(object, propertyName, value));
+}
+
+QStringList QDesignerResource::mergeWithLoadedPaths(const QStringList &paths) const
+{
+ QStringList newPaths = paths;
+#ifdef OLD_RESOURCE_FORMAT
+ QStringList loadedPaths = m_resourceBuilder->loadedQrcFiles();
+ QStringListIterator it(loadedPaths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ if (!newPaths.contains(path))
+ newPaths << path;
+ }
+#endif
+ return newPaths;
+}
+
+
+void QDesignerResource::createResources(DomResources *resources)
+{
+ QStringList paths;
+ if (resources != 0) {
+ const QList<DomResource*> dom_include = resources->elementInclude();
+ foreach (DomResource *res, dom_include) {
+ QString path = QDir::cleanPath(m_formWindow->absoluteDir().absoluteFilePath(res->attributeLocation()));
+ while (!QFile::exists(path)) {
+ QWidget *dialogParent = m_formWindow->core()->topLevel();
+ const QString promptTitle = QApplication::translate("qdesigner_internal::QDesignerResource", "Loading qrc file", 0, QApplication::UnicodeUTF8);
+ const QString prompt = QApplication::translate("qdesigner_internal::QDesignerResource", "The specified qrc file <p><b>%1</b></p><p>could not be found. Do you want to update the file location?</p>", 0, QApplication::UnicodeUTF8).arg(path);
+
+ const QMessageBox::StandardButton answer = core()->dialogGui()->message(dialogParent, QDesignerDialogGuiInterface::ResourceLoadFailureMessage,
+ QMessageBox::Warning, promptTitle, prompt, QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
+ if (answer == QMessageBox::Yes) {
+ const QFileInfo fi(path);
+ const QString fileDialogTitle = QApplication::translate("qdesigner_internal::QDesignerResource", "New location for %1", 0, QApplication::UnicodeUTF8).arg(fi.fileName());
+ const QString fileDialogPattern = QApplication::translate("qdesigner_internal::QDesignerResource", "Resource files (*.qrc)", 0, QApplication::UnicodeUTF8);
+ path = core()->dialogGui()->getOpenFileName(dialogParent, fileDialogTitle, fi.absolutePath(), fileDialogPattern);
+ if (path.isEmpty())
+ break;
+ } else {
+ break;
+ }
+ }
+ if (!path.isEmpty()) {
+ paths << path;
+ m_formWindow->addResourceFile(path);
+ }
+ }
+ }
+
+#ifdef OLD_RESOURCE_FORMAT
+ paths = mergeWithLoadedPaths(paths);
+#endif
+
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ if (resourceSet) {
+ QStringList oldPaths = resourceSet->activeQrcPaths();
+ QStringList newPaths = oldPaths;
+ QStringListIterator it(paths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ if (!newPaths.contains(path))
+ newPaths << path;
+ }
+ resourceSet->activateQrcPaths(newPaths);
+ } else {
+ resourceSet = m_formWindow->core()->resourceModel()->addResourceSet(paths);
+ m_formWindow->setResourceSet(resourceSet);
+ QObject::connect(m_formWindow->core()->resourceModel(), SIGNAL(resourceSetActivated(QtResourceSet *, bool)),
+ m_formWindow, SLOT(resourceSetActivated(QtResourceSet *, bool)));
+ }
+}
+
+DomResources *QDesignerResource::saveResources()
+{
+ QStringList paths;
+ if (m_formWindow->saveResourcesBehaviour() == FormWindowBase::SaveAll) {
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ QList<DomResource*> dom_include;
+ if (resourceSet)
+ paths = resourceSet->activeQrcPaths();
+ } else if (m_formWindow->saveResourcesBehaviour() == FormWindowBase::SaveOnlyUsedQrcFiles) {
+ paths = m_resourceBuilder->usedQrcFiles();
+ }
+
+ return saveResources(paths);
+}
+
+DomResources *QDesignerResource::saveResources(const QStringList &qrcPaths)
+{
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ QList<DomResource*> dom_include;
+ if (resourceSet) {
+ const QStringList activePaths = resourceSet->activeQrcPaths();
+ foreach (QString path, activePaths) {
+ if (qrcPaths.contains(path)) {
+ DomResource *dom_res = new DomResource;
+ QString conv_path = path;
+ if (m_resourceBuilder->isSaveRelative())
+ conv_path = m_formWindow->absoluteDir().relativeFilePath(path);
+ dom_res->setAttributeLocation(conv_path.replace(QDir::separator(), QLatin1Char('/')));
+ dom_include.append(dom_res);
+ }
+ }
+ }
+
+ DomResources *dom_resources = new DomResources;
+ dom_resources->setElementInclude(dom_include);
+
+ return dom_resources;
+}
+
+DomAction *QDesignerResource::createDom(QAction *action)
+{
+ if (!core()->metaDataBase()->item(action) || action->menu())
+ return 0;
+
+ return QAbstractFormBuilder::createDom(action);
+}
+
+DomActionGroup *QDesignerResource::createDom(QActionGroup *actionGroup)
+{
+ if (core()->metaDataBase()->item(actionGroup) != 0) {
+ return QAbstractFormBuilder::createDom(actionGroup);
+ }
+
+ return 0;
+}
+
+QAction *QDesignerResource::create(DomAction *ui_action, QObject *parent)
+{
+ if (QAction *action = QAbstractFormBuilder::create(ui_action, parent)) {
+ core()->metaDataBase()->add(action);
+ return action;
+ }
+
+ return 0;
+}
+
+QActionGroup *QDesignerResource::create(DomActionGroup *ui_action_group, QObject *parent)
+{
+ if (QActionGroup *actionGroup = QAbstractFormBuilder::create(ui_action_group, parent)) {
+ core()->metaDataBase()->add(actionGroup);
+ return actionGroup;
+ }
+
+ return 0;
+}
+
+DomActionRef *QDesignerResource::createActionRefDom(QAction *action)
+{
+ if (!core()->metaDataBase()->item(action)
+ || (!action->isSeparator() && !action->menu() && action->objectName().isEmpty()))
+ return 0;
+
+ return QAbstractFormBuilder::createActionRefDom(action);
+}
+
+void QDesignerResource::addMenuAction(QAction *action)
+{
+ core()->metaDataBase()->add(action);
+}
+
+QAction *QDesignerResource::createAction(QObject *parent, const QString &name)
+{
+ if (QAction *action = QAbstractFormBuilder::createAction(parent, name)) {
+ core()->metaDataBase()->add(action);
+ return action;
+ }
+
+ return 0;
+}
+
+QActionGroup *QDesignerResource::createActionGroup(QObject *parent, const QString &name)
+{
+ if (QActionGroup *actionGroup = QAbstractFormBuilder::createActionGroup(parent, name)) {
+ core()->metaDataBase()->add(actionGroup);
+ return actionGroup;
+ }
+
+ return 0;
+}
+
+/* Apply the attributes to a widget via property sheet where appropriate,
+ * that is, the sheet handles attributive fake properties */
+void QDesignerResource::applyAttributesToPropertySheet(const DomWidget *ui_widget, QWidget *widget)
+{
+ const DomPropertyList attributes = ui_widget->elementAttribute();
+ if (attributes.empty())
+ return;
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_formWindow->core()->extensionManager(), widget);
+ const DomPropertyList::const_iterator acend = attributes.constEnd();
+ for (DomPropertyList::const_iterator it = attributes.constBegin(); it != acend; ++it) {
+ const QString name = (*it)->attributeName();
+ const int index = sheet->indexOf(name);
+ if (index == -1) {
+ const QString msg = QString::fromUtf8("Unable to apply attributive property '%1' to '%2'. It does not exist.").arg(name, widget->objectName());
+ designerWarning(msg);
+ } else {
+ sheet->setProperty(index, domPropertyToVariant(this, widget->metaObject(), *it));
+ sheet->setChanged(index, true);
+ }
+ }
+}
+
+void QDesignerResource::loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ QAbstractFormBuilder::loadExtraInfo(ui_widget, widget, parentWidget);
+ // Apply the page id attribute of a QWizardPage (which is an attributive fake property)
+ if (qobject_cast<const QWizardPage*>(widget))
+ applyAttributesToPropertySheet(ui_widget, widget);
+}
+
+// Add user defined scripts (dialog box) belonging to QWidget to DomWidget.
+void QDesignerResource::addUserDefinedScripts(QWidget *w, DomWidget *ui_widget)
+{
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ DomScripts domScripts = ui_widget->elementScript();
+ // Look up user-defined scripts of designer
+ if (const qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<const qdesigner_internal::MetaDataBase *>(core->metaDataBase())) {
+ if (const qdesigner_internal::MetaDataBaseItem *metaItem = metaDataBase->metaDataBaseItem(w)) {
+ addScript(metaItem->script(), ScriptDesigner, domScripts);
+ }
+ }
+ if (!domScripts.empty())
+ ui_widget->setElementScript(domScripts);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.h b/tools/designer/src/components/formeditor/qdesigner_resource.h
new file mode 100644
index 0000000..3d6a842
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_RESOURCE_H
+#define QDESIGNER_RESOURCE_H
+
+#include "formeditor_global.h"
+#include "qsimpleresource_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QStack>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class DomCustomWidget;
+class DomCustomWidgets;
+class DomResource;
+
+class QDesignerContainerExtension;
+class QDesignerFormEditorInterface;
+class QDesignerCustomWidgetInterface;
+class QDesignerWidgetDataBaseItemInterface;
+
+class QTabWidget;
+class QStackedWidget;
+class QToolBox;
+class QToolBar;
+class QTreeView;
+class QTableView;
+class QDesignerDockWidget;
+class QLayoutWidget;
+class QWizardPage;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+
+class QT_FORMEDITOR_EXPORT QDesignerResource : public QEditorFormBuilder
+{
+public:
+ explicit QDesignerResource(FormWindow *fw);
+ virtual ~QDesignerResource();
+
+ virtual void save(QIODevice *dev, QWidget *widget);
+
+ virtual bool copy(QIODevice *dev, const FormBuilderClipboard &selection);
+ virtual DomUI *copy(const FormBuilderClipboard &selection);
+
+ virtual FormBuilderClipboard paste(DomUI *ui, QWidget *widgetParent, QObject *actionParent = 0);
+ virtual FormBuilderClipboard paste(QIODevice *dev, QWidget *widgetParent, QObject *actionParent = 0);
+
+ bool saveRelative() const;
+ void setSaveRelative(bool relative);
+
+ virtual QWidget *load(QIODevice *dev, QWidget *parentWidget = 0);
+
+protected:
+ using QEditorFormBuilder::create;
+ using QEditorFormBuilder::createDom;
+
+ virtual void saveDom(DomUI *ui, QWidget *widget);
+ virtual QWidget *create(DomUI *ui, QWidget *parentWidget);
+ virtual QWidget *create(DomWidget *ui_widget, QWidget *parentWidget);
+ virtual QLayout *create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget);
+ virtual QLayoutItem *create(DomLayoutItem *ui_layoutItem, QLayout *layout, QWidget *parentWidget);
+ virtual void applyProperties(QObject *o, const QList<DomProperty*> &properties);
+ virtual QList<DomProperty*> computeProperties(QObject *obj);
+ virtual DomProperty *createProperty(QObject *object, const QString &propertyName, const QVariant &value);
+
+ virtual QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name);
+ virtual QLayout *createLayout(const QString &layoutName, QObject *parent, const QString &name);
+ virtual void createCustomWidgets(DomCustomWidgets *);
+ virtual void createResources(DomResources*);
+ virtual void applyTabStops(QWidget *widget, DomTabStops *tabStops);
+
+ virtual bool addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout);
+ virtual bool addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
+
+ virtual DomWidget *createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive = true);
+ virtual DomLayout *createDom(QLayout *layout, DomLayout *ui_layout, DomWidget *ui_parentWidget);
+ virtual DomLayoutItem *createDom(QLayoutItem *item, DomLayout *ui_layout, DomWidget *ui_parentWidget);
+
+ virtual QAction *create(DomAction *ui_action, QObject *parent);
+ virtual QActionGroup *create(DomActionGroup *ui_action_group, QObject *parent);
+ virtual void addMenuAction(QAction *action);
+
+ virtual DomAction *createDom(QAction *action);
+ virtual DomActionGroup *createDom(QActionGroup *actionGroup);
+ virtual DomActionRef *createActionRefDom(QAction *action);
+
+ virtual QAction *createAction(QObject *parent, const QString &name);
+ virtual QActionGroup *createActionGroup(QObject *parent, const QString &name);
+
+ virtual bool checkProperty(QObject *obj, const QString &prop) const;
+
+ DomWidget *saveWidget(QTabWidget *widget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QStackedWidget *widget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QToolBox *widget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QWidget *widget, QDesignerContainerExtension *container, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QToolBar *toolBar, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QDesignerDockWidget *dockWidget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QTreeView *treeView, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QTableView *tableView, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QWizardPage *wizardPage, DomWidget *ui_parentWidget);
+
+ virtual DomCustomWidgets *saveCustomWidgets();
+ virtual DomTabStops *saveTabStops();
+ virtual DomResources *saveResources();
+
+ virtual void layoutInfo(DomLayout *layout, QObject *parent, int *margin, int *spacing);
+
+ virtual void loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
+
+ void changeObjectName(QObject *o, QString name);
+ DomProperty *applyProperStdSetAttribute(QObject *object, const QString &propertyName, DomProperty *property);
+
+private:
+ void addUserDefinedScripts(QWidget *w, DomWidget *ui_widget);
+ DomResources *saveResources(const QStringList &qrcPaths);
+ bool canCompressMargins(QObject *object) const;
+ bool canCompressSpacings(QObject *object) const;
+ QStringList mergeWithLoadedPaths(const QStringList &paths) const;
+ void applyAttributesToPropertySheet(const DomWidget *ui_widget, QWidget *widget);
+
+ typedef QList<DomCustomWidget*> DomCustomWidgetList;
+ void addCustomWidgetsToWidgetDatabase(DomCustomWidgetList& list);
+ FormWindow *m_formWindow;
+ bool m_isMainWidget;
+ QHash<QString, QString> m_internal_to_qt;
+ QHash<QString, QString> m_qt_to_internal;
+ QStack<QLayout*> m_chain;
+ QHash<QDesignerWidgetDataBaseItemInterface*, bool> m_usedCustomWidgets;
+ int m_topLevelSpacerCount;
+ bool m_copyWidget;
+ QWidget *m_selected;
+ class QDesignerResourceBuilder *m_resourceBuilder;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_RESOURCE_H
diff --git a/tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp b/tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp
new file mode 100644
index 0000000..e3e4a97
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlayoutwidget_propertysheet.h"
+#include "qlayout_widget_p.h"
+#include "formwindow.h"
+#include "formeditor.h"
+
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+QLayoutWidgetPropertySheet::QLayoutWidgetPropertySheet(QLayoutWidget *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent)
+{
+ clearFakeProperties();
+}
+
+QLayoutWidgetPropertySheet::~QLayoutWidgetPropertySheet()
+{
+}
+
+bool QLayoutWidgetPropertySheet::isVisible(int index) const
+{
+ static const QString layoutPropertyGroup = QLatin1String("Layout");
+ if (propertyGroup(index) == layoutPropertyGroup)
+ return QDesignerPropertySheet::isVisible(index);
+ return false;
+}
+
+void QLayoutWidgetPropertySheet::setProperty(int index, const QVariant &value)
+{
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+bool QLayoutWidgetPropertySheet::dynamicPropertiesAllowed() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.h b/tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.h
new file mode 100644
index 0000000..e96adaf
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qlayoutwidget_propertysheet.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUTWIDGET_PROPERTYSHEET_H
+#define QLAYOUTWIDGET_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+#include <qlayout_widget_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QLayoutWidgetPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit QLayoutWidgetPropertySheet(QLayoutWidget *object, QObject *parent = 0);
+ virtual ~QLayoutWidgetPropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool isVisible(int index) const;
+
+ virtual bool dynamicPropertiesAllowed() const;
+};
+
+typedef QDesignerPropertySheetFactory<QLayoutWidget, QLayoutWidgetPropertySheet> QLayoutWidgetPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QLAYOUTWIDGET_PROPERTYSHEET_H
diff --git a/tools/designer/src/components/formeditor/qmainwindow_container.cpp b/tools/designer/src/components/formeditor/qmainwindow_container.cpp
new file mode 100644
index 0000000..7fd21d1
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qmainwindow_container.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmainwindow_container.h"
+#include "qdesigner_toolbar_p.h"
+#include "formwindow.h"
+
+#include <QtCore/qdebug.h>
+
+#include <QtGui/QLayout>
+#include <QtGui/QMenuBar>
+#include <QtGui/QToolBar>
+#include <QtGui/QStatusBar>
+#include <QtGui/QDockWidget>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+QMainWindowContainer::QMainWindowContainer(QMainWindow *widget, QObject *parent)
+ : QObject(parent),
+ m_mainWindow(widget)
+{
+}
+
+int QMainWindowContainer::count() const
+{
+ return m_widgets.count();
+}
+
+QWidget *QMainWindowContainer::widget(int index) const
+{
+ if (index == -1)
+ return 0;
+
+ return m_widgets.at(index);
+}
+
+int QMainWindowContainer::currentIndex() const
+{
+ return m_mainWindow->centralWidget() ? 0 : -1;
+}
+
+void QMainWindowContainer::setCurrentIndex(int index)
+{
+ Q_UNUSED(index);
+}
+
+
+namespace {
+ // Pair of <area,break_before>
+ typedef QPair<Qt::ToolBarArea,bool> ToolBarData;
+
+ ToolBarData toolBarData(QToolBar *me) {
+ const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget());
+ if (!mw || !mw->layout() || mw->layout()->indexOf(me) == -1)
+ return ToolBarData(Qt::TopToolBarArea,false);
+ return ToolBarData(mw->toolBarArea(me), mw->toolBarBreak(me));
+ }
+
+Qt::DockWidgetArea dockWidgetArea(QDockWidget *me)
+{
+ if (const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget())) {
+ // Make sure that me is actually managed by mw, otherwise
+ // QMainWindow::dockWidgetArea() will be VERY upset
+ QList<QLayout*> candidates;
+ if (mw->layout()) {
+ candidates.append(mw->layout());
+ candidates += qFindChildren<QLayout*>(mw->layout());
+ }
+ foreach (QLayout *l, candidates) {
+ if (l->indexOf(me) != -1) {
+ return mw->dockWidgetArea(me);
+ }
+ }
+ }
+ return Qt::LeftDockWidgetArea;
+}
+}
+
+void QMainWindowContainer::addWidget(QWidget *widget)
+{
+ // remove all the occurrences of widget
+ m_widgets.removeAll(widget);
+
+ // the
+ if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
+ m_widgets.append(widget);
+ const ToolBarData data = toolBarData(toolBar);
+ m_mainWindow->addToolBar(data.first, toolBar);
+ if (data.second) m_mainWindow->insertToolBarBreak(toolBar);
+ toolBar->show();
+ }
+
+ else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
+ if (menuBar != m_mainWindow->menuBar())
+ m_mainWindow->setMenuBar(menuBar);
+
+ m_widgets.append(widget);
+ menuBar->show();
+ }
+
+ else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
+ if (statusBar != m_mainWindow->statusBar())
+ m_mainWindow->setStatusBar(statusBar);
+
+ m_widgets.append(widget);
+ statusBar->show();
+ }
+
+ else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
+ m_widgets.append(widget);
+ m_mainWindow->addDockWidget(dockWidgetArea(dockWidget), dockWidget);
+ dockWidget->show();
+
+ if (FormWindow *fw = FormWindow::findFormWindow(m_mainWindow)) {
+ fw->manageWidget(widget);
+ }
+ }
+
+ else if (widget) {
+ m_widgets.prepend(widget);
+
+ if (widget != m_mainWindow->centralWidget()) {
+ // note that qmainwindow will delete the current central widget if you
+ // call setCentralWidget(), we end up with dangeling pointers in m_widgets list
+ m_widgets.removeAll(m_mainWindow->centralWidget());
+
+ widget->setParent(m_mainWindow);
+ m_mainWindow->setCentralWidget(widget);
+ }
+ }
+}
+
+void QMainWindowContainer::insertWidget(int index, QWidget *widget)
+{
+ Q_UNUSED(index);
+
+ addWidget(widget);
+}
+
+void QMainWindowContainer::remove(int index)
+{
+ QWidget *widget = m_widgets.at(index);
+ if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
+ m_mainWindow->removeToolBar(toolBar);
+ } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
+ menuBar->hide();
+ menuBar->setParent(0);
+ m_mainWindow->setMenuBar(0);
+ } else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
+ statusBar->hide();
+ statusBar->setParent(0);
+ m_mainWindow->setStatusBar(0);
+ } else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
+ m_mainWindow->removeDockWidget(dockWidget);
+ }
+ m_widgets.removeAt(index);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qmainwindow_container.h b/tools/designer/src/components/formeditor/qmainwindow_container.h
new file mode 100644
index 0000000..aaf942f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qmainwindow_container.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMAINWINDOW_CONTAINER_H
+#define QMAINWINDOW_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+
+#include <extensionfactory_p.h>
+
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QMainWindowContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QMainWindowContainer(QMainWindow *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QMainWindow *m_mainWindow;
+ QList<QWidget*> m_widgets;
+};
+
+typedef ExtensionFactory<QDesignerContainerExtension, QMainWindow, QMainWindowContainer> QMainWindowContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QMAINWINDOW_CONTAINER_H
diff --git a/tools/designer/src/components/formeditor/qmdiarea_container.cpp b/tools/designer/src/components/formeditor/qmdiarea_container.cpp
new file mode 100644
index 0000000..fdeef03
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qmdiarea_container.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmdiarea_container.h"
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QMdiAreaContainer::QMdiAreaContainer(QMdiArea *widget, QObject *parent)
+ : QObject(parent),
+ m_mdiArea(widget)
+{
+}
+
+int QMdiAreaContainer::count() const
+{
+ return m_mdiArea->subWindowList(QMdiArea::CreationOrder).count();
+}
+
+QWidget *QMdiAreaContainer::widget(int index) const
+{
+ if (index < 0)
+ return 0;
+ return m_mdiArea->subWindowList(QMdiArea::CreationOrder).at(index)->widget();
+}
+
+int QMdiAreaContainer::currentIndex() const
+{
+ if (QMdiSubWindow *sub = m_mdiArea->activeSubWindow())
+ return m_mdiArea->subWindowList(QMdiArea::CreationOrder).indexOf(sub);
+ return -1;
+}
+
+void QMdiAreaContainer::setCurrentIndex(int index)
+{
+ if (index < 0) {
+ qDebug() << "** WARNING Attempt to QMdiAreaContainer::setCurrentIndex(-1)";
+ return;
+ }
+ QMdiSubWindow *frame = m_mdiArea->subWindowList(QMdiArea::CreationOrder).at(index);
+ m_mdiArea->setActiveSubWindow(frame);
+}
+
+void QMdiAreaContainer::addWidget(QWidget *widget)
+{
+ QMdiSubWindow *frame = m_mdiArea->addSubWindow(widget, Qt::Window);
+ frame->show();
+ m_mdiArea->cascadeSubWindows();
+ positionNewMdiChild(m_mdiArea, frame);
+}
+
+// Semi-smart positioning of new windows: Make child fill the whole MDI window below
+// cascaded other windows
+void QMdiAreaContainer::positionNewMdiChild(const QWidget *area, QWidget *mdiChild)
+{
+ enum { MinSize = 20 };
+ const QPoint pos = mdiChild->pos();
+ const QSize areaSize = area->size();
+ switch (QApplication::layoutDirection()) {
+ case Qt::LeftToRight: {
+ const QSize fullSize = QSize(areaSize.width() - pos.x(), areaSize.height() - pos.y());
+ if (fullSize.width() > MinSize && fullSize.height() > MinSize)
+ mdiChild->resize(fullSize);
+ }
+ break;
+ case Qt::RightToLeft: {
+ const QSize fullSize = QSize(pos.x() + mdiChild->width(), areaSize.height() - pos.y());
+ if (fullSize.width() > MinSize && fullSize.height() > MinSize) {
+ mdiChild->move(0, pos.y());
+ mdiChild->resize(fullSize);
+ }
+ }
+ break;
+ }
+}
+
+void QMdiAreaContainer::insertWidget(int, QWidget *widget)
+{
+ addWidget(widget);
+}
+
+void QMdiAreaContainer::remove(int index)
+{
+ QList<QMdiSubWindow *> subWins = m_mdiArea->subWindowList(QMdiArea::CreationOrder);
+ if (index >= 0 && index < subWins.size()) {
+ QMdiSubWindow *f = subWins.at(index);
+ m_mdiArea->removeSubWindow(f->widget());
+ delete f;
+ }
+}
+
+// ---------- MdiAreaPropertySheet, creates fake properties:
+// 1) window name (object name of child)
+// 2) title (windowTitle of child).
+
+static const char *subWindowTitleC = "activeSubWindowTitle";
+static const char *subWindowNameC = "activeSubWindowName";
+
+QMdiAreaPropertySheet::QMdiAreaPropertySheet(QWidget *mdiArea, QObject *parent) :
+ QDesignerPropertySheet(mdiArea, parent),
+ m_windowTitleProperty(QLatin1String("windowTitle"))
+{
+ createFakeProperty(QLatin1String(subWindowNameC), QString());
+ createFakeProperty(QLatin1String(subWindowTitleC), QString());
+}
+
+QMdiAreaPropertySheet::MdiAreaProperty QMdiAreaPropertySheet::mdiAreaProperty(const QString &name)
+{
+ typedef QHash<QString, MdiAreaProperty> MdiAreaPropertyHash;
+ static MdiAreaPropertyHash mdiAreaPropertyHash;
+ if (mdiAreaPropertyHash.empty()) {
+ mdiAreaPropertyHash.insert(QLatin1String(subWindowNameC), MdiAreaSubWindowName);
+ mdiAreaPropertyHash.insert(QLatin1String(subWindowTitleC), MdiAreaSubWindowTitle);
+ }
+ return mdiAreaPropertyHash.value(name,MdiAreaNone);
+}
+
+void QMdiAreaPropertySheet::setProperty(int index, const QVariant &value)
+{
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ if (QWidget *w = currentWindow())
+ w->setObjectName(value.toString());
+ break;
+ case MdiAreaSubWindowTitle: // Forward to window title of subwindow
+ if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
+ const int index = cws->indexOf(m_windowTitleProperty);
+ cws->setProperty(index, value);
+ cws->setChanged(index, true);
+ }
+ break;
+ default:
+ QDesignerPropertySheet::setProperty(index, value);
+ break;
+ }
+}
+
+bool QMdiAreaPropertySheet::reset(int index)
+{
+ bool rc = true;
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ setProperty(index, QVariant(QString()));
+ setChanged(index, false);
+ break;
+ case MdiAreaSubWindowTitle: // Forward to window title of subwindow
+ if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
+ const int index = cws->indexOf(m_windowTitleProperty);
+ rc = cws->reset(index);
+ }
+ break;
+ default:
+ rc = QDesignerPropertySheet::reset(index);
+ break;
+ }
+ return rc;
+}
+
+QVariant QMdiAreaPropertySheet::property(int index) const
+{
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ if (QWidget *w = currentWindow())
+ return w->objectName();
+ return QVariant(QString());
+ case MdiAreaSubWindowTitle:
+ if (QWidget *w = currentWindow())
+ return w->windowTitle();
+ return QVariant(QString());
+ case MdiAreaNone:
+ break;
+ }
+ return QDesignerPropertySheet::property(index);
+}
+
+bool QMdiAreaPropertySheet::isEnabled(int index) const
+{
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ case MdiAreaSubWindowTitle:
+ return currentWindow() != 0;
+ case MdiAreaNone:
+ break;
+ }
+ return QDesignerPropertySheet::isEnabled(index);
+}
+
+bool QMdiAreaPropertySheet::isChanged(int index) const
+{
+ bool rc = false;
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ rc = currentWindow() != 0;
+ break;
+ case MdiAreaSubWindowTitle:
+ if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
+ const int index = cws->indexOf(m_windowTitleProperty);
+ rc = cws->isChanged(index);
+ }
+ break;
+ default:
+ rc = QDesignerPropertySheet::isChanged(index);
+ break;
+ }
+ return rc;
+}
+
+QWidget *QMdiAreaPropertySheet::currentWindow() const
+{
+ if (const QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), object())) {
+ const int ci = c->currentIndex();
+ if (ci < 0)
+ return 0;
+ return c->widget(ci);
+ }
+ return 0;
+}
+
+QDesignerPropertySheetExtension *QMdiAreaPropertySheet::currentWindowSheet() const
+{
+ QWidget *cw = currentWindow();
+ if (cw == 0)
+ return 0;
+ return qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), cw);
+}
+
+bool QMdiAreaPropertySheet::checkProperty(const QString &propertyName)
+{
+ return mdiAreaProperty(propertyName) == MdiAreaNone;
+}
+}
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qmdiarea_container.h b/tools/designer/src/components/formeditor/qmdiarea_container.h
new file mode 100644
index 0000000..462c11f
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qmdiarea_container.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMDIAREA_CONTAINER_H
+#define QMDIAREA_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QMdiArea>
+#include <QtGui/QWorkspace>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Container for QMdiArea
+class QMdiAreaContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QMdiAreaContainer(QMdiArea *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+ // Semismart positioning of a new MDI child after cascading
+ static void positionNewMdiChild(const QWidget *area, QWidget *mdiChild);
+
+private:
+ QMdiArea *m_mdiArea;
+};
+
+// PropertySheet for QMdiArea: Fakes window title and name.
+// Also works for a QWorkspace as it relies on the container extension.
+
+class QMdiAreaPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit QMdiAreaPropertySheet(QWidget *mdiArea, QObject *parent = 0);
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool reset(int index);
+ virtual bool isEnabled(int index) const;
+ virtual bool isChanged(int index) const;
+ virtual QVariant property(int index) const;
+
+ // Check whether the property is to be saved. Returns false for the page
+ // properties (as the property sheet has no concept of 'stored')
+ static bool checkProperty(const QString &propertyName);
+
+private:
+ const QString m_windowTitleProperty;
+ QWidget *currentWindow() const;
+ QDesignerPropertySheetExtension *currentWindowSheet() const;
+
+ enum MdiAreaProperty { MdiAreaSubWindowName, MdiAreaSubWindowTitle, MdiAreaNone };
+ static MdiAreaProperty mdiAreaProperty(const QString &name);
+};
+
+// Factories
+
+typedef ExtensionFactory<QDesignerContainerExtension, QMdiArea, QMdiAreaContainer> QMdiAreaContainerFactory;
+typedef QDesignerPropertySheetFactory<QMdiArea, QMdiAreaPropertySheet> QMdiAreaPropertySheetFactory;
+typedef QDesignerPropertySheetFactory<QWorkspace, QMdiAreaPropertySheet> QWorkspacePropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QMDIAREA_CONTAINER_H
diff --git a/tools/designer/src/components/formeditor/qtbrushmanager.cpp b/tools/designer/src/components/formeditor/qtbrushmanager.cpp
new file mode 100644
index 0000000..c28c6b9
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qtbrushmanager.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbrushmanager.h"
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QtBrushManagerPrivate
+{
+ QtBrushManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtBrushManager)
+public:
+ QMap<QString, QBrush> theBrushMap;
+ QString theCurrentBrush;
+};
+
+QtBrushManager::QtBrushManager(QObject *parent)
+ : QDesignerBrushManagerInterface(parent)
+{
+ d_ptr = new QtBrushManagerPrivate;
+ d_ptr->q_ptr = this;
+
+}
+
+QtBrushManager::~QtBrushManager()
+{
+ delete d_ptr;
+}
+
+QBrush QtBrushManager::brush(const QString &name) const
+{
+ if (d_ptr->theBrushMap.contains(name))
+ return d_ptr->theBrushMap[name];
+ return QBrush();
+}
+
+QMap<QString, QBrush> QtBrushManager::brushes() const
+{
+ return d_ptr->theBrushMap;
+}
+
+QString QtBrushManager::currentBrush() const
+{
+ return d_ptr->theCurrentBrush;
+}
+
+QString QtBrushManager::addBrush(const QString &name, const QBrush &brush)
+{
+ if (name.isNull())
+ return QString();
+
+ QString newName = name;
+ QString nameBase = newName;
+ int i = 0;
+ while (d_ptr->theBrushMap.contains(newName)) {
+ newName = nameBase + QString::number(++i);
+ }
+ d_ptr->theBrushMap[newName] = brush;
+ emit brushAdded(newName, brush);
+
+ return newName;
+}
+
+void QtBrushManager::removeBrush(const QString &name)
+{
+ if (!d_ptr->theBrushMap.contains(name))
+ return;
+ if (currentBrush() == name)
+ setCurrentBrush(QString());
+ emit brushRemoved(name);
+ d_ptr->theBrushMap.remove(name);
+}
+
+void QtBrushManager::setCurrentBrush(const QString &name)
+{
+ QBrush newBrush;
+ if (!name.isNull()) {
+ if (d_ptr->theBrushMap.contains(name))
+ newBrush = d_ptr->theBrushMap[name];
+ else
+ return;
+ }
+ d_ptr->theCurrentBrush = name;
+ emit currentBrushChanged(name, newBrush);
+}
+
+QPixmap QtBrushManager::brushPixmap(const QBrush &brush) const
+{
+ int w = 64;
+ int h = 64;
+
+ QImage img(w, h, QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), brush);
+ return QPixmap::fromImage(img);
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qtbrushmanager.h b/tools/designer/src/components/formeditor/qtbrushmanager.h
new file mode 100644
index 0000000..f8f1b8a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qtbrushmanager.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTBRUSHMANAGER_H
+#define QTBRUSHMANAGER_H
+
+#include <QtDesigner/QDesignerBrushManagerInterface>
+#include "formeditor_global.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtGui/QBrush>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QtBrushManagerPrivate;
+
+class QT_FORMEDITOR_EXPORT QtBrushManager : public QDesignerBrushManagerInterface
+{
+ Q_OBJECT
+public:
+ QtBrushManager(QObject *parent = 0);
+ ~QtBrushManager();
+
+ QBrush brush(const QString &name) const;
+ QMap<QString, QBrush> brushes() const;
+ QString currentBrush() const;
+
+ QString addBrush(const QString &name, const QBrush &brush);
+ void removeBrush(const QString &name);
+ void setCurrentBrush(const QString &name);
+
+ QPixmap brushPixmap(const QBrush &brush) const;
+signals:
+ void brushAdded(const QString &name, const QBrush &brush);
+ void brushRemoved(const QString &name);
+ void currentBrushChanged(const QString &name, const QBrush &brush);
+
+private:
+ QtBrushManagerPrivate *d_ptr;
+ Q_DECLARE_PRIVATE(QtBrushManager)
+ Q_DISABLE_COPY(QtBrushManager)
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/designer/src/components/formeditor/qwizard_container.cpp b/tools/designer/src/components/formeditor/qwizard_container.cpp
new file mode 100644
index 0000000..669f71a
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qwizard_container.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwizard_container.h"
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QWizard>
+#include <QtGui/QWizardPage>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<int> IdList;
+typedef QList<QWizardPage *> WizardPageList;
+
+namespace qdesigner_internal {
+
+QWizardContainer::QWizardContainer(QWizard *widget, QObject *parent) :
+ QObject(parent),
+ m_wizard(widget)
+{
+}
+
+int QWizardContainer::count() const
+{
+ return m_wizard->pageIds().size();
+}
+
+QWidget *QWizardContainer::widget(int index) const
+{
+ QWidget *rc = 0;
+ if (index >= 0) {
+ const IdList idList = m_wizard->pageIds();
+ if (index < idList.size())
+ rc = m_wizard->page(idList.at(index));
+ }
+ return rc;
+}
+
+int QWizardContainer::currentIndex() const
+{
+ const IdList idList = m_wizard->pageIds();
+ const int currentId = m_wizard->currentId();
+ const int rc = idList.empty() ? -1 : idList.indexOf(currentId);
+ return rc;
+}
+
+void QWizardContainer::setCurrentIndex(int index)
+{
+ if (index < 0 || m_wizard->pageIds().empty())
+ return;
+
+ int currentIdx = currentIndex();
+
+ if (currentIdx == -1) {
+ m_wizard->restart();
+ currentIdx = currentIndex();
+ }
+
+ if (currentIdx == index)
+ return;
+
+ const int d = qAbs(index - currentIdx);
+ if (index > currentIdx) {
+ for (int i = 0; i < d; i++)
+ m_wizard->next();
+ } else {
+ for (int i = 0; i < d; i++)
+ m_wizard->back();
+ }
+}
+
+static const char *msgWrongType = "** WARNING Attempt to add oject that is not of class WizardPage to a QWizard";
+
+void QWizardContainer::addWidget(QWidget *widget)
+{
+ QWizardPage *page = qobject_cast<QWizardPage *>(widget);
+ if (!page) {
+ qWarning("%s", msgWrongType);
+ return;
+ }
+ m_wizard->addPage(page);
+ // Might be -1 after adding the first page
+ setCurrentIndex(m_wizard->pageIds().size() - 1);
+}
+
+void QWizardContainer::insertWidget(int index, QWidget *widget)
+{
+ enum { delta = 5 };
+
+ QWizardPage *newPage = qobject_cast<QWizardPage *>(widget);
+ if (!newPage) {
+ qWarning("%s", msgWrongType);
+ return;
+ }
+
+ const IdList idList = m_wizard->pageIds();
+ const int pageCount = idList.size();
+ if (index >= pageCount) {
+ addWidget(widget);
+ return;
+ }
+
+ // Insert before, reshuffle ids if required
+ const int idBefore = idList.at(index);
+ const int newId = idBefore - 1;
+ const bool needsShuffle =
+ (index == 0 && newId < 0) // At start: QWizard refuses to insert id -1
+ || (index > 0 && idList.at(index - 1) == newId); // In-between
+ if (needsShuffle) {
+ // Create a gap by shuffling pages
+ WizardPageList pageList;
+ pageList.push_back(newPage);
+ for (int i = index; i < pageCount; i++) {
+ pageList.push_back(m_wizard->page(idList.at(i)));
+ m_wizard->removePage(idList.at(i));
+ }
+ int newId = idBefore + delta;
+ const WizardPageList::const_iterator wcend = pageList.constEnd();
+ for (WizardPageList::const_iterator it = pageList.constBegin(); it != wcend; ++it) {
+ m_wizard->setPage(newId, *it);
+ newId += delta;
+ }
+ } else {
+ // Gap found, just insert
+ m_wizard->setPage(newId, newPage);
+ }
+ // Might be at -1 after adding the first page
+ setCurrentIndex(index);
+}
+
+void QWizardContainer::remove(int index)
+{
+ if (index < 0)
+ return;
+
+ const IdList idList = m_wizard->pageIds();
+ if (index >= idList.size())
+ return;
+
+ m_wizard->removePage(idList.at(index));
+ // goto next page, preferably
+ const int newSize = idList.size() - 1;
+ if (index < newSize) {
+ setCurrentIndex(index);
+ } else {
+ if (newSize > 0)
+ setCurrentIndex(newSize - 1);
+ }
+}
+
+// ---------------- QWizardPagePropertySheet
+const char *QWizardPagePropertySheet::pageIdProperty = "pageId";
+
+QWizardPagePropertySheet::QWizardPagePropertySheet(QWizardPage *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_pageIdIndex(createFakeProperty(QLatin1String(pageIdProperty), QString()))
+{
+ setAttribute(m_pageIdIndex, true);
+}
+
+bool QWizardPagePropertySheet::reset(int index)
+{
+ if (index == m_pageIdIndex) {
+ setProperty(index, QString());
+ return true;
+ }
+ return QDesignerPropertySheet::reset(index);
+}
+
+// ---------------- QWizardPropertySheet
+QWizardPropertySheet::QWizardPropertySheet(QWizard *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_startId(QLatin1String("startId"))
+{
+}
+
+bool QWizardPropertySheet::isVisible(int index) const
+{
+ if (propertyName(index) == m_startId)
+ return false;
+ return QDesignerPropertySheet::isVisible(index);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qwizard_container.h b/tools/designer/src/components/formeditor/qwizard_container.h
new file mode 100644
index 0000000..6667a1d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qwizard_container.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIZARD_CONTAINER_H
+#define QWIZARD_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QWizard>
+#include <QtGui/QWizardPage>
+
+QT_BEGIN_NAMESPACE
+
+class QWizardPage;
+
+namespace qdesigner_internal {
+
+// Container for QWizard. Care must be taken to position
+// the QWizard at some valid page after removal/insertion
+// as it is not used to having its pages ripped out.
+class QWizardContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QWizardContainer(QWizard *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QWizard *m_wizard;
+};
+
+// QWizardPagePropertySheet: Introduces a attribute string fake property
+// "pageId" that allows for specifying enumeration values (uic only).
+// This breaks the pattern of having a "currentSth" property for the
+// container, but was deemed to make sense here since the Page has
+// its own "title" properties.
+class QWizardPagePropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+public:
+ explicit QWizardPagePropertySheet(QWizardPage *object, QObject *parent = 0);
+
+ virtual bool reset(int index);
+
+ static const char *pageIdProperty;
+
+private:
+ const int m_pageIdIndex;
+};
+
+// QWizardPropertySheet: Hides the "startId" property. It cannot be used
+// as QWizard cannot handle setting it as a property before the actual
+// page is added.
+
+class QWizardPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+public:
+ explicit QWizardPropertySheet(QWizard *object, QObject *parent = 0);
+ virtual bool isVisible(int index) const;
+
+private:
+ const QString m_startId;
+};
+
+// Factories
+typedef QDesignerPropertySheetFactory<QWizard, QWizardPropertySheet> QWizardPropertySheetFactory;
+typedef QDesignerPropertySheetFactory<QWizardPage, QWizardPagePropertySheet> QWizardPagePropertySheetFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QWizard, QWizardContainer> QWizardContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QWIZARD_CONTAINER_H
diff --git a/tools/designer/src/components/formeditor/qworkspace_container.cpp b/tools/designer/src/components/formeditor/qworkspace_container.cpp
new file mode 100644
index 0000000..03cb382
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qworkspace_container.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qworkspace_container.h"
+#include "qmdiarea_container.h"
+
+#include <QtGui/QWorkspace>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QWorkspaceContainer::QWorkspaceContainer(QWorkspace *widget, QObject *parent)
+ : QObject(parent),
+ m_workspace(widget)
+{
+}
+
+int QWorkspaceContainer::count() const
+{
+ return m_workspace->windowList(QWorkspace::CreationOrder).count();
+}
+
+QWidget *QWorkspaceContainer::widget(int index) const
+{
+ if (index < 0)
+ return 0;
+ return m_workspace->windowList(QWorkspace::CreationOrder).at(index);
+}
+
+int QWorkspaceContainer::currentIndex() const
+{
+ if (QWidget *aw = m_workspace->activeWindow())
+ return m_workspace->windowList(QWorkspace::CreationOrder).indexOf(aw);
+ return -1;
+}
+
+void QWorkspaceContainer::setCurrentIndex(int index)
+{
+ m_workspace->setActiveWindow(m_workspace->windowList(QWorkspace::CreationOrder).at(index));
+}
+
+void QWorkspaceContainer::addWidget(QWidget *widget)
+{
+ QWidget *frame = m_workspace->addWindow(widget, Qt::Window);
+ frame->show();
+ m_workspace->cascade();
+ QMdiAreaContainer::positionNewMdiChild(m_workspace, frame);
+}
+
+void QWorkspaceContainer::insertWidget(int, QWidget *widget)
+{
+ addWidget(widget);
+}
+
+void QWorkspaceContainer::remove(int /* index */)
+{
+ // nothing to do here, reparenting to formwindow is apparently sufficient
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/qworkspace_container.h b/tools/designer/src/components/formeditor/qworkspace_container.h
new file mode 100644
index 0000000..fa1e66c
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qworkspace_container.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWORKSPACE_CONTAINER_H
+#define QWORKSPACE_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+
+#include <extensionfactory_p.h>
+#include <QtGui/QWorkspace>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QWorkspaceContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QWorkspaceContainer(QWorkspace *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QWorkspace *m_workspace;
+};
+
+typedef ExtensionFactory<QDesignerContainerExtension, QWorkspace, QWorkspaceContainer> QWorkspaceContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QWORKSPACE_CONTAINER_H
diff --git a/tools/designer/src/components/formeditor/spacer_propertysheet.cpp b/tools/designer/src/components/formeditor/spacer_propertysheet.cpp
new file mode 100644
index 0000000..16dd69d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/spacer_propertysheet.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "spacer_propertysheet.h"
+#include "qdesigner_widget_p.h"
+#include "formwindow.h"
+#include "spacer_widget_p.h"
+
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal
+{
+SpacerPropertySheet::SpacerPropertySheet(Spacer *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent)
+{
+ clearFakeProperties();
+}
+
+SpacerPropertySheet::~SpacerPropertySheet()
+{
+}
+
+bool SpacerPropertySheet::isVisible(int index) const
+{
+ static const QString spacerGroup = QLatin1String("Spacer");
+ return propertyGroup(index) == spacerGroup;
+}
+
+void SpacerPropertySheet::setProperty(int index, const QVariant &value)
+{
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+bool SpacerPropertySheet::dynamicPropertiesAllowed() const
+{
+ return false;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/spacer_propertysheet.h b/tools/designer/src/components/formeditor/spacer_propertysheet.h
new file mode 100644
index 0000000..a83e3d1
--- /dev/null
+++ b/tools/designer/src/components/formeditor/spacer_propertysheet.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SPACER_PROPERTYSHEET_H
+#define SPACER_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+#include <spacer_widget_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class SpacerPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit SpacerPropertySheet(Spacer *object, QObject *parent = 0);
+ virtual ~SpacerPropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool isVisible(int index) const;
+
+ virtual bool dynamicPropertiesAllowed() const;
+};
+
+typedef QDesignerPropertySheetFactory<Spacer, SpacerPropertySheet> SpacerPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SPACER_PROPERTYSHEET_H
diff --git a/tools/designer/src/components/formeditor/templateoptionspage.cpp b/tools/designer/src/components/formeditor/templateoptionspage.cpp
new file mode 100644
index 0000000..dacd0d3
--- /dev/null
+++ b/tools/designer/src/components/formeditor/templateoptionspage.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "templateoptionspage.h"
+#include "ui_templateoptionspage.h"
+
+#include <shared_settings_p.h>
+#include <iconloader_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <abstractdialoggui_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ----------------- TemplateOptionsWidget
+TemplateOptionsWidget::TemplateOptionsWidget(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_core(core),
+ m_ui(new Ui::TemplateOptionsWidget)
+{
+ m_ui->setupUi(this);
+
+ m_ui->m_addTemplatePathButton->setIcon(
+ qdesigner_internal::createIconSet(QString::fromUtf8("plus.png")));
+ m_ui->m_removeTemplatePathButton->setIcon(
+ qdesigner_internal::createIconSet(QString::fromUtf8("minus.png")));
+
+ connect(m_ui->m_templatePathListWidget, SIGNAL(itemSelectionChanged()),
+ this, SLOT(templatePathSelectionChanged()));
+ connect(m_ui->m_addTemplatePathButton, SIGNAL(clicked()), this, SLOT(addTemplatePath()));
+ connect(m_ui->m_removeTemplatePathButton, SIGNAL(clicked()), this, SLOT(removeTemplatePath()));
+}
+
+TemplateOptionsWidget::~TemplateOptionsWidget()
+{
+ delete m_ui;
+}
+
+QStringList TemplateOptionsWidget::templatePaths() const
+{
+ QStringList rc;
+ const int count = m_ui->m_templatePathListWidget->count();
+ for (int i = 0; i < count; i++) {
+ rc += m_ui->m_templatePathListWidget->item(i)->text();
+ }
+ return rc;
+}
+
+void TemplateOptionsWidget::setTemplatePaths(const QStringList &l)
+{
+ // add paths and select 0
+ m_ui->m_templatePathListWidget->clear();
+ if (l.empty()) {
+ // disable button
+ templatePathSelectionChanged();
+ } else {
+ const QStringList::const_iterator cend = l.constEnd();
+ for (QStringList::const_iterator it = l.constBegin(); it != cend; ++it)
+ m_ui->m_templatePathListWidget->addItem(*it);
+ m_ui->m_templatePathListWidget->setCurrentItem(m_ui->m_templatePathListWidget->item(0));
+ }
+}
+
+void TemplateOptionsWidget::addTemplatePath()
+{
+ const QString templatePath = chooseTemplatePath(m_core, this);
+ if (templatePath.isEmpty())
+ return;
+
+ const QList<QListWidgetItem *> existing
+ = m_ui->m_templatePathListWidget->findItems(templatePath, Qt::MatchExactly);
+ if (!existing.empty())
+ return;
+
+ QListWidgetItem *newItem = new QListWidgetItem(templatePath);
+ m_ui->m_templatePathListWidget->addItem(newItem);
+ m_ui->m_templatePathListWidget->setCurrentItem(newItem);
+}
+
+void TemplateOptionsWidget::removeTemplatePath()
+{
+ const QList<QListWidgetItem *> selectedPaths
+ = m_ui->m_templatePathListWidget->selectedItems();
+ if (selectedPaths.empty())
+ return;
+ delete selectedPaths.front();
+}
+
+void TemplateOptionsWidget::templatePathSelectionChanged()
+{
+ const QList<QListWidgetItem *> selectedPaths = m_ui->m_templatePathListWidget->selectedItems();
+ m_ui->m_removeTemplatePathButton->setEnabled(!selectedPaths.empty());
+}
+
+QString TemplateOptionsWidget::chooseTemplatePath(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ QString rc = core->dialogGui()->getExistingDirectory(parent,
+ tr("Pick a directory to save templates in"));
+ if (rc.isEmpty())
+ return rc;
+
+ if (rc.endsWith(QDir::separator()))
+ rc.remove(rc.size() - 1, 1);
+ return rc;
+}
+
+// ----------------- TemplateOptionsPage
+TemplateOptionsPage::TemplateOptionsPage(QDesignerFormEditorInterface *core) :
+ m_core(core)
+{
+}
+
+QString TemplateOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("TemplateOptionsPage", "Template Paths");
+}
+
+QWidget *TemplateOptionsPage::createPage(QWidget *parent)
+{
+ m_widget = new TemplateOptionsWidget(m_core, parent);
+ m_initialTemplatePaths = QDesignerSharedSettings(m_core).additionalFormTemplatePaths();
+ m_widget->setTemplatePaths(m_initialTemplatePaths);
+ return m_widget;
+}
+
+void TemplateOptionsPage::apply()
+{
+ if (m_widget) {
+ const QStringList newTemplatePaths = m_widget->templatePaths();
+ if (newTemplatePaths != m_initialTemplatePaths) {
+ QDesignerSharedSettings settings(m_core);
+ settings.setAdditionalFormTemplatePaths(newTemplatePaths);
+ m_initialTemplatePaths = newTemplatePaths;
+ }
+ }
+}
+
+void TemplateOptionsPage::finish()
+{
+}
+}
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/templateoptionspage.h b/tools/designer/src/components/formeditor/templateoptionspage.h
new file mode 100644
index 0000000..2f17141
--- /dev/null
+++ b/tools/designer/src/components/formeditor/templateoptionspage.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_TEMPLATEOPTIONS_H
+#define QDESIGNER_TEMPLATEOPTIONS_H
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+namespace Ui {
+ class TemplateOptionsWidget;
+}
+
+/* Present the user with a list of form template paths to save
+ * form templates. */
+class TemplateOptionsWidget : public QWidget
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(TemplateOptionsWidget)
+public:
+ explicit TemplateOptionsWidget(QDesignerFormEditorInterface *core,
+ QWidget *parent = 0);
+ ~TemplateOptionsWidget();
+
+
+ QStringList templatePaths() const;
+ void setTemplatePaths(const QStringList &l);
+
+ static QString chooseTemplatePath(QDesignerFormEditorInterface *core, QWidget *parent);
+
+private slots:
+ void addTemplatePath();
+ void removeTemplatePath();
+ void templatePathSelectionChanged();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ Ui::TemplateOptionsWidget *m_ui;
+};
+
+class TemplateOptionsPage : public QDesignerOptionsPageInterface
+{
+ Q_DISABLE_COPY(TemplateOptionsPage)
+public:
+ explicit TemplateOptionsPage(QDesignerFormEditorInterface *core);
+
+ virtual QString name() const;
+ virtual QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QStringList m_initialTemplatePaths;
+ QPointer<TemplateOptionsWidget> m_widget;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TEMPLATEOPTIONS_H
diff --git a/tools/designer/src/components/formeditor/templateoptionspage.ui b/tools/designer/src/components/formeditor/templateoptionspage.ui
new file mode 100644
index 0000000..3427ffe
--- /dev/null
+++ b/tools/designer/src/components/formeditor/templateoptionspage.ui
@@ -0,0 +1,59 @@
+<ui version="4.0" >
+ <class>qdesigner_internal::TemplateOptionsWidget</class>
+ <widget class="QWidget" name="qdesigner_internal::TemplateOptionsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>376</width>
+ <height>387</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="m_templatePathGroupBox" >
+ <property name="title" >
+ <string>Additional Template Paths</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="3" >
+ <widget class="QListWidget" name="m_templatePathListWidget" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QToolButton" name="m_addTemplatePathButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QToolButton" name="m_removeTemplatePathButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/designer/src/components/formeditor/tool_widgeteditor.cpp b/tools/designer/src/components/formeditor/tool_widgeteditor.cpp
new file mode 100644
index 0000000..aed7e80
--- /dev/null
+++ b/tools/designer/src/components/formeditor/tool_widgeteditor.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tool_widgeteditor.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+
+#include <layoutinfo_p.h>
+#include <qdesigner_dnditem_p.h>
+#include <qdesigner_resource.h>
+
+#include <QtGui/qevent.h>
+#include <QtGui/QAction>
+#include <QtGui/QMainWindow>
+#include <QtGui/QCursor>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+WidgetEditorTool::WidgetEditorTool(FormWindow *formWindow)
+ : QDesignerFormWindowToolInterface(formWindow),
+ m_formWindow(formWindow),
+ m_action(new QAction(tr("Edit Widgets"), this)),
+ m_specialDockDrag(false)
+{
+}
+
+QAction *WidgetEditorTool::action() const
+{
+ return m_action;
+}
+
+WidgetEditorTool::~WidgetEditorTool()
+{
+}
+
+QDesignerFormEditorInterface *WidgetEditorTool::core() const
+{
+ return m_formWindow->core();
+}
+
+QDesignerFormWindowInterface *WidgetEditorTool::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool WidgetEditorTool::mainWindowSeparatorEvent(QWidget *widget, QEvent *event)
+{
+ QMainWindow *mw = qobject_cast<QMainWindow*>(widget);
+ if (mw == 0)
+ return false;
+
+ if (event->type() != QEvent::MouseButtonPress
+ && event->type() != QEvent::MouseMove
+ && event->type() != QEvent::MouseButtonRelease)
+ return false;
+
+ QMouseEvent *e = static_cast<QMouseEvent*>(event);
+
+ if (event->type() == QEvent::MouseButtonPress) {
+ if (mw->isSeparator(e->pos())) {
+ m_separator_drag_mw = mw;
+ return true;
+ }
+ return false;
+ }
+
+ if (event->type() == QEvent::MouseMove)
+ return m_separator_drag_mw == mw;
+
+ if (event->type() == QEvent::MouseButtonRelease) {
+ if (m_separator_drag_mw != mw)
+ return false;
+ m_separator_drag_mw = 0;
+ return true;
+ }
+
+ return false;
+}
+
+bool WidgetEditorTool::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ const bool passive = core()->widgetFactory()->isPassiveInteractor(widget) != 0
+ || mainWindowSeparatorEvent(widget, event); // separators in QMainWindow
+ // are no longer widgets
+ switch (event->type()) {
+ case QEvent::Resize:
+ case QEvent::Move:
+ m_formWindow->updateSelection(widget);
+ break;
+
+ case QEvent::FocusOut:
+ case QEvent::FocusIn: // Popup cancelled over a form widget: Reset its focus frame
+ return !(passive || widget == m_formWindow || widget == m_formWindow->mainContainer());
+
+ case QEvent::Wheel: // Prevent spinboxes and combos from reacting
+ return !passive;
+
+ case QEvent::KeyPress:
+ return !passive && handleKeyPressEvent(widget, managedWidget, static_cast<QKeyEvent*>(event));
+
+ case QEvent::KeyRelease:
+ return !passive && handleKeyReleaseEvent(widget, managedWidget, static_cast<QKeyEvent*>(event));
+
+ case QEvent::MouseMove:
+ return !passive && handleMouseMoveEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::MouseButtonPress:
+ return !passive && handleMousePressEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::MouseButtonRelease:
+ return !passive && handleMouseReleaseEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::MouseButtonDblClick:
+ return !passive && handleMouseButtonDblClickEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::ContextMenu:
+ return !passive && handleContextMenu(widget, managedWidget, static_cast<QContextMenuEvent*>(event));
+
+ case QEvent::DragEnter:
+ return handleDragEnterMoveEvent(widget, managedWidget, static_cast<QDragEnterEvent *>(event), true);
+ case QEvent::DragMove:
+ return handleDragEnterMoveEvent(widget, managedWidget, static_cast<QDragEnterEvent *>(event), false);
+ case QEvent::DragLeave:
+ return handleDragLeaveEvent(widget, managedWidget, static_cast<QDragLeaveEvent *>(event));
+ case QEvent::Drop:
+ return handleDropEvent(widget, managedWidget, static_cast<QDropEvent *>(event));
+ default:
+ break;
+
+ } // end switch
+
+ return false;
+}
+
+// ### remove me
+
+bool WidgetEditorTool::handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e)
+{
+ return m_formWindow->handleContextMenu(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMouseButtonDblClickEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMousePressEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMouseMoveEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMouseReleaseEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
+{
+ return m_formWindow->handleKeyPressEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
+{
+ return m_formWindow->handleKeyReleaseEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handlePaintEvent(QWidget *widget, QWidget *managedWidget, QPaintEvent *e)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(managedWidget);
+ Q_UNUSED(e);
+
+ return false;
+}
+
+void WidgetEditorTool::detectDockDrag(const QDesignerMimeData *mimeData)
+{
+ m_specialDockDrag = false;
+ if (!mimeData)
+ return;
+
+ QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
+ if (!mw)
+ return;
+
+ const QList<QDesignerDnDItemInterface*> item_list = mimeData->items();
+
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ if (item->decoration() && item->decoration()->property("_q_dockDrag").toBool())
+ m_specialDockDrag = true;
+
+ }
+}
+
+bool WidgetEditorTool::handleDragEnterMoveEvent(QWidget *widget, QWidget * /*managedWidget*/, QDragMoveEvent *e, bool isEnter)
+{
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(e->mimeData());
+ if (!mimeData)
+ return false;
+
+ if (!m_formWindow->hasFeature(QDesignerFormWindowInterface::EditFeature)) {
+ e->ignore();
+ return true;
+ }
+
+ if (isEnter)
+ detectDockDrag(mimeData);
+
+
+ QPoint globalPos = QPoint(0, 0);
+ if (m_specialDockDrag) {
+ m_lastDropTarget = 0;
+ QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
+ if (mw)
+ m_lastDropTarget = mw->centralWidget();
+ } else {
+ // If custom widgets have acceptDrops=true, the event occurs for them
+ const QPoint formPos = widget != m_formWindow ? widget->mapTo(m_formWindow, e->pos()) : e->pos();
+ globalPos = m_formWindow->mapToGlobal(formPos);
+ const FormWindowBase::WidgetUnderMouseMode wum = mimeData->items().size() == 1 ? FormWindowBase::FindSingleSelectionDropTarget : FormWindowBase::FindMultiSelectionDropTarget;
+ QWidget *dropTarget = m_formWindow->widgetUnderMouse(formPos, wum);
+ if (m_lastDropTarget && dropTarget != m_lastDropTarget)
+ m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(globalPos), FormWindow::Restore);
+ m_lastDropTarget = dropTarget;
+ }
+
+ if (m_lastDropTarget)
+ m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(globalPos), FormWindow::Highlight);
+
+ if (isEnter || m_lastDropTarget)
+ mimeData->acceptEvent(e);
+ else
+ e->ignore();
+ return true;
+}
+
+bool WidgetEditorTool::handleDropEvent(QWidget *widget, QWidget *, QDropEvent *e)
+{
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(e->mimeData());
+ if (!mimeData)
+ return false;
+
+ if (!m_lastDropTarget ||
+ !m_formWindow->hasFeature(QDesignerFormWindowInterface::EditFeature)) {
+ e->ignore();
+ return true;
+ }
+ // FormWindow determines the position from the decoration.
+ const QPoint globalPos = widget->mapToGlobal(e->pos());
+ mimeData->moveDecoration(globalPos);
+ if (m_specialDockDrag) {
+ if (!m_formWindow->dropDockWidget(mimeData->items().at(0), globalPos)) {
+ e->ignore();
+ return true;
+ }
+ } else if (!m_formWindow->dropWidgets(mimeData->items(), m_lastDropTarget, globalPos)) {
+ e->ignore();
+ return true;
+ }
+ mimeData->acceptEvent(e);
+ return true;
+}
+
+bool WidgetEditorTool::restoreDropHighlighting()
+{
+ if (!m_lastDropTarget)
+ return false;
+
+ m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(QCursor::pos()), FormWindow::Restore);
+ m_lastDropTarget = 0;
+ return true;
+}
+
+bool WidgetEditorTool::handleDragLeaveEvent(QWidget *, QWidget *, QDragLeaveEvent *event)
+{
+ if (restoreDropHighlighting()) {
+ event->accept();
+ return true;
+ }
+ return false;
+}
+
+QWidget *WidgetEditorTool::editor() const
+{
+ Q_ASSERT(formWindow() != 0);
+ return formWindow()->mainContainer();
+}
+
+void WidgetEditorTool::activated()
+{
+ if (core()->widgetBox())
+ core()->widgetBox()->setEnabled(true);
+
+ if (m_formWindow == 0)
+ return;
+
+ QList<QWidget*> sel = m_formWindow->selectedWidgets();
+ foreach (QWidget *w, sel)
+ m_formWindow->raiseSelection(w);
+}
+
+void WidgetEditorTool::deactivated()
+{
+ if (core()->widgetBox())
+ core()->widgetBox()->setEnabled(false);
+
+ if (m_formWindow == 0)
+ return;
+
+ m_formWindow->clearSelection();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/tool_widgeteditor.h b/tools/designer/src/components/formeditor/tool_widgeteditor.h
new file mode 100644
index 0000000..58df974
--- /dev/null
+++ b/tools/designer/src/components/formeditor/tool_widgeteditor.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOOL_WIDGETEDITOR_H
+#define TOOL_WIDGETEDITOR_H
+
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+#include <QtGui/qevent.h>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QMainWindow;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+class QDesignerMimeData;
+
+class WidgetEditorTool: public QDesignerFormWindowToolInterface
+{
+ Q_OBJECT
+public:
+ explicit WidgetEditorTool(FormWindow *formWindow);
+ virtual ~WidgetEditorTool();
+
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowInterface *formWindow() const;
+ virtual QWidget *editor() const;
+ virtual QAction *action() const;
+
+ virtual void activated();
+ virtual void deactivated();
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+ bool handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e);
+ bool handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+ bool handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+ bool handlePaintEvent(QWidget *widget, QWidget *managedWidget, QPaintEvent *e);
+
+ bool handleDragEnterMoveEvent(QWidget *widget, QWidget *managedWidget, QDragMoveEvent *e, bool isEnter);
+ bool handleDragLeaveEvent(QWidget *widget, QWidget *managedWidget, QDragLeaveEvent *e);
+ bool handleDropEvent(QWidget *widget, QWidget *managedWidget, QDropEvent *e);
+
+private:
+ bool restoreDropHighlighting();
+ void detectDockDrag(const QDesignerMimeData *mimeData);
+
+ FormWindow *m_formWindow;
+ QAction *m_action;
+
+ bool mainWindowSeparatorEvent(QWidget *widget, QEvent *event);
+ QPointer<QMainWindow> m_separator_drag_mw;
+ QPointer<QWidget> m_lastDropTarget;
+ bool m_specialDockDrag;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TOOL_WIDGETEDITOR_H
diff --git a/tools/designer/src/components/formeditor/widgetselection.cpp b/tools/designer/src/components/formeditor/widgetselection.cpp
new file mode 100644
index 0000000..ce103ec
--- /dev/null
+++ b/tools/designer/src/components/formeditor/widgetselection.cpp
@@ -0,0 +1,746 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetselection.h"
+#include "formwindow.h"
+#include "formwindowmanager.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+// shared
+#include <qdesigner_command_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <layout_p.h>
+#include <layoutinfo_p.h>
+#include <formwindowbase_p.h>
+#include <grid_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QWidget>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QStylePainter>
+#include <QtGui/QGridLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QStyleOptionToolButton>
+#include <QtGui/QApplication>
+
+#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+enum { debugWidgetSelection = 0 };
+
+// Return the layout the widget is in
+template <class Layout>
+static inline Layout *managedLayoutOf(const QDesignerFormEditorInterface *core,
+ QWidget *w,
+ const Layout * /* vs6dummy */ = 0)
+{
+ if (QWidget *p = w->parentWidget())
+ if (QLayout *l = LayoutInfo::managedLayout(core, p))
+ return qobject_cast<Layout*>(l);
+ return 0;
+}
+
+// ----------- WidgetHandle
+WidgetHandle::WidgetHandle(FormWindow *parent, WidgetHandle::Type t, WidgetSelection *s) :
+ InvisibleWidget(parent->mainContainer()),
+ m_widget(0),
+ m_type(t),
+ m_formWindow( parent),
+ m_sel(s),
+ m_active(true)
+{
+ setMouseTracking(false);
+ setAutoFillBackground(true);
+
+ setBackgroundRole(m_active ? QPalette::Text : QPalette::Dark);
+ setFixedSize(6, 6);
+
+ updateCursor();
+}
+
+void WidgetHandle::updateCursor()
+{
+#ifndef QT_NO_CURSOR
+ if (!m_active) {
+ setCursor(Qt::ArrowCursor);
+ return;
+ }
+
+ switch (m_type) {
+ case LeftTop:
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case Top:
+ setCursor(Qt::SizeVerCursor);
+ break;
+ case RightTop:
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case Right:
+ setCursor(Qt::SizeHorCursor);
+ break;
+ case RightBottom:
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case Bottom:
+ setCursor(Qt::SizeVerCursor);
+ break;
+ case LeftBottom:
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case Left:
+ setCursor(Qt::SizeHorCursor);
+ break;
+ default:
+ Q_ASSERT(0);
+ }
+#endif
+}
+
+QDesignerFormEditorInterface *WidgetHandle::core() const
+{
+ if (m_formWindow)
+ return m_formWindow->core();
+
+ return 0;
+}
+
+void WidgetHandle::setActive(bool a)
+{
+ m_active = a;
+ setBackgroundRole(m_active ? QPalette::Text : QPalette::Dark);
+ updateCursor();
+}
+
+void WidgetHandle::setWidget(QWidget *w)
+{
+ m_widget = w;
+}
+
+void WidgetHandle::paintEvent(QPaintEvent *)
+{
+ QDesignerFormWindowManagerInterface *m = m_formWindow->core()->formWindowManager();
+
+ QStylePainter p(this);
+ if (m_formWindow->currentWidget() == m_widget) {
+ p.setPen(m->activeFormWindow() == m_formWindow ? Qt::blue : Qt::red);
+ p.drawRect(0, 0, width() - 1, height() - 1);
+ }
+}
+
+void WidgetHandle::mousePressEvent(QMouseEvent *e)
+{
+ e->accept();
+
+ if (!m_formWindow->hasFeature(FormWindow::EditFeature))
+ return;
+
+ if (!(m_widget && e->button() == Qt::LeftButton))
+ return;
+
+ if (!(m_active))
+ return;
+
+ QWidget *container = m_widget->parentWidget();
+
+ m_origPressPos = container->mapFromGlobal(e->globalPos());
+ m_geom = m_origGeom = m_widget->geometry();
+}
+
+void WidgetHandle::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!(m_widget && m_active && e->buttons() & Qt::LeftButton))
+ return;
+
+ e->accept();
+
+ QWidget *container = m_widget->parentWidget();
+
+ const QPoint rp = container->mapFromGlobal(e->globalPos());
+ const QPoint d = rp - m_origPressPos;
+
+ const QRect pr = container->rect();
+
+ qdesigner_internal::Grid grid;
+ if (const qdesigner_internal::FormWindowBase *fwb = qobject_cast<const qdesigner_internal::FormWindowBase*>(m_formWindow))
+ grid = fwb->designerGrid();
+
+ switch (m_type) {
+
+ case LeftTop: {
+ if (rp.x() > pr.width() - 2 * width() || rp.y() > pr.height() - 2 * height())
+ return;
+
+ int w = m_origGeom.width() - d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ int h = m_origGeom.height() - d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ const int dx = m_widget->width() - w;
+ const int dy = m_widget->height() - h;
+
+ trySetGeometry(m_widget, m_widget->x() + dx, m_widget->y() + dy, w, h);
+ } break;
+
+ case Top: {
+ if (rp.y() > pr.height() - 2 * height())
+ return;
+
+ int h = m_origGeom.height() - d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ const int dy = m_widget->height() - h;
+ trySetGeometry(m_widget, m_widget->x(), m_widget->y() + dy, m_widget->width(), h);
+ } break;
+
+ case RightTop: {
+ if (rp.x() < 2 * width() || rp.y() > pr.height() - 2 * height())
+ return;
+
+ int h = m_origGeom.height() - d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ const int dy = m_widget->height() - h;
+
+ int w = m_origGeom.width() + d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ trySetGeometry(m_widget, m_widget->x(), m_widget->y() + dy, w, h);
+ } break;
+
+ case Right: {
+ if (rp.x() < 2 * width())
+ return;
+
+ int w = m_origGeom.width() + d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ tryResize(m_widget, w, m_widget->height());
+ } break;
+
+ case RightBottom: {
+ if (rp.x() < 2 * width() || rp.y() < 2 * height())
+ return;
+
+ int w = m_origGeom.width() + d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ int h = m_origGeom.height() + d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ tryResize(m_widget, w, h);
+ } break;
+
+ case Bottom: {
+ if (rp.y() < 2 * height())
+ return;
+
+ int h = m_origGeom.height() + d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ tryResize(m_widget, m_widget->width(), h);
+ } break;
+
+ case LeftBottom: {
+ if (rp.x() > pr.width() - 2 * width() || rp.y() < 2 * height())
+ return;
+
+ int w = m_origGeom.width() - d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ int h = m_origGeom.height() + d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ int dx = m_widget->width() - w;
+
+ trySetGeometry(m_widget, m_widget->x() + dx, m_widget->y(), w, h);
+ } break;
+
+ case Left: {
+ if (rp.x() > pr.width() - 2 * width())
+ return;
+
+ int w = m_origGeom.width() - d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ const int dx = m_widget->width() - w;
+
+ trySetGeometry(m_widget, m_widget->x() + dx, m_widget->y(), w, m_widget->height());
+ } break;
+
+ default: break;
+
+ } // end switch
+
+ m_sel->updateGeometry();
+
+ if (LayoutInfo::layoutType(m_formWindow->core(), m_widget) != LayoutInfo::NoLayout)
+ m_formWindow->updateChildSelections(m_widget);
+}
+
+void WidgetHandle::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton || !m_active)
+ return;
+
+ e->accept();
+
+ if (!m_formWindow->hasFeature(FormWindow::EditFeature))
+ return;
+
+ switch (WidgetSelection::widgetState(m_formWindow->core(), m_widget)) {
+ case WidgetSelection::UnlaidOut:
+ if (m_geom != m_widget->geometry()) {
+ SetPropertyCommand *cmd = new SetPropertyCommand(m_formWindow);
+ cmd->init(m_widget, QLatin1String("geometry"), m_widget->geometry());
+ cmd->setOldValue(m_origGeom);
+ m_formWindow->commandHistory()->push(cmd);
+ m_formWindow->emitSelectionChanged();
+ }
+ break;
+ case WidgetSelection::LaidOut:
+ break;
+ case WidgetSelection::ManagedGridLayout:
+ changeGridLayoutItemSpan();
+ break;
+ case WidgetSelection::ManagedFormLayout:
+ changeFormLayoutItemSpan();
+ break;
+ }
+}
+
+// Match the left/right widget handle mouse movements to form layout span-changing operations
+static inline int formLayoutLeftHandleOperation(int dx, unsigned possibleOperations)
+{
+ if (dx < 0) {
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::FieldToSpanning)
+ return ChangeFormLayoutItemRoleCommand::FieldToSpanning;
+ return 0;
+ }
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::SpanningToField)
+ return ChangeFormLayoutItemRoleCommand::SpanningToField;
+ return 0;
+}
+
+static inline int formLayoutRightHandleOperation(int dx, unsigned possibleOperations)
+{
+ if (dx < 0) {
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::SpanningToLabel)
+ return ChangeFormLayoutItemRoleCommand::SpanningToLabel;
+ return 0;
+ }
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::LabelToSpanning)
+ return ChangeFormLayoutItemRoleCommand::LabelToSpanning;
+ return 0;
+}
+
+// Change form layout item horizontal span
+void WidgetHandle::changeFormLayoutItemSpan()
+{
+ QUndoCommand *cmd = 0;
+ // Figure out command according to the movement
+ const int dx = m_widget->geometry().center().x() - m_origGeom.center().x();
+ if (qAbs(dx) >= QApplication::startDragDistance()) {
+ int operation = 0;
+ if (const unsigned possibleOperations = ChangeFormLayoutItemRoleCommand::possibleOperations(m_formWindow->core(), m_widget)) {
+ switch (m_type) {
+ case WidgetHandle::Left:
+ operation = formLayoutLeftHandleOperation(dx, possibleOperations);
+ break;
+ case WidgetHandle::Right:
+ operation = formLayoutRightHandleOperation(dx, possibleOperations);
+ break;
+ default:
+ break;
+ }
+ if (operation) {
+ ChangeFormLayoutItemRoleCommand *fcmd = new ChangeFormLayoutItemRoleCommand(m_formWindow);
+ fcmd->init(m_widget, static_cast<ChangeFormLayoutItemRoleCommand::Operation>(operation));
+ cmd = fcmd;
+ }
+ }
+ }
+ if (cmd) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ // Cancelled/Invalid. Restore the size of the widget.
+ if (QFormLayout *form = managedLayoutOf<QFormLayout>(m_formWindow->core(), m_widget)) {
+ form->invalidate();
+ form->activate();
+ m_formWindow->clearSelection(false);
+ m_formWindow->selectWidget(m_widget);
+ }
+ }
+}
+
+void WidgetHandle::changeGridLayoutItemSpan()
+{
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), m_widget->parentWidget());
+ if (!deco)
+ return;
+ QGridLayout *grid = managedLayoutOf<QGridLayout>(m_formWindow->core(), m_widget);
+ if (!grid)
+ return;
+
+ const QSize size = m_widget->parentWidget()->size();
+
+ const int index = deco->indexOf(m_widget);
+ const QRect info = deco->itemInfo(index);
+ const int top = deco->findItemAt(info.top() - 1, info.left());
+ const int left = deco->findItemAt(info.top(), info.left() - 1);
+ const int bottom = deco->findItemAt(info.bottom() + 1, info.left());
+ const int right = deco->findItemAt(info.top(), info.right() + 1);
+
+ const QPoint pt = m_origGeom.center() - m_widget->geometry().center();
+
+ ChangeLayoutItemGeometry *cmd = 0;
+
+ switch (m_type) {
+ default:
+ break;
+
+ case WidgetHandle::Top: {
+ if (pt.y() < 0 && info.height() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y() + 1, info.x(), info.height() - 1, info.width());
+ } else if (pt.y() > 0 && top != -1 && grid->itemAt(top)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y() - 1, info.x(), info.height() + 1, info.width());
+ }
+ }
+ break;
+
+ case WidgetHandle::Left: {
+ if (pt.x() < 0 && info.width() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x() + 1, info.height(), info.width() - 1);
+ } else if (pt.x() > 0 && left != -1 && grid->itemAt(left)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x() - 1, info.height(), info.width() + 1);
+ }
+ }
+ break;
+
+ case WidgetHandle::Right: {
+ if (pt.x() > 0 && info.width() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height(), info.width() - 1);
+ } else if (pt.x() < 0 && right != -1 && grid->itemAt(right)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height(), info.width() + 1);
+ }
+ }
+ break;
+
+ case WidgetHandle::Bottom: {
+ if (pt.y() > 0 && info.width() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height() - 1, info.width());
+ } else if (pt.y() < 0 && bottom != -1 && grid->itemAt(bottom)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height() + 1, info.width());
+ }
+ }
+ break;
+ }
+
+ if (cmd != 0) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ grid->invalidate();
+ grid->activate();
+ m_formWindow->clearSelection(false);
+ m_formWindow->selectWidget(m_widget);
+ }
+}
+
+void WidgetHandle::trySetGeometry(QWidget *w, int x, int y, int width, int height)
+{
+ if (!m_formWindow->hasFeature(FormWindow::EditFeature))
+ return;
+
+ int minw = w->minimumSize().width();
+ minw = qMax(minw, 2 * m_formWindow->grid().x());
+
+ int minh = w->minimumSize().height();
+ minh = qMax(minh, 2 * m_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 WidgetHandle::tryResize(QWidget *w, int width, int height)
+{
+ int minw = w->minimumSize().width();
+ minw = qMax(minw, 16);
+
+ int minh = w->minimumSize().height();
+ minh = qMax(minh, 16);
+
+ w->resize(qMax(minw, width), qMax(minh, height));
+}
+
+// ------------------ WidgetSelection
+
+WidgetSelection::WidgetState WidgetSelection::widgetState(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ bool isManaged;
+ const LayoutInfo::Type lt = LayoutInfo::laidoutWidgetType(core, w, &isManaged);
+ if (lt == LayoutInfo::NoLayout)
+ return UnlaidOut;
+ if (!isManaged)
+ return LaidOut;
+ switch (lt) {
+ case LayoutInfo::Grid:
+ return ManagedGridLayout;
+ case LayoutInfo::Form:
+ return ManagedFormLayout;
+ default:
+ break;
+ }
+ return LaidOut;
+}
+
+WidgetSelection::WidgetSelection(FormWindow *parent) :
+ m_widget(0),
+ m_formWindow(parent)
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i)
+ m_handles[i] = new WidgetHandle(m_formWindow, static_cast<WidgetHandle::Type>(i), this);
+ hide();
+}
+
+void WidgetSelection::setWidget(QWidget *w)
+{
+ if (m_widget != 0)
+ m_widget->removeEventFilter(this);
+
+ if (w == 0) {
+ hide();
+ m_widget = 0;
+ return;
+ }
+
+ m_widget = w;
+
+ m_widget->installEventFilter(this);
+
+ updateActive();
+
+ updateGeometry();
+ show();
+}
+
+void WidgetSelection::updateActive()
+{
+ const WidgetState ws = widgetState(m_formWindow->core(), m_widget);
+ bool active[WidgetHandle::TypeCount];
+ qFill(active, active + WidgetHandle::TypeCount, false);
+ // Determine active handles
+ switch (ws) {
+ case UnlaidOut:
+ qFill(active, active + WidgetHandle::TypeCount, true);
+ break;
+ case ManagedGridLayout: // Grid: Allow changing span
+ active[WidgetHandle::Left] = active[WidgetHandle::Top] = active[WidgetHandle::Right] = active[WidgetHandle::Bottom] = true;
+ break;
+ case ManagedFormLayout: // Form: Allow changing column span
+ if (const unsigned operation = ChangeFormLayoutItemRoleCommand::possibleOperations(m_formWindow->core(), m_widget)) {
+ active[WidgetHandle::Left] = operation & (ChangeFormLayoutItemRoleCommand::SpanningToField|ChangeFormLayoutItemRoleCommand::FieldToSpanning);
+ active[WidgetHandle::Right] = operation & (ChangeFormLayoutItemRoleCommand::SpanningToLabel|ChangeFormLayoutItemRoleCommand::LabelToSpanning);
+ }
+ break;
+ default:
+ break;
+ }
+
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i)
+ if (WidgetHandle *h = m_handles[i]) {
+ h->setWidget(m_widget);
+ h->setActive(active[i]);
+ }
+}
+
+bool WidgetSelection::isUsed() const
+{
+ return m_widget != 0;
+}
+
+void WidgetSelection::updateGeometry()
+{
+ if (!m_widget || !m_widget->parentWidget())
+ return;
+
+ QPoint p = m_widget->parentWidget()->mapToGlobal(m_widget->pos());
+ p = m_formWindow->mapFromGlobal(p);
+ const QRect r(p, m_widget->size());
+
+ const int w = 6;
+ const int h = 6;
+
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *hndl = m_handles[ i ];
+ if (!hndl)
+ continue;
+ switch (i) {
+ case WidgetHandle::LeftTop:
+ hndl->move(r.x() - w / 2, r.y() - h / 2);
+ break;
+ case WidgetHandle::Top:
+ hndl->move(r.x() + r.width() / 2 - w / 2, r.y() - h / 2);
+ break;
+ case WidgetHandle::RightTop:
+ hndl->move(r.x() + r.width() - w / 2, r.y() - h / 2);
+ break;
+ case WidgetHandle::Right:
+ hndl->move(r.x() + r.width() - w / 2, r.y() + r.height() / 2 - h / 2);
+ break;
+ case WidgetHandle::RightBottom:
+ hndl->move(r.x() + r.width() - w / 2, r.y() + r.height() - h / 2);
+ break;
+ case WidgetHandle::Bottom:
+ hndl->move(r.x() + r.width() / 2 - w / 2, r.y() + r.height() - h / 2);
+ break;
+ case WidgetHandle::LeftBottom:
+ hndl->move(r.x() - w / 2, r.y() + r.height() - h / 2);
+ break;
+ case WidgetHandle::Left:
+ hndl->move(r.x() - w / 2, r.y() + r.height() / 2 - h / 2);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void WidgetSelection::hide()
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *h = m_handles[ i ];
+ if (h)
+ h->hide();
+ }
+}
+
+void WidgetSelection::show()
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *h = m_handles[ i ];
+ if (h) {
+ h->show();
+ h->raise();
+ }
+ }
+}
+
+void WidgetSelection::update()
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *h = m_handles[ i ];
+ if (h)
+ h->update();
+ }
+}
+
+QWidget *WidgetSelection::widget() const
+{
+ return m_widget;
+}
+
+QDesignerFormEditorInterface *WidgetSelection::core() const
+{
+ if (m_formWindow)
+ return m_formWindow->core();
+
+ return 0;
+}
+
+bool WidgetSelection::eventFilter(QObject *object, QEvent *event)
+{
+ if (object != widget())
+ return false;
+
+ switch (event->type()) {
+ default: break;
+
+ case QEvent::Move:
+ case QEvent::Resize:
+ updateGeometry();
+ break;
+ case QEvent::ZOrderChange:
+ show();
+ break;
+ } // end switch
+
+ return false;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/widgetselection.h b/tools/designer/src/components/formeditor/widgetselection.h
new file mode 100644
index 0000000..9099e89
--- /dev/null
+++ b/tools/designer/src/components/formeditor/widgetselection.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETSELECTION_H
+#define WIDGETSELECTION_H
+
+#include "formeditor_global.h"
+#include <invisible_widget_p.h>
+
+#include <QtCore/QHash>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QMouseEvent;
+class QPaintEvent;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+class WidgetSelection;
+
+class QT_FORMEDITOR_EXPORT WidgetHandle: public InvisibleWidget
+{
+ Q_OBJECT
+public:
+ enum Type
+ {
+ LeftTop,
+ Top,
+ RightTop,
+ Right,
+ RightBottom,
+ Bottom,
+ LeftBottom,
+ Left,
+
+ TypeCount
+ };
+
+ WidgetHandle(FormWindow *parent, Type t, WidgetSelection *s);
+ void setWidget(QWidget *w);
+ void setActive(bool a);
+ void updateCursor();
+
+ void setEnabled(bool) {}
+
+ QDesignerFormEditorInterface *core() const;
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+
+private:
+ void changeGridLayoutItemSpan();
+ void changeFormLayoutItemSpan();
+ void trySetGeometry(QWidget *w, int x, int y, int width, int height);
+ void tryResize(QWidget *w, int width, int height);
+
+private:
+ QWidget *m_widget;
+ const Type m_type;
+ QPoint m_origPressPos;
+ FormWindow *m_formWindow;
+ WidgetSelection *m_sel;
+ QRect m_geom, m_origGeom;
+ bool m_active;
+};
+
+class QT_FORMEDITOR_EXPORT WidgetSelection: public QObject
+{
+ Q_OBJECT
+public:
+ WidgetSelection(FormWindow *parent);
+
+ void setWidget(QWidget *w);
+ bool isUsed() const;
+
+ void updateActive();
+ void updateGeometry();
+ void hide();
+ void show();
+ void update();
+
+ QWidget *widget() const;
+
+ QDesignerFormEditorInterface *core() const;
+
+ virtual bool eventFilter(QObject *object, QEvent *event);
+
+ enum WidgetState { UnlaidOut, LaidOut, ManagedGridLayout, ManagedFormLayout };
+ static WidgetState widgetState(const QDesignerFormEditorInterface *core, QWidget *w);
+
+private:
+ WidgetHandle *m_handles[WidgetHandle::TypeCount];
+ QPointer<QWidget> m_widget;
+ FormWindow *m_formWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETSELECTION_H