Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/jsf
diff options
context:
space:
mode:
authoritrimble2006-10-30 18:59:16 +0000
committeritrimble2006-10-30 18:59:16 +0000
commit38bf0b94a9097fc95b4b875bc8f1c9c881bd53e8 (patch)
tree3441d21142de85a91748c8f8299c17ad152ae6b5 /jsf
parent676c1fe37e7743b8edcb79b521e6f965f05d0ce8 (diff)
downloadwebtools.jsf-38bf0b94a9097fc95b4b875bc8f1c9c881bd53e8.tar.gz
webtools.jsf-38bf0b94a9097fc95b4b875bc8f1c9c881bd53e8.tar.xz
webtools.jsf-38bf0b94a9097fc95b4b875bc8f1c9c881bd53e8.zip
Initial contribution.
Diffstat (limited to 'jsf')
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/.classpath7
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/.project33
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/META-INF/MANIFEST.MF163
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/about.html22
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/build.properties12
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.properties146
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.xml1559
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.properties27
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.xml119
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/configs/html_pi.xml48
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/configs/jsp_pi.xml22
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/default.properties2
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding.gifbin0 -> 133 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding_disabled.gifbin0 -> 852 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Plugin.gifbin0 -> 358 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold.gifbin0 -> 923 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold_disabled.gifbin0 -> 870 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_designer.gifbin0 -> 248 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_hsplit.gifbin0 -> 119 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic.gifbin0 -> 880 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic_disabled.gifbin0 -> 862 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont.gifbin0 -> 888 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont_disabled.gifbin0 -> 867 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_paragraph.gifbin0 -> 581 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont.gifbin0 -> 854 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont_disabled.gifbin0 -> 852 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_source.gifbin0 -> 153 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline.gifbin0 -> 916 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline_disabled.gifbin0 -> 882 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_vsplit.gifbin0 -> 113 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_nopic.jpgbin0 -> 1006 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/newsuade_wiz.gifbin0 -> 3148 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/large/PD_Palette_Default.gifbin0 -> 300 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Default.gifbin0 -> 82 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export.gifbin0 -> 958 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Disabled.gifbin0 -> 956 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Hover.gifbin0 -> 958 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import.gifbin0 -> 958 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Disabled.gifbin0 -> 957 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Hover.gifbin0 -> 958 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_A.gifbin0 -> 1039 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_FORM.gifbin0 -> 788 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_HR.gifbin0 -> 192 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_IMG.gifbin0 -> 1220 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_BUTTON.gifbin0 -> 325 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_CHECKBOX.gifbin0 -> 418 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_HIDDEN.gifbin0 -> 1109 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_IMAGE.gifbin0 -> 464 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_PASSWORD.gifbin0 -> 816 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_RADIO.gifbin0 -> 663 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_TEXT.gifbin0 -> 289 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_OBJECT.gifbin0 -> 728 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_SELECT.gifbin0 -> 467 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TABLE.gifbin0 -> 467 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TEXTAREA.gifbin0 -> 704 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_A.gifbin0 -> 218 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_BR.gifbin0 -> 885 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_FORM.gifbin0 -> 959 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_HR.gifbin0 -> 88 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_IMG.gifbin0 -> 585 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_BUTTON.gifbin0 -> 150 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_CHECKBOX.gifbin0 -> 149 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_HIDDEN.gifbin0 -> 341 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_IMAGE.gifbin0 -> 218 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_PASSWORD.gifbin0 -> 949 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_RADIO.gifbin0 -> 166 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_TEXT.gifbin0 -> 117 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_OBJECT.gifbin0 -> 176 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_SELECT.gifbin0 -> 914 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TABLE.gifbin0 -> 343 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TEXTAREA.gifbin0 -> 139 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DECLARATION.gifbin0 -> 535 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.INCLUDE.gifbin0 -> 449 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.PAGE.gifbin0 -> 1157 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.TAGLIB.gifbin0 -> 728 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_EXPRESSION.gifbin0 -> 452 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FALLBACK.gifbin0 -> 973 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FORWARD.gifbin0 -> 582 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_GETPROPERTY.gifbin0 -> 425 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_INCLUDE.gifbin0 -> 567 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAM.gifbin0 -> 636 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAMS.gifbin0 -> 726 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PLUGIN.gifbin0 -> 758 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_ROOT.gifbin0 -> 464 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SCRIPTLET.gifbin0 -> 1013 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SETPROPERTY.gifbin0 -> 425 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_TEXT.gifbin0 -> 358 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_USEBEAN.gifbin0 -> 791 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DECLARATION.gifbin0 -> 190 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.INCLUDE.gifbin0 -> 934 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.PAGE.gifbin0 -> 585 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.TAGLIB.gifbin0 -> 338 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_EXPRESSION.gifbin0 -> 126 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FALLBACK.gifbin0 -> 327 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FORWARD.gifbin0 -> 215 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_GETPROPERTY.gifbin0 -> 284 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_INCLUDE.gifbin0 -> 213 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAM.gifbin0 -> 333 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAMS.gifbin0 -> 948 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PLUGIN.gifbin0 -> 244 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_ROOT.gifbin0 -> 152 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SCRIPTLET.gifbin0 -> 531 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SETPROPERTY.gifbin0 -> 284 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_TEXT.gifbin0 -> 117 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_USEBEAN.gifbin0 -> 176 bytes
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/plugin.properties11
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/plugin.xml113
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/PaletteItemConfigContributions.exsd125
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/cmRegistry.exsd135
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/pageDesignerExtension.exsd184
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/popupMenuContributor.exsd120
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertyContributor.exsd113
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertySections.exsd141
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/schema/tagProperty.xsd154
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IHTMLConstants.java495
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJMTConstants.java63
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJSFConstants.java289
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/JMTResources.properties219
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PDPlugin.java438
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/container/ContainerActionGroup.java101
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/AbstractLinkCreator.java55
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/CreateLinkWizard.java95
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ExtensionReader.java80
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/HtmlLinkCreator.java69
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ILinkCreator.java32
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkRequest.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkUtil.java83
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkWizardPage.java155
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkAction.java214
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkCommand.java96
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/CustomedContextMenuActionGroup.java132
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/RunAction.java124
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/AlignSupport.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ChangeStyleAction.java176
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/DesignerToolBarAction.java143
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/HTagsInsertGroupAction.java191
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/InsertTagChangeStyleAction.java118
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneParagraphStyleAction.java97
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneStyleAction.java69
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphAction.java28
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphStyleAction.java172
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphSupport.java70
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeActionGroup.java195
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleAction.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleSupport.java46
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleAction.java34
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleSupport.java69
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeAttributeAction.java58
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStyleAction.java62
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStylePropertyAction.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ColorSupport.java82
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SelectEditPartAction.java41
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SingleElementActionGroup.java189
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleClassSupport.java113
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleSupport.java48
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableActionGroup.java195
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableOperationContext.java81
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/IBodyInfo.java89
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/internal/BodyInfo.java151
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CloneNodeCommand.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.properties22
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyAction.java74
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyNodeCommand.java83
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CreateItemCommand.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutAction.java71
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutNodeCommand.java83
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteAction.java64
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteNodeCommand.java117
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignAction.java64
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignResizeComponentCommand.java136
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignerCommand.java343
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/MoveNodeCommand.java91
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDDropRequest.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDRequestConstants.java20
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDTransferDropTargetListener.java62
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PaletteDropInsertCommand.java123
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteAction.java61
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteNodeCommand.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SourceViewerCommand.java115
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SwitchSelectionCommand.java72
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteColumnCommand.java103
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteHeaderFooterCommand.java81
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteRowCommand.java96
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertColumnCommand.java148
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertHeaderFooterCommand.java127
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertRowCommand.java159
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeColumnCommand.java100
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeRowCommand.java88
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/CaretPositionTracker.java28
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/HorizontalMoveCommand.java147
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/ICaretPositionMover.java21
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/VerticalMoveCommand.java204
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ApplyStyleCommand.java502
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/BlockNodeFinder.java126
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ClipboardData.java85
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ContentCommand.java118
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyCommand.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyEdit.java121
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutCommand.java49
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutEdit.java48
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteCommand.java66
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteEdit.java285
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DesignEdit.java409
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/IInputSourceProvider.java28
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertCommand.java50
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertEdit.java187
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/KeyboardData.java114
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/Paragraph.java49
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphApplyStyleCommand.java397
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphFinder.java121
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphUnapplyStyleCommand.java86
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/PasteCommand.java47
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/RangeModeCommand.java164
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/SelectAllCommand.java93
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/UnapplyStyleCommand.java88
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/WorkNode.java152
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/AddSubNodeCommand.java68
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeAttributeCommand.java115
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeStyleCommand.java80
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeTagCommand.java122
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/InsertSubNodeCommand.java47
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/RemoveSubNodeCommand.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/SingleNodeCommand.java143
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/AbstractTagConverter.java447
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConvertPosition.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java121
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterUtil.java102
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DefaultUnknownTagConverter.java91
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDeepTagConverter.java79
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDescriptionTagConverter.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumTagConverter.java94
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HTMLStringTagConverter.java107
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter.java153
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter2.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IConverterFactory.java39
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IDOMFactory.java39
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ITagConverter.java121
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/JSFConverterUtil.java66
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/PreferenceReader.java28
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToDumBlock.java59
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToInlineBlock.java79
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToSpan.java66
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/ATagConverter.java78
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/HTMLConverterFactory.java89
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/TableTagConverter.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/IncludeTagConverterPreview.java197
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/JSPConverterFactory.java96
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSTempUtil.java134
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSUtil.java242
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/ICSSStyle.java128
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/border/CSSBorder.java535
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorConverter.java129
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorDefaults.java278
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorManager.java40
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFont.java116
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFontManager.java195
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFont.java63
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFontManager.java23
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/html4.css155
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockBox.java101
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlow.java112
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowContext.java284
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowLayout.java251
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BoxUtil.java66
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBlockFlowLayout.java723
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBrFlowLayout.java62
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSFigure.java518
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSInlineFlowLayout.java319
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSLayout.java457
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSListItemLayout.java185
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSPageFlowLayout.java186
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextFigure.java302
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextLayout.java176
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSWidgetLayout.java220
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CompositeBox.java148
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/Debug.java28
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/DisplayToLayout.java100
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FigureUtil.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowBox.java161
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContainerLayout.java180
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContext.java90
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigure.java190
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigureLayout.java116
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowPage.java160
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowUtilities.java260
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSFigure.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSLayout.java55
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter.java29
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter2.java34
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/LineBox.java414
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/MultiLineLabel.java126
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/PageFlowLayout.java72
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextFragmentBox.java85
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextLayoutSupport.java386
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/WidgetBox.java41
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRGroupLayout.java179
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRLayout.java193
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCaptionLayout.java110
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCellLayout.java199
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableLayout2.java628
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CachedTableCellLayout.java251
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCaptionInfo.java63
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCellInfo.java216
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfo.java368
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfoContext.java112
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableItemInfo.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowGroupInfo.java103
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowInfo.java136
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSHtmlListStyleData.java126
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSMarkerStyleData.java89
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ContentObject.java37
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterHelper.java298
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterValueGenerator.java445
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/HTMLListInfoHelper.java71
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ICounterValueGenerator.java45
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IIndexConverter.java19
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IncrementObject.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ListStyleUtil.java30
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ResetObject.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterFactory.java52
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterUtil.java67
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/DecimalCounter.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/EnumerableCounter.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/ICounter.java21
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/RomanCounter.java121
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BackgroundColorMeta.java83
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderCollapseMeta.java39
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderColorMeta.java89
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderSpacingMeta.java122
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderStyleMeta.java188
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderWidthMeta.java245
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSMetaRegistry.java118
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSPropertyMeta.java125
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ColorPropertyMeta.java112
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ContentMeta.java52
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterIncrementMeta.java91
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterResetMeta.java88
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/DisplayMeta.java70
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/EmptyCellsMeta.java44
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FloatInfo.java149
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontFamilyMeta.java138
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontSizeMeta.java190
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontStyleMeta.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontWeightMeta.java105
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HeightMeta.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HorizontalAlignMeta.java94
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyID.java382
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyMeta.java86
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/LengthMeta.java210
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleImageMeta.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStylePositionMeta.java37
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleTypeMeta.java87
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/MarginWidthMeta.java41
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/OverflowMeta.java45
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PaddingWidthMeta.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionMeta.java47
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionOffsetMeta.java26
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TableUtil.java98
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextAlignMeta.java86
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextDecorationMeta.java95
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VerticalAlignMeta.java104
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VisibilityMeta.java45
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WhiteSpaceMeta.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WidthMeta.java52
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/DimensionInfo.java55
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSTextProvider.java40
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSWidgetProvider.java58
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/AbstractStyle.java662
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ControlOverrideSupport.java85
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/DefaultStyle.java255
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/HiddenElementStyle.java84
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/IRangeSelectionProxy.java25
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ITagEditInfo.java34
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ImageStyleHelper.java36
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/StyleUtil.java33
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/value/Length.java44
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/AbstractWidgetProvider.java57
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/BorderUtil.java268
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ButtonWidgetProvider.java205
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/CheckboxWidgetProvider.java98
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ComboWidgetProvider.java209
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/HiddenProvider.java135
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ImageWidgetProvider.java109
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/InputFileWidgetProvider.java175
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ListWidgetProvider.java211
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/RadioWidgetProvider.java108
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextAreaWidgetProvider.java202
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextInputWidgetProvider.java164
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/FeedBackInfo.java50
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/ILocalDropHandler.java83
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/LocalDropRequest.java63
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceDropTargetListener.java138
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceMouseTrackAdapter.java156
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerTemplateTransferDragSourceListener.java49
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DropSelectionWizard.java134
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropCommand.java125
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropEditPolicy.java235
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalSelectionDropTargetListener.java125
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/Messages.java34
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/PDTemplateTransferDropTargetListener.java102
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/RegistryReader.java79
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/ResouceDropTargetListener.java113
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SimpleWizardSelectionPage.java270
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewLocalDropCommand.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewerDragDropHelper.java344
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/TextEditorDropTargetListenerFactory.java50
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/messages.properties7
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/CaretMoveIterator.java263
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPosition.java123
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPositionHelper.java402
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRange.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRangeHelper.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition.java141
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition2.java129
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMStyleUtil.java173
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMUtil.java232
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditHelper.java482
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java1795
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditValidateUtil.java378
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMPosition.java58
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMRefPosition.java30
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/JSFValidatorSupport.java120
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/ValidatorSupport.java91
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/ColStructure.java54
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableChildElementPosition.java52
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableUtil.java531
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/DesignerStructuredTextEditorJSP.java46
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/HTMLEditor.java1009
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/IDesignViewer.java35
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/OutlineConfiguration.java72
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/PageDesignerActionConstants.java49
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SelectionSynchronizer.java163
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SimpleGraphicalEditor.java662
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.java37
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.properties27
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ChangeStyleAction.java179
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DataBindingViewAction.java58
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignActionBarFactory.java101
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignPageActionContributor.java218
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerStyleActionGroup.java188
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerUndoRedoAction.java107
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PageDesignerActionBarContributor2.java345
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PaletteViewAction.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PropertiesViewAction.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/RelatedViewActionGroup.java110
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/SourcePageActionContributor.java100
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/DelegatingZoomManager.java374
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/IPageDesignerConstants.java125
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/JSPEditorMessages.properties13
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/MessageFormater.java75
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/PageDesignerResources.java54
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizer.java141
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizerDialog.java217
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteImages.java30
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteRoot.java234
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewer.java199
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewerProvider.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/HTMLEditorPaletteFactory.java100
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IEntryChangeListener.java27
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteConstants.java67
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemCategory.java66
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemDescriptor.java84
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemEntry.java79
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemManager.java58
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IResourceManager.java27
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/ShowAllAction.java50
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/DocumentFactoryTLD.java33
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteElementTemplateHelper.java161
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteHelper.java313
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemCategory.java385
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemDescriptor.java383
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemManager.java978
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnHelper.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnResizableEditPolicy.java147
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DesignerElementEditPolicy.java137
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DragMoveEditPolicy.java184
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ElementResizableEditPolicy.java464
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentCornerHandle.java35
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentHandle.java197
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ITableEditAdapter.java72
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/JSFDropEditPolicy.java88
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LinkEditPolicy.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LocationHelper.java192
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/MoveSupport.java62
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PDEditPolicy.java19
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PolicyHelper.java40
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/AbstractElementEdit.java89
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java84
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEdit.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEditFactory.java35
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/HTMLElementEditFactory.java46
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/TableElementEdit.java273
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/JSPElementEditFactory.java48
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibElementEdit.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibURIAction.java145
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/extensionpoint/IContextMenuItemContributor.java29
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/AbstractFigureHandler.java73
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/BRFigureHandler.java40
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/DefaultFigureHandler.java43
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/FigureFactory.java221
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/HiddenFigureHandler.java41
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/IFigureHandler.java33
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ImgFigureHandler.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/InputFigureHandler.java193
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ObjectFigureHandler.java35
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/SelectFigureHandler.java87
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/TextareaFigureHandler.java49
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/WidgetFigureHandler.java39
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationEditPolicy.java157
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationRequest.java70
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationTool.java273
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemToolEntry.java56
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/AttributeDescriptor.java204
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/BindingHandlerDelegate.java118
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/EditorCreator.java112
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeCellEditorFactory.java68
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeDescriptor.java105
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IBindingHandler.java70
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/ICMRegistry.java34
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IElementDescriptor.java66
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IValueType.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CMRegistry.java208
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CategoryNameComparator.java77
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFacRegistryReader.java77
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFactoryRegistry.java201
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/DefaultEditorCreator.java227
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescReader.java433
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescriptor.java122
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/LocaleFallback.java109
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/SimpleCMRegistry.java72
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/CSSStyleAdapterFactory.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/DocumentEditPart.java217
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/EditProxyAdapter.java69
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/ElementEditPart.java552
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/HTMLEditPartsFactory.java59
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/NodeEditPart.java187
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/Refresher.java119
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/RefresherFactory.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/SubNodeEditPart.java26
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/TextEditPart.java178
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PageExpressionContext.java189
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewConvertContext.java112
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewHandlerNew.java119
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.java59
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.properties6
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/WindowsIEBrowser.java70
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AllPropertySection.java142
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertyDescriptor.java172
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySource.java181
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySourceProvider.java49
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/BaseCustomSection.java194
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerPropertyTool.java411
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerTabbedPropertySheetPage.java184
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ISectionFilter.java28
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ITabbedPropertiesConstants.java127
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/MyPropertySheetPage.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/NavigationHiearchyAction.java127
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/PropertyDescriptorWrapper.java149
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroup.java343
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupMessages.java76
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupSection.java111
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/DialogUtil.java121
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/IElementContextable.java36
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/messages.properties4
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CSSDialogCellEditor.java63
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorFactory.java485
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorWrapper.java358
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/EditableDialogCellEditor.java140
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledComboBoxCellEditor.java149
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledStyleComboCellEditor.java135
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LoadbundleSelectionCellEditor.java57
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/NamedBooleanCellEditor.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceBoundle.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceDialogCellEditor.java202
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/StyleComboCellEditor.java241
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/messages.properties3
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerSectionDescriptor.java274
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerTabPropertySectionDescriptorProvider.java141
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/range/RangeUtil.java367
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/LocationModifierRequest.java106
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/NodeCreationFactory.java123
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnHandle.java31
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnResizeHandle.java35
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterAction.java45
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterRequest.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteRowColumnAction.java47
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/EmptyLocator.java37
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterAction.java46
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterRequest.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertRowColumnAction.java45
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/MarqueeRectangleFigure.java85
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowHandle.java31
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowResizeHandle.java36
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandle.java64
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandleLocator.java109
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditAdapter.java158
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditConst.java22
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditHelper.java40
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableHandleKit.java53
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableInsertRequest.java39
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizableEditPolicy.java44
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizeRequest.java61
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnDeleteRequest.java29
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnRequest.java50
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandle.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandleLocator.java108
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideHandle.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemDragTracker.java75
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemHandle.java78
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeDragTracker.java175
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeHandle.java51
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ExposeHelper.java315
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ObjectModeDragTracker.java57
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeDragTracker.java304
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeSelectionTool.java285
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/CommonResourceDialog.java408
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/PartActivationHandler.java93
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/ResourceOnClasspathDialog.java257
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/TreeViewerSelectionDialog.java321
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/NestedEditorActionBarContributor.java43
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorPart.java524
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSelectionProvider.java154
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSite.java441
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableClasspathResourceButtonDialogField.java44
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableResourceButtonDialogField.java67
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/DialogFieldWrapper.java411
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ExtendedResourceButtonDialogField.java38
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/StyleButtonDialogField.java99
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroudPreferenceNode.java133
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroundPreferencePage.java317
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferenceNode.java133
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferencePage.java394
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferenceNode.java133
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferencePage.java535
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferenceNode.java134
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferencePage.java670
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.java37
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.properties83
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferenceNode.java134
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferencePage.java179
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/IStyleConstants.java110
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferenceNode.java133
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferencePage.java160
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferenceNode.java134
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferencePage.java779
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleCombo.java42
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleDialog.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferenceNode.java134
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferencePage.java522
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/BodyHelper.java327
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CMUtil.java144
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CacheManager.java75
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CommandUtil.java156
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/DOMUtil.java240
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/EntityMap.java201
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLSpecialCharHelper.java422
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLUtil.java95
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ICacheEntryCreator.java18
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ImageResolver.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/IntFlexArray.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JSPUtil.java211
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JavaUtil.java97
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/NodeLocationComparator.java73
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/PreviewUtil.java344
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ProjectResolver.java488
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectManyHelper.java211
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectionHelper.java390
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/StructuredModelUtil.java70
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/UriAdapterFactory.java54
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/WebAppUtil.java59
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/XMLUtil.java110
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ActionData.java65
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicMovementRule.java41
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicPositionRule.java93
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ContainerMoveInAndOutRule.java102
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultMovementRule.java48
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionRule.java108
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionValidator.java223
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DnDPositionValidator.java32
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/HeadDataPositionRule.java27
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IEPanelgridPositionRule.java48
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IETablePositionRule.java201
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementMediator.java32
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementRule.java21
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionMediator.java60
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionRule.java61
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IValidationRule.java19
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingNavigationMediator.java187
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingPositionMediator.java37
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/JSFRootContainerPositionRule.java172
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/NodeConstructionPositionRule.java27
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/RootContainerPositionRule.java114
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/Target.java68
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/WhitespacePositionMoveRule.java149
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretPositionResolver.java321
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretUpdater.java234
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignPosition.java186
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRange.java79
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRefPosition.java46
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/EditPartPositionHelper.java699
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/FlowBoxLine.java211
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/HTMLGraphicalViewer.java528
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewer.java63
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewerListener.java23
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/LayoutPart.java470
-rw-r--r--jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/TextPosition.java74
709 files changed, 87360 insertions, 0 deletions
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/.classpath b/jsf/plugins/org.eclipse.jst.pagedesigner/.classpath
new file mode 100644
index 000000000..cb0105380
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/.project b/jsf/plugins/org.eclipse.jst.pagedesigner/.project
new file mode 100644
index 000000000..6f05a03a6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.jst.pagedesigner</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.ibm.sse.model.structuredbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/META-INF/MANIFEST.MF b/jsf/plugins/org.eclipse.jst.pagedesigner/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..1232b2681
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/META-INF/MANIFEST.MF
@@ -0,0 +1,163 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: org.eclipse.jst.pagedesigner;singleton:=true
+Bundle-Name: %pluginName
+Bundle-Version: 1.5.0
+Bundle-ClassPath: pagedesigner.jar
+Bundle-Activator: org.eclipse.jst.pagedesigner.PDPlugin
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
+ org.eclipse.debug.ui,
+ org.eclipse.emf.ecore,
+ org.eclipse.gef;visibility:=reexport,
+ org.eclipse.jface.text;visibility:=reexport,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.wst.common.ui,
+ org.eclipse.wst.html.ui,
+ org.eclipse.wst.sse.core;visibility:=reexport,
+ org.eclipse.wst.css.core;visibility:=reexport,
+ org.eclipse.wst.html.core;visibility:=reexport,
+ org.eclipse.wst.xml.core;visibility:=reexport,
+ org.eclipse.wst.common.uriresolver;visibility:=reexport,
+ org.eclipse.wst.common.ui.properties;visibility:=reexport,
+ org.eclipse.wst.sse.ui;visibility:=reexport,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.jst.j2ee,
+ org.eclipse.jst.jsp.core;visibility:=reexport,
+ org.eclipse.jst.jsp.ui,
+ org.eclipse.jst.j2ee.web,
+ org.eclipse.jst.pagedesigner.jsp.core,
+ org.eclipse.jst.pagedesigner.common;visibility:=reexport
+Eclipse-LazyStart: true
+Provide-Package: org.eclipse.jst.pagedesigner,
+ org.eclipse.jst.pagedesigner.actions.container,
+ org.eclipse.jst.pagedesigner.actions.link,
+ org.eclipse.jst.pagedesigner.actions.menuextension,
+ org.eclipse.jst.pagedesigner.actions.range,
+ org.eclipse.jst.pagedesigner.actions.single,
+ org.eclipse.jst.pagedesigner.actions.table,
+ org.eclipse.jst.pagedesigner.adapters,
+ org.eclipse.jst.pagedesigner.adapters.internal,
+ org.eclipse.jst.pagedesigner.commands,
+ org.eclipse.jst.pagedesigner.commands.html,
+ org.eclipse.jst.pagedesigner.commands.nav,
+ org.eclipse.jst.pagedesigner.commands.range,
+ org.eclipse.jst.pagedesigner.commands.single,
+ org.eclipse.jst.pagedesigner.converter,
+ org.eclipse.jst.pagedesigner.converter.html,
+ org.eclipse.jst.pagedesigner.converter.jsp,
+ org.eclipse.jst.pagedesigner.css2,
+ org.eclipse.jst.pagedesigner.css2.border,
+ org.eclipse.jst.pagedesigner.css2.color,
+ org.eclipse.jst.pagedesigner.css2.font,
+ org.eclipse.jst.pagedesigner.css2.layout,
+ org.eclipse.jst.pagedesigner.css2.layout.table,
+ org.eclipse.jst.pagedesigner.css2.list,
+ org.eclipse.jst.pagedesigner.css2.marker,
+ org.eclipse.jst.pagedesigner.css2.property,
+ org.eclipse.jst.pagedesigner.css2.provider,
+ org.eclipse.jst.pagedesigner.css2.style,
+ org.eclipse.jst.pagedesigner.css2.value,
+ org.eclipse.jst.pagedesigner.css2.widget,
+ org.eclipse.jst.pagedesigner.dnd,
+ org.eclipse.jst.pagedesigner.dnd.internal,
+ org.eclipse.jst.pagedesigner.dom,
+ org.eclipse.jst.pagedesigner.dom.html,
+ org.eclipse.jst.pagedesigner.editors,
+ org.eclipse.jst.pagedesigner.editors.actions,
+ org.eclipse.jst.pagedesigner.editors.pagedesigner,
+ org.eclipse.jst.pagedesigner.editors.palette,
+ org.eclipse.jst.pagedesigner.editors.palette.impl,
+ org.eclipse.jst.pagedesigner.editpolicies,
+ org.eclipse.jst.pagedesigner.elementedit,
+ org.eclipse.jst.pagedesigner.elementedit.html,
+ org.eclipse.jst.pagedesigner.elementedit.jsp,
+ org.eclipse.jst.pagedesigner.extensionpoint,
+ org.eclipse.jst.pagedesigner.figurehandler,
+ org.eclipse.jst.pagedesigner.itemcreation,
+ org.eclipse.jst.pagedesigner.meta,
+ org.eclipse.jst.pagedesigner.meta.internal,
+ org.eclipse.jst.pagedesigner.parts,
+ org.eclipse.jst.pagedesigner.preview,
+ org.eclipse.jst.pagedesigner.properties,
+ org.eclipse.jst.pagedesigner.properties.attrgroup,
+ org.eclipse.jst.pagedesigner.properties.celleditors,
+ org.eclipse.jst.pagedesigner.properties.internal,
+ org.eclipse.jst.pagedesigner.range,
+ org.eclipse.jst.pagedesigner.requests,
+ org.eclipse.jst.pagedesigner.tableedit,
+ org.eclipse.jst.pagedesigner.tools,
+ org.eclipse.jst.pagedesigner.ui.common,
+ org.eclipse.jst.pagedesigner.ui.common.sash,
+ org.eclipse.jst.pagedesigner.ui.dialogfields,
+ org.eclipse.jst.pagedesigner.ui.dialogs,
+ org.eclipse.jst.pagedesigner.utils,
+ org.eclipse.jst.pagedesigner.validation.caret,
+ org.eclipse.jst.pagedesigner.viewer
+Bundle-ManifestVersion: 2
+Export-Package: org.eclipse.jst.pagedesigner,
+ org.eclipse.jst.pagedesigner.actions.container,
+ org.eclipse.jst.pagedesigner.actions.link,
+ org.eclipse.jst.pagedesigner.actions.menuextension,
+ org.eclipse.jst.pagedesigner.actions.range,
+ org.eclipse.jst.pagedesigner.actions.single,
+ org.eclipse.jst.pagedesigner.actions.table,
+ org.eclipse.jst.pagedesigner.adapters,
+ org.eclipse.jst.pagedesigner.adapters.internal,
+ org.eclipse.jst.pagedesigner.commands,
+ org.eclipse.jst.pagedesigner.commands.html,
+ org.eclipse.jst.pagedesigner.commands.nav,
+ org.eclipse.jst.pagedesigner.commands.range,
+ org.eclipse.jst.pagedesigner.commands.single,
+ org.eclipse.jst.pagedesigner.converter,
+ org.eclipse.jst.pagedesigner.converter.html,
+ org.eclipse.jst.pagedesigner.converter.jsp,
+ org.eclipse.jst.pagedesigner.css2,
+ org.eclipse.jst.pagedesigner.css2.border,
+ org.eclipse.jst.pagedesigner.css2.color,
+ org.eclipse.jst.pagedesigner.css2.font,
+ org.eclipse.jst.pagedesigner.css2.layout,
+ org.eclipse.jst.pagedesigner.css2.layout.table,
+ org.eclipse.jst.pagedesigner.css2.list,
+ org.eclipse.jst.pagedesigner.css2.marker,
+ org.eclipse.jst.pagedesigner.css2.property,
+ org.eclipse.jst.pagedesigner.css2.provider,
+ org.eclipse.jst.pagedesigner.css2.style,
+ org.eclipse.jst.pagedesigner.css2.value,
+ org.eclipse.jst.pagedesigner.css2.widget,
+ org.eclipse.jst.pagedesigner.dnd,
+ org.eclipse.jst.pagedesigner.dnd.internal,
+ org.eclipse.jst.pagedesigner.dom,
+ org.eclipse.jst.pagedesigner.dom.html,
+ org.eclipse.jst.pagedesigner.editors,
+ org.eclipse.jst.pagedesigner.editors.actions,
+ org.eclipse.jst.pagedesigner.editors.pagedesigner,
+ org.eclipse.jst.pagedesigner.editors.palette,
+ org.eclipse.jst.pagedesigner.editors.palette.impl,
+ org.eclipse.jst.pagedesigner.editpolicies,
+ org.eclipse.jst.pagedesigner.elementedit,
+ org.eclipse.jst.pagedesigner.elementedit.html,
+ org.eclipse.jst.pagedesigner.elementedit.jsp,
+ org.eclipse.jst.pagedesigner.extensionpoint,
+ org.eclipse.jst.pagedesigner.figurehandler,
+ org.eclipse.jst.pagedesigner.itemcreation,
+ org.eclipse.jst.pagedesigner.meta,
+ org.eclipse.jst.pagedesigner.meta.internal,
+ org.eclipse.jst.pagedesigner.parts,
+ org.eclipse.jst.pagedesigner.preview,
+ org.eclipse.jst.pagedesigner.properties,
+ org.eclipse.jst.pagedesigner.properties.attrgroup,
+ org.eclipse.jst.pagedesigner.properties.celleditors,
+ org.eclipse.jst.pagedesigner.properties.internal,
+ org.eclipse.jst.pagedesigner.range,
+ org.eclipse.jst.pagedesigner.requests,
+ org.eclipse.jst.pagedesigner.tableedit,
+ org.eclipse.jst.pagedesigner.tools,
+ org.eclipse.jst.pagedesigner.ui.common,
+ org.eclipse.jst.pagedesigner.ui.common.sash,
+ org.eclipse.jst.pagedesigner.ui.dialogfields,
+ org.eclipse.jst.pagedesigner.ui.dialogs,
+ org.eclipse.jst.pagedesigner.utils,
+ org.eclipse.jst.pagedesigner.validation.caret,
+ org.eclipse.jst.pagedesigner.viewer
+
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/about.html b/jsf/plugins/org.eclipse.jst.pagedesigner/about.html
new file mode 100644
index 000000000..5e763eace
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/about.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 20, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content.</p>
+
+</body>
+</html>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties
new file mode 100644
index 000000000..9297c2d89
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties
@@ -0,0 +1,12 @@
+jars.compile.order = pagedesigner.jar
+source.pagedesigner.jar = src/
+output.pagedesigner.jar = bin/
+bin.includes = pagedesigner.jar,\
+ META-INF/,\
+ configs/,\
+ icons/,\
+ jsf-tld/,\
+ plugin.properties,\
+ plugin.xml,\
+ schema/
+src.includes = src/
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.properties
new file mode 100644
index 000000000..090002103
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.properties
@@ -0,0 +1,146 @@
+Attribute.Label.abbr=Abbr
+Attribute.Label.accept=Accept
+Attribute.Label.accesskey=Accesskey
+Attribute.Label.action=Action
+Attribute.Label.align=Align
+Attribute.Label.alink=Alink
+Attribute.Label.alt=Alt
+Attribute.Label.archive=Archive
+Attribute.Label.autostart=Autostart
+Attribute.Label.axis=Axis
+Attribute.Label.background=Background
+Attribute.Label.balance=Balance
+Attribute.Label.bgcolor=Bgcolor
+Attribute.Label.border=Border
+Attribute.Label.bordercolor=Bordercolor
+Attribute.Label.bordercolordark=Bordercolordark
+Attribute.Label.bordercolorlight=Bordercolorlight
+Attribute.Label.bottommargin=Bottommargin
+Attribute.Label.cellpadding=Cellpadding
+Attribute.Label.cellspacing=Cellspacing
+Attribute.Label.checked=Checked
+Attribute.Label.cite=Cite
+Attribute.Label.class=Class
+Attribute.Label.classid=Classid
+Attribute.Label.clear=Clear
+Attribute.Label.code=Code
+Attribute.Label.codebase=Codebase
+Attribute.Label.codetype=Codetype
+Attribute.Label.color=Color
+Attribute.Label.cols=Cols
+Attribute.Label.colspan=Colspan
+Attribute.Label.compact=Compact
+Attribute.Label.content=Content
+Attribute.Label.controls=Controls
+Attribute.Label.coords=Coords
+Attribute.Label.data=Data
+Attribute.Label.datapagesize=Datapagesize
+Attribute.Label.datetime=Datetime
+Attribute.Label.declare=Declare
+Attribute.Label.defer=Defer
+Attribute.Label.delay=Delay
+Attribute.Label.dir=Dir
+Attribute.Label.disabled=Disabled
+Attribute.Label.dynsrc=Dynsrc
+Attribute.Label.enctype=Enctype
+Attribute.Label.face=Face
+Attribute.Label.for=For
+Attribute.Label.frame=Frame
+Attribute.Label.frameborder=Frameborder
+Attribute.Label.framespacing=Framespacing
+Attribute.Label.headers=Headers
+Attribute.Label.height=Height
+Attribute.Label.hidden=Hidden
+Attribute.Label.href=Href
+Attribute.Label.hreflang=Hreflang
+Attribute.Label.hspace=Hspace
+Attribute.Label.http-equiv=http-equiv
+Attribute.Label.id=ID
+Attribute.Label.ismap=Ismap
+Attribute.Label.label=Label
+Attribute.Label.lang=Lang
+Attribute.Label.language=Language
+Attribute.Label.leftmargin=Leftmargin
+Attribute.Label.link=Link
+Attribute.Label.longdesc=Longdesc
+Attribute.Label.loop=Loop
+Attribute.Label.lowsrc=Lowsrc
+Attribute.Label.marginheight=Marginheight
+Attribute.Label.marginwidth=Marginwidth
+Attribute.Label.maxlength=Maxlength
+Attribute.Label.mayscript=Mayscript
+Attribute.Label.media=Media
+Attribute.Label.method=Method
+Attribute.Label.multiple=Multiple
+Attribute.Label.name=Name
+Attribute.Label.noresize=Noresize
+Attribute.Label.noshade=Noshade
+Attribute.Label.nowrap=Nowrap
+Attribute.Label.onblur=Onblur
+Attribute.Label.onchange=Onchange
+Attribute.Label.onclick=Onclick
+Attribute.Label.ondblclick=Ondblclick
+Attribute.Label.onfocus=Onfocus
+Attribute.Label.onkeydown=Onkeydown
+Attribute.Label.onkeypress=Onkeypress
+Attribute.Label.onkeyup=Onkeyup
+Attribute.Label.onload=Onload
+Attribute.Label.onmousedown=Onmousedown
+Attribute.Label.onmousemove=Onmousemove
+Attribute.Label.onmouseout=Onmouseout
+Attribute.Label.onmouseover=Onmouseover
+Attribute.Label.onmouseup=Onmouseup
+Attribute.Label.onreset=Onreset
+Attribute.Label.onselect=Onselect
+Attribute.Label.onsubmit=Onsubmit
+Attribute.Label.onunload=Onunload
+Attribute.Label.prompt=Prompt
+Attribute.Label.readonly=Readonly
+Attribute.Label.rel=Rel
+Attribute.Label.rev=Rev
+Attribute.Label.rightmargin=Rightmargin
+Attribute.Label.rows=Rows
+Attribute.Label.rowspan=Rowspan
+Attribute.Label.rules=Rules
+Attribute.Label.scope=Scope
+Attribute.Label.scrolling=Scrolling
+Attribute.Label.selected=Selected
+Attribute.Label.shape=Shape
+Attribute.Label.size=Size
+Attribute.Label.span=Span
+Attribute.Label.src=Src
+Attribute.Label.standby=Standby
+Attribute.Label.start=Start
+Attribute.Label.style=Style
+Attribute.Label.summary=Summary
+Attribute.Label.tabindex=Tabindex
+Attribute.Label.target=Target
+Attribute.Label.text=Text
+Attribute.Label.title=Title
+Attribute.Label.topmargin=Topmargin
+Attribute.Label.type=Type
+Attribute.Label.usemap=Usemap
+Attribute.Label.valign=Valign
+Attribute.Label.value=Value
+Attribute.Label.valuetype=Valuetype
+Attribute.Label.vlink=Vlink
+Attribute.Label.volume=Volume
+Attribute.Label.vspace=Vspace
+Attribute.Label.width=Width
+Attribute.Label.wrap=Wrap
+Attribute.Label.xmlns=Xmlns
+Category.Label.Accessibility=Accessibility
+Category.Label.VisualProperty=VisualProperty
+Category.Label.Browser.Specific=Browser Specific
+Category.Label.CSS/Accessibility=CSS/Accessibility
+Category.Label.Content=Content
+Category.Label.Data.Binding=Data Binding
+Category.Label.Dynamic=Dynamic
+Category.Label.Event=Event
+Category.Label.File=File
+Category.Label.General=General
+Category.Label.HTML4.0=HTML 4.0
+Category.Label.Image=Image
+Category.Label.Language=Language
+Category.Label.Radio/Checkbox=Radio/Checkbox
+Category.Label.Text/Password=Text/Password
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.xml b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.xml
new file mode 100644
index 000000000..c3a29a649
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/html.xml
@@ -0,0 +1,1559 @@
+<?xml version="1.0" ?>
+<taglib uri="html">
+ <tag name="a">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="href" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.href" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ <referedattribute ref="lang" overridename="hreflang"
+ displaylabel="%Attribute.Label.hreflang" />
+ <referedattribute ref="linktype" overridename="rel"
+ displaylabel="%Attribute.Label.rel" />
+ <referedattribute ref="linktype" overridename="rev"
+ displaylabel="%Attribute.Label.rev" />
+ <referedattribute ref="target" />
+ <attribute name="shape" type="ENUMERATED"
+ displaylabel="%Attribute.Label.shape">
+ <option key="circle" value="circle" />
+ <option key="default" value="default" />
+ <option key="rect" value="rect" default="default" />
+ <option key="poly" value="poly" />
+ </attribute>
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="abbr">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="acronym">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="address">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="applet">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="code" displaylabel="%Attribute.Label.code" />
+ <attribute name="codebase"
+ displaylabel="%Attribute.Label.codebase" />
+ <attribute name="width" required="required"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="height" required="required"
+ displaylabel="%Attribute.Label.height" />
+ <attribute name="hspace"
+ displaylabel="%Attribute.Label.hspace" />
+ <attribute name="vspace"
+ displaylabel="%Attribute.Label.vspace" />
+ <referedattribute ref="ialign" overridename="align" />
+ <attribute name="archive"
+ displaylabel="%Attribute.Label.archive" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="alt"
+ displaylabel="%Attribute.Label.alt" />
+ </includeattrs>
+ </referedcategory>
+ </tag>
+ <tag name="area">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="shape" type="ENUMERATED"
+ displaylabel="%Attribute.Label.shape">
+ <option key="circle" value="circle" />
+ <option key="default" value="default" />
+ <option key="rect" value="rect" default="default" />
+ <option key="poly" value="poly" />
+ </attribute>
+ <attribute name="coords"
+ displaylabel="%Attribute.Label.coords" />
+ <attribute name="href" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.href" />
+ <referedattribute ref="target" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="alt" required="required"
+ displaylabel="%Attribute.Label.alt" />
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="b">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="base">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="href" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.href" />
+ <referedattribute ref="target" />
+ </category>
+ </tag>
+ <tag name="basefont">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="size" type="ENUMERATED" required="required"
+ displaylabel="%Attribute.Label.size">
+ <option key="1" value="1" />
+ <option key="2" value="2" />
+ <option key="3" value="3" />
+ <option key="4" value="4" />
+ <option key="5" value="5" />
+ <option key="6" value="6" />
+ <option key="7" value="7" />
+ </attribute>
+ <attribute name="face" displaylabel="%Attribute.Label.face" />
+ <attribute name="color" type="COLOR"
+ displaylabel="%Attribute.Label.color" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <excludeattrs refs="class,style,title" />
+ </referedcategory>
+ </tag>
+ <tag name="bdo">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="big">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="blockquote">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="cite" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.cite" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="body">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="bgcolor" type="COLOR"
+ displaylabel="%Attribute.Label.bgcolor" />
+ <attribute name="background" type="RELATIVEPATH"
+ typeparam="suffix=jpg;gif;png"
+ displaylabel="%Attribute.Label.background" />
+ <attribute name="text" type="COLOR"
+ displaylabel="%Attribute.Label.text" />
+ <attribute name="link" type="COLOR"
+ displaylabel="%Attribute.Label.link" />
+ <attribute name="vlink" type="COLOR"
+ displaylabel="%Attribute.Label.vlink" />
+ <attribute name="alink" type="COLOR"
+ displaylabel="%Attribute.Label.alink" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onload"
+ displaylabel="%Attribute.Label.onload" />
+ <attribute name="onunload"
+ displaylabel="%Attribute.Label.onunload" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="br">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="clear" type="ENUMERATED"
+ displaylabel="%Attribute.Label.clear">
+ <option key="right" value="right" />
+ <option key="none" value="none" default="default" />
+ <option key="left" value="left" />
+ <option key="all" value="all" />
+ </attribute>
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ </tag>
+ <tag name="button">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ <attribute name="type" type="ENUMERATED"
+ displaylabel="%Attribute.Label.type">
+ <option key="submit" value="submit" default="default" />
+ <option key="reset" value="reset" />
+ <option key="button" value="button" />
+ </attribute>
+ <attribute name="disabled" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.disabled" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="caption">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="align" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="right" value="right" />
+ <option key="top" value="top" />
+ <option key="left" value="left" />
+ <option key="bottom" value="bottom" />
+ </attribute>
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="center">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="cite">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="code">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="col">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="align" />
+ <attribute name="span" displaylabel="%Attribute.Label.span" />
+ <referedattribute ref="valign" />
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="colgroup">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="align" />
+ <attribute name="span" displaylabel="%Attribute.Label.span" />
+ <referedattribute ref="valign" />
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="dd">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="del">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="cite" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.cite" />
+ <attribute name="datetime"
+ displaylabel="%Attribute.Label.datetime" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="dfn">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="dir">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="compact" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.compact" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="div">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="dl">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="compact" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.compact" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="dt">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="em">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="fieldset">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="font">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="color" type="COLOR"
+ displaylabel="%Attribute.Label.color" />
+ <attribute name="size" type="ENUMERATED"
+ displaylabel="%Attribute.Label.size">
+ <option key="1" value="1" />
+ <option key="2" value="2" />
+ <option key="3" value="3" />
+ <option key="4" value="4" />
+ <option key="5" value="5" />
+ <option key="6" value="6" />
+ <option key="7" value="7" />
+ <option key="-1" value="-1" />
+ <option key="-2" value="-2" />
+ <option key="-3" value="-3" />
+ <option key="-4" value="-4" />
+ <option key="-5" value="-5" />
+ <option key="-6" value="-6" />
+ <option key="-7" value="-7" />
+ <option key="+1" value="+1" />
+ <option key="+2" value="+2" />
+ <option key="+3" value="+3" />
+ <option key="+4" value="+4" />
+ <option key="+5" value="+5" />
+ <option key="+6" value="+6" />
+ <option key="+7" value="+7" />
+ </attribute>
+ <attribute name="face" displaylabel="%Attribute.Label.face" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="form">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="action" required="required" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.action" />
+ <attribute name="method" type="ENUMERATED"
+ displaylabel="%Attribute.Label.method">
+ <option key="get" value="get" default="default" />
+ <option key="post" value="post" />
+ </attribute>
+ <attribute name="enctype" type="ENUMERATED"
+ displaylabel="%Attribute.Label.enctype">
+ <option key="application/x-www-form-urlencoded"
+ value="application/x-www-form-urlencoded" default="default" />
+ <option key="text/plain" value="text/plain" />
+ <option key="multipart/form-data"
+ value="multipart/form-data" />
+ </attribute>
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ <referedattribute ref="target" />
+ </category>
+ <referedcategory ref="CSS/Accessibility"></referedcategory>
+ <referedcategory ref="Language" />
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onreset"
+ displaylabel="%Attribute.Label.onreset" />
+ <attribute name="onsubmit"
+ displaylabel="%Attribute.Label.onsubmit" />
+ </includeattrs>
+ </referedcategory>
+ </tag>
+ <tag name="frame">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="src" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.src" />
+ <attribute name="frameborder" type="ENUMERATED"
+ displaylabel="%Attribute.Label.frameborder">
+ <option key="0" value="0" />
+ <option key="1" value="1" default="default" />
+ </attribute>
+ <attribute name="scrolling" type="ENUMERATED"
+ displaylabel="%Attribute.Label.scrolling">
+ <option key="yes" value="Yes" />
+ <option key="no" value="No" />
+ <option key="auto" value="Auto" default="default" />
+ </attribute>
+ <attribute name="noresize" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.noresize" />
+ <attribute name="marginwidth"
+ displaylabel="%Attribute.Label.marginwidth" />
+ <attribute name="marginheight"
+ displaylabel="%Attribute.Label.marginheight" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="longdesc"
+ displaylabel="%Attribute.Label.longdesc" />
+ </includeattrs>
+ </referedcategory>
+ </tag>
+ <tag name="frameset">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="rows" displaylabel="%Attribute.Label.rows" />
+ <attribute name="cols" displaylabel="%Attribute.Label.cols" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <category name="Event" displaylabel="%Category.Label.Event">
+ <attribute name="onload"
+ displaylabel="%Attribute.Label.onload" />
+ <attribute name="onunload"
+ displaylabel="%Attribute.Label.onunload" />
+ </category>
+ </tag>
+ <tag name="h1">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="h2">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="h3">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="h4">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="h5">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="h6">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="head">
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="hr">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="align" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="right" value="right" />
+ <option key="left" value="left" />
+ <option key="center" value="center" />
+ </attribute>
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="size" displaylabel="%Attribute.Label.size" />
+ <attribute name="noshade" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.noshade" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="html">
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="i">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="iframe">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="src" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.src" />
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="marginwidth"
+ displaylabel="%Attribute.Label.marginwidth" />
+ <attribute name="height"
+ displaylabel="%Attribute.Label.height" />
+ <attribute name="marginheight"
+ displaylabel="%Attribute.Label.marginheight" />
+ <referedattribute ref="ialign" overridename="align" />
+ <attribute name="scrolling" type="ENUMERATED"
+ displaylabel="%Attribute.Label.scrolling">
+ <option key="Yes" value="Yes" />
+ <option key="No" value="No" />
+ <option key="Auto" value="Auto" />
+ </attribute>
+ <attribute name="frameborder" type="ENUMERATED"
+ displaylabel="%Attribute.Label.frameborder">
+ <option key="0" value="0" />
+ <option key="1" value="1" default="default" />
+ </attribute>
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="longdesc"
+ displaylabel="%Attribute.Label.longdesc" />
+ </includeattrs>
+ </referedcategory>
+ </tag>
+ <tag name="img">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="src" type="RELATIVEPATH" required="required"
+ typeparam="suffix=jpg;gif;png" displaylabel="%Attribute.Label.src" />
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="height"
+ displaylabel="%Attribute.Label.height" />
+ <attribute name="hspace"
+ displaylabel="%Attribute.Label.hspace" />
+ <attribute name="vspace"
+ displaylabel="%Attribute.Label.vspace" />
+ <attribute name="border"
+ displaylabel="%Attribute.Label.border" />
+ <referedattribute ref="ialign" overridename="align" />
+ <attribute name="usemap"
+ displaylabel="%Attribute.Label.usemap" />
+ <attribute name="ismap" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.ismap" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="alt" required="required"
+ displaylabel="%Attribute.Label.alt" />
+ <attribute name="longdesc" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.longdesc" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="input">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="checked" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.checked" />
+ <attribute name="maxlength"
+ displaylabel="%Attribute.Label.maxlength" />
+ <attribute name="readonly" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.readonly" />
+ <attribute name="type" type="ENUMERATED"
+ displaylabel="%Attribute.Label.type">
+ <option key="password" value="Password" />
+ <option key="checkbox" value="Checkbox" />
+ <option key="text" value="Text" default="default" />
+ <option key="submit" value="Submit" />
+ <option key="hidden" value="Hidden" />
+ <option key="file" value="File" />
+ <option key="reset" value="Reset" />
+ <option key="radio" value="Radio" />
+ <option key="image" value="Image" />
+ <option key="button" value="Button" />
+ </attribute>
+ <attribute name="disabled" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.disabled" />
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ <attribute name="size" displaylabel="%Attribute.Label.size" />
+ <attribute name="accept" type="ENUMERATED"
+ displaylabel="%Attribute.Label.accept">
+ <option key="application/msword"
+ value="application/msword" />
+ <option key="image/jpeg" value="image/jpeg" />
+ <option key="image/x-MS-bmp" value="image/x-MS-bmp" />
+ <option key="image/x-portable-greymap"
+ value="image/x-portable-greymap" />
+ <option key="video/x-msvideo" value="video/x-msvideo" />
+ <option key="video/x-mpeg2" value="video/x-mpeg2" />
+ <option key="audio/x-aiff" value="audio/x-aiff" />
+ <option key="image/x-photo-cd" value="image/x-photo-cd" />
+ <option key="audio/x-waw" value="audio/x-waw" />
+ <option key="image/tiff" value="image/tiff" />
+ <option key="audio/basic" value="audio/basic" />
+ <option key="video/quicktime" value="video/quicktime" />
+ <option key="application/msexcel"
+ value="application/msexcel" />
+ <option key="image/gif" value="image/gif" />
+ <option key="audio/x-pn/realaudio"
+ value="audio/x-pn/realaudio" />
+ <option key="application/pdf" value="application/pdf" />
+ <option key="image/x-portablebitmap"
+ value="image/x-portablebitmap" />
+ <option key="application/rtf" value="application/rtf" />
+ <option key="text/html" value="text/html" />
+ <option key="image/x-portable-pixmap"
+ value="image/x-portable-pixmap" />
+ <option key="text/plain" value="text/plain" />
+ <option key="application/x-zip-compressed"
+ value="application/x-zip-compressed" />
+ <option key="audio/x-mpeg" value="audio/x-mpeg" />
+ <option key="application/postscript"
+ value="application/postscript" />
+ <option key="image/x-png" value="image/x-png" />
+ <option key="image/x-rgb" value="image/x-rgb" />
+ </attribute>
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ <attribute name="alt"
+ displaylabel="%Attribute.Label.alt" />
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onchange"
+ displaylabel="%Attribute.Label.onchange" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ <attribute name="onselect"
+ displaylabel="%Attribute.Label.onselect" />
+ </includeattrs>
+ </referedcategory>
+ <category name="Image" displaylabel="%Category.Label.Image">
+ <attribute name="src" type="RELATIVEPATH"
+ typeparam="suffix=jpg;gif;png" displaylabel="%Attribute.Label.src" />
+ <referedattribute ref="ialign" overridename="align" />
+ <attribute name="usemap"
+ displaylabel="%Attribute.Label.usemap" />
+ <attribute name="ismap" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.ismap" />
+ </category>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="ins">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="cite" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.cite" />
+ <attribute name="datetime"
+ displaylabel="%Attribute.Label.datetime" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="isindex">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="prompt"
+ displaylabel="%Attribute.Label.prompt" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="kbd">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="label">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="for" displaylabel="%Attribute.Label.for" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="legend">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="align" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="right" value="right" />
+ <option key="top" value="top - not supported by MSIE4" />
+ <option key="left" value="left" />
+ <option key="bottom" value="bottom" />
+ </attribute>
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="li">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="type" type="ENUMERATED"
+ displaylabel="%Attribute.Label.type">
+ <option key="i" value="i lower roman" />
+ <option key="I" value="I upper roman" />
+ <option key="a" value="a lower alpha" />
+ <option key="A" value="A upper alpha" />
+ <option key="1" value="1 arabic numbers" />
+ <option key="square" value="square" />
+ <option key="circle" value="circle" />
+ <option key="disc" value="disc" />
+ </attribute>
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="link">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="href" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.href" />
+ <referedattribute ref="linktype" overridename="rel"
+ displaylabel="%Attribute.Label.rel" />
+ <referedattribute ref="linktype" overridename="rev"
+ displaylabel="%Attribute.Label.rev" />
+ <referedattribute ref="lang" overridename="hreflang"
+ displaylabel="%Attribute.Label.hreflang" />
+ <referedattribute ref="media" />
+ <referedattribute ref="target" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="map">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="name" displaylabel="%Attribute.Label.name" required="required" />
+ </category>
+ <referedcategory ref="CSS/Accessibility"></referedcategory>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="menu">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="compact" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.compact" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="meta">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="http-equiv"
+ displaylabel="%Attribute.Label.http-equiv" />
+ <attribute name="content" required="required"
+ displaylabel="%Attribute.Label.content" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <category name="CSS/Accessibility"
+ displaylabel="%Category.Label.CSS/Accessibility">
+ </category>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="noframes">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="noscript">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="object">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="usemap"
+ displaylabel="%Attribute.Label.usemap" />
+ <attribute name="standby"
+ displaylabel="%Attribute.Label.standby" />
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="height"
+ displaylabel="%Attribute.Label.height" />
+ <attribute name="hspace"
+ displaylabel="%Attribute.Label.hspace" />
+ <attribute name="vspace"
+ displaylabel="%Attribute.Label.vspace" />
+ <referedattribute ref="ialign" overridename="align" />
+ <attribute name="border"
+ displaylabel="%Attribute.Label.border" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <category name="Content"
+ displaylabel="%Category.Label.Content">
+ <attribute name="classid" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.classid" />
+ <attribute name="codebase" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.codebase" />
+ <attribute name="codetype"
+ displaylabel="%Attribute.Label.codetype" />
+ <attribute name="data" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.data" />
+ <attribute name="archive"
+ displaylabel="%Attribute.Label.archive" />
+ <attribute name="declare" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.declare" />
+ </category>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="ol">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="start"
+ displaylabel="%Attribute.Label.start" />
+ <attribute name="type" type="ENUMERATED"
+ displaylabel="%Attribute.Label.type">
+ <option key="i" value="i lower roman" />
+ <option key="I" value="I upper roman" />
+ <option key="a" value="a lower alpha" />
+ <option key="A" value="A upper alpha" />
+ <option key="1" value="1 arabic numbers" />
+ </attribute>
+ <attribute name="compact" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.compact" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="optgroup">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="disabled" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.disabled" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="label" required="required"
+ displaylabel="%Attribute.Label.label" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onchange"
+ displaylabel="%Attribute.Label.onchange" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="option">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ <attribute name="selected" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.selected" />
+ <attribute name="disabled" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.disabled" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="label"
+ displaylabel="%Attribute.Label.label" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onchange"
+ displaylabel="%Attribute.Label.onchange" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="p">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="dalign" overridename="align" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Language" />
+ <referedcategory ref="Event" />
+ </tag>
+ <tag name="param">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ <attribute name="valuetype" type="ENUMERATED"
+ displaylabel="%Attribute.Label.valuetype">
+ <option key="object" value="object" />
+ <option key="ref" value="ref" />
+ <option key="data" value="data" default="default" />
+ </attribute>
+ <attribute name="name" displaylabel="%Attribute.Label.name" required="required" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <excludeattrs refs="class,style,title" />
+ </referedcategory>
+ </tag>
+ <tag name="pre">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="q">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="cite" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.cite" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="s">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="samp">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="script">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="src" type="RELATIVEPATH"
+ displaylabel="%Attribute.Label.src" />
+ <attribute name="type" type="ENUMERATED" required="required"
+ displaylabel="%Attribute.Label.type">
+ <option key="text/php" value="text/php" />
+ <option key="text/tcl" value="text/tcl" />
+ <option key="text/livescript" value="text/livescript" />
+ <option key="text/vbscript" value="text/vbscript" />
+ <option key="text/jscript" value="text/jscript" />
+ <option key="text/javascript" value="text/javascript" />
+ </attribute>
+ <attribute name="defer" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.defer" />
+ </category>
+ </tag>
+ <tag name="select">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="size" displaylabel="%Attribute.Label.size" />
+ <attribute name="multiple" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.multiple" />
+ <attribute name="disabled" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.disabled" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onchange"
+ displaylabel="%Attribute.Label.onchange" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="small">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="span">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="strike">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="strong">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="style">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="type" type="ENUMERATED" required="required"
+ displaylabel="%Attribute.Label.type">
+ <option key="text/css" value="text/css" />
+ <option key="text/javascript" value="text/javascript" />
+ </attribute>
+ <referedattribute ref="media" />
+ </category>
+ <category name="CSS/Accessibility"
+ displaylabel="%Category.Label.CSS/Accessibility">
+ <attribute name="title"
+ displaylabel="%Attribute.Label.title" />
+ </category>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="sub">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="sup">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="table">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="border"
+ displaylabel="%Attribute.Label.border" />
+ <attribute name="align" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="right" value="right" />
+ <option key="left" value="left" />
+ <option key="center" value="center" />
+ </attribute>
+ <attribute name="cellpadding"
+ displaylabel="%Attribute.Label.cellpadding" />
+ <attribute name="cellspacing"
+ displaylabel="%Attribute.Label.cellspacing" />
+ <attribute name="bgcolor" type="COLOR"
+ displaylabel="%Attribute.Label.bgcolor" />
+ <attribute name="frame" type="ENUMERATED"
+ displaylabel="%Attribute.Label.frame">
+ <option key="lhs"
+ value="Lhs - Border on the left-hand side of the table frame" />
+ <option key="above"
+ value="Above - Border on the top side of the table frame" />
+ <option key="void"
+ value="Void - Removes all outside table borders (default)" />
+ <option key="box"
+ value="Box - Border on all sides of the table frame" />
+ <option key="vsides"
+ value="Vsides - Border on the left and right sides of the table frame" />
+ <option key="below"
+ value="Below - Border on the bottom side of the table frame" />
+ <option key="border"
+ value="Border - Border on all sides of the table frame" />
+ <option key="rhs"
+ value="Rhs - Border on the right-hand side of the table frame" />
+ <option key="hsides"
+ value="Hsides - Border on the top and bottom sides of the table frame" />
+ </attribute>
+ <attribute name="rules" type="ENUMERATED"
+ displaylabel="%Attribute.Label.rules">
+ <option key="cols"
+ value="Cols - Displays vertical borders between all table columns" />
+ <option key="groups"
+ value="Groups - Displays horizontal borders between all table groups" />
+ <option key="rows"
+ value="Rows - Displays horizontal borders between all table rows" />
+ <option key="none"
+ value="None - Removes all interior table borders (default)" />
+ <option key="all"
+ value="All - Displays a border on all rows and columns" />
+ </attribute>
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="summary"
+ displaylabel="%Attribute.Label.summary" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="tbody">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="align" />
+ <referedattribute ref="valign" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="td">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="height"
+ displaylabel="%Attribute.Label.height" />
+ <attribute name="colspan"
+ displaylabel="%Attribute.Label.colspan" />
+ <attribute name="rowspan"
+ displaylabel="%Attribute.Label.rowspan" />
+ <referedattribute ref="align" />
+ <attribute name="nowrap" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.nowrap" />
+ <attribute name="bgcolor" type="COLOR"
+ displaylabel="%Attribute.Label.bgcolor" />
+ <referedattribute ref="scope" />
+ <referedattribute ref="valign" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="abbr"
+ displaylabel="%Attribute.Label.abbr" />
+ <attribute name="axis"
+ displaylabel="%Attribute.Label.axis" />
+ <attribute name="headers"
+ displaylabel="%Attribute.Label.headers" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="textarea">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="cols" required="required" displaylabel="%Attribute.Label.cols" />
+ <attribute name="rows" required="required" displaylabel="%Attribute.Label.rows" />
+ <attribute name="disabled" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.disabled" />
+ <attribute name="readonly" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.readonly" />
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="accesskey"
+ displaylabel="%Attribute.Label.accesskey" />
+ <attribute name="tabindex"
+ displaylabel="%Attribute.Label.tabindex" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event">
+ <includeattrs>
+ <attribute name="onblur"
+ displaylabel="%Attribute.Label.onblur" />
+ <attribute name="onchange"
+ displaylabel="%Attribute.Label.onchange" />
+ <attribute name="onfocus"
+ displaylabel="%Attribute.Label.onfocus" />
+ <attribute name="onselect"
+ displaylabel="%Attribute.Label.onselect" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="tfoot">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="align" />
+ <referedattribute ref="valign" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="th">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="width"
+ displaylabel="%Attribute.Label.width" />
+ <attribute name="height"
+ displaylabel="%Attribute.Label.height" />
+ <attribute name="colspan"
+ displaylabel="%Attribute.Label.colspan" />
+ <attribute name="rowspan"
+ displaylabel="%Attribute.Label.rowspan" />
+ <referedattribute ref="align" />
+ <attribute name="nowrap" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.nowrap" />
+ <attribute name="bgcolor" type="COLOR"
+ displaylabel="%Attribute.Label.bgcolor" />
+ <referedattribute ref="scope" />
+ <referedattribute ref="valign" />
+ </category>
+ <referedcategory ref="CSS/Accessibility">
+ <includeattrs>
+ <attribute name="abbr"
+ displaylabel="%Attribute.Label.abbr" />
+ <attribute name="axis"
+ displaylabel="%Attribute.Label.axis" />
+ <attribute name="headers"
+ displaylabel="%Attribute.Label.headers" />
+ </includeattrs>
+ </referedcategory>
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="thead">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="align" />
+ <referedattribute ref="valign" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="title">
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="tr">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <referedattribute ref="align" />
+ <referedattribute ref="valign" />
+ <attribute name="bgcolor" type="COLOR"
+ displaylabel="%Attribute.Label.bgcolor" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="tt">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="u">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="ul">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="type" type="ENUMERATED"
+ displaylabel="%Attribute.Label.type">
+ <option key="square" value="square" />
+ <option key="circle" value="circle" />
+ <option key="disc" value="disc" />
+ </attribute>
+ <attribute name="compact" type="NAMED-BOOLEAN"
+ displaylabel="%Attribute.Label.compact" />
+ </category>
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <tag name="var">
+ <referedcategory ref="CSS/Accessibility" />
+ <referedcategory ref="Event" />
+ <referedcategory ref="Language" />
+ </tag>
+ <definition>
+ <categories>
+ <category name="CSS/Accessibility"
+ displaylabel="%Category.Label.CSS/Accessibility">
+ <attribute name="class" type="CSSCLASS"
+ displaylabel="%Attribute.Label.class" />
+ <attribute name="id" type="CSSID"
+ displaylabel="%Attribute.Label.id" />
+ <attribute name="style" type="CSSSTYLE"
+ typeparam="style=STYLE" displaylabel="%Attribute.Label.style" />
+ <attribute name="title"
+ displaylabel="%Attribute.Label.title" />
+ </category>
+ <category name="Event"
+ displaylabel="%Category.Label.Event">
+ <attribute name="onclick" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onclick" />
+ <attribute name="ondblclick" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.ondblclick" />
+ <attribute name="onmousedown" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onmousedown" />
+ <attribute name="onmousemove" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onmousemove" />
+ <attribute name="onmouseout" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onmouseout" />
+ <attribute name="onmouseover" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onmouseover" />
+ <attribute name="onmouseup" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onmouseup" />
+ <attribute name="onkeydown" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onkeydown" />
+ <attribute name="onkeypress" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onkeypress" />
+ <attribute name="onkeyup" type="JAVASCRIPT"
+ displaylabel="%Attribute.Label.onkeyup" />
+ </category>
+ <category name="Language"
+ displaylabel="%Category.Label.Language">
+ <attribute name="dir" type="ENUMERATED"
+ displaylabel="%Attribute.Label.dir">
+ <option key="ltr" value="left-to-right" />
+ <option key="rtl" value="right-to-left" />
+ </attribute>
+ <referedattribute ref="lang" />
+ </category>
+ </categories>
+ <attributes>
+ <attribute name="align" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="right" value="right" />
+ <option key="char" value="char" />
+ <option key="left" value="left" />
+ <option key="center" value="center" />
+ <option key="justify" value="justify" />
+ </attribute>
+ <attribute name="dalign" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="right" value="right" />
+ <option key="left" value="left" />
+ <option key="center" value="center" />
+ <option key="justify" value="justify" />
+ </attribute>
+ <attribute name="ialign" type="ENUMERATED"
+ displaylabel="%Attribute.Label.align">
+ <option key="bottom" value="bottom" />
+ <option key="middle" value="middle" />
+ <option key="top" value="top" />
+ <option key="right" value="right" />
+ <option key="left" value="left" />
+ </attribute>
+ <attribute name="lang" type="ENUMERATED"
+ displaylabel="%Attribute.Label.lang">
+ <option key="af" value="af Afrikaans" />
+ <option key="ar" value="ar Arabic (needs subtype)" />
+ <option key="be" value="be Belarusian" />
+ <option key="bg" value="bg Bulgarian" />
+ <option key="br" value="br Breton" />
+ <option key="ca" value="ca Catalan" />
+ <option key="cs" value="cs Czech" />
+ <option key="da" value="da Danish" />
+ <option key="de" value="de German (Standard)" />
+ <option key="el" value="el Greek" />
+ <option key="en" value="en English" />
+ <option key="es" value="es Spanish (Spain)" />
+ <option key="et" value="et Estonian" />
+ <option key="eu" value="eu Basque" />
+ <option key="fa" value="fa Farsi" />
+ <option key="fi" value="fi Finnish" />
+ <option key="fo" value="fo Faeroese" />
+ <option key="fr" value="fr French (Standard)" />
+ <option key="gd" value="gd Gaelic (Scotland)" />
+ <option key="he" value="he Hebrew" />
+ <option key="hi" value="hi Hindi" />
+ <option key="hr" value="hr Croatian" />
+ <option key="hu" value="hu Hungarian" />
+ <option key="id" value="id Indonesian" />
+ <option key="is" value="is Icelandic" />
+ <option key="it" value="it Italian (Standard)" />
+ <option key="ja" value="ja Japanese" />
+ <option key="ko" value="ko Korean" />
+ <option key="lt" value="lt Lithuanian" />
+ <option key="lv" value="lv Latvian" />
+ <option key="mk" value="mk Macedonian" />
+ <option key="ms" value="ms Malaysian" />
+ <option key="mt" value="mt Maltese" />
+ <option key="nl" value="nl Dutch (Standard)" />
+ <option key="no" value="no Norwegian (Bokmal/Nynorsk)" />
+ <option key="pl" value="pl Polish" />
+ <option key="pt" value="pt Portuguese (Standard)" />
+ <option key="rm" value="rm Rhaeto-Romanic" />
+ <option key="ro" value="ro Romanian" />
+ <option key="ru" value="ru Russian" />
+ <option key="sk" value="sk Slovak" />
+ <option key="sl" value="sl Slovenian" />
+ <option key="sq" value="sq Albanian" />
+ <option key="sr" value="sr Serbian (Cyrillic/Latin)" />
+ <option key="sv" value="sv Swedish" />
+ <option key="sx" value="sx Sutu" />
+ <option key="sz" value="sz Sami (Lappish)" />
+ <option key="th" value="th Thai" />
+ <option key="tn" value="tn Setswana" />
+ <option key="tr" value="tr Turkish" />
+ <option key="ts" value="ts Tsonga" />
+ <option key="uk" value="uk Ukrainian" />
+ <option key="ur" value="ur Urdu" />
+ <option key="vi" value="vi Vietnamese" />
+ <option key="xh" value="xh Xhosa" />
+ <option key="yi" value="yi Yiddish" />
+ <option key="zh" value="zh Chinese (needs subtype)" />
+ <option key="zu" value="zu Zulu" />
+ </attribute>
+ <attribute name="linktype">
+ <option key="index" value="index" />
+ <option key="subsection" value="subsection" />
+ <option key="bookmark" value="bookmark" />
+ <option key="start" value="start" />
+ <option key="next" value="next" />
+ <option key="stylesheet" value="stylesheet" />
+ <option key="chapter" value="chapter" />
+ <option key="help" value="help" />
+ <option key="alternate" value="alternate" />
+ <option key="appendix" value="appendix" />
+ <option key="contents" value="contents" />
+ <option key="section" value="section" />
+ <option key="prev" value="prev" />
+ <option key="previous" value="previous" />
+ <option key="glossary" value="glossary" />
+ <option key="copyright" value="copyright" />
+ </attribute>
+ <attribute name="media" type="ENUMERATED"
+ displaylabel="%Attribute.Label.media">
+ <option key="tv" value="tv" />
+ <option key="braille" value="braille" />
+ <option key="tty" value="tty" />
+ <option key="print" value="print" />
+ <option key="all" value="all" />
+ <option key="projection" value="projection" />
+ <option key="handheld" value="handheld" />
+ <option key="screen" value="screen" />
+ <option key="aural" value="aural" />
+ </attribute>
+ <attribute name="scope" type="ENUMERATED"
+ displaylabel="%Attribute.Label.scope">
+ <option key="row" value="row" />
+ <option key="col" value="col" />
+ <option key="rowgroup" value="rowgroup" />
+ <option key="colgroup" value="colgroup" />
+ </attribute>
+ <attribute name="target" type="ENUMERATED"
+ displaylabel="%Attribute.Label.target">
+ <option key="_self" value="_self" />
+ <option key="_blank" value="_blank" />
+ <option key="_parent" value="_parent" />
+ <option key="_top" value="_top" />
+ </attribute>
+ <attribute name="valign" type="ENUMERATED"
+ displaylabel="%Attribute.Label.valign">
+ <option key="middle" value="middle" />
+ <option key="top" value="top" />
+ <option key="baseline" value="baseline" />
+ <option key="bottom" value="bottom" />
+ </attribute>
+ </attributes>
+ </definition>
+</taglib> \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.properties
new file mode 100644
index 000000000..c0d235e71
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.properties
@@ -0,0 +1,27 @@
+Attribute.Label.align=Align
+Attribute.Label.beanName=BeanName
+Attribute.Label.class=Class
+Attribute.Label.code=Code
+Attribute.Label.codebase=Codebase
+Attribute.Label.contentType=ContentType
+Attribute.Label.flush=Flush
+Attribute.Label.file=File
+Attribute.Label.height=Height
+Attribute.Label.hspace=Hspace
+Attribute.Label.id=ID
+Attribute.Label.iepluginurl=Eepluginurl
+Attribute.Label.import=Import
+Attribute.Label.jreversion=Jreversion
+Attribute.Label.name=Name
+Attribute.Label.nspluginurl=Nspluginurl
+Attribute.Label.page=Page
+Attribute.Label.param=Param
+Attribute.Label.property=Property
+Attribute.Label.scope=Scope
+Attribute.Label.type=Type
+Attribute.Label.value=Value
+Attribute.Label.version=Version
+Attribute.Label.vspace=Vspace
+Attribute.Label.width=Width
+Attribute.Label.xmlnsjsp=xmlns:jsp
+Category.Label.General=General
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.xml b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.xml
new file mode 100644
index 000000000..6736eef80
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/cm/jsp.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" ?>
+<taglib uri="jsp">
+ <tag name="declaration" />
+ <tag name="expression" />
+ <tag name="fallback" />
+ <tag name="forward">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="page" type="RELATIVEPATH"
+ typeparam="suffix=jsp;htm;html" displaylabel="%Attribute.Label.page" />
+ </category>
+ </tag>
+ <tag name="getproperty">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ <attribute name="property"
+ displaylabel="%Attribute.Label.property" />
+ </category>
+ </tag>
+ <tag name="include">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="page" type="RELATIVEPATH"
+ typeparam="suffix=jsp;htm;html" displaylabel="%Attribute.Label.page" />
+ <attribute name="flush" type="BOOLEAN"
+ displaylabel="%Attribute.Label.flush" />
+ </category>
+ </tag>
+ <tag name="directive.include">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="file" type="RELATIVEPATH"
+ typeparam="suffix=jsp;htm;html" displaylabel="%Attribute.Label.file" />
+ </category>
+ </tag>
+ <tag name="directive.page">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="import"
+ displaylabel="%Attribute.Label.import" />
+ <attribute name="contentType"
+ displaylabel="%Attribute.Label.contentType" />
+ </category>
+ </tag>
+ <tag name="param">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ </category>
+ </tag>
+ <tag name="params" />
+ <tag name="plugin">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="type" type="ENUMERATED"
+ displaylabel="%Attribute.Label.type">
+ <option key="applet" value="applet" />
+ <option key="bean" value="bean" />
+ </attribute>
+ <attribute name="jreversion"
+ displaylabel="%Attribute.Label.jreversion" type="ENUMERATED">
+ <option key="1.2" value="1.2" />
+ </attribute>
+ <attribute name="nspluginurl"
+ displaylabel="%Attribute.Label.nspluginurl" />
+ <attribute name="iepluginurl"
+ displaylabel="%Attribute.Label.iepluginurl" />
+ </category>
+ </tag>
+ <tag name="root">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="version" type="ENUMERATED"
+ displaylabel="%Attribute.Label.version">
+ <option key="1.2" value="1.2" />
+ <option key="2.0" value="2.0" />
+ </attribute>
+ <attribute name="xmlns:jsp" type="ENUMERATED"
+ displaylabel="%Attribute.Label.xmlnsjsp">
+ <option key="http://java.sun.com/JSP/Page" value="http://java.sun.com/JSP/Page" />
+ </attribute>
+ </category>
+ </tag>
+ <tag name="scriptlet" />
+ <tag name="setproperty">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="name" displaylabel="%Attribute.Label.name" />
+ <attribute name="property"
+ displaylabel="%Attribute.Label.property" />
+ <attribute name="param"
+ displaylabel="%Attribute.Label.param" />
+ <attribute name="value"
+ displaylabel="%Attribute.Label.value" />
+ </category>
+ </tag>
+ <tag name="directive.taglib" />
+ <tag name="usebean">
+ <category name="General"
+ displaylabel="%Category.Label.General">
+ <attribute name="id" displaylabel="%Attribute.Label.id" />
+ <attribute name="scope" type="ENUMERATED"
+ displaylabel="%Attribute.Label.scope">
+ <option key="page" value="page" />
+ <option key="session" value="session" />
+ <option key="request" value="request" />
+ <option key="application" value="application" />
+ </attribute>
+ <attribute name="class" type="CLASSNAME"
+ displaylabel="%Attribute.Label.class" />
+ <attribute name="type" displaylabel="%Attribute.Label.type" />
+ <attribute name="beanName"
+ displaylabel="%Attribute.Label.beanName" />
+ </category>
+ </tag>
+</taglib> \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/configs/html_pi.xml b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/html_pi.xml
new file mode 100644
index 000000000..d709f7180
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/html_pi.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<palette-item>
+ <category label="HTML" uri="html" iconPrefix="icons/palette/HTML/">
+ <item tagName="BR" label="Line Break" shortDesc="The element is used to enforce a line break." smallIcon="small/HTML_BR.gif" largeIcon="large/HTML_BR.gif" expert="true" />
+ <item tagName="INPUT" label="Button" shortDesc="An INPUT element with TYPE=SUBMIT represents an input option, typically a button, that instructs the user agent to submit the form." smallIcon="small/HTML_INPUT_BUTTON.gif" largeIcon="large/HTML_INPUT_BUTTON.gif">
+ <attribute name="type" value="submit"/>
+ <attribute name="name" value="submit"/>
+ <attribute name="value" value="submit"/>
+ </item>
+ <item tagName="INPUT" label="Check Box" shortDesc="An INPUT element with TYPE=CHECKBOX represents a boolean choice. A set of such elements with the same name represents an n-of-many choice field." smallIcon="small/HTML_INPUT_CHECKBOX.gif" largeIcon="large/HTML_INPUT_CHECKBOX.gif">
+ <attribute name="type" value="checkbox" />
+ </item>
+ <item tagName="FORM" label="Form" shortDesc="The FORM element contains a sequence of input elements, along with document structuring elements." smallIcon="small/HTML_FORM.gif" largeIcon="large/HTML_FORM.gif" />
+ <item tagName="INPUT" label="Hidden Field" shortDesc="An INPUT element with TYPE=HIDDEN represents a hidden field.The user does not interact with this field; instead, the VALUE attribute specifies the value of the field." smallIcon="small/HTML_INPUT_HIDDEN.gif" largeIcon="large/HTML_INPUT_HIDDEN.gif">
+ <attribute name="type" value="hidden" />
+ </item>
+ <item tagName="HR" label="Horizontal Rule" shortDesc="The HR element is a divider between sections of text; typically a full width horizontal rule or equivalent graphic." smallIcon="small/HTML_HR.gif" largeIcon="large/HTML_HR.gif"/>
+ <item tagName="IMG" label="Image" shortDesc="The IMG element refers to an image or icon via a hyperlink." smallIcon="small/HTML_IMG.gif" largeIcon="large/HTML_IMG.gif"/>
+ <item tagName="INPUT" label="Image Button" shortDesc="An INPUT element with TYPE=IMAGE specifies an image resource to display, and allows input of two form fields: the x and y coordinate of a pixel chosen from the image." smallIcon="small/HTML_INPUT_IMAGE.gif" largeIcon="large/HTML_INPUT_IMAGE.gif">
+ <attribute name="type" value="image" />
+ </item>
+ <item tagName="A" label="Link" shortDesc="The element allows the user to navigate the content of the document." smallIcon="small/HTML_A.gif" largeIcon="large/HTML_A.gif">
+ <attribute name="href" value="#" />
+ <template>Link</template>
+ </item>
+ <item tagName="INPUT" label="Password Field" shortDesc="An INPUT element with TYPE=PASSWORD is a text field as above, except that the value is obscured as it is entered." smallIcon="small/HTML_INPUT_PASSWORD.gif" largeIcon="large/HTML_INPUT_PASSWORD.gif">
+ <attribute name="type" value="password" />
+ </item>
+ <item tagName="INPUT" label="Radio Button" shortDesc="An INPUT element with TYPE=RADIO represents a boolean choice. A set of such elements with the same name represents a 1-of-many choice field." smallIcon="small/HTML_INPUT_RADIO.gif" largeIcon="large/HTML_INPUT_RADIO.gif">
+ <attribute name="type" value="radio" />
+ </item>
+ <item tagName="SELECT" label="Select" shortDesc="The SELECT element constrains the form field to an enumerated list of values." smallIcon="small/HTML_SELECT.gif" largeIcon="large/HTML_SELECT.gif" />
+ <item tagName="TABLE" label="Table" shortDesc="HTML Tables are contained within a TABLE element. The TABLE element denotes the range of the table, and uses attribute to define properties of it." smallIcon="small/HTML_TABLE.gif" largeIcon="large/HTML_TABLE.gif">
+ <attribute name="border" value="1" />
+ <attribute name="style" value="width:100;height:50"/>
+ <template>
+ <tr>
+ <td />
+ <td />
+ </tr>
+ </template>
+ </item>
+ <item tagName="TEXTAREA" label="Text Area" shortDesc="The TEXTAREA element represents a multi-line text field." smallIcon="small/HTML_TEXTAREA.gif" largeIcon="large/HTML_TEXTAREA.gif"/>
+ <item tagName="INPUT" label="Text Field" shortDesc="The default vaule of the TYPE attribute is TEXT, indicating a single line text entry field." smallIcon="small/HTML_INPUT_TEXT.gif" largeIcon="large/HTML_INPUT_TEXT.gif">
+ <attribute name="type" value="text" />
+ </item>
+ </category>
+</palette-item>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/configs/jsp_pi.xml b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/jsp_pi.xml
new file mode 100644
index 000000000..42f8e9df8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/configs/jsp_pi.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<palette-item>
+ <category label="JSP" uri="jsp" iconPrefix="icons/palette/JSP/">
+ <item tagName="jsp:plugin" label="Plugin" shortDesc="Causes the execution of an applet or bean. The applet or bean executes in the specified plugin. If the plugin is not available, displays a dialog to initiate the download of the plugin software." smallIcon="small/JSP_PLUGIN.gif" largeIcon="large/JSP_PLUGIN.gif"/>
+ <item tagName="jsp:fallback" label="Fallback" shortDesc="The element provides a message for the user if the plugin does not start" smallIcon="small/JSP_FALLBACK.gif" largeIcon="large/JSP_FALLBACK.gif"/>
+ <item tagName="jsp:root" label="Root" shortDesc="Defines standard elements and namespace attributes of tag libraries." smallIcon="small/JSP_ROOT.gif" largeIcon="large/JSP_ROOT.gif"/>
+ <item tagName="jsp:text" label="Text" shortDesc="Encloses template data." smallIcon="small/JSP_TEXT.gif" largeIcon="large/JSP_TEXT.gif"/>
+ <item tagName="jsp:expression" label="Expression" shortDesc="Contains an expression valid in the scripting language used in the page." smallIcon="small/JSP_EXPRESSION.gif" largeIcon="large/JSP_EXPRESSION.gif"/>
+ <item tagName="jsp:scriptlet" label="Scriptlet" shortDesc="Contains a code fragment valid in the scripting language used in the page." smallIcon="small/JSP_SCRIPTLET.gif" largeIcon="large/JSP_SCRIPTLET.gif"/>
+ <item tagName="jsp:declaration" label="Declaration" shortDesc="Declares a variable or method valid in the scripting language used in the page." smallIcon="small/JSP_DECLARATION.gif" largeIcon="large/JSP_DECLARATION.gif"/>
+ <item tagName="jsp:forward" label="Forward" shortDesc="Forwards a request to an HTML file, JSP page, or servlet." smallIcon="small/JSP_FORWARD.gif" largeIcon="large/JSP_FORWARD.gif"/>
+ <item tagName="jsp:param" label="Param" shortDesc="The element passes the name and value of a parameter to the resource." smallIcon="small/JSP_PARAM.gif" largeIcon="large/JSP_PARAM.gif"/>
+ <item tagName="jsp:params" label="Params" shortDesc="The element sends parameter names and values to an applet or Bean at startup." smallIcon="small/JSP_PARAMS.gif" largeIcon="large/JSP_PARAMS.gif"/>
+ <item tagName="jsp:include" label="Include" shortDesc="Includes a static resource or the result from another web component." smallIcon="small/JSP_INCLUDE.gif" largeIcon="large/JSP_INCLUDE.gif"/>
+ <item tagName="jsp:useBean" label="UseBean" shortDesc="Instantiates or references a bean with a specific name and scope." smallIcon="small/JSP_USEBEAN.gif" largeIcon="large/JSP_USEBEAN.gif"/>
+ <item tagName="jsp:getProperty" label="GetProperty" shortDesc="Inserts the value of a bean property into the response." smallIcon="small/JSP_GETPROPERTY.gif" largeIcon="large/JSP_GETPROPERTY.gif"/>
+ <item tagName="jsp:setProperty" label="SetProperty" shortDesc="Sets a bean property value or values." smallIcon="small/JSP_SETPROPERTY.gif" largeIcon="large/JSP_SETPROPERTY.gif"/>
+ <item tagName="jsp:directive.include" label="Directive.Include" shortDesc="Includes a resource of text or code when the JSP page is translated." smallIcon="small/JSP_DIRECTIVE.INCLUDE.gif" largeIcon="large/JSP_DIRECTIVE.INCLUDE.gif"/>
+ <item tagName="jsp:directive.page" label="Directive.Page" shortDesc="Defines attributes that apply to an entire JSP page." smallIcon="small/JSP_DIRECTIVE.PAGE.gif" largeIcon="large/JSP_DIRECTIVE.PAGE.gif"/>
+ <item tagName="jsp:directive.taglib" label="Directive.Taglib" shortDesc="Defines a tag library and prefix for the custom tags used in the JSP page." smallIcon="small/JSP_DIRECTIVE.TAGLIB.gif" largeIcon="large/JSP_DIRECTIVE.TAGLIB.gif"/>
+ </category>
+</palette-item>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/default.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/default.properties
new file mode 100644
index 000000000..3d245ee8d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/default.properties
@@ -0,0 +1,2 @@
+# This file contains all the Default Preference Settings
+
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding.gif
new file mode 100644
index 000000000..6638a992e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding_disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding_disabled.gif
new file mode 100644
index 000000000..c5064fd96
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Binding_disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Plugin.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Plugin.gif
new file mode 100644
index 000000000..e24c70225
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Plugin.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold.gif
new file mode 100644
index 000000000..f81485150
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold_disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold_disabled.gif
new file mode 100644
index 000000000..639de4673
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_bold_disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_designer.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_designer.gif
new file mode 100644
index 000000000..fdfcae0ab
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_designer.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_hsplit.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_hsplit.gif
new file mode 100644
index 000000000..4dae95d76
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_hsplit.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic.gif
new file mode 100644
index 000000000..fb765fe70
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic_disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic_disabled.gif
new file mode 100644
index 000000000..74753155d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_italic_disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont.gif
new file mode 100644
index 000000000..39afd385b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont_disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont_disabled.gif
new file mode 100644
index 000000000..fe38ccbf2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_largefont_disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_paragraph.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_paragraph.gif
new file mode 100644
index 000000000..b129090b1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_paragraph.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont.gif
new file mode 100644
index 000000000..f0b4eba11
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont_disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont_disabled.gif
new file mode 100644
index 000000000..c02528af2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_smallfont_disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_source.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_source.gif
new file mode 100644
index 000000000..86986dfa8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_source.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline.gif
new file mode 100644
index 000000000..b8ac9775a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline_disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline_disabled.gif
new file mode 100644
index 000000000..f06517b0f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_underline_disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_vsplit.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_vsplit.gif
new file mode 100644
index 000000000..6564d07f1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_Toolbar_vsplit.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_nopic.jpg b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_nopic.jpg
new file mode 100644
index 000000000..f98b2330f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/PD_nopic.jpg
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/newsuade_wiz.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/newsuade_wiz.gif
new file mode 100644
index 000000000..ecd75f41b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/newsuade_wiz.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/large/PD_Palette_Default.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/large/PD_Palette_Default.gif
new file mode 100644
index 000000000..a320fcb59
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/large/PD_Palette_Default.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Default.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Default.gif
new file mode 100644
index 000000000..5e7fb3339
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Default.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export.gif
new file mode 100644
index 000000000..095beb0c4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Disabled.gif
new file mode 100644
index 000000000..04800a616
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Hover.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Hover.gif
new file mode 100644
index 000000000..095beb0c4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Export_Hover.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import.gif
new file mode 100644
index 000000000..0af690308
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Disabled.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Disabled.gif
new file mode 100644
index 000000000..5c828d472
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Disabled.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Hover.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Hover.gif
new file mode 100644
index 000000000..0af690308
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/GENERIC/small/PD_Palette_Import_Hover.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_A.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_A.gif
new file mode 100644
index 000000000..4c57d0e22
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_A.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_FORM.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_FORM.gif
new file mode 100644
index 000000000..cc27deb97
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_FORM.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_HR.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_HR.gif
new file mode 100644
index 000000000..44e283d13
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_HR.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_IMG.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_IMG.gif
new file mode 100644
index 000000000..776fc8feb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_IMG.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_BUTTON.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_BUTTON.gif
new file mode 100644
index 000000000..9ead4e44a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_BUTTON.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_CHECKBOX.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_CHECKBOX.gif
new file mode 100644
index 000000000..4a02dde9c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_CHECKBOX.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_HIDDEN.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_HIDDEN.gif
new file mode 100644
index 000000000..d14d09fa9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_HIDDEN.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_IMAGE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_IMAGE.gif
new file mode 100644
index 000000000..b12850f31
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_IMAGE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_PASSWORD.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_PASSWORD.gif
new file mode 100644
index 000000000..05d5fe549
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_PASSWORD.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_RADIO.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_RADIO.gif
new file mode 100644
index 000000000..f6aeac0f5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_RADIO.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_TEXT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_TEXT.gif
new file mode 100644
index 000000000..1c8fa1ecd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_INPUT_TEXT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_OBJECT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_OBJECT.gif
new file mode 100644
index 000000000..cba93bf83
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_OBJECT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_SELECT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_SELECT.gif
new file mode 100644
index 000000000..3831d9583
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_SELECT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TABLE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TABLE.gif
new file mode 100644
index 000000000..9873b0928
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TABLE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TEXTAREA.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TEXTAREA.gif
new file mode 100644
index 000000000..25f22d860
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/large/HTML_TEXTAREA.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_A.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_A.gif
new file mode 100644
index 000000000..5fd9c9494
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_A.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_BR.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_BR.gif
new file mode 100644
index 000000000..b46868549
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_BR.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_FORM.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_FORM.gif
new file mode 100644
index 000000000..3081f3235
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_FORM.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_HR.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_HR.gif
new file mode 100644
index 000000000..19ab61434
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_HR.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_IMG.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_IMG.gif
new file mode 100644
index 000000000..115cbc6fe
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_IMG.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_BUTTON.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_BUTTON.gif
new file mode 100644
index 000000000..8e721c512
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_BUTTON.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_CHECKBOX.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_CHECKBOX.gif
new file mode 100644
index 000000000..00da14ec8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_CHECKBOX.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_HIDDEN.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_HIDDEN.gif
new file mode 100644
index 000000000..f18865b9a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_HIDDEN.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_IMAGE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_IMAGE.gif
new file mode 100644
index 000000000..2a7596399
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_IMAGE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_PASSWORD.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_PASSWORD.gif
new file mode 100644
index 000000000..25c2e2670
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_PASSWORD.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_RADIO.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_RADIO.gif
new file mode 100644
index 000000000..2598367c8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_RADIO.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_TEXT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_TEXT.gif
new file mode 100644
index 000000000..7f506d902
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_INPUT_TEXT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_OBJECT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_OBJECT.gif
new file mode 100644
index 000000000..745f6d914
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_OBJECT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_SELECT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_SELECT.gif
new file mode 100644
index 000000000..247efe030
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_SELECT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TABLE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TABLE.gif
new file mode 100644
index 000000000..d11c996e5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TABLE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TEXTAREA.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TEXTAREA.gif
new file mode 100644
index 000000000..a2fa616a9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/HTML/small/HTML_TEXTAREA.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DECLARATION.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DECLARATION.gif
new file mode 100644
index 000000000..5403f7229
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DECLARATION.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.INCLUDE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.INCLUDE.gif
new file mode 100644
index 000000000..592667047
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.INCLUDE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.PAGE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.PAGE.gif
new file mode 100644
index 000000000..e21e763b9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.PAGE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.TAGLIB.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.TAGLIB.gif
new file mode 100644
index 000000000..723a10de7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_DIRECTIVE.TAGLIB.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_EXPRESSION.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_EXPRESSION.gif
new file mode 100644
index 000000000..53a23e102
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_EXPRESSION.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FALLBACK.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FALLBACK.gif
new file mode 100644
index 000000000..2507aacd0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FALLBACK.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FORWARD.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FORWARD.gif
new file mode 100644
index 000000000..774759510
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_FORWARD.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_GETPROPERTY.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_GETPROPERTY.gif
new file mode 100644
index 000000000..4d11f8d44
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_GETPROPERTY.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_INCLUDE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_INCLUDE.gif
new file mode 100644
index 000000000..88e62b4cc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_INCLUDE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAM.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAM.gif
new file mode 100644
index 000000000..79e07c22c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAM.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAMS.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAMS.gif
new file mode 100644
index 000000000..9f517aeb0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PARAMS.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PLUGIN.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PLUGIN.gif
new file mode 100644
index 000000000..2ba7b4b11
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_PLUGIN.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_ROOT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_ROOT.gif
new file mode 100644
index 000000000..922b61d03
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_ROOT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SCRIPTLET.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SCRIPTLET.gif
new file mode 100644
index 000000000..a1d2e61c8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SCRIPTLET.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SETPROPERTY.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SETPROPERTY.gif
new file mode 100644
index 000000000..4d11f8d44
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_SETPROPERTY.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_TEXT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_TEXT.gif
new file mode 100644
index 000000000..4cc147e98
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_TEXT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_USEBEAN.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_USEBEAN.gif
new file mode 100644
index 000000000..9d54e8b0c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/large/JSP_USEBEAN.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DECLARATION.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DECLARATION.gif
new file mode 100644
index 000000000..35f48efff
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DECLARATION.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.INCLUDE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.INCLUDE.gif
new file mode 100644
index 000000000..1ef9c8fa9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.INCLUDE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.PAGE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.PAGE.gif
new file mode 100644
index 000000000..37c1e7cd8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.PAGE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.TAGLIB.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.TAGLIB.gif
new file mode 100644
index 000000000..33ef3d820
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_DIRECTIVE.TAGLIB.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_EXPRESSION.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_EXPRESSION.gif
new file mode 100644
index 000000000..66fd649da
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_EXPRESSION.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FALLBACK.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FALLBACK.gif
new file mode 100644
index 000000000..4fb415010
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FALLBACK.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FORWARD.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FORWARD.gif
new file mode 100644
index 000000000..1d3bafb31
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_FORWARD.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_GETPROPERTY.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_GETPROPERTY.gif
new file mode 100644
index 000000000..af4450a4b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_GETPROPERTY.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_INCLUDE.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_INCLUDE.gif
new file mode 100644
index 000000000..2584c3185
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_INCLUDE.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAM.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAM.gif
new file mode 100644
index 000000000..b3e0727e8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAM.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAMS.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAMS.gif
new file mode 100644
index 000000000..40759226c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PARAMS.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PLUGIN.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PLUGIN.gif
new file mode 100644
index 000000000..04bab8e34
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_PLUGIN.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_ROOT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_ROOT.gif
new file mode 100644
index 000000000..f6d19d4a0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_ROOT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SCRIPTLET.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SCRIPTLET.gif
new file mode 100644
index 000000000..1753b9627
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SCRIPTLET.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SETPROPERTY.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SETPROPERTY.gif
new file mode 100644
index 000000000..af4450a4b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_SETPROPERTY.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_TEXT.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_TEXT.gif
new file mode 100644
index 000000000..7f506d902
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_TEXT.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_USEBEAN.gif b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_USEBEAN.gif
new file mode 100644
index 000000000..ba33db70f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/icons/palette/JSP/small/JSP_USEBEAN.gif
Binary files differ
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/plugin.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/plugin.properties
new file mode 100644
index 000000000..7ec60e359
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/plugin.properties
@@ -0,0 +1,11 @@
+####################################################
+# Plugin XML information.
+####################################################
+pluginName=Pagedesigner Plug-in
+providerName=Eclipse.org
+perspectiveName=Web Application Development
+
+# views
+Resource_Contributions_Extension.name=Resource
+
+PaletteItem_Config_Contributions_Extension.name= PaletteItem Config Contributions
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/plugin.xml b/jsf/plugins/org.eclipse.jst.pagedesigner/plugin.xml
new file mode 100644
index 000000000..13be36f31
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/plugin.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+ <extension-point id="pageDesignerExtension" name="Web Page Editor Extension" schema="schema/pageDesignerExtension.exsd" />
+ <extension-point id="ResourceContributions" name="%Resource_Contributions_Extension.name" schema="schema/ResourceContributions.exsd" />
+ <extension-point id="propertySections" name="Property Section" schema="schema/propertySections.exsd" />
+ <extension-point id="propertyContributor" name="property contributor" schema="schema/propertyContributor.exsd" />
+ <extension-point id="popupMenuContributor" name="popupMenu Contributor" schema="schema/popupMenuContributor.exsd"/>
+ <extension-point id="cmRegistry" name="Content Model Meta Data" schema="schema/cmRegistry.exsd"/>
+ <extension-point id="PaletteItemConfigContributions" name="%PaletteItem_Config_Contributions_Extension.name" schema="schema/PaletteItemConfigContributions.exsd"/>
+
+ <extension point="org.eclipse.ui.editors">
+ <editor class="org.eclipse.jst.pagedesigner.editors.HTMLEditor"
+ contributorClass="org.eclipse.jst.pagedesigner.editors.actions.PageDesignerActionBarContributor2"
+ default="true"
+ extensions="jsp,jsf,html,htm,xhtml"
+ icon="icons/PD_Plugin.gif"
+ id="org.eclipse.jst.pagedesigner.PageDesignerEditor"
+ name="Web Page Editor">
+ </editor>
+ </extension>
+
+ <extension point="org.eclipse.core.runtime.adapters">
+ <factory
+ class="org.eclipse.jst.pagedesigner.utils.UriAdapterFactory"
+ adaptableType="org.eclipse.core.resources.IProject">
+ <adapter type="org.eclipse.wst.sse.core.util.URIResolver" />
+ </factory>
+ <factory
+ class="org.eclipse.jst.pagedesigner.dnd.internal.TextEditorDropTargetListenerFactory"
+ adaptableType="org.eclipse.jst.jsp.ui.internal.editor.StructuredTextEditorJSP">
+ <adapter type="org.eclipse.ui.texteditor.ITextEditorDropTargetListener" />
+ </factory>
+ </extension>
+
+ <extension point="org.eclipse.wst.common.ui.properties.propertyTabs">
+ <propertyTabs
+ contributorId="org.eclipse.jst.pagedesigner.pageDesigner.tabPropertyContributor">
+ <propertyTab label="Quick Edit" category="Quick Edit" id="org.eclipse.jst.pagedesigner.tabQuickEdit" />
+ <propertyTab label="Attributes" category="Attributes" id="org.eclipse.jst.pagedesigner.tabAttributes" />
+ </propertyTabs>
+ </extension>
+
+ <extension
+ point="org.eclipse.wst.common.ui.properties.propertyContributor">
+ <propertyContributor
+ sectionDescriptorProvider="org.eclipse.jst.pagedesigner.properties.internal.DesignerTabPropertySectionDescriptorProvider"
+ contributorId="org.eclipse.jst.pagedesigner.pageDesigner.tabPropertyContributor">
+ <propertyCategory category="Quick Edit" />
+ <propertyCategory category="Attributes" />
+ </propertyContributor>
+ </extension>
+
+ <extension
+ point="org.eclipse.jst.pagedesigner.propertySections">
+ <propertySections>
+ <propertySection afterSection="top"
+ class="org.eclipse.jst.pagedesigner.properties.AllPropertySection"
+ tab="org.eclipse.jst.pagedesigner.tabAttributes"
+ id="section.allproperty" />
+ </propertySections>
+ </extension>
+
+ <extension point="org.eclipse.jst.pagedesigner.pageDesignerExtension">
+ <linkCreator class="org.eclipse.jst.pagedesigner.actions.link.HtmlLinkCreator" linkIdentifier="Html Link"/>
+ </extension>
+
+ <extension point="org.eclipse.jst.pagedesigner.PaletteItemConfigContributions">
+ <config path="configs/html_pi.xml" index="10"/>
+ <config path="configs/jsp_pi.xml" index="20" />
+ </extension>
+
+ <extension id="org.eclipse.jst.pagedesigner.commands" point="org.eclipse.ui.commands">
+ <category id="org.eclipse.jst.pagedesigner.pagelayout" name="Page Layout"/>
+ <command categoryId="org.eclipse.jst.pagedesigner.pagelayout"
+ id="org.eclipse.jst.pagedesigner.vertical"
+ name="vertical Layout"/>
+ <command categoryId="org.eclipse.jst.pagedesigner.pagelayout"
+ id="org.eclipse.jst.pagedesigner.horizotal"
+ name="horizotal Layout"/>
+ <command categoryId="org.eclipse.jst.pagedesigner.pagelayout"
+ id="org.eclipse.jst.pagedesigner.design"
+ name="graphical designer"/>
+ <command categoryId="org.eclipse.jst.pagedesigner.pagelayout"
+ id="org.eclipse.jst.pagedesigner.source"
+ name="source code"/>
+ </extension>
+
+ <extension point="org.eclipse.ui.bindings">
+ <key commandId="org.eclipse.jst.pagedesigner.vertical"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ contextId="org.eclipse.ui.contexts.window"
+ sequence="M1+M2+F9"/>
+ <key commandId="org.eclipse.jst.pagedesigner.horizotal"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ contextId="org.eclipse.ui.contexts.window"
+ sequence="M1+M2+F10"/>
+ <key commandId="org.eclipse.jst.pagedesigner.design"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ contextId="org.eclipse.ui.contexts.window"
+ sequence="M1+M2+F11"/>
+ <key commandId="org.eclipse.jst.pagedesigner.source"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ contextId="org.eclipse.ui.contexts.window"
+ sequence="M1+M2+F12"/>
+ </extension>
+
+ <extension point="org.eclipse.wst.sse.ui.editorConfiguration">
+ <contentOutlineConfiguration
+ class="org.eclipse.jst.pagedesigner.editors.OutlineConfiguration"
+ target="org.eclipse.jst.pagedesigner.editors.DesignerStructuredTextEditorJSP"/>
+ </extension>
+</plugin> \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/PaletteItemConfigContributions.exsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/PaletteItemConfigContributions.exsd
new file mode 100644
index 000000000..d40062c77
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/PaletteItemConfigContributions.exsd
@@ -0,0 +1,125 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.pagedesigner">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.pagedesigner" id="PaletteItemConfigContributions" name="Palette Item Config"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="config" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="config">
+ <annotation>
+ <documentation>
+ User must provide either &quot;index&quot; attribute or &quot;path&quot; attribute.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="path" type="string">
+ <annotation>
+ <documentation>
+ A path relative to the root of the declaring plugin. Point to a config file that contains the information for the specified tag lib of the uri.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="index" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/cmRegistry.exsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/cmRegistry.exsd
new file mode 100644
index 000000000..e217ffe92
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/cmRegistry.exsd
@@ -0,0 +1,135 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.pagedesigner">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.pagedesigner" id="cmRegistry" name="Content Model Meta Data"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="registry" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="registry">
+ <annotation>
+ <documentation>
+ User must provide either &quot;configFile&quot; attribute or &quot;class&quot; attribute.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="configFile" type="string">
+ <annotation>
+ <documentation>
+ A path relative to the root of the declaring plugin. Point to a config file that contains the information for the specified tag lib of the uri.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ A class that implements ICMRegistry. The implemented ICMRegistry must return the same uri as the uri attribute in getSupportedURI() method.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="uri" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/pageDesignerExtension.exsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/pageDesignerExtension.exsd
new file mode 100644
index 000000000..e0ad58758
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/pageDesignerExtension.exsd
@@ -0,0 +1,184 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.pagedesigner">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.pagedesigner" id="pageDesignerExtension" name="Web Page Editor Extension"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="localDropHandler" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="attributeCellEditorFactory" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="tagConverterFactory" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="elementEditFactory" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="linkCreator" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="localDropHandler">
+ <complexType>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="attributeCellEditorFactory">
+ <complexType>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="tagConverterFactory">
+ <complexType>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="elementEditFactory">
+ <complexType>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="linkCreator">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jst.pagedesigner.actions.link.ILinkCreator"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="linkIdentifier" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/popupMenuContributor.exsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/popupMenuContributor.exsd
new file mode 100644
index 000000000..6f08030d0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/popupMenuContributor.exsd
@@ -0,0 +1,120 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.pagedesigner">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.pagedesigner" id="popupMenuContributor" name="popupMenu Contributor"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="menuItemContributor" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="menuItemContributor">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="URI" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertyContributor.exsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertyContributor.exsd
new file mode 100644
index 000000000..ef93be6e1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertyContributor.exsd
@@ -0,0 +1,113 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.pagedesigner">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.pagedesigner" id="propertyContributor" name="property contributor"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="propertyContributor" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="propertyContributor">
+ <complexType>
+ <attribute name="sectionDescriptorProvider" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertySections.exsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertySections.exsd
new file mode 100644
index 000000000..2eb0bc8e4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/propertySections.exsd
@@ -0,0 +1,141 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.pagedesigner">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.pagedesigner" id="propertySections" name="Property Sections"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="propertySections"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ The identifier of the extension point, i.e. &lt;tt&gt;org.eclipse.wst.ui.properties.propertySections&lt;/tt&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="propertySections">
+ <complexType>
+ <sequence>
+ <element ref="propertySection" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="propertySection">
+ <complexType>
+ <sequence>
+ <element ref="tagFilter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="tab" type="string" use="required">
+ <annotation>
+ <documentation>
+ The tab in which this section appears.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id for the section.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class that implements the section, i.e. implements &lt;tt&gt;org.eclipse.wst.ui.properties.IPropertySection&lt;/tt&gt;.
+Or, the class could extends &lt;code&gt;AttributeGroup&lt;/code&gt;, in that case, system will automatically create a &lt;code&gt;AttributeGroupSection&lt;/code&gt; for it.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="afterSection" type="string">
+ <annotation>
+ <documentation>
+ When there is more than one section in a tab, sections are sorted by the afterSection attribute.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="filter" type="string">
+ <annotation>
+ <documentation>
+ The class that implements a ISectionFilter
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="tagFilter">
+ <complexType>
+ <attribute name="uri" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="tagName" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="caseSensitive" type="boolean" use="default" value="true">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/schema/tagProperty.xsd b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/tagProperty.xsd
new file mode 100644
index 000000000..f970c0844
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/schema/tagProperty.xsd
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema">
+ <element name="taglib">
+ <complexType>
+ <sequence>
+ <element ref="tag" maxOccurs="unbounded"></element>
+ <element ref="definition" minOccurs="0" maxOccurs="1"></element>
+ </sequence>
+ <attribute ref="uri" />
+ </complexType>
+ </element>
+
+ <element name="tag">
+ <complexType>
+ <sequence>
+ <element ref="category" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ <element ref="referedcategory" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ </sequence>
+ <attribute ref="name"></attribute>
+ </complexType>
+ </element>
+
+ <element name="category">
+ <complexType>
+ <sequence>
+ <element ref="attribute" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ <element ref="referedattribute" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ </sequence>
+ <attribute ref="name"></attribute>
+ <attribute ref="displaylabel"></attribute>
+ </complexType>
+ </element>
+
+ <element name="referedcategory">
+ <complexType>
+ <sequence>
+ <element ref="includeattrs" minOccurs="0"
+ maxOccurs="1">
+ </element>
+ <element ref="excludeattrs" minOccurs="0"
+ maxOccurs="1">
+ </element>
+ </sequence>
+ <attribute ref="ref"></attribute>
+ <attribute ref="displaylabel"></attribute>
+ </complexType>
+ </element>
+
+ <element name="definition">
+ <complexType>
+ <sequence>
+ <element ref="categories" minOccurs="0" maxOccurs="1"></element>
+ <element ref="attributes" minOccurs="0" maxOccurs="1"></element>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="attribute">
+ <complexType>
+ <sequence>
+ <element ref="option" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ </sequence>
+ <attribute ref="name"></attribute>
+ <attribute ref="displaylabel"></attribute>
+ <attribute ref="required"></attribute>
+ <attribute ref="type"></attribute>
+ <attribute ref="typeparam"></attribute>
+ </complexType>
+ </element>
+
+ <element name="referedattribute">
+ <complexType>
+ <attribute ref="ref"></attribute>
+ <attribute ref="overridename"></attribute>
+ <attribute ref="displaylabel"></attribute>
+ </complexType>
+ </element>
+
+ <element name="includeattrs">
+ <complexType>
+ <sequence>
+ <element ref="attribute" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ <element ref="referedattribute" minOccurs="0"
+ maxOccurs="unbounded">
+ </element>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="excludeattrs">
+ <complexType>
+ <attribute ref="refs"></attribute>
+ </complexType>
+ </element>
+
+ <element name="categories">
+ <complexType>
+ <sequence>
+ <element ref="category"></element>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="attributes">
+ <complexType>
+ <sequence>
+ <element ref="attribute"></element>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="option">
+ <complexType>
+ <attribute ref="key"></attribute>
+ <attribute ref="value"></attribute>
+ <attribute ref="default"></attribute>
+ </complexType>
+ </element>
+
+ <attribute name="name" type="string"></attribute>
+
+ <attribute name="displaylabel" type="string"></attribute>
+
+ <attribute name="ref" type="string"></attribute>
+
+ <attribute name="refs" type="string"></attribute>
+
+ <attribute name="uri" type="string"></attribute>
+
+ <attribute name="type" type="string"></attribute>
+
+ <attribute name="typeparam" type="string"></attribute>
+
+ <attribute name="key" type="string"></attribute>
+
+ <attribute name="value" type="string"></attribute>
+
+ <attribute name="overridename" type="string"></attribute>
+ <attribute name="default" type="string" fixed="default"></attribute>
+ <attribute name="required" type="string" fixed="required"></attribute>
+
+</schema> \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IHTMLConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IHTMLConstants.java
new file mode 100644
index 000000000..edd96d4a4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IHTMLConstants.java
@@ -0,0 +1,495 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner;
+
+/**
+ * @author mengbo
+ */
+public class IHTMLConstants {
+ public static final String TAG_A = "a"; // anchor
+
+ public static final String TAG_ABBR = "abbr"; // abbreviated form (e.g.,
+
+ // WWW, HTTP, etc.)
+
+ public static final String TAG_ACRONYM = "acronym";
+
+ public static final String TAG_ADDRESS = "address"; // information on author
+
+ public static final String TAG_APPLET = "applet"; // Java applet
+
+ public static final String TAG_AREA = "area"; // client-side image map
+
+ // area
+
+ public static final String TAG_B = "b"; // bold text style
+
+ public static final String TAG_BASE = "base"; // document base URI
+
+ public static final String TAG_BASEFONT = "basefont"; // base font size
+
+ public static final String TAG_BDO = "bdo"; // I18N BiDi over-ride
+
+ public static final String TAG_BIG = "big"; // large text style
+
+ public static final String TAG_BLOCKQUOTE = "blockquote"; // long
+
+ // quotation
+
+ public static final String TAG_BODY = "body"; // document body
+
+ public static final String TAG_BR = "br"; // forced line break
+
+ public static final String TAG_BUTTON = "button"; // push button
+
+ public static final String TAG_CAPTION = "caption"; // table caption
+
+ public static final String TAG_CENTER = "center"; // shorthand for DIV
+
+ // align=center
+
+ public static final String TAG_CITE = "cite"; // citation
+
+ public static final String TAG_CODE = "code"; // computer code fragment
+
+ public static final String TAG_COL = "col"; // table column
+
+ public static final String TAG_COLGROUP = "colgroup"; // table column
+
+ // group
+
+ public static final String TAG_DD = "dd"; // definition description
+
+ public static final String TAG_DEL = "del"; // deleted text
+
+ public static final String TAG_DFN = "dfn"; // instance definition
+
+ public static final String TAG_DIR = "dir"; // directory list
+
+ public static final String TAG_DIV = "div"; // generic language/style
+
+ // container
+
+ public static final String TAG_DL = "dl"; // definition list
+
+ public static final String TAG_DT = "dt"; // definition term
+
+ public static final String TAG_EM = "em"; // emphasis
+
+ public static final String TAG_FIELDSET = "fieldset"; // form control
+
+ // group
+
+ public static final String TAG_FONT = "font"; // local change to font
+
+ public static final String TAG_FORM = "form"; // interactive form
+
+ public static final String TAG_FRAME = "frame"; // subwindow
+
+ public static final String TAG_FRAMESET = "frameset"; // window
+
+ // subdivision
+
+ public static final String TAG_H1 = "h1"; // heading
+
+ public static final String TAG_H2 = "h2"; // heading
+
+ public static final String TAG_H3 = "h3"; // heading
+
+ public static final String TAG_H4 = "h4"; // heading
+
+ public static final String TAG_H5 = "h5"; // heading
+
+ public static final String TAG_H6 = "h6"; // heading
+
+ public static final String TAG_HEAD = "head"; // document head
+
+ public static final String TAG_HR = "hr"; // horizontal rule
+
+ public static final String TAG_HTML = "html"; // document root element
+
+ public static final String TAG_I = "i"; // italic text style
+
+ public static final String TAG_IFRAME = "iframe"; // inline subwindow
+
+ public static final String TAG_IMG = "img"; // Embedded image
+
+ public static final String TAG_INPUT = "input"; // form control
+
+ public static final String TAG_INS = "ins"; // inserted text
+
+ public static final String TAG_ISINDEX = "isindex"; // single line prompt
+
+ public static final String TAG_KBD = "kbd"; // text to be entered by the
+
+ // user
+
+ public static final String TAG_LABEL = "label"; // form field label text
+
+ public static final String TAG_LEGEND = "legend"; // fieldset legend
+
+ public static final String TAG_LI = "li"; // list item
+
+ public static final String TAG_LINK = "link"; // a media-independent link
+
+ public static final String TAG_MAP = "map"; // client-side image map
+
+ public static final String TAG_MENU = "menu"; // menu list
+
+ public static final String TAG_META = "meta"; // generic metainformation
+
+ public static final String TAG_NOEMBED = "noembed";
+
+ public static final String TAG_NOFRAMES = "noframes"; // alternate content
+
+ // container for non
+ // frame-based
+ // rendering
+
+ public static final String TAG_NOSCRIPT = "noscript"; // alternate content
+
+ // container for non
+ // script-based
+ // rendering
+
+ public static final String TAG_OBJECT = "object"; // generic embedded
+
+ // object
+
+ public static final String TAG_OL = "ol"; // ordered list
+
+ public static final String TAG_OPTGROUP = "optgroup"; // option group
+
+ public static final String TAG_OPTION = "option"; // selectable choice
+
+ public static final String TAG_P = "p"; // paragraph
+
+ public static final String TAG_PARAM = "param"; // named property value
+
+ public static final String TAG_PRE = "pre"; // preformatted text
+
+ public static final String TAG_Q = "q"; // short inline quotation
+
+ public static final String TAG_S = "s"; // strike-through text style
+
+ public static final String TAG_SAMP = "samp"; // sample program output,
+
+ // scripts, etc.
+
+ public static final String TAG_SCRIPT = "script"; // script statements
+
+ public static final String TAG_SELECT = "select"; // option selector
+
+ public static final String TAG_SMALL = "small"; // small text style
+
+ public static final String TAG_SPAN = "span"; // generic language/style
+
+ // container
+
+ public static final String TAG_STRIKE = "strike"; // strike-through text
+
+ public static final String TAG_STRONG = "strong"; // strong emphasis
+
+ public static final String TAG_STYLE = "style"; // style info
+
+ public static final String TAG_SUB = "sub"; // subscript
+
+ public static final String TAG_SUP = "sup"; // superscript
+
+ public static final String TAG_TABLE = "table";
+
+ public static final String TAG_TBODY = "tbody"; // table body
+
+ public static final String TAG_TD = "td"; // table data cell
+
+ public static final String TAG_TEXTAREA = "textarea"; // multi-line text
+
+ // field
+
+ public static final String TAG_TFOOT = "tfoot"; // table footer
+
+ public static final String TAG_TH = "th"; // table header cell
+
+ public static final String TAG_THEAD = "thead"; // table header
+
+ public static final String TAG_TITLE = "title"; // document title
+
+ public static final String TAG_TR = "tr"; // table row
+
+ public static final String TAG_TT = "tt"; // teletype or monospaced text
+
+ // style
+
+ public static final String TAG_U = "u"; // underlined text style
+
+ public static final String TAG_UL = "ul"; // unordered list
+
+ public static final String TAG_VAR = "var"; // instance of a variable or
+
+ // program argument
+
+ public static final String ATTR_ABBR = "abbr";
+
+ public static final String ATTR_ACCEPTCHARSET = "accept-charset";
+
+ public static final String ATTR_ACCEPT = "accept";
+
+ public static final String ATTR_ACCESSKEY = "accesskey";
+
+ public static final String ATTR_ACTION = "action";
+
+ public static final String ATTR_ALIGN = "align";
+
+ public static final String ATTR_ALINK = "alink";
+
+ public static final String ATTR_ALT = "alt";
+
+ public static final String ATTR_ARCHIVE = "archive";
+
+ public static final String ATTR_AXIS = "axis";
+
+ public static final String ATTR_BACKGROUND = "background";
+
+ public static final String ATTR_BGCOLOR = "bgcolor";
+
+ public static final String ATTR_BORDER = "border";
+
+ public static final String ATTR_CELLPADDING = "cellpadding";
+
+ public static final String ATTR_CELLSPACING = "cellspacing";
+
+ public static final String ATTR_CHAR = "char";
+
+ public static final String ATTR_CHAROFF = "charoff";
+
+ public static final String ATTR_CHARSET = "charset";
+
+ public static final String ATTR_CHECKED = "checked";
+
+ public static final String ATTR_CITE = "cite";
+
+ public static final String ATTR_CLASS = "class";
+
+ public static final String ATTR_CLASSID = "classid";
+
+ public static final String ATTR_CLEAR = "clear";
+
+ public static final String ATTR_CODE = "code";
+
+ public static final String ATTR_CODEBASE = "codebase";
+
+ public static final String ATTR_CODETYPE = "codetype";
+
+ public static final String ATTR_COLOR = "color";
+
+ public static final String ATTR_COLS = "cols";
+
+ public static final String ATTR_COLSPAN = "colspan";
+
+ public static final String ATTR_COMPACT = "compact";
+
+ public static final String ATTR_CONTENT = "content";
+
+ public static final String ATTR_COORDS = "coords";
+
+ public static final String ATTR_DATA = "data";
+
+ public static final String ATTR_DATETIME = "datetime";
+
+ public static final String ATTR_DECLARE = "declare";
+
+ public static final String ATTR_DEFER = "defer";
+
+ public static final String ATTR_DIR = "dir";
+
+ public static final String ATTR_DISABLED = "disabled";
+
+ public static final String ATTR_ENCTYPE = "enctype";
+
+ public static final String ATTR_FACE = "face";
+
+ public static final String ATTR_FOR = "for";
+
+ public static final String ATTR_FRAME = "frame";
+
+ public static final String ATTR_FRAMEBORDER = "frameborder";
+
+ public static final String ATTR_HEADERS = "headers";
+
+ public static final String ATTR_HEIGHT = "height";
+
+ public static final String ATTR_HREF = "href";
+
+ public static final String ATTR_HREFLANG = "hreflang";
+
+ public static final String ATTR_HSPACE = "hspace";
+
+ public static final String ATTR_HTTPEQUIV = "http-equiv";
+
+ public static final String ATTR_ID = "id";
+
+ public static final String ATTR_ISMAP = "ismap";
+
+ public static final String ATTR_LABEL = "label";
+
+ public static final String ATTR_LANG = "lang";
+
+ public static final String ATTR_LANGUAGE = "language";
+
+ public static final String ATTR_LINK = "link";
+
+ public static final String ATTR_LONGDESC = "longdesc";
+
+ public static final String ATTR_MARGINHEIGHT = "marginheight";
+
+ public static final String ATTR_MARGINWIDTH = "marginwidth";
+
+ public static final String ATTR_MAXLENGTH = "maxlength";
+
+ public static final String ATTR_MEDIA = "media";
+
+ public static final String ATTR_METHOD = "method";
+
+ public static final String ATTR_MULTIPLE = "multiple";
+
+ public static final String ATTR_NAME = "name";
+
+ public static final String ATTR_NOHREF = "nohref";
+
+ public static final String ATTR_NORESIZE = "noresize";
+
+ public static final String ATTR_NOSHADE = "noshade";
+
+ public static final String ATTR_NOWRAP = "nowrap";
+
+ public static final String ATTR_OBJECT = "object";
+
+ public static final String ATTR_ONBLUR = "onblur";
+
+ public static final String ATTR_ONCHANGE = "onchange";
+
+ public static final String ATTR_ONCLICK = "onclick";
+
+ public static final String ATTR_ONDBLCLICK = "ondblclick";
+
+ public static final String ATTR_ONFOCUS = "onfocus";
+
+ public static final String ATTR_ONKEYDOWN = "onkeydown";
+
+ public static final String ATTR_ONKEYPRESS = "onkeypress";
+
+ public static final String ATTR_ONKEYUP = "onkeyup";
+
+ public static final String ATTR_ONLOAD = "onload";
+
+ public static final String ATTR_ONMOUSEDOWN = "onmousedown";
+
+ public static final String ATTR_ONMOUSEMOVE = "onmousemove";
+
+ public static final String ATTR_ONMOUSEOUT = "onmouseout";
+
+ public static final String ATTR_ONMOUSEOVER = "onmouseover";
+
+ public static final String ATTR_ONMOUSEUP = "onmouseup";
+
+ public static final String ATTR_ONRESET = "onreset";
+
+ public static final String ATTR_ONSELECT = "onselect";
+
+ public static final String ATTR_ONSUBMIT = "onsubmit";
+
+ public static final String ATTR_ONUNLOAD = "onunload";
+
+ public static final String ATTR_PROFILE = "profile";
+
+ public static final String ATTR_PROMPT = "prompt";
+
+ public static final String ATTR_READONLY = "readonly";
+
+ public static final String ATTR_REL = "rel";
+
+ public static final String ATTR_REV = "rev";
+
+ public static final String ATTR_ROWS = "rows";
+
+ public static final String ATTR_ROWSPAN = "rowspan";
+
+ public static final String ATTR_RULES = "rules";
+
+ public static final String ATTR_SCHEME = "scheme";
+
+ public static final String ATTR_SCOPE = "scope";
+
+ public static final String ATTR_SCROLLING = "scrolling";
+
+ public static final String ATTR_SELECTED = "selected";
+
+ public static final String ATTR_SHAPE = "shape";
+
+ public static final String ATTR_SIZE = "size";
+
+ public static final String ATTR_SPAN = "span";
+
+ public static final String ATTR_SRC = "src";
+
+ public static final String ATTR_STANDBY = "standby";
+
+ public static final String ATTR_START = "start";
+
+ public static final String ATTR_STYLE = "style";
+
+ public static final String ATTR_SUMMARY = "summary";
+
+ public static final String ATTR_TABINDEX = "tabindex";
+
+ public static final String ATTR_TARGET = "target";
+
+ public static final String ATTR_TEXT = "text";
+
+ public static final String ATTR_TITLE = "title";
+
+ public static final String ATTR_TYPE = "type";
+
+ public static final String ATTR_USEMAP = "usemap";
+
+ public static final String ATTR_VALIGN = "valign";
+
+ public static final String ATTR_VALUE = "value";
+
+ public static final String ATTR_VALUETYPE = "valuetype";
+
+ public static final String ATTR_VERSION = "version";
+
+ public static final String ATTR_VLINK = "vlink";
+
+ public static final String ATTR_VSPACE = "vspace";
+
+ public static final String ATTR_WIDTH = "width";
+
+ public static final String TYPE_SUBMIT = "submit";
+
+ public static final String TYPE_CHECKBOX = "checkbox";
+
+ public static final String TYPE_RADIO = "radio";
+
+ public static final String TYPE_IMAGE = "image";
+
+ public static final String TYPE_PASSWORD = "password";
+
+ public static final String TYPE_TEXT = "text";
+
+ public static final String TYPE_HIDDEN = "hidden";
+
+ public static final String SUBMIT_LABEL = "Submit Query";
+
+ public static final String RESET_LABEL = "Reset";
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJMTConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJMTConstants.java
new file mode 100644
index 000000000..27091be32
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJMTConstants.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner;
+
+/**
+ * JMT constants that would be used through the JMT core plugin.
+ *
+ * @author mengbo
+ */
+public interface IJMTConstants {
+ public static final String PAGEDESIGNER_RESOURCE_BUNDLE_FILE = "org.eclipse.jst.pagedesigner.editors.pagedesigner.JSPEditorMessages"; //$NON-NLS-1$
+
+ // Properties contains general properties and defaults to preferences.
+ public static final String ROOT_RESOURCEBUNDLE = "org.eclipse.jst.pagedesigner.JMTResources"; //$NON-NLS-1$
+
+ public static final String DEFAULT_PROPERTIES = "default.properties"; //$NON-NLS-1$
+
+ public static final String USERAGENT = "html4.css"; //$NON-NLS-1$
+
+ public static final String EDITORID_HTML = "org.eclipse.jst.pagedesigner.PageDesignerEditor"; //$NON-NLS-1$
+
+ public static final String PREF_PALETTE_SHOW_ALL = "pref.palette.showall"; //$NON-NLS-1$
+
+ // each name space is represented by an URI. As there are multiversion of
+ // html and jsp,
+ // so we use a special string for them.
+ public static final String URI_HTML = "html"; //$NON-NLS-1$
+
+ public static final String URI_JSP = "jsp"; //$NON-NLS-1$
+
+ public static final String URI_JSF_CORE = "http://java.sun.com/jsf/core"; //$NON-NLS-1$
+
+ public static final String URI_JSF_HTML = "http://java.sun.com/jsf/html"; //$NON-NLS-1$
+
+ public static final String EXTENSION_POINT_PAGEDESIGNER = "pageDesignerExtension"; //$NON-NLS-1$
+
+ public static final String EXTENSION_POINT_CMREGISTRY = "cmRegistry"; //$NON-NLS-1$
+
+ public static final String EXTENSION_POINT_PALETTEITEMCONFIG = "PaletteItemConfigContributions"; //$NON-NLS-1$
+
+ public static final String ATTRIBUTE_PATH_PALETTEITEMCONFIG = "path"; //$NON-NLS-1$
+
+ public static final String ATTRIBUTE_INDEX_PALETTEITEMCONFIG = "index"; //$NON-NLS-1$
+
+ public static final String LOCAL_DROP_HANDLER = "localDropHandler"; //$NON-NLS-1$
+
+ public static final String TAG_CONVERTER_FACTORY = "tagConverterFactory"; //$NON-NLS-1$
+
+ public static final String ATTRIBUTE_CELLEDITOR_FACTORY = "attributeCellEditorFactory"; //$NON-NLS-1$
+
+ public static final String ELEMENT_EDIT_FACTORY = "elementEditFactory"; //$NON-NLS-1$
+
+ public static final String LINK_CREATOR = "linkCreator"; //$NON-NLS-1$
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJSFConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJSFConstants.java
new file mode 100644
index 000000000..1fbc067be
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/IJSFConstants.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner;
+
+/**
+ * @author mengbo
+ */
+public interface IJSFConstants {
+ // tag name
+ final static public String TAG_ACTIONLISTENER = "actionListener";
+
+ final static public String TAG_ATTRIBUTE = "attribute";
+
+ final static public String TAG_CONVERTDATETIME = "convertDateTime";
+
+ final static public String TAG_CONVERTER = "converter";
+
+ final static public String TAG_CONVERTNUMBER = "convertNumber";
+
+ final static public String TAG_FACET = "facet";
+
+ final static public String TAG_LOADBUNDLE = "loadBundle";
+
+ final static public String TAG_PARAM = "param";
+
+ final static public String TAG_SELECTITEM = "selectItem";
+
+ final static public String TAG_SELECTITEMS = "selectItems";
+
+ final static public String TAG_SUBVIEW = "subview";
+
+ final static public String TAG_VALIDATEDOUBLERANGE = "validateDoubleRange";
+
+ final static public String TAG_VALIDATELENGTH = "validateLength";
+
+ final static public String TAG_VALIDATELONGRANGE = "validateLongRange";
+
+ final static public String TAG_VALIDATOR = "validator";
+
+ final static public String TAG_VALUECHANGELISTENER = "valueChangeListener";
+
+ final static public String TAG_VERBATIM = "verbatim";
+
+ final static public String TAG_VIEW = "view";
+
+ final static public String TAG_COLUMN = "column";
+
+ final static public String TAG_COMMANDBUTTON = "commandButton";
+
+ final static public String TAG_COMMANDLINK = "commandLink";
+
+ final static public String TAG_DATATABLE = "dataTable";
+
+ final static public String TAG_FORM = "form";
+
+ final static public String TAG_GRAPHICIMAGE = "graphicImage";
+
+ final static public String TAG_INPUTHIDDEN = "inputHidden";
+
+ final static public String TAG_INPUTSECRET = "inputSecret";
+
+ final static public String TAG_INPUTTEXT = "inputText";
+
+ final static public String TAG_INPUTTEXTAREA = "inputTextarea";
+
+ final static public String TAG_MESSAGE = "message";
+
+ final static public String TAG_MESSAGES = "messages";
+
+ final static public String TAG_OUTPUTFORMAT = "outputFormat";
+
+ final static public String TAG_OUTPUTLABEL = "outputLabel";
+
+ final static public String TAG_OUTPUTLINK = "outputLink";
+
+ final static public String TAG_OUTPUTTEXT = "outputText";
+
+ final static public String TAG_PANELGRID = "panelGrid";
+
+ final static public String TAG_PANELGROUP = "panelGroup";
+
+ final static public String TAG_SELECTBOOLEANCHECKBOX = "selectBooleanCheckbox";
+
+ final static public String TAG_SELECTMANYCHECKBOX = "selectManyCheckbox";
+
+ final static public String TAG_SELECTMANYLISTBOX = "selectManyListbox";
+
+ final static public String TAG_SELECTMANYMENU = "selectManyMenu";
+
+ final static public String TAG_SELECTONELISTBOX = "selectOneListbox";
+
+ final static public String TAG_SELECTONEMENU = "selectOneMenu";
+
+ final static public String TAG_SELECTONERADIO = "selectOneRadio";
+
+ // attribute name
+ final static public String ATTR_ACCEPT = "accept";
+
+ final static public String ATTR_ACCEPTCHARSET = "acceptcharset";
+
+ final static public String ATTR_ACCESSKEY = "accesskey";
+
+ final static public String ATTR_ACTION = "action";
+
+ final static public String ATTR_ACTIONLISTENER = "actionListener";
+
+ final static public String ATTR_ALT = "alt";
+
+ final static public String ATTR_BASENAME = "basename";
+
+ final static public String ATTR_BGCOLOR = "bgcolor";
+
+ final static public String ATTR_BINDING = "binding";
+
+ final static public String ATTR_BORDER = "border";
+
+ final static public String ATTR_CELLPADDING = "cellpadding";
+
+ final static public String ATTR_CELLSPACING = "cellspacing";
+
+ final static public String ATTR_CHARSET = "charset";
+
+ final static public String ATTR_COLS = "cols";
+
+ final static public String ATTR_COLUMNCLASSES = "columnClasses";
+
+ final static public String ATTR_COLUMNS = "columns";
+
+ final static public String ATTR_CONVERTERID = "converterId";
+
+ final static public String ATTR_COORDS = "coords";
+
+ final static public String ATTR_CURRENCYCODE = "currencyCode";
+
+ final static public String ATTR_CURRENCYSYMBOL = "currencySymbol";
+
+ final static public String ATTR_DATESTYLE = "dateStyle";
+
+ final static public String ATTR_DIR = "dir";
+
+ final static public String ATTR_DISABLED = "disabled";
+
+ final static public String ATTR_ERRORCLASS = "errorClass";
+
+ final static public String ATTR_ERRORSTYLE = "errorStyle";
+
+ final static public String ATTR_ESCAPE = "escape";
+
+ final static public String ATTR_FATALCLASS = "fatalClass";
+
+ final static public String ATTR_FATALSTYLE = "fatalStyle";
+
+ final static public String ATTR_FIRST = "first";
+
+ final static public String ATTR_FOOTERCLASS = "footerClass";
+
+ final static public String ATTR_FOR = "for";
+
+ final static public String ATTR_FRAME = "frame";
+
+ final static public String ATTR_GLOBEONLY = "globalOnly";
+
+ final static public String ATTR_HEADERCLASS = "headerClass";
+
+ final static public String ATTR_HREFLANG = "hreflang";
+
+ final static public String ATTR_ID = "id";
+
+ final static public String ATTR_IMAGE = "image";
+
+ final static public String ATTR_IMMEDIATE = "immediate";
+
+ final static public String ATTR_INFOCLASS = "infoClass";
+
+ final static public String ATTR_INFOSTYLE = "infoStyle";
+
+ final static public String ATTR_ITEMDESCRIPTION = "itemDescription";
+
+ final static public String ATTR_ITEMDISABLED = "itemDisabled";
+
+ final static public String ATTR_ITEMLABEL = "itemLabel";
+
+ final static public String ATTR_ITEMVALUE = "itemValue";
+
+ final static public String ATTR_LANG = "lang";
+
+ final static public String ATTR_LAYOUT = "layout";
+
+ final static public String ATTR_LOCALE = "locale";
+
+ final static public String ATTR_MAXIMUM = "maximum";
+
+ final static public String ATTR_MINIMUM = "minimum";
+
+ final static public String ATTR_NAME = "name";
+
+ final static public String ATTR_ONBLUR = "onblur";
+
+ final static public String ATTR_ONCHANGE = "onchange";
+
+ final static public String ATTR_ONCLICK = "onclick";
+
+ final static public String ATTR_ONDBLCLICK = "ondblclick";
+
+ final static public String ATTR_ONFOCUS = "onfocus";
+
+ final static public String ATTR_ONKEYDOWN = "onkeydown";
+
+ final static public String ATTR_ONKEYPRESS = "onkeypress";
+
+ final static public String ATTR_ONKEYUP = "onkeyup";
+
+ final static public String ATTR_ONMOUSEDOWN = "onmousedown";
+
+ final static public String ATTR_ONMOUSEMOVE = "onmousemove";
+
+ final static public String ATTR_ONMOUSEOUT = "onmouseout";
+
+ final static public String ATTR_ONMOUSEOVER = "onmouseover";
+
+ final static public String ATTR_ONMOUSEUP = "onmouseup";
+
+ final static public String ATTR_ONSELECT = "onselect";
+
+ final static public String ATTR_PATTERN = "pattern";
+
+ final static public String ATTR_READONLY = "readonly";
+
+ final static public String ATTR_REL = "rel";
+
+ final static public String ATTR_RENDERED = "rendered";
+
+ final static public String ATTR_REV = "rev";
+
+ final static public String ATTR_ROWCLASSES = "rowClasses";
+
+ final static public String ATTR_ROWS = "rows";
+
+ final static public String ATTR_RULES = "rules";
+
+ final static public String ATTR_SHAPE = "shape";
+
+ final static public String ATTR_SHOWDETAIL = "showDetail";
+
+ final static public String ATTR_SHOWSUMMARY = "showSummary";
+
+ final static public String ATTR_SIZE = "size";
+
+ final static public String ATTR_STYLE = "style";
+
+ final static public String ATTR_STYLECLASS = "styleClass";
+
+ final static public String ATTR_SUMMARY = "summary";
+
+ final static public String ATTR_TABINDEX = "tabindex";
+
+ final static public String ATTR_TARGET = "target";
+
+ final static public String ATTR_TIMESTYLE = "timeStyle";
+
+ final static public String ATTR_TITLE = "title";
+
+ final static public String ATTR_TOOLTIP = "tooltip";
+
+ final static public String ATTR_TYPE = "type";
+
+ final static public String ATTR_URL = "url";
+
+ final static public String ATTR_VALIDATORID = "validatorId";
+
+ final static public String ATTR_VALUE = "value";
+
+ final static public String ATTR_VAR = "var";
+
+ final static public String ATTR_WARNCLASS = "warnClass";
+
+ final static public String ATTR_WARNSTYLE = "warnStyle";
+
+ final static public String ATTR_WIDTH = "width";
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/JMTResources.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/JMTResources.properties
new file mode 100644
index 000000000..cb5fede34
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/JMTResources.properties
@@ -0,0 +1,219 @@
+####################################################
+# Resource message for Logging
+####################################################
+Log.Error.PageDesignerResources.Open=Error occurred getting the source bundle.
+Log.Error.MessageFormater.Format0=Error in message format.
+Log.Error.ExtensionReader.ReadLinkExtension=can't create linkCreator instance
+Log.Error.PreviewResources.ResouceNotFound=resource {0} not found
+
+Error.StringBufferWriter.Write.0=Error in string buffer writing.
+Error.RangeModeCommand.SetSelection=Selection error
+Error.SourceViewerCommand.Execution=Error in command execution
+Error.PDPlugin.Installation.0=Error starting plug-in.
+Error.PDPlugin.Installation.1=Problems starting plug-in Web Application Development.
+Error.PDPlugin.Installation.6=Problems starting plug-in Web Application Development.
+Error.DesignerPropertyTool.NatureQuerying=Error in project Java nature querying.
+Error.PDPlugin.Installation.10=log.PDPlugin.image.error
+Error.PDPlugin.Installation.13=log.PDPlugin.image.error
+Error.PDPlugin.Installation.15=error in installtion query.
+Error.ProjectResolver.GetlocationByURI.0=Error in taglib locating.
+Error.ProjectFileDialogContentProvider.0=Core error, you may need to restart the application.
+Error.EditValidateUtil.Position = Error in position validation.
+Error.EditValidateUtil.Text = Error occurred in text validation.
+Error.EditValidateUtil.Node = Error occurred in node validation.
+Error.EditValidateUtil.Range = Error occurred in range validation.
+Error.EditValidateUtil.StringIndex = Invalid string.
+Error.EditValidateUtil.IndexOffset = Invalid index or offset of string.
+CSSColorConverter.0=Error in color expression:
+CSSColorConverter.1=Error in color expression:
+Error.CSSFigure.0=Error in flowContext setting.
+Error.CSSUtil.0=Could not cast to CSS style
+Error.CSSUtil.1=Could not cast to CSS style
+Error.CSSUtil.2=Could not cast to CSS style
+Error.CSSUtil.3=Could not cast to CSS style
+Error.HTMLEditor.0=
+Error.HTMLEditor.1=Error occurred getting storage contents
+Error.HTMLEditor.2=Error occurred closing content.
+Error.HTMLEditor.3=The core has exception
+Error.HTMLEditor.4=Error occurred closing stream.
+Error.HTMLEditor.5=Error occurred initializing the editor.
+Error.HTMLEditor.6=Error occurred changing the page.
+Error.FontSizeMeta.0=Error occurred in tag font attribute calculating.
+Error.EditModelQuery.0=Error in position creation:
+Error.EditModelQuery.1=Error occurred getting node at indexed position
+Error.CommonResourceDialog.0.1=Error in project memeber querying
+Error.CommonResourceDialog.0.2=Please refer to error log for details
+Error.ImgFileFilter.1=CoreException is thrown, please refer to error log for details
+Error.ImgFileFilter.3=CoreException is thrown, please refer to error log for details
+Error.ImgFileFilter.0=Error in filtering the tree
+Error.ImgFileFilter.2=Error in getting project Nature
+Info.FontWeightMeta.0=Error occurred in integer processing.
+Warn.PolicyHelper.0=cannot get status line manager
+Warn.PolicyHelper.1=viewer is not HTML viewer
+Debug.EntityMap.0=Error occurred in integer formatting
+Debug.HTMLEditor.0=Editor is disposed
+HTMLSpecialCharHelper.3=Exception thrown
+HTMLSpecialCharHelper.2=Truncated & without ;
+HTMLSpecialCharHelper.1=Not an entity and not a &\#XXXX;
+HTMLSpecialCharHelper.0=Error in number expression
+
+####################################################
+# Resource message for RenderingTraverser
+####################################################
+RenderingTraverser.Error.FileNotFound = File Not Found
+RenderingTraverser.Error.UnsupportedEncoding = Unsupport Encoding
+RenderingTraverser.Error.IO = IO exception
+
+PaletteItemManager.error=error in constructor
+PaletteItemManager.initForPluginExtension.error.IOException=IOExcetpion in initForPluginExtension error
+PaletteItemManager.initForPluginExtension.error.MalformedURLException=MalformedURLException in initForPluginExtension
+PaletteItemManager.initForPluginExtension.error.InstantiationException=InstantiationException in initForPluginExtension
+PaletteItemManager.save.error.IOException=IOException when save
+ParagraphSupport.CommandLabel.Preformated=Preformated
+PaletteItemManager.loadPaletteItemState.error.IOException=IOException in loadPaletteItemState
+PaletteItemManager.loadPaletteItemState.error.SAXException=SAXException in loadPaletteItemState
+PaletteItemManager.loadPaletteItemState.error.getDocumentBuilderFail=getDocumentBuilder Failed
+
+PreviewUtil.previewFile.CoreException= CoreException previewing file
+PreviewUtil.previewFile.IOException= IOException previewing file
+
+#context menu
+ActionGroup.Submenu.TextStyle=Text Style
+ActionGroup.Submenu.Align=Align
+ActionGroup.Submenu.ParagraphFormat=Paragraph Format
+ActionGroup.Submenu.StyleClasses=Style Classes
+ActionGroup.Submenu.BorderStyle=Border Style
+ActionGroup.Submenu.Color=Color
+ActionGroup.Submenu.BackgroundColor=Background Color
+ActionGroup.Submenu.Link=Make Link...
+
+TableActionGroup.Submenu.SelectTable=Select Table
+TableActionGroup.Submenu.InsertRowBefore=Insert Row Before
+TableActionGroup.Submenu.InsertRowAfter=Insert Row After
+TableActionGroup.Submenu.InsertColumnBefore=Insert Column Before
+TableActionGroup.Submenu.InsertColumnAfter=Insert Column After
+TableActionGroup.Submenu.DeleteRow=Delete Row
+TableActionGroup.Submenu.DeleteColumn=Delete Column
+ElementEdit.Submenu.Table=Table
+ElementEdit.Submenu.SelectTable=Select Table
+ElementEdit.Submenu.InsertRowBefore=Insert Row Before
+ElementEdit.Submenu.InsertRowAfter=Insert Row After
+ElementEdit.Submenu.InsertColumnBefore=Insert Column Before
+ElementEdit.Submenu.InsertColumnAfter=Insert Column After
+ElementEdit.Submenu.DeleteRow=Delete Row
+ElementEdit.Submenu.DeleteColumn=Delete Column
+ElementEdit.Submenu.InsertHeader=Insert Header
+ElementEdit.Submenu.InsertFooter=Insert Footer
+ElementEdit.Submenu.DeleteHeader=Delete Header
+ElementEdit.Submenu.DeleteFooter=Delete Footer
+ElementEdit.Submenu.Taglib=Open Definition File
+TableInsertHeaderFooterCommand.ColumnHeader=Column Header
+TableInsertHeaderFooterCommand.ColumnFooter=Column Footer
+
+Action.Name.Copy=Copy
+Action.Name.Cut=Cut
+Action.Name.Paste=Paste
+
+Message.Warning.Title=Warning
+Taglib.OpenFile.ERROR=The file that the URI refers to does not exist.
+
+MakeLinkAction.Wizard.PageTitle=Please select link type
+CreateLinkWizard.Title=Select Link Type
+LinkWizardPage.GroupTitle=Link Types
+LinkWizardPage.PreviewLabel=Preview
+
+ItemCreationEditPolicy.CommandLabel.CreateItem=Create Item
+MakeLinkCommand.Label.MakeLink=Make Link
+AttributePropertySource.CommandLabel.ChangeAttribute=Change Attribute
+ChangeAttributeAction.CommandLabel.ChangeStyleClass=Change Style Class
+BorderStyleSupport.CommandLabel.Hidden=Hidden
+BorderStyleSupport.CommandLabel.Dotted=Dotted
+BorderStyleSupport.CommandLabel.Dashed=Dashed
+BorderStyleSupport.CommandLabel.Solid=Solid
+BorderStyleSupport.CommandLabel.Double=Double
+BorderStyleSupport.CommandLabel.Groove=Groove
+BorderStyleSupport.CommandLabel.Ridge=Ridge
+BorderStyleSupport.CommandLabel.Inset=Inset
+BorderStyleSupport.CommandLabel.Outset=Outset
+ColorSupport.CommandLabel.Aqua=Aqua
+ColorSupport.CommandLabel.Black=Black
+ColorSupport.CommandLabel.Blue=Blue
+ColorSupport.CommandLabel.Fuchsia=Fuchsia
+ColorSupport.CommandLabel.Gray=Gray
+ColorSupport.CommandLabel.Green=Green
+ColorSupport.CommandLabel.Lime=Lime
+ColorSupport.CommandLabel.Maroon=Maroon
+ColorSupport.CommandLabel.Navy=Navy
+ColorSupport.CommandLabel.Olive=Olive
+ColorSupport.CommandLabel.Orange=Orange
+ColorSupport.CommandLabel.Purple=Purple
+ColorSupport.CommandLabel.Red=Red
+ColorSupport.CommandLabel.Silver=Silver
+ColorSupport.CommandLabel.Teal=Teal
+ColorSupport.CommandLabel.White=White
+ColorSupport.CommandLabel.Yellow=Yellow
+ColorSupport.CommandLabel.Default=Default
+ParagraphSupport.CommandLabel.None=None
+ParagraphSupport.CommandLabel.Paragraph=Paragraph
+ParagraphSupport.CommandLabel.Heading1=Heading 1
+ParagraphSupport.CommandLabel.Heading2=Heading 2
+ParagraphSupport.CommandLabel.Heading3=Heading 3
+ParagraphSupport.CommandLabel.Heading4=Heading 4
+ParagraphSupport.CommandLabel.Heading5=Heading 5
+ParagraphSupport.CommandLabel.Heading6=Heading 6
+ParagraphSupport.CommandLabel.P=P
+ParagraphSupport.CommandLabel.H1=H1
+ParagraphSupport.CommandLabel.H2=H2
+ParagraphSupport.CommandLabel.H3=H3
+ParagraphSupport.CommandLabel.H4=H4
+ParagraphSupport.CommandLabel.H5=H5
+ParagraphSupport.CommandLabel.H6=H6
+ParagraphSupport.CommandLabel.PRE=PRE
+HTagsInsertGroupAction.ActionLabel.Hx=Hx
+RangeStyleSupport.ActionLabel.Bold=Bold
+RangeStyleSupport.ActionLabel.Italic=Italic
+RangeStyleSupport.ActionLabel.Underline=Underline
+ShowAllAction.ActionLabel.ShowAll=Show All
+AlignSupport.ActionLabel.Left=Left
+AlignSupport.ActionLabel.Center=Center
+AlignSupport.ActionLabel.Right=Right
+AlignSupport.ActionLabel.Justify=Justify
+
+Info.ElementDescReader.ReadPropertyFile=The property file:{0} is not found
+Info.ElementDescReader.ReadPropertyFile.Key=The key:{0} is not found in file:{1}
+ChangeStyleAction.Text=Edit Style...
+
+Log.Error.HTMLStringTagConverter.Error=Error
+ConverterUtil.Description= Drag and drop Web page content here
+
+SimpleGraphicalEditor.help.id=org.eclipse.jst.pagedesigner.graphicalEditor
+DesignerTabbedPropertySheetPage.help.id=org.eclipse.jst.pagedesigner.QuickEditor
+MyPropertySheetPage.help.id=org.eclipse.jst.pagedesigner.Attributes
+StyleDialog.help.id=org.eclipse.jst.pagedesigner.styleDialog
+DesignerPaletteViewerProvider.help.id=org.eclipse.jst.pagedesigner.palette_help
+
+StyleClassSupport.Default=Default
+XMLUtil.Error.0=Error in create documentBuilder:
+XMLUtil.Error.2=Error in object persistance:
+PreviewUtil.Error.0=Error occurred processing the resource bundle:
+PreviewUtil.Error.3=Error occurred opening the file:
+PreviewHandlerNew.Error.0=Error in model release:
+PreviewConvertContext.Error.0=Error:
+CellEditorFactoryRegistry.Info.2=Error in fields retrieving:
+CellEditorFactoryRegistry.Info.3=Error in fields retrieving:
+PageExpressionContext.Info.0=Error:
+TextLayoutSupport.Info.1=Error in text painting:
+
+CMRegistry.ReadConfigration=Reading Properties Configurations
+CMRegistry.HTMLConfigration=Reading HTML Configuration ...
+CMRegistry.JSPConfigration=Reading JSP Configuration ...
+CMRegistry.OtherConfigration=Reading Other Configuration ...
+
+HTMLEditor.Design=Design
+HTMLEditor.Source=Source
+
+LocalSelectionDropTargetListener.MessageDialog.Title=Info
+LocalSelectionDropTargetListener.MessageDialog.Message=The page is deleted, save it first.
+
+LoadBundleTagConverter.convertRefresh.MalformedURLException= MalformedURLException in LoadBundleTagConverter
+LoadBundleTagConverter.convertRefresh.IOException= IOException in LoadBundleTagConverter
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PDPlugin.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PDPlugin.java
new file mode 100644
index 000000000..80af43832
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PDPlugin.java
@@ -0,0 +1,438 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.internal.runtime.InternalPlatform;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jst.pagedesigner.common.guiutils.Alerts;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class PDPlugin extends AbstractUIPlugin {
+ private static final String ICONS_LIB_PATH = "icons";
+
+ private static final boolean ROOT_PLUGIN = false;
+
+ // The shared instance.
+ private static PDPlugin _plugin;
+
+ private static Logger _log;
+
+ private static Alerts _alerts;
+
+ private ResourceBundle _resourceBundle;
+
+ private Properties _properties;
+
+ private URL _pluginBase;
+
+ /**
+ * The constructor.
+ */
+ public PDPlugin() {
+ super();
+ _plugin = this;
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+
+ try {
+ // get resource bundle.
+ _resourceBundle = ResourceBundle
+ .getBundle(IJMTConstants.ROOT_RESOURCEBUNDLE);
+ _alerts = new Alerts(this, _resourceBundle);
+
+ // get properties.
+ _properties = new Properties();
+ InputStream input = null;
+ _pluginBase = getBundle().getEntry("/");
+ try {
+ input = (new URL(_pluginBase, IJMTConstants.DEFAULT_PROPERTIES))
+ .openStream();
+ _properties.load(input);
+ } finally {
+ try {
+ input.close();
+ } catch (IOException ee)// NOPMD
+ {
+ // nothing to do when IOException throwed in closing files.
+ }
+ }
+
+ // set up logging for this plugin and everthing under it.
+ _log = new Logger(this.getBundle(), _resourceBundle);
+
+ // NOTE: add in any other plugin code statup HERE!!!!
+
+ // log.CommonPlugin=Web Application Development Common Plugin
+ // initialized on eclipse version {0}.
+
+ // log.info("log.CommonPlugin", version);
+
+ } catch (Exception ee) {
+ // only log if the logger was configured correctly.
+ if (_log != null) {
+ _log
+ .error(
+ "log.msg",
+ "Problems starting plug-in Web Application Development Common.",
+ ee);
+ }
+
+ throw new CoreException(
+ new Status(
+ IStatus.ERROR,
+ getBundle().getSymbolicName(),
+ IStatus.OK,
+ "Problems starting plug-in Web Application Development Common",
+ ee));
+ }
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static PDPlugin getDefault() {
+ return _plugin;
+ }
+
+ /**
+ * get the alerts objects associated with this plugin for alerting the user.
+ *
+ * @return
+ */
+ public static Alerts getAlerts() {
+ return _alerts;
+ }
+
+ /**
+ * Returns a logger for the new class using this plugin for reference.
+ */
+ public static Logger getLogger(Class theClass) {
+ if (getDefault() != null && getDefault().getRootLogger() != null) {
+ return getDefault().getRootLogger();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the plugin's root logger
+ */
+ public Logger getRootLogger() {
+ return _log;
+ }
+
+ /**
+ * Returns this plugin's unique identifier
+ *
+ * @retun this plugin's unique identifier
+ */
+ public static String getPluginId() {
+ return getDefault().getBundle().getSymbolicName();
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return _resourceBundle;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle, or 'key' if not
+ * found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = PDPlugin.getDefault().getResourceBundle();
+ try {
+ return (bundle != null) ? bundle.getString(key) : key;
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Returns the plugin's descriptor's resource bundle,
+ */
+ public ResourceBundle getPluginDecriptorBundle() {
+ return Platform.getResourceBundle(getDefault().getBundle());
+ }
+
+ /**
+ * Returns the plugin's default properties. These are normally used for
+ * default preferences.
+ */
+ public Properties getProperties() {
+ return _properties;
+ }
+
+ /**
+ * Returns the standard display to be used. The method first checks, if the
+ * thread calling this method has an associated dispaly. If so, this display
+ * is returned. Otherwise the method returns the default display.
+ */
+ public static Display getStandardDisplay() {
+ Display display;
+ display = Display.getCurrent();
+ if (display == null) {
+ display = Display.getDefault();
+ }
+ return display;
+ }
+
+ /**
+ * Returns the workspace instance.
+ */
+ public static IWorkspace getWorkspace() {
+ return ResourcesPlugin.getWorkspace();
+ }
+
+ /**
+ * Returns a shared image for the given name
+ * <p>
+ * Note: Images returned from this method will be automitically disposed of
+ * when this plug-in shuts down. Callers must not dispose of these images
+ * themselves.
+ * </p>
+ *
+ * @param name
+ * the image name found in /icons (with extension)
+ * @return the image, null on error or not found.
+ */
+ public Image getImage(String name) {
+ if (name == null) {
+ return null;
+ }
+
+ ImageRegistry images = getImageRegistry();
+ Image image = (Image) images.get(name);
+ if (image == null) {
+ try {
+ ImageDescriptor id = ImageDescriptor.createFromURL(new URL(
+ _pluginBase, ICONS_LIB_PATH + "/" + name));
+ images.put(name, id);
+
+ image = images.get(name);
+ } catch (MalformedURLException ee) {
+ // log.PDPlugin.image.error=Image {0} not found.
+ _log.error("Error.PDPlugin.Installation.10", name, ee); //$NON-NLS-2$
+ }
+ }
+ return image;
+ }
+
+ /**
+ * Returns a shared ImageDescriptor for the given name
+ * <p>
+ * Note: ImageDescriptor returned from this method will be automitically
+ * disposed of when this plug-in shuts down. Callers must not dispose of
+ * these ImageDescriptor themselves.
+ * </p>
+ *
+ * @param name
+ * the ImageDescriptor name found in /icons (with extension)
+ * @return the ImageDescriptor, null on error or not found.
+ */
+ public ImageDescriptor getImageDescriptor(String name) {
+ if (name == null) {
+ return null;
+ }
+
+ ImageRegistry images = getImageRegistry();
+ ImageDescriptor id = (ImageDescriptor) images.getDescriptor(name);
+ if (id == null) {
+ try {
+ id = ImageDescriptor.createFromURL(new URL(_pluginBase,
+ ICONS_LIB_PATH + "/" + name));
+ images.put(name, id);
+ } catch (MalformedURLException ee) {
+ // log.PDPlugin.image.error=Image {0} not found.
+ _log.error("Error.PDPlugin.Installation.13", name, ee); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return id;
+ }
+
+ /**
+ * Read a file resource. The file should contain any partial path and the
+ * filename from the plugin base. The caller is responsible for closing the
+ * file.
+ */
+ public InputStream readFile(String file) throws MalformedURLException,
+ IOException {
+ return (new URL(_pluginBase, file)).openStream();
+ }
+
+ public File getFile(String file) throws MalformedURLException, IOException {
+ return new File((new URL(_pluginBase, file)).getPath());
+ }
+
+ public static Path getInstallLocation() {
+ try {
+ URL url = getDefault().getBundle().getEntry("/");
+ String s1 = Platform.resolve(url).getFile();
+ if (s1.startsWith("/")) //$NON-NLS-1$
+ {
+ s1 = s1.substring(1);
+ }
+ s1 = (new Path(s1)).toOSString();
+ String s;
+ if (s1.endsWith(File.separator)) {
+ s = s1;
+ } else {
+ s = s1 + File.separator;
+ }
+ return new Path(s);
+ } catch (Exception exception) {
+ _log.error("Error.PDPlugin.Installation.15", exception); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ public static String getEclipseDir() {
+ URL installedIn = InternalPlatform.getDefault().getInstallURL();
+ String url = installedIn.getPath();
+ return url;
+ }
+
+ public static IModelManager getModelManager() {
+ return StructuredModelManager.getModelManager();
+ }
+
+ /**
+ * Returns the active workbench window.
+ *
+ * @return the active workbench window. this can be null but I've never seen
+ * it.
+ */
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ if (getDefault().getWorkbench() == null) {
+ return null;
+ } else {
+ return getDefault().getWorkbench().getActiveWorkbenchWindow();
+ }
+ }
+
+ /**
+ * Returns the active workbench page. Note that the active page may not be
+ * the one that the user perceives as active in some situations so this
+ * method of obtaining the activate page should only be used if no other
+ * method is available.
+ *
+ * @return the active workbench page
+ */
+ public static IWorkbenchPage getActivePage() {
+ IWorkbenchWindow window = getActiveWorkbenchWindow();
+ if (window == null) {
+ return null;
+ }
+ return window.getActivePage();
+ }
+
+ /**
+ * Initializes the preference controls to the default values. These values
+ * are used the first time the preference page is displayed or when the user
+ * presses the Defaults button in the preferences page.
+ */
+ protected void initializeDefaultPreferences(IPreferenceStore store) {
+ // initialize any preferences for this plugin.
+ }
+
+ /**
+ * Returns the active workbench Shell. Used for some funciton need IShell
+ * Parameter.
+ *
+ * @return
+ */
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow window = getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getShell();
+ }
+ IWorkbenchWindow[] windows = getDefault().getWorkbench()
+ .getWorkbenchWindows();
+ if (windows.length > 0) {
+ return windows[0].getShell();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the active display.
+ *
+ * @return
+ */
+ public static Display getDisplay() {
+ Shell shell = getActiveWorkbenchShell();
+ if (shell != null) {
+ return shell.getDisplay();
+ } else {
+ return Display.getDefault();
+ }
+ }
+
+ /**
+ * Returns current active project.
+ *
+ * @return
+ */
+ public static IProject getCurrentProject() {
+ IProject curProject = null;
+ IEditorPart editor = PDPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ IEditorInput input = editor.getEditorInput();
+ IFile inputFile = null;
+ if (input != null && input instanceof IFileEditorInput) {
+ inputFile = ((IFileEditorInput) input).getFile();
+ curProject = inputFile.getProject();
+ }
+ return curProject;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/container/ContainerActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/container/ContainerActionGroup.java
new file mode 100644
index 000000000..24b84e40e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/container/ContainerActionGroup.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.container;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.ui.actions.ActionGroup;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ContainerActionGroup extends ActionGroup {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ ISelection selection = this.getContext().getSelection();
+
+ EditPart part = findCommonAncesterPart(selection);
+ if (!(part instanceof NodeEditPart)) {
+ return;
+ }
+
+ NodeEditPart original = (NodeEditPart) part;
+ // start from the parent of part
+ while (part.getParent() instanceof ElementEditPart) {
+ ElementEditPart elementEditPart = (ElementEditPart) part
+ .getParent();
+
+ IElementEdit elementEdit = elementEditPart.getElementEdit();
+ if (elementEdit != null) {
+ boolean filled = elementEdit.fillContainerContextMenu(menu,
+ elementEditPart, original, selection);
+ if (filled) {
+ break;
+ }
+ }
+
+ part = part.getParent();
+ }
+ }
+
+ /**
+ * Give a selection, find a single common container node as start for table
+ * related operations.
+ *
+ * @param selection
+ * @return
+ */
+ private EditPart findCommonAncesterPart(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structsel = (IStructuredSelection) selection;
+ if (structsel.size() != 1) {
+ return null;
+ } else if (structsel.getFirstElement() instanceof EditPart) {
+ return (EditPart) structsel.getFirstElement();
+ } else {
+ return null;
+ }
+ } else if (selection instanceof DesignRange) {
+ DesignRange range = (DesignRange) selection;
+ if (!range.isValid()) {
+ return null;
+ }
+ if (range.isEmpty()) {
+ DesignPosition position = range.getStartPosition();
+ if (position.getOffset() == 0
+ || position.getContainerNode() instanceof Text) {
+ return position.getContainerPart();
+ } else {
+ return position.getSiblingEditPart(false);
+ }
+ } else {
+ return RangeUtil.findCommonAncestor(range);
+ }
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/AbstractLinkCreator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/AbstractLinkCreator.java
new file mode 100644
index 000000000..c2f6e25d7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/AbstractLinkCreator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class AbstractLinkCreator implements ILinkCreator,
+ IExecutableExtension {
+ private String _identifier;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.actions.link.ILinkCreator#canExcute(org.eclipse.jst.pagedesigner.viewer.DesignRange)
+ */
+ public boolean canExecute(DesignRange range) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.actions.link.ILinkCreator#getLinkIdentifier()
+ */
+ public String getLinkIdentifier() {
+ return this._identifier;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
+ * java.lang.String, java.lang.Object)
+ */
+ public void setInitializationData(IConfigurationElement config,
+ String propertyName, Object data) throws CoreException {
+ this._identifier = config.getAttribute(ILinkCreator.LINK_IDENTIFIER);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/CreateLinkWizard.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/CreateLinkWizard.java
new file mode 100644
index 000000000..e36848abe
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/CreateLinkWizard.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import java.util.Map;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CreateLinkWizard extends Wizard {
+ private static final String WIZARD_TITLE = PDPlugin
+ .getResourceString("CreateLinkWizard.Title");
+
+ private static final String INTIAL_DEFAULT_PAGE_IMAGE = "newsuade_wiz.gif";
+
+ private static final String PAGE_NAME = "first";
+
+ private String _pageTitle;
+
+ private EditPart _part;
+
+ private DesignRange _range;
+
+ private Map _linkMap;
+
+ private String _linkType;
+
+ public CreateLinkWizard(EditPart part, DesignRange range, Map linkMap) {
+ this._part = part;
+ this._range = range;
+ this._linkMap = linkMap;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.IWizard#addPages()
+ */
+ public void addPages() {
+ addPage(new LinkWizardPage(PAGE_NAME, _pageTitle, this._part,
+ this._range, this._linkMap));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.IWizard#canFinish()
+ */
+ public boolean canFinish() {
+ return super.canFinish();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.IWizard#performFinish()
+ */
+ public boolean performFinish() {
+ LinkWizardPage page = (LinkWizardPage) getPage(PAGE_NAME);
+ this._linkType = page.getChosenLinkType();
+ return true;
+ }
+
+ public void setPageTitle(String pageTitle) {
+ _pageTitle = pageTitle;
+ initializeDefaultPageImageDescriptor();
+ }
+
+ protected void initializeDefaultPageImageDescriptor() {
+ ImageDescriptor desc = PDPlugin.getDefault().getImageDescriptor(
+ INTIAL_DEFAULT_PAGE_IMAGE);
+ setDefaultPageImageDescriptor(desc);
+ setWindowTitle(WIZARD_TITLE);
+ }
+
+ public String getChosenLinkType() {
+ return this._linkType;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ExtensionReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ExtensionReader.java
new file mode 100644
index 000000000..769e2c18c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ExtensionReader.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ExtensionReader {
+ private static Logger _log = PDPlugin.getLogger(ExtensionReader.class);
+
+ private static ILinkCreator[] _handlers = null;
+
+ private static final String ATTR_CLASS = "class";
+
+ public static synchronized ILinkCreator[] getAllLinkHandlers() {
+ if (_handlers == null) {
+ _handlers = readAllLinkHandlers();
+ }
+ return _handlers;
+
+ }
+
+ private static ILinkCreator[] readAllLinkHandlers() {
+ List result = new ArrayList();
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+ IExtension[] extensions = extensionPoint.getExtensions();
+
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension ext = extensions[i];
+ IConfigurationElement[] linkHandlers = ext
+ .getConfigurationElements();
+
+ for (int j = 0; j < linkHandlers.length; j++) {
+ if (linkHandlers[j].getName()
+ .equals(IJMTConstants.LINK_CREATOR)) {
+ linkHandlers[j].getAttribute(ATTR_CLASS);
+ Object obj;
+ try {
+ obj = linkHandlers[j]
+ .createExecutableExtension(ATTR_CLASS);
+
+ if (obj instanceof ILinkCreator) {
+ result.add(obj);
+ }
+ } catch (CoreException e) {
+ _log
+ .error("Log.Error.ExtensionReader.ReadLinkExtension");
+ }
+ }
+ }
+ }
+ ILinkCreator[] ret = new ILinkCreator[result.size()];
+ result.toArray(ret);
+ return ret;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/HtmlLinkCreator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/HtmlLinkCreator.java
new file mode 100644
index 000000000..8e3c6f9a5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/HtmlLinkCreator.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class HtmlLinkCreator extends AbstractLinkCreator {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.actions.link.ILinkCreator#makeLinkElement(org.eclipse.gef.EditPart,
+ * org.eclipse.jst.pagedesigner.viewer.DesignRange)
+ */
+ public Element makeLinkElement(EditPart part, DesignRange range) {
+ if (part instanceof TextEditPart) {
+ Text middleNode = LinkUtil.splitDomText(part, range);
+ EditPart parent = part.getParent();
+ Node parentNode = (Node) parent.getModel();
+ Document doc = (parentNode instanceof Document) ? (Document) parentNode
+ : (parentNode.getOwnerDocument());
+
+ Element htmlLink = doc.createElement(IHTMLConstants.TAG_A);
+ htmlLink.setAttribute(ICSSPropertyID.ATTR_HREF, "");
+ Text text = doc.createTextNode(middleNode.getNodeValue());
+ htmlLink.appendChild(text);
+ parentNode.replaceChild(htmlLink, middleNode);
+ return htmlLink;
+ }
+
+ return null;
+ }
+
+ public String getSourcePreview(EditPart part, DesignRange range) {
+ if (part instanceof TextEditPart) {
+ TextEditPart textPart = (TextEditPart) part;
+ int[] offsets = textPart.getSelectedRange();
+ String displayData = textPart.getTextData();
+
+ String linkExp = displayData.substring(offsets[0], offsets[1]);
+ StringBuffer sb = new StringBuffer();
+ sb.append("<a href=\"\">");
+ sb.append(linkExp);
+ sb.append("</a>");
+ return sb.toString();
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ILinkCreator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ILinkCreator.java
new file mode 100644
index 000000000..83b332b72
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/ILinkCreator.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ILinkCreator {
+ public static final String LINK_IDENTIFIER = "linkIdentifier";
+
+ public Element makeLinkElement(EditPart part, DesignRange range);
+
+ public String getLinkIdentifier();
+
+ public boolean canExecute(DesignRange range);
+
+ public String getSourcePreview(EditPart part, DesignRange range);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkRequest.java
new file mode 100644
index 000000000..4f1152e98
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkRequest.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import org.eclipse.gef.Request;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class LinkRequest extends Request {
+ private String _identifier = "";
+
+ private DesignRange _range = null;
+
+ public LinkRequest(String identifier, DesignRange range) {
+ this._identifier = identifier;
+ this._range = range;
+ }
+
+ public String getIdentifier() {
+ return this._identifier;
+ }
+
+ public DesignRange getDesignRange() {
+ return this._range;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkUtil.java
new file mode 100644
index 000000000..271b8c108
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkUtil.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRangeHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class LinkUtil {
+ public static String getSelectedText(EditPart part, DesignRange range) {
+ if (part instanceof TextEditPart) {
+ TextEditPart textPart = (TextEditPart) part;
+ int[] offsets = textPart.getSelectedRange();
+ String displayData = textPart.getTextData();
+
+ String linkExp = displayData.substring(offsets[0], offsets[1]);
+ return linkExp;
+ }
+ return null;
+ }
+
+ public static Text splitDomText(EditPart part, DesignRange range) {
+ if (part instanceof TextEditPart) {
+ Text textNode = (Text) part.getModel();
+
+ DOMRange domRange = DOMRangeHelper.toDOMRange(range);
+ IDOMPosition start = domRange.getStartPosition();
+ IDOMPosition end = domRange.getEndPosition();
+ int domTempStartOffset = computeOffset(start, textNode);
+ int domTempEndOffset = computeOffset(end, textNode);
+
+ int domStartOffset = Math.min(domTempStartOffset, domTempEndOffset);
+ int domEndOffset = Math.max(domTempStartOffset, domTempEndOffset);
+
+ Text lastNode = textNode;
+ if (domStartOffset > 0) {
+ lastNode = textNode.splitText(domStartOffset);
+ }
+ lastNode = lastNode.splitText(domEndOffset - domStartOffset);
+ Text middleNode = (Text) lastNode.getPreviousSibling();
+ return middleNode;
+ }
+ return null;
+ }
+
+ private static int computeOffset(IDOMPosition pos, Text textNode) {
+ int domOffset = 0;
+ if (pos instanceof DOMRefPosition) {
+ DOMRefPosition rep = (DOMRefPosition) pos;
+ boolean forward = rep.isForward();
+ Node refNode = rep.getReferenceNode();
+
+ if ((refNode != textNode) && forward || (refNode == textNode)
+ && !forward) {
+ domOffset = 0;
+ } else {
+ domOffset = textNode.getLength();
+ }
+ } else {
+ domOffset = pos.getOffset();
+ }
+ return domOffset;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkWizardPage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkWizardPage.java
new file mode 100644
index 000000000..f64d5e48f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/LinkWizardPage.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class LinkWizardPage extends WizardPage {
+ private static final String GROUP_TITLE = PDPlugin
+ .getResourceString("LinkWizardPage.GroupTitle");
+
+ private static final String PREVIEW_TAG_LABEL = PDPlugin
+ .getResourceString("LinkWizardPage.PreviewLabel");
+
+ private StyledText _text = null;
+
+ private Map _linkMap = null;
+
+ private String _linkType = null;
+
+ private EditPart _part = null;
+
+ private DesignRange _range = null;
+
+ public LinkWizardPage(String pageName, String title, EditPart editPart,
+ DesignRange range, Map linkMap) {
+ super(pageName, title, null);
+ this._part = editPart;
+ this._range = range;
+ this._linkMap = linkMap;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ layout = new GridLayout();
+ layout.marginWidth = 20;
+ parent.setLayout(layout);
+ data = new GridData(GridData.FILL_BOTH | GridData.CENTER);
+ parent.setLayoutData(data);
+
+ Group group = new Group(parent, SWT.NONE);
+ group.setText(GROUP_TITLE);
+ layout = new GridLayout();
+ group.setLayout(layout);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ group.setLayoutData(data);
+
+ String defaultLink = "";
+ Set set = this._linkMap.keySet();
+ int size = set.size();
+ String[] keys = new String[size];
+ Iterator itr = set.iterator();
+ int i = 0;
+ while (itr.hasNext()) {
+ String key = (String) itr.next();
+ keys[i++] = key;
+ }
+ Arrays.sort(keys);
+ for (int j = 0; j < size; j++) {
+ Button bt = new Button(group, SWT.RADIO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ bt.setLayoutData(data);
+ bt.setText(keys[j]);
+ if (j == 0) {
+ bt.setSelection(true);
+ defaultLink = keys[j];
+ }
+ bt.addSelectionListener(new SelectLinkListener(keys[j]));
+ }
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(PREVIEW_TAG_LABEL);
+
+ _text = new StyledText(parent, SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
+ data = new GridData(GridData.FILL_BOTH);
+ data.heightHint = 50;
+ _text.setLayoutData(data);
+
+ ILinkCreator creator = (ILinkCreator) _linkMap.get(defaultLink);
+ _linkType = creator.getLinkIdentifier();
+ String previewText = creator.getSourcePreview(_part, _range);
+ previewText = previewText == null ? "" : previewText;
+ _text.setText(previewText);
+ _text.setEditable(false);
+
+ super.setControl(group);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.IWizardPage#isPageComplete()
+ */
+ public boolean isPageComplete() {
+ return true;
+ }
+
+ public String getChosenLinkType() {
+ return this._linkType;
+ }
+
+ class SelectLinkListener extends SelectionAdapter {
+ private String _key;
+
+ public SelectLinkListener(String key) {
+ this._key = key;
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ ILinkCreator creator = (ILinkCreator) _linkMap.get(this._key);
+ _linkType = creator.getLinkIdentifier();
+ String previewText = creator.getSourcePreview(_part, _range);
+ previewText = previewText == null ? "" : previewText;
+ _text.setText(previewText);
+ super.widgetSelected(e);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkAction.java
new file mode 100644
index 000000000..0b51084e0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkAction.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.dialogs.CommonWizardDialog;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class MakeLinkAction extends Action {
+ private final static String MAKE_LINK = PDPlugin
+ .getResourceString("ActionGroup.Submenu.Link");
+
+ private final static String WIZARD_PAGE_TITLE = PDPlugin
+ .getResourceString("MakeLinkAction.Wizard.PageTitle");
+
+ private EditPart _editPart;
+
+ private DesignRange _range;
+
+ private String _linkType;
+
+ /**
+ * @param text
+ */
+ public MakeLinkAction(DesignRange range) {
+ super(MAKE_LINK);
+ _range = range;
+ _editPart = convertToEditPart(_range);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ Map map = calAvailableLinkCreator();
+ if (map.size() > 1) {
+ CreateLinkWizard wizard = new CreateLinkWizard(_editPart, _range,
+ map);
+ wizard.setPageTitle(WIZARD_PAGE_TITLE);
+ CommonWizardDialog wizardDialog = new CommonWizardDialog(
+ getShell(), wizard);
+ wizardDialog.create();
+ if (wizardDialog.open() == Window.OK) {
+ _linkType = wizard.getChosenLinkType();
+ }
+ }
+ // else must be html link
+ else if (map.size() == 1) {
+ Set set = map.entrySet();
+ Iterator itr = set.iterator();
+ while (itr.hasNext()) {
+ ILinkCreator creator = (ILinkCreator) itr.next();
+ _linkType = creator.getLinkIdentifier();
+ }
+ }
+
+ if (_linkType != null) {
+ Request request = new LinkRequest(_linkType, _range);
+ Command cmd = _editPart.getCommand(request);
+ if (cmd != null && cmd.canExecute()) {
+ cmd.execute();
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#isEnabled()
+ */
+ public boolean isEnabled() {
+ if (_editPart == null) {
+ return false;
+ }
+ return super.isEnabled();
+ }
+
+ private EditPart convertToEditPart(DesignRange range) {
+ DesignPosition startPosition = range.getStartPosition();
+ EditPart startPart = startPosition.getContainerPart();
+
+ DesignPosition endPosition = range.getEndPosition();
+ EditPart endPart = endPosition.getContainerPart();
+
+ if (startPosition == endPosition) {
+ return null;
+ }
+
+ if (startPart instanceof TextEditPart
+ && endPart instanceof TextEditPart) {
+ if ((startPart == endPart)) {
+ return startPart;
+ }
+ } else if (!(startPart instanceof TextEditPart)
+ && !(endPart instanceof TextEditPart)) {
+ Node[] startNodeOptions = null;
+ startNodeOptions = getSideNodes(startPosition);
+ Node[] endNodeOptions = null;
+ endNodeOptions = getSideNodes(endPosition);
+ Node selectedNode = null;
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (startNodeOptions[i] == endNodeOptions[j]) {
+ selectedNode = startNodeOptions[i];
+ break;
+ }
+ }
+ if (selectedNode != null) {
+ break;
+ }
+ }
+ if (selectedNode != null) {
+ EditPart part = (EditPart) ((INodeNotifier) selectedNode)
+ .getAdapterFor(EditPart.class);
+ return part;
+ }
+ } else {
+ if (startPart instanceof TextEditPart) {
+ Node[] endNodeOptions = null;
+ endNodeOptions = getSideNodes(endPosition);
+ if (startPart.getModel() == endNodeOptions[0]
+ || startPart.getModel() == endNodeOptions[1]) {
+ return startPart;
+ }
+ }
+ if (endPart instanceof TextEditPart) {
+ Node[] startNodeOptions = null;
+ startNodeOptions = getSideNodes(startPosition);
+ if (endPart.getModel() == startNodeOptions[0]
+ || endPart.getModel() == startNodeOptions[1]) {
+ return endPart;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private Node[] getSideNodes(DesignPosition pos) {
+ Node[] nodes = new Node[2];
+
+ EditPart part = pos.getContainerPart();
+ Node node = (Node) part.getModel();
+ NodeList list = node.getChildNodes();
+
+ if (list.getLength() == pos.getOffset()) {
+ nodes[0] = list.item(pos.getOffset() - 1);
+ nodes[1] = list.item(pos.getOffset() - 1);
+ } else if (pos.getOffset() == 0) {
+ nodes[0] = list.item(0);
+ nodes[1] = list.item(0);
+ } else if (pos.getOffset() > 0 && pos.getOffset() < list.getLength()) {
+ nodes[0] = list.item(pos.getOffset() - 1);
+ nodes[1] = list.item(pos.getOffset());
+ }
+
+ return nodes;
+ }
+
+ private Shell getShell() {
+ if (_editPart != null) {
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) _editPart
+ .getViewer();
+ return viewer.getControl().getShell();
+ }
+ return null;
+ }
+
+ private Map calAvailableLinkCreator() {
+ Map map = new HashMap();
+ ILinkCreator[] linkCreators = ExtensionReader.getAllLinkHandlers();
+ for (int i = 0, size = linkCreators.length; i < size; i++) {
+ String identifier = linkCreators[i].getLinkIdentifier();
+ boolean canExecute = linkCreators[i].canExecute(_range);
+ if (canExecute) {
+ map.put(identifier, linkCreators[i]);
+ }
+ }
+ return map;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkCommand.java
new file mode 100644
index 000000000..9ccd1d17b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/link/MakeLinkCommand.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.link;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class MakeLinkCommand extends DesignerCommand {
+ private String _identifier = null;
+
+ private EditPart _part = null;
+
+ private DesignRange _range = null;
+
+ private ILinkCreator _linkcreator = null;
+
+ private Element _ele = null;
+
+ public MakeLinkCommand(String identifier, IHTMLGraphicalViewer viewer,
+ EditPart part, DesignRange range) {
+ super(identifier, viewer);
+ setLabel(PDPlugin.getResourceString("MakeLinkCommand.Label.MakeLink"));//$NON-NLS-1$
+ this._identifier = identifier;
+ this._part = part;
+ this._range = range;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ ILinkCreator[] creators = ExtensionReader.getAllLinkHandlers();
+ if (creators != null) {
+ for (int i = 0, size = creators.length; i < size; i++) {
+ ILinkCreator linkCreator = creators[i];
+ String identifier = linkCreator.getLinkIdentifier();
+ if (this._identifier.equalsIgnoreCase(identifier)) {
+ this._linkcreator = linkCreator;
+ break;
+ }
+ }
+ }
+ if (this._linkcreator != null) {
+ return this._linkcreator.canExecute(_range);
+ }
+
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ if (this._linkcreator != null) {
+ Element ele = this._linkcreator.makeLinkElement(this._part,
+ this._range);
+ Node node = (Node) this._part.getModel();
+ Node parent = node.getParentNode();
+ formatNode(parent);
+
+ this._ele = ele;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_ele);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/CustomedContextMenuActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/CustomedContextMenuActionGroup.java
new file mode 100644
index 000000000..b6721fc1b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/CustomedContextMenuActionGroup.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.menuextension;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.extensionpoint.IContextMenuItemContributor;
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CustomedContextMenuActionGroup extends ActionGroup {
+ private final static String POPUPMENU_EXTENSION_ID = "org.eclipse.jst.pagedesigner.popupMenuContributor"; //$NON-NLS-1$
+
+ private List _contributedMenuListener;
+
+ private Control _parentControl;
+
+ private IStructuredModel _model;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ populateContributedMenu(menu);
+ }
+
+ private List getListeners() {
+ if (_contributedMenuListener == null) {
+ _contributedMenuListener = computeContributedMenuListener();
+ }
+ return _contributedMenuListener;
+ }
+
+ private List computeContributedMenuListener() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extensionPoint = registry
+ .getExtensionPoint(POPUPMENU_EXTENSION_ID);
+ IExtension[] extensions = extensionPoint.getExtensions();
+ List results = new ArrayList();
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] elements = extensions[i]
+ .getConfigurationElements();
+ for (int j = 0; j < elements.length; j++) {
+ try {
+ Object listener = elements[j]
+ .createExecutableExtension("class");//$NON-NLS-1$
+
+ if (listener instanceof IContextMenuItemContributor) {
+ results.add(listener);
+ ((IContextMenuItemContributor) listener)
+ .setURI(elements[j].getAttribute("URI"));//$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ // ignore
+ }
+ }
+ }
+ return results;
+ }
+
+ private void populateContributedMenu(IMenuManager menuMgr) {
+ List list = getListeners();
+ for (int i = 0, n = list.size(); i < n; i++) {
+ IContextMenuItemContributor contributor = (IContextMenuItemContributor) list
+ .get(i);
+ IFile file = StructuredModelUtil.getFileFor(_model);
+ if (file != null && contributor.getURI() != null) {
+ if (JSPUtil.supportTaglib(contributor.getURI(), file)) {
+ contributor.fillContextMenu(menuMgr, getContext()
+ .getSelection(), _model, _parentControl);
+ }
+ }
+ }
+ }
+
+ /**
+ * @return Returns the model.
+ */
+ public IStructuredModel getModel() {
+ return _model;
+ }
+
+ /**
+ * @param model
+ * The model to set.
+ */
+ public void setModel(IStructuredModel model) {
+ this._model = model;
+ }
+
+ /**
+ * @return Returns the parentControl.
+ */
+ public Control getParentControl() {
+ return _parentControl;
+ }
+
+ /**
+ * @param parentControl
+ * The parentControl to set.
+ */
+ public void setParentControl(Control parentControl) {
+ this._parentControl = parentControl;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/RunAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/RunAction.java
new file mode 100644
index 000000000..b729e76cb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/menuextension/RunAction.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.menuextension;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RunAction extends Action {
+ public static final String LAUNCH_MODE_DEBUG = "debug";
+
+ public static final String LAUNCH_MODE_RUN = "run";
+
+ private final String ID = "org.eclipse.jst.pagedesigner.actions.menuextension.RunAction";
+
+ private EditorPart _editor;
+
+ private String _mode;
+
+ public RunAction(EditorPart editor, String mode) {
+ _editor = editor;
+ _mode = mode;
+ }
+
+ public void run() {
+
+ List allShortCuts = DebugUIPlugin.getDefault()
+ .getLaunchConfigurationManager().getLaunchShortcuts();
+ Iterator iter = allShortCuts.iterator();
+ LaunchShortcutExtension ext = null;
+ while (iter.hasNext()) {
+ ext = (LaunchShortcutExtension) iter.next();
+ try {
+ if (ext.getId().equals("org.eclipse.wst.server.launchShortcut")) {
+ break;
+ }
+ } catch (Exception e) {
+ // not supported
+ }
+ }
+ if (ext != null) {
+ ext.launch(getSelection(), _mode);
+ }
+ }
+
+ private IStructuredSelection getSelection() {
+ IEditorInput input = ((HTMLEditor) _editor).getEditorInput();
+ List elements = new ArrayList();
+ if (input instanceof FileEditorInput) {
+ elements.add(((FileEditorInput) input).getFile());
+ }
+ return new StructuredSelection(elements);
+ }
+
+ public String getId() {
+ return ID;
+ }
+
+ public String getText() {
+ return _mode.substring(0, 1).toUpperCase()
+ + _mode.substring(1, _mode.length());
+ }
+
+ private ImageDescriptor getImageDescriptorForModel(String id) {
+ IConfigurationElement[] elements = Platform.getExtensionRegistry()
+ .getConfigurationElementsFor("org.eclipse.ui.actionSets");
+ for (int i = 0; i < elements.length; i++) {
+ if ("actionSet".equals(elements[i].getName())) {
+ IConfigurationElement[] actions = elements[i]
+ .getChildren("action");
+ for (int j = 0; j < actions.length; j++) {
+ if (id.equals(actions[j].getAttribute("id"))) {
+ String iconPath = actions[j].getAttribute("icon");
+ if (iconPath != null) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(
+ actions[j].getDeclaringExtension()
+ .getNamespace(), iconPath);
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ if (_mode == LAUNCH_MODE_DEBUG) {
+ return getImageDescriptorForModel("org.eclipse.debug.internal.ui.actions.DebugDropDownAction");
+ } else if (_mode == LAUNCH_MODE_RUN) {
+ return getImageDescriptorForModel("org.eclipse.debug.internal.ui.actions.RunDropDownAction");
+ } else {
+ return super.getImageDescriptor();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/AlignSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/AlignSupport.java
new file mode 100644
index 000000000..e1ac246c8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/AlignSupport.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class AlignSupport {
+
+ public static final String[] ALIGN_VALUES = new String[] {
+ PDPlugin.getResourceString("AlignSupport.ActionLabel.Left"), //$NON-NLS-1$
+ PDPlugin.getResourceString("AlignSupport.ActionLabel.Center"), //$NON-NLS-1$
+ PDPlugin.getResourceString("AlignSupport.ActionLabel.Right"), //$NON-NLS-1$
+ PDPlugin.getResourceString("AlignSupport.ActionLabel.Justify") //$NON-NLS-1$
+ };
+
+ private static Element[] _nodes = null;
+
+ public static void createAlignActions(IMenuManager menu,
+ IHTMLGraphicalViewer viewer) {
+ for (int i = 0; i < ALIGN_VALUES.length; i++) {
+ ParagraphStyleAction action = new ParagraphStyleAction(
+ ALIGN_VALUES[i], _nodes[i], null, IAction.AS_CHECK_BOX);
+ action.setViewer(viewer);
+ menu.add(action);
+ }
+ }
+
+ public static void setAlignNodes(Element[] nodes) {
+ if (_nodes != nodes) {
+ _nodes = nodes;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ChangeStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ChangeStyleAction.java
new file mode 100644
index 000000000..868c54ac9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ChangeStyleAction.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.commands.range.ApplyStyleCommand;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRangeHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class ChangeStyleAction extends DesignerToolBarAction {
+ private String _expectedTag;
+
+ /**
+ * @param text
+ * @param image
+ */
+ public ChangeStyleAction(String text, String name, ImageDescriptor image,
+ int style) {
+ super(text, style);
+ _expectedTag = name;
+ this.setImageDescriptor(image);
+ }
+
+ public ChangeStyleAction(String text, String name, ImageDescriptor enabled,
+ ImageDescriptor disabled, int style) {
+ super(text, style);
+ _expectedTag = name;
+ setImageDescriptor(enabled);
+ setDisabledImageDescriptor(disabled);
+ }
+
+ protected String getExpectedCSSProperty() {
+ return null;
+ }
+
+ protected String getExpectedCSSPropertyValue() {
+ return null;
+ }
+
+ protected boolean isApplied(DOMRange range) {
+ if (range == null) {
+ return false;
+ }
+
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+ Node startnode = start.getContainerNode();
+ Node endnode = end.getContainerNode();
+ if (!EditModelQuery.hasAncestor(startnode, _expectedTag, true)) {
+ return false;
+ }
+ for (Node node = startnode; node != endnode; node = EditModelQuery
+ .getInstance().getNextLeafNeighbor(node)) {
+ if (!EditModelQuery.hasAncestor(node, _expectedTag, true)) {
+ return false;
+ }
+ }
+ if (!EditModelQuery.hasAncestor(endnode, _expectedTag, true)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @return
+ */
+ protected String getExpectedTag() {
+ return _expectedTag;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#getCommand()
+ */
+ protected Command getCommand() {
+ DesignRange range = getViewer().getRangeSelection();
+ DOMRange dRange = DOMRangeHelper.toDOMRange(range);
+ Command command;
+ if (isApplied(dRange)) {
+ // command = new UnapplyStyleCommand(getViewer(), _expectedTag,
+ // null, null);
+ // since the un-applystyle is not implemented yet,we do nothing
+ // here.
+ command = null;
+ this.setChecked(true);
+ } else {
+ command = new ApplyStyleCommand(getViewer(), _expectedTag, null,
+ null);
+ }
+ return command;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void update() {
+ if (canRun(getViewer())) {
+ setEnabled(true);
+ } else {
+ setEnabled(false);
+ }
+ updateStatus();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.actions.range.DesignerToolBarAction#updateStatus()
+ */
+ public void updateStatus() {
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer != null && viewer.isInRangeMode()
+ && viewer.getModel().getDocument().hasChildNodes()) {
+ DesignRange range = getViewer().getRangeSelection();
+ if (range != null && range.isValid()) {
+ DOMRange domRange = null;
+ domRange = new DOMRange(DOMPositionHelper.toDOMPosition(range
+ .getStartPosition()), DOMPositionHelper
+ .toDOMPosition(range.getEndPosition()));
+ if (isApplied(domRange)) {
+ this.setChecked(true);
+ } else {
+ this.setChecked(false);
+ }
+ return;
+ }
+ }
+ this.setChecked(false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.actions.range.DesignerToolBarAction#canRun(org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer)
+ */
+ protected boolean canRun(IHTMLGraphicalViewer viewer) {
+ if (viewer != null && viewer.isInRangeMode()
+ && viewer.getModel().getDocument().hasChildNodes()) {
+ DesignRange range = viewer.getRangeSelection();
+ if (range != null && range.isValid()) {
+ DesignPosition startPos = range.getStartPosition();
+ DesignPosition endPos = range.getEndPosition();
+ if (startPos != endPos) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/DesignerToolBarAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/DesignerToolBarAction.java
new file mode 100644
index 000000000..084071aaa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/DesignerToolBarAction.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * @author mengbo
+ */
+public abstract class DesignerToolBarAction extends Action implements IUpdate,
+ ISelectionChangedListener {
+ private IHTMLGraphicalViewer _viewer;
+
+ /**
+ * @param text
+ * @param style
+ */
+ public DesignerToolBarAction(String text, int style) {
+ super(text, style);
+ }
+
+ /**
+ * @param text
+ * @param image
+ */
+ public DesignerToolBarAction(String text, ImageDescriptor image) {
+ super(text, image);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ update();
+ }
+
+ /**
+ *
+ */
+ public void update() {
+ if (canRun(this._viewer)) {
+ setEnabled(true);
+ updateStatus();
+ } else {
+ setEnabled(false);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void updateStatus() {
+ DesignRange range = _viewer.getRangeSelection();
+ DOMRange domRange = null;
+ if (range != null) {
+ domRange = new DOMRange(DOMPositionHelper.toDOMPosition(range
+ .getStartPosition()), DOMPositionHelper.toDOMPosition(range
+ .getEndPosition()));
+ if (isApplied(domRange)) {
+ this.setChecked(true);
+ } else {
+ this.setChecked(false);
+ }
+ }
+ }
+
+ protected abstract boolean isApplied(DOMRange range);
+
+ protected boolean canRun(IHTMLGraphicalViewer viewer) {
+ if (viewer != null && viewer.isInRangeMode()
+ && viewer.getModel().getDocument().hasChildNodes()) {
+ DesignRange range = viewer.getRangeSelection();
+ if (range != null && range.isValid()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setViewer(IHTMLGraphicalViewer viewer) {
+ if (viewer == _viewer) {
+ return;
+ } else {
+ if (_viewer != null) {
+ _viewer.removeSelectionChangedListener(this);
+ }
+ _viewer = viewer;
+ if (_viewer != null) {
+ _viewer.addSelectionChangedListener(this);
+ }
+ update();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ // Assert.isTrue(_viewer != null && _viewer.isInRangeMode());
+ DesignRange range = _viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ return;
+ }
+ Command command = getCommand();
+ if (command != null) {
+ command.execute();
+ }
+ }
+
+ protected abstract Command getCommand();
+
+ /**
+ * @return Returns the _viewer.
+ */
+ public IHTMLGraphicalViewer getViewer() {
+ return _viewer;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/HTagsInsertGroupAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/HTagsInsertGroupAction.java
new file mode 100644
index 000000000..ec5ee2763
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/HTagsInsertGroupAction.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+
+/**
+ * @author mengbo
+ */
+public class HTagsInsertGroupAction extends DesignerToolBarAction implements
+ IMenuCreator {
+ private Menu _menu;
+
+ private static Map _actions = new HashMap();
+
+ public HTagsInsertGroupAction(ImageDescriptor image, int style) {
+ super(
+ PDPlugin
+ .getResourceString("HTagsInsertGroupAction.ActionLabel.Hx"), IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
+ this.setImageDescriptor(image);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control)
+ */
+ public Menu getMenu(Control parent) {
+ if (_menu != null) {
+ _menu.dispose();
+ }
+ _menu = new Menu(parent);
+ addActionToMenu(_menu, IHTMLConstants.TAG_H1);
+ addActionToMenu(_menu, IHTMLConstants.TAG_H2);
+ addActionToMenu(_menu, IHTMLConstants.TAG_H3);
+ addActionToMenu(_menu, IHTMLConstants.TAG_H4);
+ addActionToMenu(_menu, IHTMLConstants.TAG_H5);
+ addActionToMenu(_menu, IHTMLConstants.TAG_H6);
+
+ return _menu;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu)
+ */
+ public Menu getMenu(Menu parent) {
+ return null;
+ }
+
+ protected void addActionToMenu(Menu parent, String name) {
+ DesignerToolBarAction action;
+ if (_actions.get(name) == null) {
+ action = new ParagraphStyleAction(name, name, null,
+ IAction.AS_CHECK_BOX);
+ _actions.put(name, action);
+ } else {
+ action = (ParagraphStyleAction) _actions.get(name);
+ }
+ action.setViewer(getViewer());
+ action.update();
+ ActionContributionItem item = new ActionContributionItem(action);
+ item.fill(parent, -1);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IMenuCreator#dispose()
+ */
+ public void dispose() {
+ if (_menu != null) {
+ _menu.dispose();
+ _menu = null;
+ _actions.clear();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#getMenuCreator()
+ */
+ public IMenuCreator getMenuCreator() {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.InsertTagChangeStyleAction#supportSingle(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected boolean supportSingle() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.actions.DesignerToolBarAction#canRun(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected boolean isApplied(DOMRange range) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.InsertTagChangeStyleAction#setEnabled(org.eclipse.jst.pagedesigner.viewer.DesignRange)
+ */
+ public void setStatus(DesignRange range) {
+ this.setEnabled(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#getCommand()
+ */
+ protected Command getCommand() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#setViewer(org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer)
+ */
+ public void setViewer(IHTMLGraphicalViewer viewer) {
+ if (_actions != null && _actions.size() > 0) {
+ Collection values = _actions.values();
+ Iterator iterator = values.iterator();
+ while (iterator.hasNext()) {
+ DesignerToolBarAction action = (DesignerToolBarAction) iterator
+ .next();
+ action.setViewer(viewer);
+ }
+ }
+ super.setViewer(viewer);
+ }
+
+ /*
+ * The group will delegate update to its children.
+ */
+ public void updateStatus() {
+ if (_actions != null && _actions.size() > 0) {
+ Collection values = _actions.values();
+ Iterator iterator = values.iterator();
+ while (iterator.hasNext()) {
+ DesignerToolBarAction action = (DesignerToolBarAction) iterator
+ .next();
+ action.updateStatus();
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/InsertTagChangeStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/InsertTagChangeStyleAction.java
new file mode 100644
index 000000000..e9fdd8e1a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/InsertTagChangeStyleAction.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.editors.actions.ChangeStyleAction;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class InsertTagChangeStyleAction extends ChangeStyleAction {
+ /**
+ * @param text
+ * @param image
+ * @param style
+ */
+ public InsertTagChangeStyleAction(String text, String tag,
+ ImageDescriptor image, int style) {
+ super(text, tag, image, style);
+ }
+
+ protected String getExpectedCSSProperty() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ protected String getExpectedCSSPropertyValue() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void update() {
+ if (_viewer == null) {
+ this.setChecked(false);
+ this.setEnabled(false);
+ return;
+ }
+ if (!_viewer.isInRangeMode()) {
+ // XXX: later we may support in range mode.
+ this.setChecked(false);
+ this.setEnabled(false);
+ return;
+ }
+ DesignRange range = _viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ this.setChecked(false);
+ this.setEnabled(false);
+ return;
+ }
+ setEnabled(range);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void setEnabled(DesignRange range) {
+ DOMRange domRange = null;
+ // We didn't deal with undo, so only enable is set.
+ domRange = new DOMRange(DOMPositionHelper.toDOMPosition(range
+ .getStartPosition()), DOMPositionHelper.toDOMPosition(range
+ .getEndPosition()));
+ if (canRun(domRange)) {
+ this.setEnabled(true);
+ } else {
+ this.setEnabled(false);
+ }
+ }
+
+ private boolean canRun(DOMRange range) {
+ if (range != null) {
+ if (EditModelQuery.isSame(range) && !supportSingle()) {
+ return false;
+ }
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+ Node common = null;
+ common = EditModelQuery.getInstance().getCommonAncestor(start, end);
+ if (getExpectedTag() == null
+ || EditModelQuery.hasAncestor(common, getExpectedTag(),
+ true)) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ protected boolean supportSingle() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneParagraphStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneParagraphStyleAction.java
new file mode 100644
index 000000000..101504894
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneParagraphStyleAction.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.commands.range.Paragraph;
+import org.eclipse.jst.pagedesigner.commands.range.ParagraphFinder;
+import org.eclipse.jst.pagedesigner.commands.range.ParagraphUnapplyStyleCommand;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class NoneParagraphStyleAction extends ParagraphStyleAction {
+ public static final String[] HH = { "h1", "h2", "h3", "h4", "h5", "h6" };
+
+ private String[] _applyingTags;
+
+ /**
+ * @param text
+ * @param name
+ * @param image
+ * @param style
+ */
+ public NoneParagraphStyleAction(String text, String[] tags,
+ ImageDescriptor image, int style) {
+ super(text, "", image, style);
+ _applyingTags = tags;
+ }
+
+ /**
+ * @param text
+ * @param node
+ * @param image
+ * @param style
+ */
+ public NoneParagraphStyleAction(String text, Node node,
+ ImageDescriptor image, int style) {
+ super(text, node, image, style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.actions.DesignerToolBarAction#isApplied(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected boolean isApplied(DOMRange range) {
+ if (range != null) {
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+ Node common = null;
+ if (EditModelQuery.isSame(range)) {
+ ParagraphFinder finder = new ParagraphFinder(start);
+ Paragraph p = finder.getParagraph(start);
+ common = p.getLowestContainer();
+ } else {
+ common = EditModelQuery.getInstance().getCommonAncestor(start,
+ end);
+ }
+ // the lowest common block parent is the container to apply style.
+ if (EditModelQuery.hasAncestor(common, _applyingTags, true)) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#getCommand()
+ */
+ protected Command getCommand() {
+ ParagraphUnapplyStyleCommand command = new ParagraphUnapplyStyleCommand(
+ getViewer(), _applyingTags, null, null);
+ return command;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneStyleAction.java
new file mode 100644
index 000000000..86ac0cc1d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/NoneStyleAction.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.commands.range.UnapplyStyleCommand;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class NoneStyleAction extends ChangeStyleAction {
+ private String[] _applyingStyleTags;
+
+ /**
+ * @param text
+ * @param names
+ * @param image
+ * @param style
+ */
+ public NoneStyleAction(String text, String[] names, ImageDescriptor image,
+ int style) {
+ super(text, "", image, style);
+ _applyingStyleTags = names;
+ }
+
+ protected boolean isApplied(DOMRange range) {
+ if (range != null) {
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+ Node common = null;
+ common = EditModelQuery.getInstance().getCommonAncestor(start, end);
+ if (EditModelQuery.hasAncestor(common, _applyingStyleTags, true)) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#getCommand()
+ */
+ protected Command getCommand() {
+ UnapplyStyleCommand command = new UnapplyStyleCommand(getViewer(),
+ getExpectedTag(), null, null);
+ return command;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphAction.java
new file mode 100644
index 000000000..5752653b8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphAction.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.action.Action;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ParagraphAction extends Action {
+ /**
+ * @param text
+ * @param string
+ */
+ public ParagraphAction(String text, String htmlTag) {
+ super(text);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphStyleAction.java
new file mode 100644
index 000000000..ea8a66339
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphStyleAction.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.commands.range.Paragraph;
+import org.eclipse.jst.pagedesigner.commands.range.ParagraphApplyStyleCommand;
+import org.eclipse.jst.pagedesigner.commands.range.ParagraphFinder;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class ParagraphStyleAction extends DesignerToolBarAction {
+ private String _tagName;
+
+ private Node _applyingNode;
+
+ /**
+ * @param text
+ * @param name
+ * @param image
+ * @param style
+ */
+ public ParagraphStyleAction(String text, String name,
+ ImageDescriptor image, int style) {
+ super(text, style);
+ _tagName = name;
+ setImageDescriptor(image);
+ }
+
+ public ParagraphStyleAction(String text, Node node, ImageDescriptor image,
+ int style) {
+ super(text, style);
+ _applyingNode = node;
+ setImageDescriptor(image);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.actions.DesignerToolBarAction#isApplied(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected boolean isApplied(DOMRange range) {
+ Assert.isTrue(getExpectedTag() != null);
+ if (range != null) {
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+ Node common = null;
+ if (EditModelQuery.isSame(range)) {
+ ParagraphFinder finder = new ParagraphFinder(start);
+ Paragraph p = finder.getParagraph(start);
+ common = p.getLowestContainer();
+ } else {
+ common = EditModelQuery.getInstance().getCommonAncestor(start,
+ end);
+ }
+ // the lowest common block parent is the container to apply style.
+ if (containsTag(common)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ protected boolean containsTag(Node common) {
+ // the lowest common block parent is the container to apply style.
+ if (_applyingNode == null) {
+ return common.getNodeName() != null
+ && getExpectedTag().equalsIgnoreCase(
+ common.getNodeName().toLowerCase());
+ }
+ // return false;
+ else {
+ String align = ((Element) _applyingNode).getAttribute("align");
+ if (!(common instanceof Element)) {
+ return false;
+ }
+ String cAlign = ((Element) common).getAttribute("align");
+ if (align == null || cAlign == null) {
+ return false;
+ }
+ if (align.equals(cAlign)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ }
+
+ /**
+ * @return Returns the _expectedTag.
+ */
+ public String getExpectedTag() {
+ if (_tagName == null) {
+ return _applyingNode.getNodeName().toLowerCase();
+ } else {
+ return _tagName.toLowerCase();
+ }
+ }
+
+ /**
+ * @return Returns the _applyingNode.
+ */
+ public Element getApplyingNode() {
+ if (_applyingNode != null) {
+ return (Element) _applyingNode;
+ } else {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#getCommand()
+ */
+ protected Command getCommand() {
+ ParagraphApplyStyleCommand command = null;
+ if (getApplyingNode() != null) {
+ command = new ParagraphApplyStyleCommand(getViewer(),
+ getApplyingNode(), null, null);
+ } else {
+ command = new ParagraphApplyStyleCommand(getViewer(),
+ getExpectedTag(), null, null);
+ }
+ return command;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignerToolBarAction#setViewer(org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer)
+ */
+ public void setViewer(IHTMLGraphicalViewer viewer) {
+ // TODO Auto-generated method stub
+ super.setViewer(viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void update() {
+ // TODO Auto-generated method stub
+ super.update();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphSupport.java
new file mode 100644
index 000000000..52616e447
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/ParagraphSupport.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ParagraphSupport {
+ static final String[] labels = new String[] {
+ PDPlugin.getResourceString("ParagraphSupport.CommandLabel.None"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Paragraph"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Heading1"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Heading2"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Heading3"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Heading4"),//$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Heading5"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Heading6"), //$NON-NLS-1$
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.Preformated") //$NON-NLS-1$
+ };
+
+ static final String[] tags = new String[] {
+ null,
+ PDPlugin.getResourceString("ParagraphSupport.CommandLabel.P"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.H1"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.H2"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.H3"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.H4"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.H5"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.H6"), PDPlugin.getResourceString("ParagraphSupport.CommandLabel.PRE") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
+ };
+
+ public static int getCurrentParagraphMode(DesignRange range) {
+ return 0;
+ }
+
+ public static void createParagraphActions(IMenuManager man,
+ DesignRange range, int currentMode, IHTMLGraphicalViewer viewer) {
+ ParagraphStyleAction action = new NoneParagraphStyleAction(
+ PDPlugin
+ .getResourceString("ParagraphSupport.CommandLabel.None"), tags, null, IAction.AS_CHECK_BOX); //$NON-NLS-1$
+ action.setViewer(viewer);
+ action.update();
+ man.add(action);
+ for (int i = 1; i < labels.length; i++) {
+ action = new ParagraphStyleAction(labels[i], tags[i], null,
+ IAction.AS_CHECK_BOX);
+ action.setViewer(viewer);
+ action.update();
+ man.add(action);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeActionGroup.java
new file mode 100644
index 000000000..cdb67adad
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeActionGroup.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.actions.link.MakeLinkAction;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.jst.pagedesigner.editors.actions.DesignActionBarFactory;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.ui.actions.ActionGroup;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RangeActionGroup extends ActionGroup {
+ public static Action action = new Action() {
+ };
+
+ /**
+ *
+ */
+ public RangeActionGroup() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ DesignRange selection = fixUpSelection(getContext().getSelection());
+ if (selection == null) {
+ return;
+ }
+ if (getContext().getInput() instanceof IHTMLGraphicalViewer) {
+ addParagraphFormatMenu(menu, selection,
+ (IHTMLGraphicalViewer) getContext().getInput());
+ addHorizontalAlignMenu(menu, selection,
+ (IHTMLGraphicalViewer) getContext().getInput());
+ addTextStyleMenu(menu, (IHTMLGraphicalViewer) getContext()
+ .getInput());
+ }
+ addListModeMenu(menu, selection);
+
+ addTextFontMenu(menu, selection);
+
+ addLinkMenu(menu, selection);
+ }
+
+ /**
+ * @param selection
+ * @return
+ */
+ private DesignRange fixUpSelection(ISelection selection) {
+ if (selection instanceof DesignRange) {
+ return (DesignRange) selection;
+ } else {
+ return null;
+ }
+ }
+
+ private void addLinkMenu(IMenuManager menu, final DesignRange selection) {
+ Action action = new MakeLinkAction(selection);
+ menu.appendToGroup(PageDesignerActionConstants.GROUP_STYLE, action);
+ }
+
+ private void addTextStyleMenu(IMenuManager menu,
+ final IHTMLGraphicalViewer viewer) {
+ final IMenuManager submenu = new MenuManager(PDPlugin
+ .getResourceString("ActionGroup.Submenu.TextStyle"));//$NON-NLS-1$
+ submenu.add(action);
+
+ submenu.setRemoveAllWhenShown(true);
+ submenu.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ DesignerToolBarAction action = null;
+ action = DesignActionBarFactory.getInstance().getStyleAction(
+ IHTMLConstants.TAG_U);
+ action.setViewer(viewer);
+ submenu.add(action);
+
+ action = DesignActionBarFactory.getInstance().getStyleAction(
+ IHTMLConstants.TAG_B);
+ action.setViewer(viewer);
+ submenu.add(action);
+
+ action = DesignActionBarFactory.getInstance().getStyleAction(
+ IHTMLConstants.TAG_I);
+ action.setViewer(viewer);
+ submenu.add(action);
+
+ action = DesignActionBarFactory.getInstance().getStyleAction(
+ IHTMLConstants.TAG_SMALL);
+ action.setViewer(viewer);
+ submenu.add(action);
+
+ action = DesignActionBarFactory.getInstance().getStyleAction(
+ IHTMLConstants.TAG_BIG);
+ action.setViewer(viewer);
+ submenu.add(action);
+
+ }
+ });
+ menu.appendToGroup(PageDesignerActionConstants.GROUP_STYLE, submenu);
+ }
+
+ /**
+ * @param menu
+ * @param selection
+ */
+ private void addTextFontMenu(IMenuManager menu, DesignRange selection) {
+
+ }
+
+ /**
+ * @param menu
+ * @param selection
+ */
+ private void addHorizontalAlignMenu(IMenuManager menu,
+ final DesignRange selection, final IHTMLGraphicalViewer viewer) {
+ // we have to initialize align nodes here for some refresh problem
+ Element[] alignNodes = new Element[4];
+ final String[] alignValues = new String[] { "left", "center", "right",
+ "justify" };
+ Document document = viewer.getModel().getDocument();
+ for (int i = 0; i < 4; i++) {
+ Element node = document.createElement(IHTMLConstants.TAG_P);
+ node.setAttribute(IHTMLConstants.ATTR_ALIGN, alignValues[i]);
+ alignNodes[i] = node;
+ }
+ AlignSupport.setAlignNodes(alignNodes);
+
+ final IMenuManager submenu = new MenuManager(PDPlugin
+ .getResourceString("ActionGroup.Submenu.Align"));//$NON-NLS-1$
+ submenu.add(action);
+ submenu.setRemoveAllWhenShown(true);
+ submenu.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ AlignSupport.createAlignActions(submenu, viewer);
+ }
+ });
+ menu.appendToGroup(PageDesignerActionConstants.GROUP_STYLE, submenu);
+
+ }
+
+ /**
+ * @param menu
+ * @param selection
+ */
+ private void addListModeMenu(IMenuManager menu, DesignRange selection) {
+ }
+
+ /**
+ * @param menu
+ * @param selection
+ */
+ private void addParagraphFormatMenu(IMenuManager menu,
+ final DesignRange selection, final IHTMLGraphicalViewer viewer) {
+ final IMenuManager submenu = new MenuManager(PDPlugin
+ .getResourceString("ActionGroup.Submenu.ParagraphFormat"));//$NON-NLS-1$
+ submenu.add(action);
+ // Add the submenu.
+ final int mode = ParagraphSupport.getCurrentParagraphMode(selection);
+
+ submenu.addMenuListener(new IMenuListener() {
+
+ public void menuAboutToShow(IMenuManager manager) {
+ submenu.removeAll();
+ ParagraphSupport.createParagraphActions(submenu, selection,
+ mode, viewer);
+ }
+ });
+ menu.appendToGroup(PageDesignerActionConstants.GROUP_STYLE, submenu);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleAction.java
new file mode 100644
index 000000000..ba633ab5f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleAction.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RangeStyleAction extends Action {
+ /**
+ * @param text
+ */
+ public RangeStyleAction(String text, DesignRange range, String htmlTag,
+ String cssProperty, String cssValue) {
+ super(text);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ if (isChecked()) {
+ // un-apply the style here
+ } else {
+ // apply the style here.
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleSupport.java
new file mode 100644
index 000000000..754870ac6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/range/RangeStyleSupport.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.range;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RangeStyleSupport {
+ public static final String[] ActionLabel = new String[] {
+ PDPlugin.getResourceString("RangeStyleSupport.ActionLabel.Bold"),//$NON-NLS-1$
+ PDPlugin.getResourceString("RangeStyleSupport.ActionLabel.Italic"),//$NON-NLS-1$
+ PDPlugin
+ .getResourceString("RangeStyleSupport.ActionLabel.Underline"), }; //$NON-NLS-1$
+
+ public static final String[] HtmlTag = new String[] { "STRONG", "I", "U", }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ public static final String[] CSSProperty = new String[] {
+ "font-weight", "font-style", "text-decoration", }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ public static final String[] CSSValue = new String[] { "bolder", "italic",
+ "underline", };
+
+ public static void createRangeStyleActions(IMenuManager menu,
+ DesignRange range) {
+ for (int i = 0; i < ActionLabel.length; i++) {
+ RangeStyleAction action = new RangeStyleAction(ActionLabel[i],
+ range, HtmlTag[i], CSSProperty[i], CSSValue[i]);
+
+ menu.add(action);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleAction.java
new file mode 100644
index 000000000..17236629b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleAction.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BorderStyleAction extends Action {
+
+ /**
+ * @param stylevalue
+ * @param ele
+ * @param text
+ *
+ */
+ public BorderStyleAction(String text, IDOMElement ele, String stylevalue) {
+ super(text);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleSupport.java
new file mode 100644
index 000000000..4e968a4b6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/BorderStyleSupport.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BorderStyleSupport {
+ public static final String VAL_HIDDEN = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Hidden"); //$NON-NLS-1$
+
+ public static final String VAL_DOTTED = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Dotted"); //$NON-NLS-1$
+
+ public static final String VAL_DASHED = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Dashed"); //$NON-NLS-1$
+
+ public static final String VAL_SOLID = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Solid"); //$NON-NLS-1$
+
+ public static final String VAL_DOUBLE = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Double"); //$NON-NLS-1$
+
+ public static final String VAL_GROOVE = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Groove"); //$NON-NLS-1$
+
+ public static final String VAL_RIDGE = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Ridge"); //$NON-NLS-1$
+
+ public static final String VAL_INSET = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Inset"); //$NON-NLS-1$
+
+ public static final String VAL_OUTSET = PDPlugin
+ .getResourceString("BorderStyleSupport.CommandLabel.Outset"); //$NON-NLS-1$
+
+ public static final String[] BORDERSTYLES = new String[] { VAL_HIDDEN,
+ VAL_DOTTED, VAL_DASHED, VAL_SOLID, VAL_DOUBLE, VAL_GROOVE,
+ VAL_RIDGE, VAL_INSET, VAL_OUTSET };
+
+ public static final String getCurrentBorderStyle(IDOMElement ele) {
+ return VAL_HIDDEN;
+ }
+
+ public static void createParagraphActions(IMenuManager man,
+ IDOMElement ele, String currentMode) {
+ for (int i = 0; i < BORDERSTYLES.length; i++) {
+ BorderStyleAction action = new BorderStyleAction(BORDERSTYLES[i],
+ ele, BORDERSTYLES[i]);
+ if (BORDERSTYLES[i].equalsIgnoreCase(currentMode)) {
+ action.setChecked(true);
+ }
+ man.add(action);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeAttributeAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeAttributeAction.java
new file mode 100644
index 000000000..85c4ec984
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeAttributeAction.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeAttributeCommand;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ChangeAttributeAction extends Action {
+ IDOMElement _ele;
+
+ String _attrValue;
+
+ private String _attrName;
+
+ /**
+ * @param string
+ * @param ele
+ * @param string2
+ */
+ public ChangeAttributeAction(String label, IDOMElement ele,
+ String attrName, String attrValue) {
+ super(label);
+ this._ele = ele;
+ this._attrName = attrName;
+ this._attrValue = attrValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ if (this.isChecked()) {
+ return;
+ }
+
+ ChangeAttributeCommand c = new ChangeAttributeCommand(
+ PDPlugin
+ .getResourceString("ChangeAttributeAction.CommandLabel.ChangeStyleClass"), _ele, _attrName, _attrValue); //$NON-NLS-1$
+ c.execute();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStyleAction.java
new file mode 100644
index 000000000..83a031b95
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStyleAction.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeStyleCommand;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.ui.dialogs.StyleDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclaration;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.css.ElementCSSInlineStyle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ChangeStyleAction extends Action {
+ private static final String TEXT = PDPlugin
+ .getResourceString("ChangeStyleAction.Text");
+
+ private ElementEditPart _editPart;
+
+ private IDOMElement _element;
+
+ public ChangeStyleAction(ElementEditPart part, IDOMElement ele) {
+ super(TEXT);
+ this._editPart = part;
+ this._element = ele;
+ }
+
+ public void run() {
+ ICSSStyleDeclaration styleDeclaration = (ICSSStyleDeclaration) ((ElementCSSInlineStyle) this._element)
+ .getStyle();
+ PreferenceManager manager = new PreferenceManager();
+ EditPartViewer viewer = this._editPart.getViewer();
+ Shell shell = viewer.getControl().getShell();
+
+ CSSPropertyContext context = new CSSPropertyContext(styleDeclaration);
+ StyleDialog dialog = new StyleDialog(shell, manager, _element, context);
+ if (dialog.open() == Window.OK) {
+ if (context.isModified()) {
+ ChangeStyleCommand c = new ChangeStyleCommand(_element, context);
+ c.execute();
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStylePropertyAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStylePropertyAction.java
new file mode 100644
index 000000000..b89fda730
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ChangeStylePropertyAction.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeStyleCommand;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ChangeStylePropertyAction extends Action {
+ private IDOMElement _ele;
+
+ private String _cssProperty;
+
+ private String _cssValue;
+
+ /**
+ * @param text
+ */
+ public ChangeStylePropertyAction(String text, IDOMElement ele,
+ String cssProperty, String cssValue) {
+ super(text);
+ this._ele = ele;
+ this._cssProperty = cssProperty;
+ this._cssValue = cssValue;
+ }
+
+ public void run() {
+ if (isChecked()) {
+ return;
+ }
+
+ Map map = new HashMap();
+ map.put(_cssProperty, _cssValue);
+ ChangeStyleCommand command = new ChangeStyleCommand(_ele, map);
+ command.execute();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ColorSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ColorSupport.java
new file mode 100644
index 000000000..e63f87f35
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/ColorSupport.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.dom.DOMStyleUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ColorSupport {
+ public static final String[] COLOR_VALUES = new String[] {
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Aqua"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Black"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Blue"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Fuchsia"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Gray"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Green"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Lime"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Maroon"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Navy"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Olive"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Orange"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Purple"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Red"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Silver"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Teal"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.White"), //$NON-NLS-1$
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Yellow") //$NON-NLS-1$
+ };
+
+ /**
+ *
+ * @param menu
+ * @param ele
+ * @param cssProperty
+ * will be "color" or "background-color"
+ */
+ public static void createColorActions(IMenuManager menu, IDOMElement ele,
+ String cssProperty) {
+ boolean needAdditional = true;
+ String currentValue = DOMStyleUtil.getInlineStyleProperty(ele,
+ cssProperty);
+ ChangeStylePropertyAction defaultAction = new ChangeStylePropertyAction(
+ PDPlugin.getResourceString("ColorSupport.CommandLabel.Default"), ele, cssProperty, null); //$NON-NLS-1$
+ if (currentValue == null || currentValue.length() == 0) {
+ defaultAction.setChecked(true);
+ needAdditional = false;
+ }
+ menu.add(defaultAction);
+ menu.add(new Separator());
+ for (int i = 0; i < COLOR_VALUES.length; i++) {
+ ChangeStylePropertyAction action = new ChangeStylePropertyAction(
+ COLOR_VALUES[i], ele, cssProperty, COLOR_VALUES[i]);
+ if (COLOR_VALUES[i].equalsIgnoreCase(currentValue)) {
+ action.setChecked(true);
+ needAdditional = false;
+ }
+ menu.add(action);
+ }
+
+ if (needAdditional) {
+ ChangeStylePropertyAction action = new ChangeStylePropertyAction(
+ currentValue, ele, cssProperty, currentValue);
+ action.setChecked(true);
+ menu.add(action);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SelectEditPartAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SelectEditPartAction.java
new file mode 100644
index 000000000..42d9dc531
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SelectEditPartAction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class SelectEditPartAction extends Action {
+ ElementEditPart _part;
+
+ /**
+ * @param text
+ */
+ public SelectEditPartAction(String text, ElementEditPart part) {
+ super(text);
+ this._part = part;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ _part.getViewer().setSelection(new StructuredSelection(_part));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SingleElementActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SingleElementActionGroup.java
new file mode 100644
index 000000000..e84c19696
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/SingleElementActionGroup.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.dom.DOMStyleUtil;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class SingleElementActionGroup extends ActionGroup {
+ public static Action action = new Action() {
+ };
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ ElementEditPart part = fixUpSelection(getContext().getSelection());
+ if (part == null) {
+ return;
+ }
+ IDOMElement ele = (IDOMElement) part.getIDOMNode();
+ addStylelMenu(menu, part, ele);
+
+ // next add element special actions
+ IElementEdit elementEdit = part.getElementEdit();
+ if (elementEdit != null) {
+ elementEdit.fillContextMenu(menu, ele);
+ }
+ }
+
+ /**
+ * @param selection
+ * @return
+ */
+ private ElementEditPart fixUpSelection(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection sel = (IStructuredSelection) selection;
+ if (sel.size() != 1) {
+ return null;
+ }
+ if (sel.getFirstElement() instanceof ElementEditPart) {
+ return (ElementEditPart) sel.getFirstElement();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param menu
+ * @param part
+ */
+ private void addStylelMenu(IMenuManager menu, ElementEditPart part,
+ IDOMElement ele) {
+ // IMenuManager stylesub = new MenuManager("Style");
+ IMenuManager stylesub = menu;
+
+ addStyle(menu, part, ele);
+ addStyleClassesMenu(stylesub, part, ele);
+
+ if (DOMStyleUtil.supportStyleAttribute(ele)) {
+ // addBorderStyleMenu(stylesub, part, ele);
+ addColorMenu(stylesub, part, ele);
+ addBackgroundMenu(stylesub, part, ele);
+ }
+
+ // menu.add(stylesub);
+ }
+
+ /**
+ *
+ * @param menu
+ * @param part
+ * @param ele
+ */
+ private void addStyle(IMenuManager menu, ElementEditPart part,
+ IDOMElement ele) {
+ StyleSupport.createStyleAction(menu, part, ele);
+ }
+
+ /**
+ * @param stylesub
+ * @param part
+ */
+ private void addStyleClassesMenu(IMenuManager stylesub,
+ ElementEditPart part, final IDOMElement ele) {
+ final IMenuManager classmenu = new MenuManager(PDPlugin
+ .getResourceString("ActionGroup.Submenu.StyleClasses"));//$NON-NLS-1$
+ StyleClassSupport.createStyleClassActions(classmenu, ele);
+ /*
+ * classmenu.add(action); classmenu.addMenuListener(new IMenuListener() {
+ *
+ * public void menuAboutToShow(IMenuManager manager) {
+ * classmenu.removeAll();
+ * StyleClassSupport.createStyleClassActions(classmenu, ele); } } );
+ */
+
+ stylesub.appendToGroup(PageDesignerActionConstants.GROUP_STYLE,
+ classmenu);
+ }
+
+ /**
+ * @param stylesub
+ * @param part
+ */
+ /*
+ * private void addBorderStyleMenu(IMenuManager stylesub, ElementEditPart
+ * part, final IDOMElement ele) { final IMenuManager borderStyleSub = new
+ * MenuManager(PDPlugin
+ * .getResourceString("ActionGroup.Submenu.BorderStyle"));//$NON-NLS-1$
+ * borderStyleSub.add(action);
+ *
+ * final String mode = BorderStyleSupport.getCurrentBorderStyle(ele);
+ *
+ * borderStyleSub.addMenuListener(new IMenuListener() { public void
+ * menuAboutToShow(IMenuManager manager) { borderStyleSub.removeAll();
+ * BorderStyleSupport.createParagraphActions(borderStyleSub, ele, mode); }
+ * }); stylesub.appendToGroup(PageDesignerActionConstants.GROUP_STYLE,
+ * borderStyleSub); }
+ */
+
+ /**
+ * @param stylesub
+ * @param part
+ */
+ private void addColorMenu(IMenuManager stylesub, ElementEditPart part,
+ final IDOMElement ele) {
+ final IMenuManager colorSub = new MenuManager(PDPlugin
+ .getResourceString("ActionGroup.Submenu.Color"));//$NON-NLS-1$
+ colorSub.add(action);
+ colorSub.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ colorSub.removeAll();
+ ColorSupport.createColorActions(colorSub, ele,
+ ICSSPropertyID.ATTR_COLOR);
+ }
+ });
+ stylesub.appendToGroup(PageDesignerActionConstants.GROUP_STYLE,
+ colorSub);
+
+ }
+
+ /**
+ * @param stylesub
+ * @param part
+ */
+ private void addBackgroundMenu(IMenuManager stylesub, ElementEditPart part,
+ final IDOMElement ele) {
+ final IMenuManager colorSub = new MenuManager(PDPlugin
+ .getResourceString("ActionGroup.Submenu.BackgroundColor"));//$NON-NLS-1$
+ colorSub.add(action);
+ colorSub.addMenuListener(new IMenuListener() {
+
+ public void menuAboutToShow(IMenuManager manager) {
+ colorSub.removeAll();
+ ColorSupport.createColorActions(colorSub, ele,
+ ICSSPropertyID.ATTR_BACKGROUND_COLOR);
+ }
+ });
+
+ stylesub.appendToGroup(PageDesignerActionConstants.GROUP_STYLE,
+ colorSub);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleClassSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleClassSupport.java
new file mode 100644
index 000000000..4b43d767f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleClassSupport.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.css2.CSSUtil;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class StyleClassSupport {
+ private final static String DEFAULT = PDPlugin
+ .getResourceString("StyleClassSupport.Default");
+
+ /**
+ * @param classmenu
+ */
+ public static void createStyleClassActions(IMenuManager classmenu,
+ IDOMElement ele) {
+ String styleClassAttr = getStyleClassAttributeName(ele);
+ if (styleClassAttr == null) {
+ return; // don't support style class
+ }
+ String styleClass = getStyleClass(ele);
+
+ boolean needAdditional = true;
+ ChangeAttributeAction action = new ChangeAttributeAction(DEFAULT, ele,
+ styleClassAttr, null);
+ if (styleClass == null || styleClass.length() == 0) {
+ action.setChecked(true);
+ needAdditional = false;
+ }
+ classmenu.add(action);
+ String[] classes = CSSUtil.getCSSClasses(ele.getOwnerDocument());
+ if (classes.length > 0) {
+ classmenu.add(new Separator());
+ }
+ for (int i = 0; i < classes.length; i++) {
+ ChangeAttributeAction action2 = new ChangeAttributeAction(
+ classes[i], ele, styleClassAttr, classes[i]);
+ if (classes[i].equalsIgnoreCase(styleClass)) {
+ action2.setChecked(true);
+ needAdditional = false;
+ }
+ classmenu.add(action2);
+ }
+ if (needAdditional) {
+ ChangeAttributeAction action2 = new ChangeAttributeAction(
+ styleClass, ele, styleClassAttr, styleClass);
+ action2.setChecked(true);
+ classmenu.add(action2);
+ }
+ }
+
+ /**
+ * @param ele
+ * @return
+ */
+ public static String getStyleClass(IDOMElement ele) {
+ String styleClassAttr = getStyleClassAttributeName(ele);
+ if (styleClassAttr != null) {
+ return ele.getAttribute(styleClassAttr);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * FIXME: This is a temparary impelementation, with everything hard coded.
+ * In the future, should have some INodeAdapter mechanism for each node to
+ * tell the style class attribute name.
+ *
+ * @param ele
+ * @return
+ */
+ public static String getStyleClassAttributeName(IDOMElement ele) {
+ CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
+ if (decl == null) {
+ return null;
+ }
+ String taguri = CMUtil.getTagURI(decl);
+ if (taguri == null || IJMTConstants.URI_HTML.equals(taguri)) {
+ if (decl.getAttributes().getNamedItem("class") != null) {
+ return "class";
+ } else {
+ return null;
+ }
+ } else if (decl.getAttributes().getNamedItem("styleClass") != null) {
+ return "styleClass";
+ } else if (decl.getAttributes().getNamedItem("class") != null) {
+ return "class";
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleSupport.java
new file mode 100644
index 000000000..918af8daf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/single/StyleSupport.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.single;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class StyleSupport {
+ public static void createStyleAction(IMenuManager menu,
+ ElementEditPart part, IDOMElement ele) {
+ if (part == null) {
+ return;
+ }
+ if (hasStyleAttribute(ele)) {
+ IAction action = new ChangeStyleAction(part, ele);
+ menu.appendToGroup(PageDesignerActionConstants.GROUP_STYLE, action);
+ }
+ }
+
+ private static boolean hasStyleAttribute(IDOMElement ele) {
+ CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
+ if (decl == null) {
+ return false;
+ }
+ if (decl.getAttributes().getNamedItem("style") != null) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableActionGroup.java
new file mode 100644
index 000000000..c5192bd12
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableActionGroup.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.table;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.actions.single.SelectEditPartAction;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.tableedit.DeleteRowColumnAction;
+import org.eclipse.jst.pagedesigner.tableedit.InsertRowColumnAction;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableActionGroup extends ActionGroup {
+ public static Action action = new Action() {
+ };
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ ISelection selection = this.getContext().getSelection();
+
+ EditPart part = findCommonAncesterPart(selection);
+ if (part == null) {
+ return;
+ }
+
+ TableOperationContext context = TableOperationContext
+ .getTableOperationContext(part);
+ if (context == null) {
+ return;
+ }
+
+ final ElementEditPart tablePart = context._tablePart;
+
+ if (tablePart == null || !supportTableActions(tablePart)) {
+ return;
+ }
+
+ final int cellRow = context._rowIndex;
+ final int cellColumn = context._columnIndex;
+
+ String tag = ((IDOMElement) tablePart.getIDOMNode()).getLocalName();
+ final IMenuManager tableMenu = new MenuManager(tag);
+
+ // ok, we passed the checking, now let's create the actions.
+ tableMenu.add(action);
+ tableMenu.addMenuListener(new IMenuListener() {
+
+ public void menuAboutToShow(IMenuManager manager) {
+ tableMenu.removeAll();
+ fillTableMenu(tablePart, cellRow, cellColumn, tableMenu);
+ }
+ });
+ menu.appendToGroup(PageDesignerActionConstants.GROUP_CONTAINER,
+ tableMenu);
+ }
+
+ /**
+ * @param tablePart
+ * @param cellRow
+ * @param cellColumn
+ * @param tableMenu
+ */
+ private void fillTableMenu(ElementEditPart tablePart, int cellRow,
+ int cellColumn, IMenuManager tableMenu) {
+ SelectEditPartAction action = new SelectEditPartAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.SelectTable"), tablePart);//$NON-NLS-1$
+ tableMenu.add(action);
+
+ tableMenu.add(new Separator());
+
+ {
+ InsertRowColumnAction insertRowBeforeAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.InsertRowBefore"),//$NON-NLS-1$
+ tablePart, cellRow, true, true);
+ tableMenu.add(insertRowBeforeAction);
+
+ InsertRowColumnAction insertRowAfterAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.InsertRowAfter"),//$NON-NLS-1$
+ tablePart, cellRow, true, false);
+ tableMenu.add(insertRowAfterAction);
+
+ tableMenu.add(new Separator());
+ }
+
+ {
+ InsertRowColumnAction insertColumnBeforeAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.InsertColumnBefore"),//$NON-NLS-1$
+ tablePart, cellColumn, true, true);
+ tableMenu.add(insertColumnBeforeAction);
+
+ InsertRowColumnAction insertColumnAfterAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.InsertColumnAfter"),//$NON-NLS-1$
+ tablePart, cellColumn, true, false);
+ tableMenu.add(insertColumnAfterAction);
+
+ tableMenu.add(new Separator());
+ }
+
+ {
+ DeleteRowColumnAction deleteRowAction = new DeleteRowColumnAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.DeleteRow"),//$NON-NLS-1$
+ tablePart, cellRow, true);
+ tableMenu.add(deleteRowAction);
+
+ DeleteRowColumnAction deleteColumnAction = new DeleteRowColumnAction(
+ PDPlugin
+ .getResourceString("TableActionGroup.Submenu.DeleteColumn"),//$NON-NLS-1$
+ tablePart, cellColumn, false);
+ tableMenu.add(deleteColumnAction);
+ }
+ }
+
+ /**
+ * @param tablePart
+ * @return
+ */
+ private boolean supportTableActions(ElementEditPart tablePart) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ /**
+ * Give a selection, find a single common container node as start for table
+ * related operations.
+ *
+ * @param selection
+ * @return
+ */
+ private EditPart findCommonAncesterPart(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structsel = (IStructuredSelection) selection;
+ if (structsel.size() != 1) {
+ return null;
+ } else if (structsel.getFirstElement() instanceof EditPart) {
+ return (EditPart) structsel.getFirstElement();
+ } else {
+ return null;
+ }
+ } else if (selection instanceof DesignRange) {
+ DesignRange range = (DesignRange) selection;
+ if (!range.isValid()) {
+ return null;
+ }
+ if (range.isEmpty()) {
+ DesignPosition position = range.getStartPosition();
+ if (position.getOffset() == 0) {
+ return position.getContainerPart();
+ } else {
+ return position.getSiblingEditPart(true);
+ }
+ } else {
+ return RangeUtil.findCommonAncestor(range);
+ }
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableOperationContext.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableOperationContext.java
new file mode 100644
index 000000000..22e254972
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/actions/table/TableOperationContext.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.actions.table;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableCellLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableLayout2;
+import org.eclipse.jst.pagedesigner.css2.layout.table.TableCellInfo;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+
+/**
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableOperationContext {
+ public ElementEditPart _tablePart;
+
+ public int _rowIndex;
+
+ public int _columnIndex;
+
+ public static TableOperationContext getTableOperationContext(EditPart part) {
+ EditPart originalPart = part;
+ ElementEditPart tablePart = null;
+ CSSTableLayout2 tableLayout = null;
+
+ while (part.getParent() instanceof ElementEditPart) {
+ part = (ElementEditPart) part.getParent();
+ IFigure figure = ((GraphicalEditPart) part).getFigure();
+
+ if (figure.getLayoutManager() instanceof CSSTableLayout2) {
+ tableLayout = (CSSTableLayout2) figure.getLayoutManager();
+ tablePart = ((ElementEditPart) part);
+ break;
+ }
+ }
+ if (tablePart == null) {
+ return null;
+ }
+
+ part = originalPart;
+
+ IFigure figure = ((GraphicalEditPart) originalPart).getFigure();
+ while (figure instanceof CSSFigure) {
+ if (figure.getLayoutManager() instanceof CSSTableCellLayout) {
+ CSSTableCellLayout cellLayout = (CSSTableCellLayout) figure
+ .getLayoutManager();
+ if (cellLayout.getTableLayout() == tableLayout) {
+ // ok, we found.
+ TableCellInfo cellInfo = cellLayout.getTableCellInfo();
+ if (cellInfo == null) {
+ return null;
+ } else {
+ TableOperationContext context = new TableOperationContext();
+ context._tablePart = tablePart;
+ context._rowIndex = cellInfo.getRowIndex();
+ context._columnIndex = cellInfo.getColumnIndex();
+ return context;
+ }
+ } else {
+ return null;
+ }
+ }
+ figure = figure.getParent();
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/IBodyInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/IBodyInfo.java
new file mode 100644
index 000000000..b037992fa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/IBodyInfo.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.adapters;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * This is an adapter interface. Will be adapted to all the node in the
+ * document. It provides additional information to support designer.
+ *
+ * Basicaly it tells the correspoinding node's body related information.
+ *
+ * @author mengbo
+ */
+// XXX: in the future will use adapter mechanism to support dynamic information
+public interface IBodyInfo // extends INodeAdapter
+{
+ // /**
+ // * whether this node is runtime visible.
+ // *
+ // * @return
+ // */
+ // public boolean isRuntimeVisible(INodeNotifier node);
+ //
+ // /**
+ // * whether this node is design time visible.
+ // * @return
+ // */
+ // public boolean isDesignTimeVisible(INodeNotifier node);
+
+ // /**
+ // * whether is HTML tag.
+ // * @param node
+ // * @return
+ // */
+ // public boolean isHTML(IDOMNode node);
+ //
+ // /**
+ // * whether is JSP tag.
+ // * @param node
+ // * @return
+ // */
+ // public boolean isJSP(IDOMNode node);
+ //
+ // /**
+ // * whether is custom tag.
+ // * @param node
+ // * @return
+ // */
+ // public boolean isCustomTag(IDOMNode node);
+ //
+ // /**
+ // * for custom tag, there may have a corresponding HTML tag name.
+ // * This can be used for content model validation.
+ // *
+ // * @param node
+ // * @return
+ // */
+ // public String getCorrespondingHTMLTag(IDOMNode node);
+
+ /**
+ * whether this node is body node. We treat the document node and certain
+ * element node like "HTML", "BODY", "f:view", "f:subview" as body node. At
+ * design time we may want to move those visual node into the body.
+ *
+ * @return
+ */
+ public boolean isBodyContainer(IDOMNode node);
+
+ /**
+ * this method should only be called isBodyContainer return true; It checks
+ * whether the uri/localname should belong to the head part of this body
+ * container.
+ *
+ * @param uri
+ * @param localname
+ * @return
+ */
+ public boolean isBodyHeader(IDOMNode node, String uri, String localname);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/internal/BodyInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/internal/BodyInfo.java
new file mode 100644
index 000000000..df446edd0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/adapters/internal/BodyInfo.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.adapters.internal;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.adapters.IBodyInfo;
+import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+// XXX: currently hardcoded as sigleton implementation,
+// it is believed in the future will not use singleton, because we want to
+// dynamically
+// support other taglibs.
+public class BodyInfo implements IBodyInfo {
+ public static final BodyInfo _instance = new BodyInfo();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.adapters.IDesignInfo#isBodyContainer(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier)
+ */
+ public boolean isBodyContainer(IDOMNode node) {
+ switch (node.getNodeType()) {
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ case Node.DOCUMENT_NODE:
+ return true;
+ case Node.ELEMENT_NODE:
+ return isBodyContainerElement((Element) node);
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * @param element
+ * @return
+ */
+ private boolean isBodyContainerElement(Element element) {
+ String localname = element.getLocalName();
+ /*
+ * String namespaceURI = CMUtil.getElementNamespaceURI(element); if
+ * (IJMTConstants.URI_HTML.equals(namespaceURI)) { return
+ * "html".equalsIgnoreCase(localname) ||
+ * "body".equalsIgnoreCase(localname); } if
+ * (IJMTConstants.URI_JSF_CORE.equals(namespaceURI)) { return
+ * "view".equals(localname) || "subview".equals(localname); }
+ */
+ return IHTMLConstants.TAG_HTML.equalsIgnoreCase(localname)
+ || IHTMLConstants.TAG_BODY.equalsIgnoreCase(localname)
+ || IJSFConstants.TAG_VIEW.equals(localname)
+ || IJSFConstants.TAG_SUBVIEW.equals(localname);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.adapters.IDesignInfo#isBodyHeader(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * java.lang.String, java.lang.String)
+ */
+ public boolean isBodyHeader(IDOMNode node, String uri, String localname) {
+ switch (node.getNodeType()) {
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ case Node.DOCUMENT_NODE:
+ return isDocumentHeader(uri, localname);
+ case Node.ELEMENT_NODE:
+ return isElementHeader((Element) node, uri, localname);
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * @param element
+ * @param uri
+ * @param localname
+ * @return
+ */
+ private boolean isElementHeader(Element element, String uri,
+ String localname) {
+ String elelocalname = element.getLocalName();
+ String namespaceURI = CMUtil.getElementNamespaceURI(element);
+ if (IJMTConstants.URI_HTML.equals(namespaceURI)
+ && IHTMLConstants.TAG_HTML.equalsIgnoreCase(elelocalname)) {
+ return IHTMLConstants.TAG_HEAD.equalsIgnoreCase(localname);
+ }
+ if (IJMTConstants.URI_JSF_CORE.equals(namespaceURI)
+ && IJSFConstants.TAG_VIEW.equalsIgnoreCase(elelocalname)) {
+ return IJSFConstants.TAG_LOADBUNDLE.equalsIgnoreCase(localname);
+ }
+ return false;
+ }
+
+ /**
+ * @param uri
+ * @param localname
+ * @return
+ */
+ private boolean isDocumentHeader(String uri, String localname) {
+ // FIXME: temparary commented out, since the dragged node do not have
+ // uri information for now.
+ // if (IJMTConstants.URI_JSP.equals(uri))
+ return IJSPCoreConstants.TAG_DIRECTIVE_PAGE.equals(localname)
+ || IJSPCoreConstants.TAG_DIRECTIVE_TAGLIB.equals(localname);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ return (type == IBodyInfo.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ }
+
+ /**
+ * @return
+ */
+ public static IBodyInfo getInstance() {
+ return _instance;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CloneNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CloneNodeCommand.java
new file mode 100644
index 000000000..129208666
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CloneNodeCommand.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * This is when user control+mouse drag. Can also be used in other places.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class CloneNodeCommand extends DesignerCommand {
+ IDOMPosition _insertPosition;
+
+ Node _originalNode;
+
+ Node _resultNode;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public CloneNodeCommand(IHTMLGraphicalViewer viewer,
+ IDOMPosition insertionPoint, Node originalNode) {
+ super(
+ CommandResources.getString("CloneNodeCommand.Label.CloneNode"), viewer); //$NON-NLS-1$
+ this._insertPosition = insertionPoint;
+ this._originalNode = originalNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ Node newNode = DOMUtil.cloneNodeDeep(this.getDocument(), _originalNode);
+ DOMUtil.insertNode(_insertPosition, newNode);
+ _resultNode = newNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_resultNode);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.java
new file mode 100644
index 000000000..77e548964
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CommandResources {
+ private static final String BUNDLE_NAME = "org.eclipse.jst.pagedesigner.commands.CommandResources"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private CommandResources() {
+ }
+
+ public static String getString(String key) {
+ // TODO Auto-generated method stub
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.properties
new file mode 100644
index 000000000..0aef70ae1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CommandResources.properties
@@ -0,0 +1,22 @@
+PasteNodeCommand.Label.DeleteNode=Delete Node
+CutNodeCommand.Label.CutNode=Cut Node
+DeleteNodeCommand.Label.DeleteNode=Delete Node
+DeleteAction.CommandLabel.Delete=Delete
+TableDeleteColumnCommand.Label.DeleteColumn=Delete Column
+TableInsertColumnCommand.Label.InsertColumn=Insert Column
+TableResizeColumnCommand.Label.ResizeColumn=Resize Column
+TableResizeRowCommand.Label.ResizeColumn=Resize Column
+TableDeleteRowCommand.Label.DeleteRow=Delete Row
+TableInsertRowCommand.Label.InsertRow=Insert Row
+TableDeleteHeaderFooterCommand.Label.DeleteHeader=Delete Header
+TableDeleteHeaderFooterCommand.Label.DeleteFooter=Delete Footer
+TableInsertHeaderFooterCommand.Label.InsertHeader=Insert Header
+TableInsertHeaderFooterCommand.Label.InsertFooter=Insert Footer
+PasteCommand.Label.Paste=Paste
+DeleteCommand.Label.Delete=Delete
+CutCommand.Label.Cut=Cut
+CopyCommand.Label.Copy=Copy
+ApplyStyleCommand.Label.ApplyStyle=Apply Style
+ChangeStyleCommand.Label.ChangeStyle=Change Style
+MoveNodeCommand.Label.MoveNode=Move Node
+CloneNodeCommand.Label.CloneNode=Copy Node
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyAction.java
new file mode 100644
index 000000000..a40175c06
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyAction.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.ui.actions.UpdateAction;
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.range.CopyCommand;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class CopyAction extends DesignAction implements UpdateAction {
+ /**
+ * @param text
+ */
+ public CopyAction(GraphicalEditor editor) {
+ super(editor, PDPlugin.getResourceString("Action.Name.Copy"));//$NON-NLS-1$
+ // this.setAccelerator(SWT.CTRL | SWT.INSERT);
+ // this.setActionDefinitionId(ITextEditorActionDefinitionIds.CUT);
+ }
+
+ public void perform() {
+ DesignerCommand command = null;
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer.isInRangeMode()) {
+ command = new CopyCommand(viewer);
+ command.execute();
+ } else {
+ Command nodeCopy = new CopyNodeCommand(viewer);
+ nodeCopy.execute();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#isEnabled()
+ */
+ public boolean isEnabled() {
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer != null) {
+ if (viewer.isInRangeMode()
+ && !EditModelQuery.isSame(viewer.getRangeSelection())) {
+ return true;
+ } else if (!viewer.isInRangeMode()
+ && viewer.getSelectedEditParts().size() > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.actions.UpdateAction#update()
+ */
+ public void update() {
+ this.setEnabled(isEnabled());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyNodeCommand.java
new file mode 100644
index 000000000..6a2af3462
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CopyNodeCommand.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.w3c.dom.Node;
+
+/**
+ * As copy operation won't change anything in the current document, so it is not
+ * extending from DesignerCommand.
+ *
+ * @author mengbo
+ */
+public class CopyNodeCommand extends Command {
+ IHTMLGraphicalViewer _viewer;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public CopyNodeCommand(IHTMLGraphicalViewer viewer) {
+ super("");
+ this._viewer = viewer;
+ }
+
+ public IHTMLGraphicalViewer getViewer() {
+ return _viewer;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ public void execute() {
+ List parts = getViewer().getSelectedEditParts();
+ Vector result = new Vector();
+ if (parts.size() > 0) {
+ for (int i = 0, n = parts.size(); i < n; i++) {
+ EditPart part = (EditPart) parts.get(i);
+ Object model = part.getModel();
+ if (model instanceof Node) {
+ EditValidateUtil.validNode((Node) model);
+ result.add(((Node) model).cloneNode(true));
+ }
+ }
+ setClipboard(result);
+ }
+ }
+
+ private void setClipboard(Vector result) {
+ Node[] nodes = (Node[]) result.toArray(new Node[result.size()]);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, size = nodes.length; i < size; i++) {
+ DOMUtil.nodeToString(nodes[i], sb);
+ }
+ // TemplateTransfer.getInstance().setObject(result);
+ Clipboard board = new Clipboard(_viewer.getControl().getDisplay());
+ board.setContents(new Object[] { result, sb.toString() },
+ new Transfer[] { TemplateTransfer.getInstance(),
+ TextTransfer.getInstance() });
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CreateItemCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CreateItemCommand.java
new file mode 100644
index 000000000..444dfbb0a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CreateItemCommand.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.utils.CommandUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class CreateItemCommand extends DesignerCommand {
+ IDOMPosition _position;
+
+ IPaletteItemDescriptor _itemDescriptor;
+
+ Element _ele;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public CreateItemCommand(String label, IHTMLGraphicalViewer viewer,
+ IDOMPosition position, IPaletteItemDescriptor itemDesc) {
+ super(label, viewer);
+ this._position = position;
+ this._itemDescriptor = itemDesc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ Element element = CommandUtil.excuteInsertion(this._itemDescriptor,
+ getViewer(), this._position);
+ if (element != null) {
+ formatNode(element);
+ }
+ this._ele = element;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_ele);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutAction.java
new file mode 100644
index 000000000..82d5f02ed
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutAction.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.ui.actions.UpdateAction;
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.range.CutCommand;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class CutAction extends DesignAction implements UpdateAction {
+ /**
+ * @param text
+ */
+ public CutAction(GraphicalEditor editor) {
+ super(editor, PDPlugin.getResourceString("Action.Name.Cut"));//$NON-NLS-1$
+ }
+
+ public void perform() {
+ DesignerCommand command = null;
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer.isInRangeMode()) {
+ command = new CutCommand(viewer);
+ command.execute();
+ } else {
+ command = new CutNodeCommand(viewer);
+ command.execute();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#isEnabled()
+ */
+ public boolean isEnabled() {
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer != null) {
+ if (viewer.isInRangeMode()
+ && !EditModelQuery.isSame(viewer.getRangeSelection())) {
+ return true;
+ } else if (!viewer.isInRangeMode()
+ && viewer.getSelectedEditParts().size() > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.actions.UpdateAction#update()
+ */
+ public void update() {
+ setEnabled(isEnabled());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutNodeCommand.java
new file mode 100644
index 000000000..4627a7132
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/CutNodeCommand.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class CutNodeCommand extends DesignerCommand {
+ private static final String COMMAND_LABEL = CommandResources
+ .getString("CutNodeCommand.Label.CutNode"); //$NON-NLS-1$
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ List parts = getViewer().getSelectedEditParts();
+ Vector result = new Vector();
+ if (parts.size() > 0) {
+ for (int i = 0, n = parts.size(); i < n; i++) {
+ EditPart part = (EditPart) parts.get(i);
+ Object model = part.getModel();
+ if (model instanceof Node) {
+ EditValidateUtil.validNode((Node) model);
+ Node parent = ((Node) model).getParentNode();
+ model = parent.removeChild((Node) model);
+ result.add(model);
+ }
+ }
+ setClipboard(result);
+ }
+ }
+
+ protected ISelection getAfterCommandDesignerSelection() {
+ return null;
+ }
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public CutNodeCommand(IHTMLGraphicalViewer viewer) {
+ super(COMMAND_LABEL, viewer);
+ // TODO Auto-generated constructor stub
+ }
+
+ private void setClipboard(Vector result) {
+ Node[] nodes = (Node[]) result.toArray(new Node[result.size()]);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, size = nodes.length; i < size; i++) {
+ DOMUtil.nodeToString(nodes[i], sb);
+ }
+ // TemplateTransfer.getInstance().setObject(result);
+ Clipboard board = new Clipboard(_viewer.getControl().getDisplay());
+ board.setContents(new Object[] { result, sb.toString() },
+ new Transfer[] { TemplateTransfer.getInstance(),
+ TextTransfer.getInstance() });
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteAction.java
new file mode 100644
index 000000000..706b36ab2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteAction.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.jst.pagedesigner.commands.range.DeleteCommand;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class DeleteAction extends DesignAction {
+ public DeleteAction(GraphicalEditor editor) {
+ super(editor, CommandResources
+ .getString("DeleteAction.CommandLabel.Delete")); //$NON-NLS-1$
+ }
+
+ public void perform() {
+ DesignerCommand command = null;
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer.isInRangeMode()) {
+ command = new DeleteCommand(true, viewer);
+ command.execute();
+ } else {
+ command = new DeleteNodeCommand(viewer);
+ command.execute();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#isEnabled()
+ */
+ public boolean isEnabled() {
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer != null) {
+ if (viewer.isInRangeMode()
+ && !EditModelQuery.isSame(viewer.getRangeSelection())) {
+ return true;
+ } else if (!viewer.isInRangeMode()) {
+ int size = viewer.getSelectedEditParts().size();
+ if (size > 1) {
+ return true;
+ } else if (size == 1
+ && !(viewer.getSelectedEditParts().get(0) instanceof DocumentEditPart)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteNodeCommand.java
new file mode 100644
index 000000000..3e475914e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DeleteNodeCommand.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.parts.SubNodeEditPart;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class DeleteNodeCommand extends DesignerCommand {
+ private static final String COMMAND_LABEL = CommandResources
+ .getString("DeleteNodeCommand.Label.DeleteNode"); //$NON-NLS-1$
+
+ private DesignRange _prevRange;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public DeleteNodeCommand(IHTMLGraphicalViewer viewer) {
+ super(COMMAND_LABEL, viewer);
+ }
+
+ protected void preExecute() {
+ _prevRange = _viewer.getRangeSelection();
+ DesignPosition position = findObjectModePosition();
+ _prevRange = new DesignRange(position, position);
+ super.preExecute();
+ }
+
+ private DesignPosition findObjectModePosition() {
+ DesignPosition result = null;
+ IMovementMediator validator = new InlineEditingNavigationMediator(
+ new ActionData(ActionData.KEYBOARD_NAVAGATION, null));
+ DesignPosition position = getCurrentObjectPosition();
+ if (position != null) {
+ if (!validator.isValidPosition(position)) {
+ result = null;
+ } else {
+ result = position;
+ }
+ }
+ return result;
+ }
+
+ private DesignPosition getCurrentObjectPosition() {
+ DesignRange result = null;
+ if (_viewer.isInRangeMode()) {
+ result = _viewer.getRangeSelection();
+ } else {
+ List parts = _viewer.getSelectedEditParts();
+ if (parts.size() > 0) {
+ EditPart selection = (EditPart) parts.get(0);
+ if (selection instanceof SubNodeEditPart) {
+ DesignPosition position = new DesignRefPosition(selection,
+ false);
+ position = DOMPositionHelper.toDesignPosition(EditHelper
+ .ensureDOMPosition(DOMPositionHelper
+ .toDOMPosition(position)));
+ result = new DesignRange(position, position);
+ }
+ }
+ }
+ return result != null && result.isValid() ? result.getEndPosition()
+ : null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ List parts = getViewer().getSelectedEditParts();
+ for (int i = 0, n = parts.size(); i < n; i++) {
+ EditPart part = (EditPart) parts.get(i);
+ Object model = part.getModel();
+ if (model instanceof Node) {
+ EditValidateUtil.validNode((Node) model);
+ Node parent = ((Node) model).getParentNode();
+ model = parent.removeChild((Node) model);
+ }
+ }
+ }
+
+ protected ISelection getAfterCommandDesignerSelection() {
+ if (_prevRange.isValid()) {
+ return _prevRange;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignAction.java
new file mode 100644
index 000000000..c665553f4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignAction.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.ui.actions.UpdateAction;
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.editors.IDesignViewer;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public abstract class DesignAction extends Action implements UpdateAction {
+ private GraphicalEditor _editor;
+
+ public DesignAction(GraphicalEditor editor, String text) {
+ super(text);
+ _editor = editor;
+ }
+
+ /**
+ * @return Returns the _editor.
+ */
+ protected GraphicalEditor getEditor() {
+ return _editor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ perform();
+ // Since the parameters don't affect, so they could be null, may change
+ // in the future
+ _editor.selectionChanged(null, null);
+ }
+
+ abstract void perform();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.actions.UpdateAction#update()
+ */
+ public void update() {
+ setEnabled(isEnabled());
+ }
+
+ protected IHTMLGraphicalViewer getViewer() {
+ return ((IDesignViewer) _editor).getGraphicViewer();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignResizeComponentCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignResizeComponentCommand.java
new file mode 100644
index 000000000..08cc1af56
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignResizeComponentCommand.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.DefaultEditDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editparts.ScalableRootEditPart;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class DesignResizeComponentCommand extends Command {
+ private EditPart _part;
+
+ private Object _constraint;
+
+ private SourceViewer _viewer;
+
+ public DesignResizeComponentCommand(EditPart child, Object constraint) {
+ this._part = child;
+ this._constraint = constraint;
+ EditPart part = child;
+ if (part instanceof ScalableRootEditPart) {
+ } else {
+ while (part != null
+ && !(part.getParent() instanceof ScalableRootEditPart)) {
+ part = part.getParent();
+ }
+ }
+ if (part != null) {
+ EditPartViewer viewer = ((ScalableRootEditPart) part.getParent())
+ .getViewer();
+ HTMLEditor editor = ((HTMLEditor) ((DefaultEditDomain) ((HTMLGraphicalViewer) viewer)
+ .getEditDomain()).getEditorPart());
+ _viewer = editor.getTextEditor().getTextViewer();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void execute() {
+ Element element = ((Element) _part.getModel());
+ String width = element.getAttribute(ICSSPropertyID.ATTR_WIDTH);
+ // String height = element.getAttribute(ICSSPropertyID.ATTR_HEIGHT);
+ String originalStyle = element.getAttribute(ICSSPropertyID.ATTR_STYLE);
+ StringBuffer style;
+ if (originalStyle != null) {
+ originalStyle = this.removeOthers(originalStyle,
+ ICSSPropertyID.ATTR_WIDTH);
+ originalStyle = this.removeOthers(originalStyle,
+ ICSSPropertyID.ATTR_HEIGHT);
+ style = new StringBuffer(originalStyle);
+ } else {
+ style = new StringBuffer(50);
+ }
+ if (null == width) {
+ style.append(";").append(ICSSPropertyID.ATTR_WIDTH).append(":")
+ .append(((Rectangle) _constraint).width).append(";");
+ style.append(ICSSPropertyID.ATTR_HEIGHT).append(":").append(
+ ((Rectangle) _constraint).height).append("");
+ }
+ element.setAttribute(ICSSPropertyID.ATTR_STYLE, style.toString());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#redo()
+ */
+ public void redo() {
+ _viewer.doOperation(ITextOperationTarget.REDO);
+ }
+
+ public String removeOthers(String style, String item) {
+ String result = null;
+ int pos = style.indexOf(item);
+ if (pos < 0) {
+ return style;
+ }
+ int pos1 = pos;
+ if (pos > 0) {
+ if (style.charAt(pos - 1) == ';') {
+ pos--;
+ }
+ }
+ char ch = style.charAt(pos1);
+ while (!(ch == ';' || ch == '"' || ch == '\'')) {
+ pos1++;
+ if (pos1 >= style.length()) {
+ break;
+ }
+ ch = style.charAt(pos1);
+ }
+ if (pos1 < style.length()) {
+ result = style.substring(0, pos)
+ + style.substring(pos1 + 1, style.length());
+ } else {
+ result = style.substring(0, pos);
+ }
+ if (result.indexOf(item) >= 0) {
+ return removeOthers(result, item);
+ } else {
+ return result;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#undo()
+ */
+ public void undo() {
+ _viewer.doOperation(ITextOperationTarget.UNDO);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignerCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignerCommand.java
new file mode 100644
index 000000000..a05b785a0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/DesignerCommand.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.utils.SelectionHelper;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.html.core.internal.format.HTMLFormatProcessorImpl;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * This class is intended to be the base class for all designer GEF commands.
+ * Basically, it will wrap the real command with common actions like handle
+ * undo/redo, etc.
+ *
+ * @author mengbo
+ */
+public abstract class DesignerCommand extends Command {
+ private IDOMModel _model;
+
+ protected IHTMLGraphicalViewer _viewer;
+
+ private static final Logger _log = PDPlugin
+ .getLogger(DesignerCommand.class);
+
+ public DesignerCommand(String label, IHTMLGraphicalViewer viewer) {
+ super(label);
+ this._viewer = viewer;
+ this._model = viewer.getModel();
+ }
+
+ /**
+ * @param label
+ * @param node
+ * the node must be a node in the IHTMLGraphicalViewer.
+ */
+ public DesignerCommand(String label, IDOMNode node) {
+ super(label);
+ this._model = node.getModel();
+ IDOMDocument doc = (IDOMDocument) node.getOwnerDocument();
+
+ EditPart part = (EditPart) doc.getAdapterFor(EditPart.class);
+ if (part != null) {
+ this._viewer = (IHTMLGraphicalViewer) part.getViewer();
+ }
+ }
+
+ public IHTMLGraphicalViewer getViewer() {
+ return _viewer;
+ }
+
+ public IDOMModel getModel() {
+ return _model;
+ }
+
+ public IDOMDocument getDocument() {
+ return getModel().getDocument();
+ }
+
+ /**
+ * executes the Command. This method should not be called if the Command is
+ * not executable.
+ */
+ public final void execute() {
+ boolean ok = prePreExecute();
+ if (ok) {
+ try {
+ preExecute();
+ doExecute();
+ postExecute();
+ } catch (Exception ex) {
+ handleException(ex);
+ } finally {
+ postPostExecute();
+ }
+ }
+ }
+
+ /**
+ * child class can override.
+ *
+ * @param ex
+ */
+ protected void handleException(Exception ex) {
+ ex.printStackTrace();
+ }
+
+ /**
+ * prePreExecute and postPostExecute is a pair. prePreExecute() SHOULD NOT
+ * throw any exception, if it throw any exception, it should catch itself
+ * and return false to indicate not continue.
+ */
+ protected boolean prePreExecute() {
+ int position = -1;
+ int length = -1;
+ ISelection selection = getViewer().getSelection();
+ if (selection != null) {
+ if (getViewer().isInRangeMode()) {
+ DesignRange range = (DesignRange) selection;
+ if (range.isValid()) {
+ IDOMPosition domPos = DOMPositionHelper.toDOMPosition(range
+ .getStartPosition());
+ IDOMPosition domEnd = DOMPositionHelper.toDOMPosition(range
+ .getEndPosition());
+ if (EditValidateUtil.validPosition(domPos)
+ && EditValidateUtil.validPosition(domEnd)) {
+ position = EditModelQuery
+ .getIndexedRegionLocation(domPos);
+ int end = EditModelQuery
+ .getIndexedRegionLocation(domEnd);
+ if (end < position) {
+ length = position - end;
+ position = end;
+ } else {
+ length = end - position;
+ }
+ }
+ }
+ } else {
+ Object object = ((IStructuredSelection) selection)
+ .getFirstElement();
+ if (object instanceof ElementEditPart) {
+ Node node = ((ElementEditPart) object).getIDOMNode();
+ position = EditModelQuery.getNodeStartIndex(node);
+ length = EditModelQuery.getNodeLenth(node);
+ }
+ }
+ }
+ if (position >= 0 && length >= 0) {
+ getModel().beginRecording(this, getLabel(), position, length);
+ } else {
+ getModel().beginRecording(this, getLabel());
+ }
+ getViewer().startSelectionChange();
+ getModel().aboutToChangeModel();
+ return true;
+ }
+
+ /**
+ * child class can override this method for any pre action.
+ */
+ protected void preExecute() {
+ }
+
+ /**
+ * child class should override this method for the real action.
+ */
+ protected abstract void doExecute();
+
+ /**
+ * child class can override this method for any post action. NOTE: if
+ * preExecute() or doExecute() throw exception, then this method will NOT be
+ * called.
+ */
+ protected void postExecute() {
+ }
+
+ /**
+ * if prePreExecute() return true, then this method will always be called
+ * even preExecute()/doExecute() and postExecute() fail.
+ */
+ protected void postPostExecute() {
+ getModel().changedModel();
+
+ // after "changedModel()" is called, model will fire out batched events
+ // about model change
+ // and EditPart will be refreshed. Only at this time, could we use
+ // EditPart to construct the
+ // result selection.
+
+ // enforce a validate, so things get layed out, thus all the figures
+ // will be valid.
+ this.getViewer().getViewport().validate();
+
+ ISelection sel = getAfterCommandDesignerSelection();
+ if (sel != null) {
+ ITextSelection textSel = SelectionHelper
+ .convertFromDesignSelectionToTextSelection(sel);
+ if (textSel != null) {
+ getModel().endRecording(this, textSel.getOffset(),
+ textSel.getLength());
+ } else {
+ getModel().endRecording(this);
+ }
+ } else {
+ getModel().endRecording(this);
+ }
+
+ if (sel != null) {
+ getViewer().setSelection(sel);
+ } else {
+ getViewer().deselectAll();
+ }
+ if (getViewer() != null) {
+ getViewer().selectionChanged();
+ }
+ }
+
+ /**
+ * child class should override this method to provide the selection after
+ * command. This method is called after model changed. So at time of this
+ * call, the editpart should be valid. Default implementation.
+ *
+ * @return
+ */
+ protected abstract ISelection getAfterCommandDesignerSelection();
+
+ protected ISelection toDesignRange(DOMRange range) {
+ try {
+ if (range == null) {
+ return null;
+ }
+ IDOMPosition startPos = range.getStartPosition();
+ DesignPosition start = DOMPositionHelper.toDesignPosition(startPos);
+ if (range.isEmpty()) {
+ return new DesignRange(start, start);
+ } else {
+ IDOMPosition endPos = range.getEndPosition();
+ return new DesignRange(start, DOMPositionHelper
+ .toDesignPosition(endPos));
+ }
+ } catch (Exception e) {
+ // "Selection error"
+ _log.error("Error.RangeModeCommand.SetSelection"); //$NON-NLS-1$
+ return null;
+ }
+
+ }
+
+ protected IStructuredSelection toDesignSelection(Node node) {
+ if (node instanceof INodeNotifier) {
+ EditPart part = (EditPart) ((INodeNotifier) node)
+ .getAdapterFor(EditPart.class);
+ if (part != null) {
+ return new StructuredSelection(part);
+ }
+ }
+ return null;
+ }
+
+ //
+ // /**
+ // * set selection to the specified node. Normally called by child class in
+ // <code>setSelection()</code> implementation.
+ // *
+ // * @param node
+ // */
+ // protected final void setSelection(Node node)
+ // {
+ // EditPart part = (EditPart) ((INodeNotifier)
+ // node).getAdapterFor(EditPart.class);
+ //
+ // StructuredSelection sel = new StructuredSelection(part);
+ // getViewer().setSelection(sel);
+ // }
+
+ /**
+ * format the specified node in source code. Utility method that can be
+ * called by child classes
+ *
+ * @param node
+ */
+ public void formatNode(Node node) {
+ // XXX: there should have some other way to get the FormatProcessor.
+ // currently hardcoded to HTMLFormatProcessorImpl().
+ new HTMLFormatProcessorImpl().formatNode(node);
+ }
+
+ /**
+ * Re-executes the Command. This method should only be called after
+ * <code>undo()</code> has been called.
+ */
+ public void redo() {
+ // this method should in fact never be called, because we have already
+ // delegate undo
+ // operations to source view.
+ getModel().getUndoManager().redo();
+ }
+
+ /**
+ * Undoes the changes performed during <code>execute()</code>. This
+ * method should only be called after <code>execute</code> has been
+ * called, and only when <code>canUndo()</code> returns <code>true</code>.
+ *
+ * @see #canUndo()
+ */
+ public void undo() {
+ // this method should in fact never be called, because we have already
+ // delegate undo
+ // operations to source view.
+ getModel().getUndoManager().undo();
+ }
+
+ /**
+ * a utility method. NOTE: this method can ONLY be called BEFORE you change
+ * anything in the model.
+ *
+ * @param ele
+ * @return
+ */
+ public IFigure getFigureInfo(Element ele) {
+ if (ele instanceof IDOMElement) {
+ EditPart part = (EditPart) ((IDOMElement) ele)
+ .getAdapterFor(EditPart.class);
+ if (part instanceof GraphicalEditPart) {
+ return ((GraphicalEditPart) part).getFigure();
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/MoveNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/MoveNodeCommand.java
new file mode 100644
index 000000000..79c0cad55
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/MoveNodeCommand.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Move a node from one place to another place.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class MoveNodeCommand extends DesignerCommand {
+ IDOMPosition _insertPosition;
+
+ Node _originalNode;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public MoveNodeCommand(IHTMLGraphicalViewer viewer,
+ IDOMPosition insertionPoint, Node originalNode) {
+ super(
+ CommandResources.getString("MoveNodeCommand.Label.MoveNode"), viewer); //$NON-NLS-1$
+ this._insertPosition = insertionPoint;
+ this._originalNode = originalNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ Node originalParent = _originalNode.getParentNode();
+ if (originalParent == null) {
+ return;
+ }
+ // when remove the _originalNode, may affect the insertionPosition.
+ if (originalParent == _insertPosition.getContainerNode()) {
+ // under same parent, may affect it.
+ int insertIndex = _insertPosition.getOffset();
+ int nodeIndex = -1;
+ NodeList list = originalParent.getChildNodes();
+ for (int i = 0, length = list.getLength(); i < length; i++) {
+ if (_originalNode == list.item(i)) {
+ nodeIndex = i;
+ }
+ }
+ if (nodeIndex == -1) {
+ return; // should not happen.
+ }
+ if (insertIndex < nodeIndex) {
+ _insertPosition = new DOMPosition(originalParent, insertIndex);
+ } else if (insertIndex == nodeIndex || insertIndex == nodeIndex + 1) {
+ // move to same position, do nothing.
+ return;
+ } else {
+ _insertPosition = new DOMPosition(originalParent,
+ insertIndex - 1);
+ }
+ }
+ originalParent.removeChild(_originalNode);
+ DOMUtil.insertNode(_insertPosition, _originalNode);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_originalNode);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDDropRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDDropRequest.java
new file mode 100644
index 000000000..7a194beff
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDDropRequest.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.requests.DropRequest;
+import org.eclipse.swt.dnd.DropTargetEvent;
+
+/**
+ * @author mengbo
+ */
+public class PDDropRequest extends Request implements DropRequest {
+ private Point _location;
+
+ private DropTargetEvent _currentEvent;
+
+ /**
+ *
+ */
+ public PDDropRequest() {
+ setType(PDRequestConstants.REQ_DROP);
+ }
+
+ /**
+ * Returns the location of the object to be created.
+ *
+ * @return the location
+ */
+ public Point getLocation() {
+ return _location;
+ }
+
+ /**
+ * Sets the location where the new object will be placed.
+ *
+ * @param location
+ * the location
+ */
+ public void setLocation(Point location) {
+ this._location = location;
+ }
+
+ public void setCurrentEvent(DropTargetEvent ev) {
+ _currentEvent = ev;
+ }
+
+ public DropTargetEvent getCurrentEvent() {
+ return _currentEvent;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDRequestConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDRequestConstants.java
new file mode 100644
index 000000000..181d6243f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDRequestConstants.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+/**
+ * @author mengbo
+ */
+public interface PDRequestConstants {
+
+ String REQ_DROP = "pd drop";
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDTransferDropTargetListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDTransferDropTargetListener.java
new file mode 100644
index 000000000..772b0312a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PDTransferDropTargetListener.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.dnd.AbstractTransferDropTargetListener;
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemCreationRequest;
+import org.eclipse.swt.dnd.Transfer;
+
+/**
+ * @author mengbo
+ */
+public class PDTransferDropTargetListener extends
+ AbstractTransferDropTargetListener {
+ /**
+ * @param viewer
+ * @param xfer
+ */
+ public PDTransferDropTargetListener(EditPartViewer viewer, Transfer xfer) {
+ super(viewer, xfer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ ItemCreationRequest request = new ItemCreationRequest();
+ PaletteItemDescriptor itemDescriptor = (PaletteItemDescriptor) TemplateTransfer
+ .getInstance().getObject();
+ request.setItemDescriptor(itemDescriptor);
+ request.setLocation(getDropLocation());
+ return request;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#updateTargetRequest()
+ */
+ protected void updateTargetRequest() {
+ ItemCreationRequest request = (ItemCreationRequest) getTargetRequest();
+ PaletteItemDescriptor itemDescriptor = (PaletteItemDescriptor) TemplateTransfer
+ .getInstance().getObject();
+ request.setItemDescriptor(itemDescriptor);
+ request.setLocation(getDropLocation());
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PaletteDropInsertCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PaletteDropInsertCommand.java
new file mode 100644
index 000000000..1fd716c07
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PaletteDropInsertCommand.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dnd.internal.SourceViewerDragDropHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.dom.JSFValidatorSupport;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.utils.CommandUtil;
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class PaletteDropInsertCommand extends SourceViewerCommand {
+ private final Logger _log = PDPlugin
+ .getLogger(PaletteDropInsertCommand.class);
+
+ private PaletteItemDescriptor _descriptor;
+
+ private int _location;
+
+ private List _nodesToFormat = new ArrayList();
+
+ private Element _element;
+
+ public PaletteDropInsertCommand(String label, StructuredTextEditor editor,
+ PaletteItemDescriptor descriptor, int location) {
+ super(label, editor);
+ _descriptor = descriptor;
+ _location = location;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void doExecute() {
+ IDOMModel model = getModel();
+ try {
+ Node node = getSourceEditingTextTools().getNode(_location);
+ IDOMPosition position = null;
+ if (node != null) {
+ position = SourceViewerDragDropHelper.getInstance()
+ .findPosition(_location, node);
+ } else {
+ // empty file
+ position = new DOMPosition(getModel().getDocument(), 0);
+ }
+ Assert.isTrue(position != null);
+ if (!_descriptor.getURI().equalsIgnoreCase(IJMTConstants.URI_HTML)
+ && //
+ !_descriptor.getURI().equalsIgnoreCase(
+ IJMTConstants.URI_JSP)) {
+ position = JSFValidatorSupport.prepareView(position);
+ }
+ _element = CommandUtil
+ .excuteInsertion(_descriptor, model, position);
+ if (_element != null) {
+ _nodesToFormat.add(_element);
+ SourceViewerDragDropHelper.getInstance().changeCaret(_editor,
+ true);
+ formatNodes();
+ }
+ } catch (Exception e) {
+ _log.error("Bad text insertion location", e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.requests.NodeCreationFactory#getPrefix(int)
+ */
+ public String getPrefix(String uri, IDOMModel model, String suggested,
+ Node nodes[]) {
+ if (IJMTConstants.URI_HTML.equals(uri)
+ || IJMTConstants.URI_JSP.equals(uri)) {
+ return null;
+ }
+
+ // now handles custom tag lib
+
+ return JSPUtil.getOrCreatePrefix(model, uri, suggested, nodes);
+ }
+
+ public void setSelection() {
+ if (_element != null) {
+ int offset = EditModelQuery.getNodeStartIndex(_element);
+ int length = EditModelQuery.getNodeEndIndex(_element) - offset;
+ _editor.getTextViewer().setSelectedRange(offset, length);
+ }
+ }
+
+ private void formatNodes() {
+ for (int i = 0, n = _nodesToFormat.size(); i < n; i++) {
+ formatNode((Node) _nodesToFormat.get(i));
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteAction.java
new file mode 100644
index 000000000..287a3de9c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteAction.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.range.PasteCommand;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+
+/**
+ * @author mengbo
+ */
+public class PasteAction extends DesignAction {
+
+ /**
+ * @param text
+ */
+ public PasteAction(GraphicalEditor editor) {
+ super(editor, PDPlugin.getResourceString("Action.Name.Paste"));//$NON-NLS-1$
+ }
+
+ public void perform() {
+ DesignerCommand command = null;
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer.isInRangeMode()) {
+ command = new PasteCommand(viewer);
+ command.execute();
+ } else {
+ return;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#isEnabled()
+ */
+ public boolean isEnabled() {
+ IHTMLGraphicalViewer viewer = getViewer();
+ if (viewer != null && viewer.isInRangeMode()
+ && viewer.getRangeSelection().isValid()) {
+ Clipboard clipboard = new Clipboard(viewer.getControl()
+ .getDisplay());
+ return clipboard.getContents(TemplateTransfer.getInstance()) != null
+ || clipboard.getContents(TextTransfer.getInstance()) != null;
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteNodeCommand.java
new file mode 100644
index 000000000..7dd9e40ce
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/PasteNodeCommand.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jst.pagedesigner.commands.nav.ICaretPositionMover;
+import org.eclipse.wst.html.core.internal.document.ElementStyleImpl;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class PasteNodeCommand extends Command implements ICaretPositionMover {
+ private static final String COMMAND_LABEL = CommandResources
+ .getString("PasteNodeCommand.Label.DeleteNode"); //$NON-NLS-1$
+
+ private Node child;
+
+ private SourceViewer _sourceViewer;
+
+ public PasteNodeCommand(SourceViewer viewer) {
+ super(COMMAND_LABEL);
+ this._sourceViewer = viewer;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void execute() {
+ _sourceViewer.getTextWidget().setSelection(
+ ((ElementStyleImpl) child).getStartOffset(),
+ ((ElementStyleImpl) child).getStartOffset());
+ _sourceViewer.doOperation(ITextOperationTarget.PASTE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#redo()
+ */
+ public void redo() {
+ _sourceViewer.doOperation(ITextOperationTarget.REDO);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#undo()
+ */
+ public void undo() {
+ _sourceViewer.doOperation(ITextOperationTarget.UNDO);
+
+ }
+
+ /**
+ * @param child
+ * The child to set.
+ */
+ public void setChild(Node child) {
+ this.child = child;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SourceViewerCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SourceViewerCommand.java
new file mode 100644
index 000000000..f9eceb47f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SourceViewerCommand.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.wst.html.core.internal.format.HTMLFormatProcessorImpl;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.ui.internal.provisional.IDOMSourceEditingTextTools;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public abstract class SourceViewerCommand extends Command {
+ protected StructuredTextEditor _editor;
+
+ private Document _document;
+
+ private Logger _log = PDPlugin.getLogger(SourceViewerCommand.class);
+
+ /**
+ *
+ */
+ public SourceViewerCommand(String label, StructuredTextEditor editor) {
+ super();
+ _editor = editor;
+ IDOMSourceEditingTextTools tools = getSourceEditingTextTools();
+ _document = tools.getDOMDocument();
+ }
+
+ protected IDOMSourceEditingTextTools getSourceEditingTextTools() {
+ IDOMSourceEditingTextTools tools = (IDOMSourceEditingTextTools) _editor
+ .getAdapter(ISourceEditingTextTools.class);
+ return tools;
+ }
+
+ /**
+ * preExecute and postExecute is a pair. () SHOULD NOT throw any exception,
+ * if it throw any exception, it should catch itself and return false to
+ * indicate not continue.
+ */
+ protected final boolean preExecute() {
+ int position = 0;
+ int length = 0;
+ ISelection selection = _editor.getTextViewer().getSelection();
+ if (selection instanceof TextSelection) {
+ position = ((TextSelection) selection).getOffset();
+ length = ((TextSelection) selection).getLength();
+ }
+ getModel().beginRecording(this, getLabel(), position, length);
+ getModel().aboutToChangeModel();
+ return true;
+ }
+
+ /**
+ * if preExecute() return true, then this method will always be called even
+ * preExecute()/doExecute() and postExecute() fail.
+ */
+ protected final void postExecute() {
+ getModel().changedModel();
+ getModel().endRecording(this);
+ setSelection();
+ }
+
+ /**
+ * format the specified node in source code. Utility method that can be
+ * called by child classes
+ *
+ * @param node
+ */
+ public final void formatNode(Node node) {
+ new HTMLFormatProcessorImpl().formatNode(node);
+ }
+
+ protected IDOMModel getModel() {
+ Assert.isTrue(_document != null && _document instanceof IDOMNode);
+ return ((IDOMNode) _document).getModel();
+ }
+
+ public final void execute() {
+ boolean ok = preExecute();
+ if (ok) {
+ try {
+ doExecute();
+ } catch (Exception ex) {
+ // "Error in command execution"
+ _log.error("Error.SourceViewerCommand.Execution", ex); //$NON-NLS-1$
+ } finally {
+ postExecute();
+ }
+ }
+ }
+
+ public abstract void doExecute();
+
+ public abstract void setSelection();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SwitchSelectionCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SwitchSelectionCommand.java
new file mode 100644
index 000000000..fced2484b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/SwitchSelectionCommand.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands;
+
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.parts.SubNodeEditPart;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class SwitchSelectionCommand extends Command {
+ IHTMLGraphicalViewer _viewer;
+
+ public SwitchSelectionCommand(IHTMLGraphicalViewer viewer) {
+ _viewer = viewer;
+ }
+
+ public void execute() {
+ if (_viewer.isInRangeMode()) {
+ ISelection selection = _viewer.getSelection();
+ if (selection instanceof DesignRange) {
+ DesignPosition posStart = ((DesignRange) selection)
+ .getStartPosition();
+ DesignPosition posEnd = ((DesignRange) selection)
+ .getEndPosition();
+ if (EditValidateUtil.validPosition(posStart)
+ && EditValidateUtil.validPosition(posEnd)) {
+ Node ancestor = EditModelQuery.getInstance()
+ .getCommonAncestor(posStart.getContainerNode(),
+ posEnd.getContainerNode());
+ if (ancestor instanceof Text) {
+ ancestor = ancestor.getParentNode();
+ }
+ if (ancestor instanceof Element) {
+ EditPart part = Target.resolvePart(ancestor);
+ if (part instanceof SubNodeEditPart) {
+ _viewer.select(part);
+ }
+ }
+ }
+ }
+ } else {
+ List parts = _viewer.getSelectedEditParts();
+ if (parts.size() > 0) {
+ EditPart parent = ((EditPart) parts.get(0)).getParent();
+ if (!(parent instanceof DocumentEditPart)) {
+ _viewer.select(parent);
+ }
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteColumnCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteColumnCommand.java
new file mode 100644
index 000000000..d9ba50d3d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteColumnCommand.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableDeleteColumnCommand extends DesignerCommand {
+ private Element _tableEle;
+
+ private int _columnIndex;
+
+ private TableUtil _tableUtil;
+
+ /**
+ * @param viewer
+ * @param dataTable
+ * @param index
+ */
+ public TableDeleteColumnCommand(IHTMLGraphicalViewer viewer,
+ Element dataTable, int index) {
+ super(
+ CommandResources
+ .getString("TableDeleteColumnCommand.Label.DeleteColumn"), viewer); //$NON-NLS-1$
+ this._tableEle = dataTable;
+ this._columnIndex = index;
+ this._tableUtil = new TableUtil(this._tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ if (this._columnIndex < 0) {
+ return false;
+ }
+ boolean hasColSpan = _tableUtil.hasColumnSpanElement(this._columnIndex);
+ boolean isAffectedByColSpan = _tableUtil
+ .isAffectedByColSpan(this._columnIndex);
+ if (hasColSpan || isAffectedByColSpan) {
+ return false;
+ }
+
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ List trList = new ArrayList();
+ TableUtil.getTrElements(this._tableEle, trList);
+
+ List[] lists = _tableUtil.getTrCellLists();
+
+ for (int i = 0, size = trList.size(); i < size; i++) {
+ Element tr = (Element) trList.get(i);
+ List cells = lists[i];
+ if (cells.size() <= this._columnIndex) {
+ continue;
+ }
+ Element cell = (Element) cells.get(this._columnIndex);
+ if (!cell.getTagName().equalsIgnoreCase("fake")) //$NON-NLS-1$
+ {
+ tr.removeChild(cell);
+ }
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteHeaderFooterCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteHeaderFooterCommand.java
new file mode 100644
index 000000000..31248a9e8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteHeaderFooterCommand.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableDeleteHeaderFooterCommand extends DesignerCommand {
+ private Element _table;
+
+ private boolean _isHeader;
+
+ public TableDeleteHeaderFooterCommand(IHTMLGraphicalViewer viewer,
+ Element table, boolean isHeader) {
+ super(
+ isHeader ? CommandResources
+ .getString("TableDeleteHeaderFooterCommand.Label.DeleteHeader") : CommandResources.getString("TableDeleteHeaderFooterCommand.Label.DeleteFooter"), viewer); //$NON-NLS-1$ //$NON-NLS-2$
+ this._table = table;
+ this._isHeader = isHeader;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ String sectionName = this._isHeader ? IHTMLConstants.TAG_THEAD
+ : IHTMLConstants.TAG_TFOOT;
+ int rows = TableUtil.countSectionRows(this._table, sectionName);
+ if (rows == 0) {
+ return false;
+ }
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ String sectionName = this._isHeader ? IHTMLConstants.TAG_THEAD
+ : IHTMLConstants.TAG_TFOOT;
+ List list = DOMUtil.getChildElementsByTagIgnoreCase(this._table,
+ sectionName);
+ Node delNode = (Node) list.get(0);
+ this._table.removeChild(delNode);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return this.toDesignSelection(this._table);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteRowCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteRowCommand.java
new file mode 100644
index 000000000..3ee5ea733
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableDeleteRowCommand.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableDeleteRowCommand extends DesignerCommand {
+ Element _tableEle;
+
+ int _rowIndex;
+
+ /**
+ * @param viewer
+ * @param table
+ * @param index
+ */
+ public TableDeleteRowCommand(IHTMLGraphicalViewer viewer, Element table,
+ int index) {
+ super(CommandResources
+ .getString("TableDeleteRowCommand.Label.DeleteRow"), viewer); //$NON-NLS-1$
+ this._tableEle = table;
+ this._rowIndex = index;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ if (this._rowIndex < 0) {
+ return false;
+ }
+ List list = new ArrayList();
+ TableUtil.getTrElements(this._tableEle, list);
+ // int index = TableUtil.countRowIndexInDOMTree(this._tableEle,
+ // this._rowIndex);
+ int index = this._rowIndex;
+ Element tr = (Element) list.get(index);
+ boolean hasRowSpan = TableUtil.hasRowSpanElement(tr);
+ boolean isAffectedByRowSpan = TableUtil.isAffectedByRowSpan(list, tr,
+ index);
+ if (hasRowSpan || isAffectedByRowSpan) {
+ return false;
+ }
+
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ List list = new ArrayList();
+ TableUtil.getTrElements(this._tableEle, list);
+ // int index = TableUtil.countRowIndexInDOMTree(this._tableEle,
+ // this._rowIndex);
+ int index = this._rowIndex;
+ Element tr = (Element) list.get(index);
+ tr.getParentNode().removeChild(tr);
+ formatNode(this._tableEle);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertColumnCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertColumnCommand.java
new file mode 100644
index 000000000..4db65c888
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertColumnCommand.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableInsertColumnCommand extends DesignerCommand {
+ private Element _tableEle;
+
+ private int _columnIndex;
+
+ private TableUtil _tableUtil;
+
+ /**
+ * @param viewer
+ * @param dataTable
+ * @param index
+ */
+ public TableInsertColumnCommand(IHTMLGraphicalViewer viewer,
+ Element dataTable, int index) {
+ super(
+ CommandResources
+ .getString("TableInsertColumnCommand.Label.InsertColumn"), viewer); //$NON-NLS-1$
+ this._tableEle = dataTable;
+ this._columnIndex = index;
+ this._tableUtil = new TableUtil(this._tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ if (this._columnIndex < 0) {
+ return false;
+ }
+ boolean isAffectedByColSpan = _tableUtil
+ .isAffectedByColSpan(this._columnIndex);
+ if (isAffectedByColSpan) {
+ return false;
+ }
+
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ List trList = new ArrayList();
+ TableUtil.getTrElements(this._tableEle, trList);
+
+ List[] lists = _tableUtil.getTrCellLists();
+ int maxColumn = _tableUtil.getColumnCount();
+
+ boolean isAtLastColumn = false;
+ if (this._columnIndex >= maxColumn) {
+ isAtLastColumn = true;
+ }
+
+ for (int i = 0, size = trList.size(); i < size; i++) {
+ Element tr = (Element) trList.get(i);
+ boolean hasTH = (DOMUtil.getChildElementsByTagIgnoreCase(tr,
+ IHTMLConstants.TAG_TH).size() > 0);
+
+ List cells = lists[i];
+ if (isAtLastColumn || (cells.size() <= this._columnIndex)) {
+ int index = this._columnIndex + 1;
+ for (int k = cells.size(); k < index; k++) {
+ tr.appendChild(createDefaultElement(hasTH));
+ }
+ } else {
+ Element cell = (Element) cells.get(this._columnIndex);
+ if (!cell.getTagName().equalsIgnoreCase("fake")) //$NON-NLS-1$
+ {
+ tr.insertBefore(createDefaultElement(hasTH), cell);
+ } else {
+ boolean hasRealElement = false;
+ for (int k = _columnIndex + 1; k < cells.size(); k++) {
+ Element td = (Element) cells.get(k);
+ if (!td.getTagName().equalsIgnoreCase("fake")) //$NON-NLS-1$
+ {
+ hasRealElement = true;
+ tr.insertBefore(createDefaultElement(hasTH), td);
+ break;
+ }
+ }
+ if (!hasRealElement) {
+ tr.appendChild(createDefaultElement(hasTH));
+ }
+ }
+ }
+
+ }
+ formatNode(this._tableEle);
+ }
+
+ private Element createDefaultElement(boolean createTH) {
+ Document doc = this._tableEle.getOwnerDocument();
+ Element td = null;
+ if (createTH) {
+ td = doc.createElement(IHTMLConstants.TAG_TH);
+ } else {
+ td = doc.createElement(IHTMLConstants.TAG_TD);
+ }
+
+ Node node = doc.createTextNode(""); //$NON-NLS-1$
+ td.appendChild(node);
+ return td;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertHeaderFooterCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertHeaderFooterCommand.java
new file mode 100644
index 000000000..49b33b526
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertHeaderFooterCommand.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableInsertHeaderFooterCommand extends DesignerCommand {
+ private Element _table;
+
+ private Element _headerOrFooter;
+
+ private boolean _isHeader;
+
+ private TableUtil _tableUtil;
+
+ public TableInsertHeaderFooterCommand(IHTMLGraphicalViewer viewer,
+ Element table, boolean isHeader) {
+ super(
+ isHeader ? CommandResources
+ .getString("TableInsertHeaderFooterCommand.Label.InsertHeader") : CommandResources.getString("TableInsertHeaderFooterCommand.Label.InsertFooter"), viewer); //$NON-NLS-1$ //$NON-NLS-2$
+ this._table = table;
+ this._isHeader = isHeader;
+ this._tableUtil = new TableUtil(this._table);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ String sectionName = this._isHeader ? IHTMLConstants.TAG_THEAD
+ : IHTMLConstants.TAG_TFOOT;
+ int rows = TableUtil.countSectionRows(this._table, sectionName);
+ if (rows > 0) {
+ return false;
+ }
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ String sectionName = this._isHeader ? IHTMLConstants.TAG_THEAD
+ : IHTMLConstants.TAG_TFOOT;
+ this._headerOrFooter = this._table.getOwnerDocument().createElement(
+ sectionName);
+ Element tr = createDefaultElement();
+ this._headerOrFooter.appendChild(tr);
+ if (this._isHeader) {
+ Node child = this._table.getFirstChild();
+ this._table.insertBefore(this._headerOrFooter, child);
+ } else {
+ int headRows = TableUtil.countSectionRows(this._table,
+ IHTMLConstants.TAG_THEAD);
+ Node refNode = null;
+ if (headRows > 0) {
+ List list = DOMUtil.getChildElementsByTagIgnoreCase(
+ this._table, IHTMLConstants.TAG_THEAD);
+ Node header = (Node) list.get(0);
+ refNode = header.getNextSibling();
+ } else {
+ refNode = this._table.getFirstChild();
+ }
+ this._table.insertBefore(this._headerOrFooter, refNode);
+ }
+ formatNode(this._headerOrFooter);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return this.toDesignSelection(this._headerOrFooter);
+ }
+
+ private Element createDefaultElement() {
+ String key = this._isHeader ? "TableInsertHeaderFooterCommand.ColumnHeader" //$NON-NLS-1$
+ : "TableInsertHeaderFooterCommand.ColumnFooter"; //$NON-NLS-1$
+ String name = PDPlugin.getResourceString(key);
+ Document doc = this._table.getOwnerDocument();
+ Element ele = doc.createElement(IHTMLConstants.TAG_TR);
+ int columnCount = _tableUtil.getColumnCount();
+ for (int i = 0; i < columnCount; i++) {
+ Element td = null;
+ if (this._isHeader) {
+ td = doc.createElement(IHTMLConstants.TAG_TH);
+ } else {
+ td = doc.createElement(IHTMLConstants.TAG_TD);
+ }
+ Node node = doc.createTextNode(name);
+ td.appendChild(node);
+ ele.appendChild(td);
+ }
+ return ele;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertRowCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertRowCommand.java
new file mode 100644
index 000000000..d725b3178
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableInsertRowCommand.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableInsertRowCommand extends DesignerCommand {
+ private Element _tableEle;
+
+ private int _rowIndex;
+
+ private boolean _isBefore;
+
+ private TableUtil _tableUtil;
+
+ /**
+ * @param viewer
+ * @param table
+ * @param index
+ */
+ public TableInsertRowCommand(IHTMLGraphicalViewer viewer, Element table,
+ int index, boolean isBefore) {
+ super(CommandResources
+ .getString("TableInsertRowCommand.Label.InsertRow"), viewer); //$NON-NLS-1$
+ this._tableEle = table;
+ this._rowIndex = index;
+ this._isBefore = isBefore;
+ this._tableUtil = new TableUtil(this._tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ if (this._rowIndex < 0) {
+ return false;
+ }
+ List list = new ArrayList();
+ TableUtil.getTrElements(this._tableEle, list);
+ // if the row neither at the beginning nor the end then count
+ if (_rowIndex > 0 && _rowIndex < list.size()) {
+ // int index = TableUtil.countRowIndexInDOMTree(this._tableEle,
+ // this._rowIndex);
+ int index = this._rowIndex;
+ Element tr = (Element) list.get(index);
+ boolean isAffectedByRowSpan = TableUtil.isAffectedByRowSpan(list,
+ tr, index);
+ if (isAffectedByRowSpan) {
+ return false;
+ }
+
+ }
+
+ return super.canExecute();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_tableEle);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ List list = new ArrayList();
+ TableUtil.getTrElements(this._tableEle, list);
+ Element insertElement = createDefaultElement();
+
+ if (this._rowIndex < list.size()) {
+ // int index = TableUtil.countRowIndexInDOMTree(this._tableEle,
+ // this._rowIndex);
+ int index = this._rowIndex;
+ Element tr = (Element) list.get(index);
+ Element nextTr = tr;
+
+ // int headRows = TableUtil.countSectionRows(this._tableEle,
+ // IHTMLConstants.TAG_THEAD);
+ // int footRows = TableUtil.countSectionRows(this._tableEle,
+ // IHTMLConstants.TAG_TFOOT);
+ if (!_isBefore) {
+ int parentIndex = index - 1;
+ /**
+ * doesn't need any more,since the row index is from model now
+ * int bodyRows = list.size() - headRows - footRows; boolean
+ * hasBodyRow = false; boolean hasFootRow = false; if (bodyRows >
+ * 0) { hasBodyRow = true; } if (footRows > 0) { hasFootRow =
+ * true; } //last row in THEAD excute insert row after command
+ * if ((this._rowIndex == headRows) && hasBodyRow && hasFootRow) {
+ * parentIndex = index - footRows - 1; } //last row in TBODY
+ * excute insert row after command if ((this._rowIndex ==
+ * (list.size() - footRows)) && hasBodyRow && hasFootRow) {
+ * parentIndex = list.size() - 1; }
+ */
+
+ tr = (Element) list.get(parentIndex);
+ }
+
+ if (tr.getParentNode() == nextTr.getParentNode()) {
+ tr.getParentNode().insertBefore(insertElement, nextTr);
+ } else {
+ tr.getParentNode().appendChild(insertElement);
+ }
+ } else {
+ // int index = TableUtil.countRowIndexInDOMTree(this._tableEle,
+ // this._rowIndex - 1);
+ int index = this._rowIndex - 1;
+ Element tr = (Element) list.get(index);
+ tr.getParentNode().insertBefore(insertElement, null);
+ }
+ formatNode(this._tableEle);
+
+ }
+
+ private Element createDefaultElement() {
+ Document doc = this._tableEle.getOwnerDocument();
+ Element ele = doc.createElement(IHTMLConstants.TAG_TR);
+ int columnCount = _tableUtil.getColumnCount();
+ for (int i = 0; i < columnCount; i++) {
+ Element td = doc.createElement(IHTMLConstants.TAG_TD);
+ Node node = doc.createTextNode(""); //$NON-NLS-1$
+ td.appendChild(node);
+ ele.appendChild(td);
+ }
+ return ele;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeColumnCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeColumnCommand.java
new file mode 100644
index 000000000..f4e8b823f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeColumnCommand.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.dom.DOMStyleUtil;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableResizeColumnCommand extends DesignerCommand {
+ private Element _table;
+
+ private TableUtil _tableUtil;
+
+ private int _columnIndex;
+
+ private int _delta;
+
+ public TableResizeColumnCommand(IHTMLGraphicalViewer viewer, Element table,
+ int columnIndex, int delta) {
+ super(
+ CommandResources
+ .getString("TableResizeColumnCommand.Label.ResizeColumn"), viewer); //$NON-NLS-1$
+ this._table = table;
+ this._columnIndex = columnIndex;
+ this._delta = delta;
+ _tableUtil = new TableUtil(this._table);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(_table);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ int index = this._columnIndex - 1;
+ if (index < 0) {
+ index = 0;
+ }
+ List list = _tableUtil.getColumnCells(index);
+ Iterator itr = list.iterator();
+ Element cell = null;
+ while (itr.hasNext()) {
+ Element ele = (Element) itr.next();
+ if (ele.getTagName().equalsIgnoreCase("fake") || DOMUtil.getIntAttributeIgnoreCase(ele, IHTMLConstants.ATTR_COLSPAN, 1) > 1) //$NON-NLS-1$
+ {
+ continue;
+ }
+ cell = ele;
+ break;
+ }
+
+ IFigure cellFigure = getFigureInfo(cell);
+ int oldColumnWidth = cellFigure.getBounds().width;
+ int cellPadding = cellFigure.getInsets().getWidth();
+ int newWidth = oldColumnWidth + this._delta - cellPadding;
+ if (this._columnIndex - 1 < 0) {
+ newWidth = oldColumnWidth - this._delta - cellPadding;
+ }
+ Map map = new HashMap();
+ if (newWidth > 0) {
+ map.put(ICSSPropertyID.ATTR_WIDTH, newWidth + "px"); //$NON-NLS-1$
+ DOMStyleUtil.insertStyle(cell, map);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeRowCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeRowCommand.java
new file mode 100644
index 000000000..19db48b6d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/html/TableResizeRowCommand.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.html;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.dom.DOMStyleUtil;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableResizeRowCommand extends DesignerCommand {
+ private Element _table;
+
+ private int _rowIndex;
+
+ private int _delta;
+
+ public TableResizeRowCommand(IHTMLGraphicalViewer viewer, Element table,
+ int rowIndex, int delta) {
+ super(CommandResources
+ .getString("TableResizeRowCommand.Label.ResizeColumn"), viewer); //$NON-NLS-1$
+ this._table = table;
+ this._rowIndex = rowIndex;
+ this._delta = delta;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected ISelection getAfterCommandDesignerSelection() {
+ return toDesignSelection(this._table);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ int index = this._rowIndex - 1;
+ if (index < 0) {
+ index = 0;
+ }
+ // int domIndex = TableUtil.countRowIndexInDOMTree(this._table, index);
+ int domIndex = index;
+
+ List list = new ArrayList();
+ TableUtil.getTrElements(this._table, list);
+ Element tr = (Element) list.get(domIndex);
+
+ IFigure cellFigure = getFigureInfo(tr);
+ int oldRowHeight = cellFigure.getBounds().height;
+ int cellPadding = cellFigure.getInsets().getHeight();
+ int newHeight = oldRowHeight + this._delta - cellPadding;
+ if (this._rowIndex - 1 < 0) {
+ newHeight = oldRowHeight - this._delta - cellPadding;
+ }
+ Map map = new HashMap();
+ if (newHeight > 0) {
+ map.put(ICSSPropertyID.ATTR_HEIGHT, newHeight + "px"); //$NON-NLS-1$ //$NON-NLS-2$
+ DOMStyleUtil.insertStyle(tr, map);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/CaretPositionTracker.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/CaretPositionTracker.java
new file mode 100644
index 000000000..729521087
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/CaretPositionTracker.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.nav;
+
+/**
+ * @author mengbo
+ */
+public interface CaretPositionTracker {
+ /**
+ * @return Returns the xoffset.
+ */
+ public int getXoffset();
+
+ /**
+ * @param xoffset
+ * The xoffset to set.
+ */
+ public void setXoffset(int xoffset);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/HorizontalMoveCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/HorizontalMoveCommand.java
new file mode 100644
index 000000000..9c157cad3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/HorizontalMoveCommand.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.nav;
+
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.parts.SubNodeEditPart;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class HorizontalMoveCommand extends Command implements
+ ICaretPositionMover {
+ private static Logger _log = PDPlugin
+ .getLogger(HorizontalMoveCommand.class);
+
+ IHTMLGraphicalViewer _viewer;
+
+ boolean _forward;
+
+ boolean _onlyMoveEnd;
+
+ /**
+ * @param viewer
+ * @param b
+ * @param c
+ */
+ public HorizontalMoveCommand(IHTMLGraphicalViewer viewer, boolean b,
+ boolean c) {
+ _viewer = viewer;
+ _forward = b;
+ _onlyMoveEnd = c;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void execute() {
+ DesignPosition position = null;
+ if (_viewer.isInRangeMode()) {
+ if (_viewer.getRangeSelection() != null
+ && _viewer.getRangeSelection().isValid()) {
+ position = _viewer.getRangeSelection().getEndPosition();
+ position = performInlineMode(_forward);
+ }
+ } else {
+ position = performObjectMode();
+ }
+ setRange(position);
+ }
+
+ private DesignPosition performObjectMode() {
+ DesignPosition result = null;
+ IMovementMediator validator = new InlineEditingNavigationMediator(
+ new ActionData(ActionData.KEYBOARD_NAVAGATION, null));
+ DesignPosition position = getCurrentObjectPosition();
+ if (position != null) {
+ _viewer.setRange(position, position);
+ if (!validator.isValidPosition(position)) {
+ position = performInlineMode(_forward);
+ if (validator.isValidPosition(position)) {
+ result = position;
+ } else {
+ result = performInlineMode(!_forward);
+ }
+ } else {
+ result = position;
+ }
+ }
+ return result;
+ }
+
+ private DesignPosition performInlineMode(boolean forward) {
+ DesignRange range = _viewer.getRangeSelection();
+
+ if (range == null || !range.isValid()) {
+ _log.error("invalud range");
+ return null;
+ }
+
+ DesignPosition position = range.getEndPosition();
+ if (position.getContainerPart() instanceof TextEditPart) {
+ int length = ((TextEditPart) position.getContainerPart())
+ .getTextData().length();
+ int newoffset = position.getOffset() + (_forward ? 1 : -1);
+ if (newoffset >= 0 && newoffset <= length) {
+ DesignPosition newposi = new DesignPosition(position
+ .getContainerPart(), newoffset);
+ return newposi;
+ }
+ }
+ DesignPosition newpos = EditHelper.moveToNextEditPosition(
+ ActionData.KEYBOARD_NAVAGATION, position, forward);
+ return newpos;
+ }
+
+ private void setRange(DesignPosition newpos) {
+ if (_onlyMoveEnd) {
+ _viewer.setRangeEndPosition(newpos);
+ } else {
+ _viewer.setRange(newpos, newpos);
+ }
+ }
+
+ private DesignPosition getCurrentObjectPosition() {
+ DesignRange result = null;
+ if (_viewer.isInRangeMode()) {
+ result = _viewer.getRangeSelection();
+ } else {
+ List parts = _viewer.getSelectedEditParts();
+ if (parts.size() > 0) {
+ EditPart selection = (EditPart) parts.get(0);
+ if (selection instanceof SubNodeEditPart) {
+ DesignPosition position = new DesignRefPosition(selection,
+ _forward);
+ result = new DesignRange(position, position);
+ }
+ }
+ }
+ return result != null && result.isValid() ? result.getEndPosition()
+ : null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/ICaretPositionMover.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/ICaretPositionMover.java
new file mode 100644
index 000000000..2b8549085
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/ICaretPositionMover.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.nav;
+
+/**
+ * @author mengbo
+ *
+ * TODO To change the template for this generated type comment go to Window -
+ * Preferences - Java - Code Style - Code Templates
+ */
+public interface ICaretPositionMover {
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/VerticalMoveCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/VerticalMoveCommand.java
new file mode 100644
index 000000000..d4f2f9882
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/nav/VerticalMoveCommand.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.nav;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.widgets.Caret;
+
+/**
+ * @author mengbo
+ */
+public class VerticalMoveCommand extends Command {
+ private static Logger _log = PDPlugin
+ .getLogger(HorizontalMoveCommand.class);
+
+ IHTMLGraphicalViewer _viewer;
+
+ boolean _up;
+
+ boolean _onlyMoveEnd;
+
+ /**
+ * @param viewer
+ * @param b
+ * @param c
+ */
+ public VerticalMoveCommand(IHTMLGraphicalViewer viewer, boolean up,
+ boolean c) {
+ _viewer = viewer;
+ _up = up;
+ _onlyMoveEnd = c;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void execute() {
+ int OFFSET = 2;
+ DesignRange range = _viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ _log.error("invalud range");
+ return;
+ }
+ IMovementMediator moveMediator = new InlineEditingNavigationMediator(
+ new ActionData(ActionData.KEYBOARD_NAVAGATION, null));
+ DesignPosition position = range.getEndPosition();
+ Caret caret = _viewer.getCaret();
+ Point point = null;
+ DesignPosition newPos = position;
+ EditPart containerpart = null, rootpart1;
+ if (_up) {
+ point = new Point(((CaretPositionTracker) _viewer).getXoffset(),
+ caret.getBounds().y);
+ } else {
+ point = new Point(((CaretPositionTracker) _viewer).getXoffset(),
+ caret.getBounds().y + caret.getBounds().height);
+
+ }
+ rootpart1 = getRootEditablePart(position.getContainerPart(),
+ moveMediator);// position.getContainerPart();
+ if (rootpart1 == null) {
+ return;
+ } else {
+ point = adjustLocation(rootpart1, point);
+ }
+ Rectangle bound = EditPartPositionHelper.getAbsoluteBounds(rootpart1);
+ // get current according to the point.
+ // FlowBoxLine line =
+ // getCurrentLine(moveMediator.getEditableContainer(new
+ // Target(rootpart)), point, moveMediator);
+ while (true) {
+ // try to change offset and then to search for new point.
+ if (_up) {
+ point.y -= OFFSET;
+ if (point.y <= bound.y) {
+ newPos = position;
+ break;
+ }
+ } else {
+ point.y += OFFSET;
+ if (point.y >= bound.y + bound.height) {
+ newPos = position;
+ break;
+ }
+ }
+ containerpart = ((InlineEditingNavigationMediator) moveMediator)
+ .getConstainedEditableContainer(position, point, _viewer);
+ if (containerpart != null) {
+ if (!EditModelQuery.isChild(Target.resolveNode(rootpart1),
+ Target.resolveNode(containerpart))) {
+ containerpart = rootpart1;
+ }
+ bound = EditPartPositionHelper.getAbsoluteBounds(rootpart1);
+ newPos = EditPartPositionHelper
+ .findEditPartPositionConstrained(containerpart, point,
+ moveMediator);
+ } else {
+ newPos = position;
+ break;
+ }
+ if (newPos != null) {
+ if (found(newPos, position)) {
+ break;
+ }
+ }
+ }
+ setRange(position, newPos);
+ }
+
+ private void setRange(DesignPosition position, DesignPosition newPos) {
+ if (!EditModelQuery.isSame(position, newPos)) {
+ {
+ if (_onlyMoveEnd) {
+ _viewer.setRangeEndPosition(newPos);
+ } else {
+ _viewer.setRange(newPos, newPos);
+ }
+ }
+ }
+ }
+
+ /*
+ * We should change this, it is too tricky to do in this way.
+ */
+ private Point adjustLocation(EditPart rootPart, Point point) {
+ Point result = point.getCopy();
+ Rectangle bounds = EditPartPositionHelper.getAbsoluteBounds(rootPart);
+ if (!bounds.contains(point)) {
+ if (bounds.getLeft().x > point.x) {
+ result.x = bounds.getLeft().x;
+ } else if (bounds.getRight().x < point.x) {
+ result.x = bounds.getRight().x;
+ }
+ }
+ return result;
+ }
+
+ private EditPart getRootEditablePart(EditPart part,
+ IMovementMediator moveMediator) {
+ EditPart rootpart = null;
+ if ((rootpart = ((InlineEditingNavigationMediator) moveMediator)
+ .getRootConstainedEditableContainer(new Target(part))) == null) {
+ rootpart = moveMediator.getEditableContainer(new Target(part));
+ }
+ return rootpart;
+ }
+
+ private boolean found(DesignPosition newPos, DesignPosition prevPos) {
+ Rectangle newRec = EditPartPositionHelper
+ .convertToAbsoluteCaretRect(newPos);
+ Rectangle prevRec = EditPartPositionHelper
+ .convertToAbsoluteCaretRect(prevPos);
+ if (_up) {
+ return getYDistance(newRec, prevRec, _up) < 0;
+ } else {
+ return getYDistance(newRec, prevRec, _up) > 0;
+ }
+ }
+
+ /**
+ * Distance from rec1 to rec2 at y coordination, if top, compare top,
+ * otherwise compare bottom.
+ *
+ * @param rec1
+ * @param rec2
+ * @param up
+ * @return
+ */
+ private int getYDistance(Rectangle rec1, Rectangle rec2, boolean top) {
+ if (rec1.getCopy().intersect(rec2).height > 0) {
+ return 0;
+ } else {
+ if (top) {
+ return rec1.getTop().y - rec2.getTop().y;
+ } else {
+ return rec1.getBottom().y - rec2.getBottom().y;
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ApplyStyleCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ApplyStyleCommand.java
new file mode 100644
index 000000000..43cc37117
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ApplyStyleCommand.java
@@ -0,0 +1,502 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class ApplyStyleCommand extends RangeModeCommand {
+ private String _tag;
+
+ private String _cssProperty;
+
+ private String _cssPropertyValue;
+
+ protected Element _applyingNode;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public ApplyStyleCommand(IHTMLGraphicalViewer viewer, String tag,
+ String property, String value) {
+ super(
+ CommandResources
+ .getString("ApplyStyleCommand.Label.ApplyStyle"), viewer); //$NON-NLS-1$
+ this._tag = tag;
+ this._cssProperty = property;
+ this._cssPropertyValue = value;
+ }
+
+ public ApplyStyleCommand(IHTMLGraphicalViewer viewer, Element node,
+ String property, String value) {
+ super(
+ CommandResources
+ .getString("ApplyStyleCommand.Label.ApplyStyle"), viewer); //$NON-NLS-1$
+ this._applyingNode = node;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected DOMRange doRangeExecute(DOMRange range) {
+ if (range == null || range.isEmpty()) {
+ return null;
+ }
+
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+
+ Node startContainer = start.getContainerNode();
+ Node endContainer = end.getContainerNode();
+
+ Node common = DOMUtil.findCommonAncester(start.getContainerNode(), end
+ .getContainerNode());
+ if (common == null) {
+ // should not happen.
+ return null;
+ }
+
+ if (common instanceof Text) {
+ // under the same Text scope
+ range = doTextNodeStyleApply((Text) common, start.getOffset(), end
+ .getOffset());
+
+ return range;
+ } else {
+
+ if (startContainer instanceof Text) {
+ // if the start offset is 0,then skip split the Text
+ if (start.getOffset() > 0) {
+ startContainer = ((Text) startContainer).splitText(start
+ .getOffset());
+ start = new DOMRefPosition(startContainer, false);
+ }
+ } else {
+ startContainer = start.getNextSiblingNode();
+ }
+ if (endContainer instanceof Text) {
+ if (end.getOffset() > 0) {
+ endContainer = ((Text) endContainer).splitText(end
+ .getOffset());
+ endContainer = endContainer.getPreviousSibling();
+ } else {
+ endContainer = endContainer.getPreviousSibling();
+ }
+ } else {
+ endContainer = end.getPreviousSiblingNode();
+ }
+
+ for (Node node = startContainer; node != endContainer; node = EditModelQuery
+ .getInstance().getNextLeafNeighbor(node)) {
+ if (EditModelQuery.hasAncestor(node, getTag(), true)) {
+ continue;
+ }
+ Element newnode = createStyleElement();
+ node.getParentNode().insertBefore(newnode, node);
+ newnode.appendChild(node);
+ }
+ if (!EditModelQuery.hasAncestor(endContainer, getTag(), true)) {
+ Element newnode = createStyleElement();
+ endContainer.getParentNode()
+ .insertBefore(newnode, endContainer);
+ newnode.appendChild(endContainer);
+ }
+
+ }
+
+ // merge the style tags
+
+ for (Node node = startContainer; node != endContainer; node = EditModelQuery
+ .getInstance().getNextLeafNeighbor(node)) {
+ Node stylenode = node;
+ while (stylenode != null
+ && !stylenode.getNodeName().equalsIgnoreCase(getTag())) {
+ stylenode = stylenode.getParentNode();
+ }
+ if (stylenode == null) {
+ continue;
+ }
+ if (stylenode.getNextSibling() != null
+ && stylenode.getNextSibling().getNodeName()
+ .equalsIgnoreCase(getTag())) {
+ Node sibling = stylenode.getNextSibling();
+ while (sibling.getFirstChild() != null) {
+ stylenode.appendChild(sibling.getFirstChild());
+ }
+ stylenode.getParentNode().removeChild(sibling);
+ node = startContainer;
+ }
+ }
+
+ return new DOMRange(start, end);
+
+ /*
+ * boolean ordered = range.isOrdered(); IDOMPosition start = ordered ?
+ * range.getStartPosition() : range.getEndPosition(); IDOMPosition end =
+ * ordered ? range.getEndPosition() : range.getStartPosition();
+ *
+ * Node common = DOMUtil.findCommonAncester(start.getContainerNode(),
+ * end.getContainerNode()); if (common == null) { // should not happen.
+ * return null; }
+ *
+ * DOMRange result = null; if (common instanceof Text) { result =
+ * doTextNodeStyleApply((Text) common, start.getOffset(),
+ * end.getOffset()); } else { IDOMPosition startPosition = start;
+ * IDOMPosition endPosition = end; Node ancester = common; DOMRange[]
+ * leftRange = new DOMRange[1]; DOMRange[] rightRange = new DOMRange[1];
+ *
+ * startPosition = partialApply(startPosition, ancester, true,
+ * leftRange); endPosition = partialApply(endPosition, ancester, false,
+ * rightRange); DOMRange middle = middleApply(ancester, startPosition,
+ * endPosition);
+ *
+ * IDOMPosition startref = null; if (leftRange[0] != null &&
+ * leftRange[0].getStartPosition() != null) { startref =
+ * leftRange[0].getStartPosition(); } else if (middle != null &&
+ * middle.getStartPosition() != null) { startref =
+ * middle.getStartPosition(); } else if (rightRange[0] != null &&
+ * rightRange[0].getStartPosition() != null) { startref =
+ * rightRange[0].getStartPosition(); }
+ *
+ * IDOMPosition endref = null; if (rightRange[0] != null &&
+ * rightRange[0].getEndPosition() != null) { endref =
+ * rightRange[0].getEndPosition(); } else if (middle != null &&
+ * middle.getEndPosition() != null) { endref = middle.getEndPosition(); }
+ * else if (leftRange[0] != null && leftRange[0].getEndPosition() !=
+ * null) { endref = leftRange[0].getEndPosition(); }
+ *
+ * if (startref == null) { result = null; } else { startref = new
+ * DOMPosition(EditModelQuery.getInstance().getNextLeafNeighbor(startref.getContainerNode()),
+ * 0); System.out.println(startref.toString()); endref = new
+ * DOMPosition(endref.getContainerNode(), 0); result = new
+ * DOMRange(startref, endref); } }
+ *
+ * if (result == null) { return null; }
+ *
+ * if (ordered) { return result; } else { return new
+ * DOMRange(result.getEndPosition(), result.getStartPosition()); }
+ */
+ }
+
+ private DOMRange middleApply(Node ancester, IDOMPosition startPosition,
+ IDOMPosition endPosition) {
+ startPosition = skip(startPosition, true);
+ if (startPosition.getNextSiblingNode() == null
+ || startPosition.getOffset() >= endPosition.getOffset()) {
+ return null;
+ } else {
+ List needMove = new ArrayList();
+ Node startNext = startPosition.getNextSiblingNode();
+ Node endNext = endPosition.getNextSiblingNode();
+ while (startNext != null && startNext != endNext) {
+ needMove.add(startNext);
+ startNext = startNext.getNextSibling();
+ }
+ Element newEle = createStyleElement();
+ ancester.insertBefore(newEle, startPosition.getNextSiblingNode());
+ for (int i = 0, n = needMove.size(); i < n; i++) {
+ newEle.appendChild((Node) needMove.get(i));
+ }
+ return new DOMRange(new DOMRefPosition(newEle, false),
+ new DOMRefPosition(newEle, true));
+ }
+
+ }
+
+ private IDOMPosition partialApply(IDOMPosition position, Node ancester,
+ boolean forward, DOMRange[] result) {
+ IDOMPosition startRef = null, endRef = null;
+
+ while (position != null && position.getContainerNode() != ancester) {
+ Node container = position.getContainerNode();
+ if (container instanceof Text) {
+ // splitText will move the position up one level
+ position = splitText(position);
+ } else {
+ // skip those nodes that can't have the style applied.
+ position = skip(position, forward);
+ Node sibling = position.getSibling(forward);
+ if (sibling != null) {
+ List needMove = new ArrayList();
+ while (sibling != null) {
+ needMove.add(sibling);
+ sibling = forward ? sibling.getNextSibling() : sibling
+ .getPreviousSibling();
+ }
+
+ // ok, there is nodes that need the style
+ Element newEle = createStyleElement();
+ container.insertBefore(newEle, position
+ .getNextSiblingNode());
+ for (int i = 0, size = needMove.size(); i < size; i++) {
+ newEle.appendChild((Node) needMove.get(i));
+ }
+ if (startRef == null) {
+ startRef = new DOMRefPosition(newEle, !forward);
+ }
+ endRef = new DOMRefPosition(newEle, forward);
+ }
+ // move the position up one level
+ position = new DOMRefPosition(container, forward);
+ }
+ }
+ if (startRef == null) {
+ result[0] = null;
+ } else {
+ result[0] = forward ? new DOMRange(startRef, endRef)
+ : new DOMRange(endRef, startRef);
+ }
+ return position;
+ }
+
+ /**
+ * @param position
+ * @return
+ */
+ private IDOMPosition splitText(IDOMPosition position) {
+ Text text = (Text) position.getContainerNode();
+ int offset = position.getOffset();
+ if (offset <= 0) {
+ return new DOMRefPosition(text, false);
+ } else if (offset >= text.getData().length()) {
+ return new DOMRefPosition(text, true);
+ } else {
+ text.splitText(offset);
+ return new DOMRefPosition(text, true);
+ }
+ }
+
+ /**
+ * @param start
+ * @param end
+ * @param common
+ */
+ private DOMRange doTextNodeStyleApply(Text textNode, int startOffset,
+ int endOffset) {
+ String data = textNode.getData();
+ String before = data.substring(0, startOffset);
+ String middle = data.substring(startOffset, endOffset);
+ String tail = data.substring(endOffset);
+
+ Text middleText = getModel().getDocument().createTextNode(middle);
+
+ // case 1: normal one
+ if (!isEmptyString(before) && !isEmptyString(tail)) {
+ Node parent = textNode.getParentNode();
+ parent.insertBefore(
+ getModel().getDocument().createTextNode(before), textNode);
+ Element bnode = createStyleElement();
+ bnode.appendChild(middleText);
+ parent.insertBefore(bnode, textNode);
+ textNode.setNodeValue(tail);
+ }
+
+ if (isEmptyString(before) && !isEmptyString(tail)) {
+ Node sibling = textNode.getPreviousSibling();
+ if (sibling != null
+ && sibling.getNodeName().equalsIgnoreCase(getTag())) {
+ sibling.appendChild(middleText);
+ } else {
+ Node parent = textNode.getParentNode();
+ parent.insertBefore(getModel().getDocument().createTextNode(
+ before), textNode);
+ Element bnode = createStyleElement();
+ bnode.appendChild(middleText);
+ parent.insertBefore(bnode, textNode);
+ }
+ textNode.setNodeValue(tail);
+ }
+
+ if (!isEmptyString(before) && isEmptyString(tail)) {
+ Node sibling = textNode.getNextSibling();
+ textNode.setNodeValue(before);
+ if (sibling != null
+ && sibling.getNodeName().equalsIgnoreCase(getTag())) {
+ sibling.insertBefore(middleText, sibling.getFirstChild());
+ } else {
+ Element bnode = createStyleElement();
+ bnode.appendChild(middleText);
+ textNode.getParentNode().insertBefore(bnode, sibling);
+ }
+ }
+
+ if (isEmptyString(before) && isEmptyString(tail)) {
+
+ Node previousSibling = textNode.getPreviousSibling();
+ Node nextSibling = textNode.getNextSibling();
+ //
+ if (getTag().equalsIgnoreCase(IHTMLConstants.TAG_P)) {
+ Element bnode = createStyleElement();
+ bnode.appendChild(middleText);
+ textNode.getParentNode().insertBefore(bnode, textNode);
+ textNode.getParentNode().removeChild(textNode);
+ }
+ //
+ else {
+ if (previousSibling != null
+ && previousSibling.getNodeName().equalsIgnoreCase(
+ getTag()) && nextSibling != null
+ && nextSibling.getNodeName().equalsIgnoreCase(getTag())) {
+ previousSibling.appendChild(middleText);
+ while (nextSibling.getFirstChild() != null) {
+ previousSibling
+ .appendChild(nextSibling.getFirstChild());
+ }
+ nextSibling.getParentNode().removeChild(nextSibling);
+ } else if (previousSibling != null
+ && previousSibling.getNodeName().equalsIgnoreCase(
+ getTag())) {
+ previousSibling.appendChild(middleText);
+ } else if (nextSibling != null
+ && nextSibling.getNodeName().equalsIgnoreCase(getTag())) {
+ nextSibling.insertBefore(middleText, nextSibling
+ .getFirstChild());
+ } else {
+ Element bnode = createStyleElement();
+ bnode.appendChild(middleText);
+ textNode.getParentNode().insertBefore(bnode, textNode);
+ }
+ textNode.getParentNode().removeChild(textNode);
+ }
+ }
+
+ return new DOMRange(new DOMRefPosition(middleText, false),
+ new DOMRefPosition(middleText, true));
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @return
+ */
+ protected Element createStyleElement() {
+ if (_applyingNode != null) {
+ return _applyingNode;
+ } else {
+ Element element = getModel().getDocument().createElement(getTag());
+ if (_cssProperty != null && _cssPropertyValue != null) {
+ element.setAttribute(_cssProperty, _cssPropertyValue);
+ }
+ return element;
+ }
+ }
+
+ /**
+ * @param position
+ * @param b
+ * @return
+ */
+ private IDOMPosition skip(IDOMPosition position, boolean forward) {
+ Node node = position.getSibling(forward);
+
+ if (node == null) {
+ return position;
+ }
+ boolean canSkip = false;
+ if (node instanceof Text) {
+ canSkip = ((IDOMText) node).isElementContentWhitespace();
+ } else if (node instanceof Element) {
+ if (getTag().equalsIgnoreCase(((Element) node).getTagName())) {
+ canSkip = true;
+ } else {
+ canSkip = false;
+ }
+ } else {
+ canSkip = true;
+ }
+ if (canSkip) {
+ return new DOMRefPosition(node, forward);
+ } else {
+ return position;
+ }
+ }
+
+ /**
+ * @return Returns the _cssProperty.
+ */
+ public final String getCssProperty() {
+ return _cssProperty;
+ }
+
+ /**
+ * @param property
+ * The _cssProperty to set.
+ */
+ public final void setCssProperty(String property) {
+ _cssProperty = property;
+ }
+
+ /**
+ * @return Returns the _cssPropertyValue.
+ */
+ public final String getCssPropertyValue() {
+ return _cssPropertyValue;
+ }
+
+ /**
+ * @param propertyValue
+ * The _cssPropertyValue to set.
+ */
+ public final void setCssPropertyValue(String propertyValue) {
+ _cssPropertyValue = propertyValue;
+ }
+
+ /**
+ * @return Returns the _tag.
+ */
+ public final String getTag() {
+ if (_tag != null) {
+ return _tag;
+ } else {
+ return _applyingNode.getNodeName();
+ }
+ }
+
+ /**
+ * @param _tag
+ * The _tag to set.
+ */
+ public final void setTag(String _tag) {
+ this._tag = _tag;
+ }
+
+ private void updateStyleElement() {
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/BlockNodeFinder.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/BlockNodeFinder.java
new file mode 100644
index 000000000..9fe12ad85
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/BlockNodeFinder.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class BlockNodeFinder {
+ private String[] _additionalTags;
+
+ private IDOMPosition _position;
+
+ public BlockNodeFinder(IDOMPosition position, String[] additionalTags) {
+ _position = position;
+ _additionalTags = additionalTags;
+ }
+
+ private Node findInlineSiblings(IDOMPosition position, List result,
+ boolean forward) {
+ Node container = EditModelQuery.getInstance().getSibling(position,
+ forward);
+ if (!forward) {
+ while (container != null) {
+ if (EditModelQuery.isInline(container)) {
+ result.add(container);
+ } else {
+ return container;
+ }
+ container = container.getPreviousSibling();
+ }
+ } else {
+ while (container != null) {
+ if (EditModelQuery.isInline(container)) {
+ result.add(container);
+ } else {
+ return container;
+ }
+ container = container.getNextSibling();
+ }
+ }
+ // the result will be non-zero length.
+ return null;
+ }
+
+ private Node getParagraphNodes(IDOMPosition position, List result,
+ boolean forward) {
+ Node sResult = findInlineSiblings(position, result, forward);
+ Node container = position.getContainerNode();
+ container = position.isText() ? container.getParentNode() : container;
+ while (sResult == null) {
+ // stop at block, special container and H style nodes.
+ if (EditModelQuery.isBlockNode(container)
+ || EditModelQuery.isDocument(container)
+ || (container.getLocalName() != null && (container
+ .getLocalName().equals(IJSFConstants.TAG_VIEW) || container
+ .getLocalName().equalsIgnoreCase(
+ IHTMLConstants.TAG_HTML))) || //
+ (_additionalTags != null
+ && Arrays.asList(_additionalTags).contains(
+ getTagName()) && Arrays.asList(
+ _additionalTags).contains(container))) {
+ return container;
+ }
+ position = new DOMRefPosition(container, forward);
+ sResult = findInlineSiblings(position, result, forward);
+ container = container.getParentNode();
+ }
+ return sResult;
+ }
+
+ /**
+ * Search for an area between two block nodes or within a block node, search
+ * will stop before or under a node which has block display-type, or
+ * particular container like "html", jsf "view", .etc, two positions (left
+ * and right) are returned in result.
+ *
+ * The searcher will search parent's directly children, if no block node is
+ * found, then go up the node tree to search again.
+ *
+ * @param position
+ * @param result
+ */
+ public void getParagraphNodes(IDOMPosition position, List result) {
+ List tempResult = new ArrayList();
+ Node r1 = getParagraphNodes(position, tempResult, true);
+ if (EditModelQuery.isChild(r1, position.getContainerNode())) {
+ result.add(new DOMPosition(r1, r1.getChildNodes().getLength()));
+ } else {
+ result.add(new DOMRefPosition(r1, false));
+ }
+
+ Node r2 = getParagraphNodes(position, tempResult, false);
+ if (EditModelQuery.isChild(r2, position.getContainerNode())) {
+ result.add(new DOMPosition(r2, 0));
+ } else {
+ result.add(new DOMRefPosition(r2, true));
+ }
+ }
+
+ private String getTagName() {
+ String name = _position.getContainerNode().getNodeName();
+ name = name == null ? "" : name.toLowerCase();
+ return name;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ClipboardData.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ClipboardData.java
new file mode 100644
index 000000000..f41c95c7e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ClipboardData.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.Vector;
+
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.widgets.Control;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class ClipboardData implements IInputSourceProvider {
+
+ private Control _control;
+
+ /**
+ *
+ */
+ public ClipboardData(Control control) {
+ super();
+ _control = control;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.IInputSourceProvider#getNodes()
+ */
+ public Node[] getNodes() {
+ Object data = getClipboardData();
+ if (data instanceof Vector && ((Vector) data).size() > 0) {
+ return (Node[]) ((Vector) data).toArray(new Node[] {});
+ } else if (data instanceof Node[]) {
+ return (Node[]) data;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.IInputSourceProvider#getStringData()
+ */
+ public String getStringData() {
+ Object data = getClipboardData();
+ if (data instanceof String) {
+ return (String) data;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.IInputSourceProvider#getCharacterData()
+ */
+ public Character getCharacterData() {
+ return null;
+ }
+
+ public Object getClipboardData() {
+ Clipboard clipboard = new Clipboard(_control.getDisplay());
+
+ Object cuted = clipboard.getContents(TemplateTransfer.getInstance());
+ if (cuted instanceof Node[] || cuted instanceof Vector) {
+ return cuted;
+ } else {
+ cuted = clipboard.getContents(TextTransfer.getInstance());
+ return cuted;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ContentCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ContentCommand.java
new file mode 100644
index 000000000..c1a9cdbc4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ContentCommand.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Text;
+
+/**
+ * This command can used to handle things like "paste". Or keyboard printable
+ * ascii key. Note: ENTER key is not handled here.
+ *
+ * @author mengbo
+ */
+// FIXME: \r \n in the content string is not handled.
+public class ContentCommand extends RangeModeCommand {
+
+ private String _content;
+
+ /**
+ * @param label
+ * @param model
+ * @param viewer
+ */
+ public ContentCommand(IHTMLGraphicalViewer viewer, String content) {
+ super("", viewer);
+ _content = content;
+ }
+
+ public ContentCommand(IHTMLGraphicalViewer viewer, char c) {
+ super("", viewer);
+ _content = String.valueOf(c);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected DOMRange doRangeExecute(DOMRange range) {
+ if (range == null)
+ return null;
+
+ IDOMPosition position = DOMPositionHelper.removeRange(range);
+ position = doContent(position);
+ return new DOMRange(position, position);
+
+ }
+
+ protected IDOMPosition doContent(IDOMPosition position) {
+ position = DOMPositionHelper.mergeIntoText(position);
+
+ if (position.getContainerNode() instanceof Text) {
+ Text text = (Text) position.getContainerNode();
+ String data = text.getData();
+ int offset = position.getOffset();
+ String newData = data.substring(0, offset) + _content
+ + data.substring(offset);
+ text.setData(newData);
+ return new DOMPosition(text, offset + _content.length());
+ } else {
+ // we need to create a text node.
+ Text text = getDocument().createTextNode(_content);
+ position.getContainerNode().insertBefore(text,
+ position.getNextSiblingNode());
+ return new DOMRefPosition(text, true);
+ }
+ }
+
+ // protected DesignPosition doContent()
+ // {
+ // // DesignPosition position = removeRange();
+ // DesignPosition position = this.getSelectionRange().getEndPosition();
+ // if ('\r' == _content || '\n' == _content)
+ // {
+ // Element br = getModel().getDocument().createElement("BR");
+ // Node node = RangeUtil.insertElement(position, br);
+ //
+ // // we need set the new range to the node.
+ // // FIXME: temp code, need to reconsider how to do refresh, when those
+ // editpart
+ // // are recreated.
+ // IDOMNode parent = (IDOMNode) node.getParentNode();
+ // EditPart parentPart = (EditPart) parent.getAdapterFor(EditPart.class);
+ // List childParts = parentPart.getChildren();
+ // for (int i=0; i<childParts.size(); i++)
+ // {
+ // if (node == ((EditPart)childParts.get(i)).getModel())
+ // {
+ // return new DesignPosition(parentPart, i+1);
+ // }
+ // }
+ // return new DesignPosition(parentPart, childParts.size());
+ // }
+ // else
+ // {
+ // TextPosition textPosition = RangeUtil.insertText(position,
+ // String.valueOf(_content));
+ // IDOMText text = textPosition.getTextNode();
+ // EditPart part = (EditPart) text.getAdapterFor(EditPart.class);
+ // return new DesignPosition(part, textPosition.getOffset());
+ // }
+ // }
+ //
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyCommand.java
new file mode 100644
index 000000000..9581781f4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyCommand.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class CopyCommand extends RangeModeCommand {
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public CopyCommand(IHTMLGraphicalViewer viewer) {
+ super(CommandResources.getString("CopyCommand.Label.Copy"), viewer); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange selection) {
+ DesignEdit edit = new CopyEdit(selection, getViewer());
+ edit.operate();
+ return selection;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyEdit.java
new file mode 100644
index 000000000..8ae5e5ad2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CopyEdit.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.Stack;
+
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class CopyEdit extends DesignEdit {
+ private static Logger _log = PDPlugin.getLogger(CopyEdit.class);
+
+ private Stack result = new Stack();
+
+ /**
+ * @param range
+ * @param viewer
+ */
+ public CopyEdit(DOMRange range, GraphicalViewer viewer) {
+ super(range, viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignEdit#operate()
+ */
+ protected boolean operate() {
+ WorkNode root = getRootWorkNode();
+ Node rootNode = root.getNode();
+ result = getProcessedResult();
+ collectOtherStyles(rootNode, result);
+ setClipboard(result);
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignEdit#processContainer(org.eclipse.jst.pagedesigner.commands.range.WorkNode)
+ */
+ protected Node processContainer(WorkNode node) {
+ return node.getNode().cloneNode(false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processNode(org.w3c.dom.Node,
+ * int[], java.util.Stack)
+ */
+ protected Node processNode(WorkNode node) {
+ int pos[] = node.getPosOffsets();
+ // the text could be tranparent, or 0 length.
+ Assert.isTrue(pos[0] <= pos[1]);
+ if (pos[0] == pos[1]) {
+ return null;
+ }
+ return node.getNode().cloneNode(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processText(org.w3c.dom.Text,
+ * int[], java.util.Stack)
+ */
+ protected Text processText(WorkNode node) {
+ Text currentNode = (Text) node.getNode();
+ int left = EditModelQuery.getNodeStartIndex(currentNode);
+ int right = EditModelQuery.getNodeEndIndex(currentNode);
+ int location1 = EditHelper.getInstance().getLocation(currentNode,
+ node.getPosOffsets()[0], true);
+ int location2 = EditHelper.getInstance().getLocation(currentNode,
+ node.getPosOffsets()[1], true);
+ int start = 0;
+ int end = right - left;
+ // left index
+ if (location1 > EditHelper.IN_MIDDLE
+ || location2 < EditHelper.IN_MIDDLE) {
+ return null;
+ }
+ if (location1 <= EditHelper.IN_MIDDLE) {
+ start = node.getQualifiedOffsets()[0];
+ }
+ if (location2 >= EditHelper.IN_MIDDLE) {
+ end = node.getQualifiedOffsets()[1];
+ }
+ if (start == end) {
+ return null;
+ } else {
+ try {
+ String text = currentNode.getData().substring(start, end);
+ return EditModelQuery.getDocumentNode(currentNode)
+ .createTextNode(text);
+ } catch (Exception e) {
+ _log.error("Exception", e);
+ return null;
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutCommand.java
new file mode 100644
index 000000000..6416ac582
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutCommand.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class CutCommand extends RangeModeCommand {
+ /**
+ * @param label
+ * @param viewer
+ */
+ public CutCommand(IHTMLGraphicalViewer viewer) {
+ super(CommandResources.getString("CutCommand.Label.Cut"), viewer); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange selection) {
+ DesignEdit edit = new CutEdit(selection, getViewer());
+ if (EditModelQuery.isSame(selection)) {
+ return null;
+ } else {
+ if (edit.perform()) {
+ return new DOMRange(edit.getOperationPosition(), edit
+ .getOperationPosition());
+ } else {
+ return selection;
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutEdit.java
new file mode 100644
index 000000000..340cebf10
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/CutEdit.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.Stack;
+
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+
+/**
+ * @author mengbo
+ */
+public class CutEdit extends DeleteEdit {
+ /**
+ * @param range
+ */
+ public CutEdit(DOMRange range, GraphicalViewer viewer) {
+ super(range, viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignEdit#operate()
+ */
+ protected boolean operate() {
+ Stack result = deleteRange();
+ setClipboard(result);
+ return true;
+ }
+
+ /*
+ * private Text cutText(Text text, int start, int end) {
+ * EditValidateUtil.validStringIndexOffset(text, start, end - start); String
+ * content = text.substringData(start, end - start); if (content == null ||
+ * content.length() == 0) { return null; } text.deleteData(start, end -
+ * start); return _document.createTextNode(content); }
+ */
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteCommand.java
new file mode 100644
index 000000000..ef701210b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteCommand.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.commands.nav.ICaretPositionMover;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * @author mengbo
+ */
+public class DeleteCommand extends RangeModeCommand implements
+ ICaretPositionMover {
+ private boolean _forward;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public DeleteCommand(boolean forward, IHTMLGraphicalViewer viewer) {
+ super(CommandResources.getString("DeleteCommand.Label.Delete"), viewer); //$NON-NLS-1$
+ _forward = forward;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected DOMRange doRangeExecute(DOMRange selection) {
+ if (selection == null) {
+ return null;
+ }
+
+ DesignEdit edit = new DeleteEdit(selection, getViewer(), _forward);
+ Listener listener = new Listener() {
+ public void handleEvent(Event event) {
+ event.type = SWT.NONE;
+ }
+ };
+ getViewer().getControl().getDisplay()
+ .addFilter(SWT.Selection, listener);
+ boolean status = edit.perform();
+ getViewer().getControl().getDisplay().removeFilter(SWT.Selection,
+ listener);
+ if (status) {
+ return new DOMRange(edit.getOperationPosition(), edit
+ .getOperationPosition());
+ } else {
+ return selection;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteEdit.java
new file mode 100644
index 000000000..47be5b7e2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DeleteEdit.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.Stack;
+import java.util.Vector;
+
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IETablePositionRule;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.viewer.LayoutPart;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class DeleteEdit extends DesignEdit {
+ private static final Logger _log = PDPlugin.getLogger(DeleteEdit.class);
+
+ private static final boolean INNER_DEBUG = false;
+
+ private boolean _forward;
+
+ Vector deleted = new Vector();
+
+ /**
+ * @param range
+ * @param viewer
+ */
+ public DeleteEdit(DOMRange range, GraphicalViewer viewer, boolean forward) {
+ super(range, viewer);
+ _forward = forward;
+ }
+
+ public DeleteEdit(DOMRange range, GraphicalViewer viewer) {
+ super(range, viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignEdit#operate()
+ */
+ protected boolean operate() {
+ try {
+ boolean result = true;
+ if (EditModelQuery.isSame(getRange())) {
+ deleteSingle();
+ } else {
+ deleteRange();
+ }
+ return result;
+ } catch (Exception e) {
+ _log.error("Exception", e);
+ return false;
+ }
+ }
+
+ /**
+ * Delete one node or char at operation position.
+ */
+ private void deleteSingle() {
+ IDOMPosition opPosition = getOperationPosition();
+ opPosition = EditHelper.moveToNextEditPosition(getOperationPosition(),
+ _forward, new InlineEditingNavigationMediator(new ActionData(
+ ActionData.INLINE_EDIT, null)));
+ // for inner debug
+ if (INNER_DEBUG) {
+ _log.info("EditHelper, now we are at:" + opPosition);
+ }
+ if (EditModelQuery.isSame(opPosition, getOperationPosition())) {
+ return;
+ } else {
+ setRange(new DOMRange(opPosition, getOperationPosition()));
+ deleteRange();
+ }
+ }
+
+ protected Stack deleteRange() {
+ WorkNode root = getRootWorkNode();
+ Node rootNode = root.getNode();
+ Stack result = getProcessedResult();
+ collectOtherStyles(rootNode, result);
+ return result;
+ }
+
+ private boolean isTableComponents(WorkNode node) {
+ String name = node.getNode().getNodeName();
+ return (IHTMLConstants.TAG_TD.equalsIgnoreCase(name) || //
+ IHTMLConstants.TAG_TH.equalsIgnoreCase(name) || //
+ IHTMLConstants.TAG_TR.equalsIgnoreCase(name) || //
+ IHTMLConstants.TAG_THEAD.equalsIgnoreCase(name) || //
+ IHTMLConstants.TAG_TBODY.equalsIgnoreCase(name) || //
+ IHTMLConstants.TAG_TFOOT.equalsIgnoreCase(name));
+ }
+
+ private Node processContainerTable(WorkNode node) {
+ Node result = null;
+ if ((isTableComponents(node) || IHTMLConstants.TAG_TABLE
+ .equalsIgnoreCase(node.getNode().getNodeName())) //
+ && new IETablePositionRule(null, null).isInValidTable(node
+ .getNode())) {
+ result = node.getNode().cloneNode(false);
+ }
+ return result;
+ }
+
+ private Node processContainerStyleNodes(WorkNode node) {
+ String name = node.getNode().getNodeName();
+ Node result = null;
+ if (IHTMLConstants.TAG_LI.equalsIgnoreCase(name) || //
+ EditModelQuery.HTML_STYLE_NODES.contains(node.getNode()
+ .getLocalName())) {
+ if (node.getNode().hasChildNodes()) {
+ result = node.getNode().cloneNode(false);
+ }
+ }
+ return result;
+ }
+
+ private Node processContainerView(WorkNode node) {
+ Node result = null;
+ if (IJSFConstants.TAG_VIEW.equalsIgnoreCase(node.getNode()
+ .getLocalName())) {
+ result = EditModelQuery.getDocumentNode(node.getNode())
+ .createElement(IJSFConstants.TAG_SUBVIEW);
+ result.setPrefix(node.getNode().getPrefix());
+ } else if (IHTMLConstants.TAG_BODY.equalsIgnoreCase(node.getNode()
+ .getNodeName())
+ || IHTMLConstants.TAG_HTML.equalsIgnoreCase(node.getNode()
+ .getNodeName())) {
+ result = EditModelQuery.getDocumentNode(node.getNode())
+ .createElement(node.getNode().getNodeName());
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processContainer(org.eclipse.jst.pagedesigner.commands.range.WorkNode)
+ */
+ protected Node processContainer(WorkNode node) {
+ Node result = processContainerView(node);
+ if (result == null) {
+ result = processContainerTable(node);
+ }
+ if (result == null) {
+ result = processContainerStyleNodes(node);
+ }
+ if (result == null) {
+ // strip out container
+ if (LayoutPart.getConcreteNode(node.getNode()) != null) {
+ Node parent = node.getNode().getParentNode();
+ Node refNode = node.getNode();
+ Node child = node.getNode().getFirstChild();
+ Node first = null, last = null;
+ int index = 0;
+ NodeList children = node.getNode().getChildNodes();
+ int size = children.getLength();
+ while (child != null) {
+ Node next = child.getNextSibling();
+ Node n = EditHelper.deleteNode(child);
+ parent.insertBefore(n, refNode);
+ if (index == 0) {
+ if (refNode != null) {
+ first = refNode.getPreviousSibling();
+ } else {
+ first = parent.getLastChild();
+ }
+ }
+ if (index == size - 1) {
+ if (refNode != null) {
+ last = refNode.getPreviousSibling();
+ } else {
+ last = parent.getLastChild();
+ }
+ }
+ index++;
+ child = next;
+ }
+ if (node.getPosOffsets()[0] <= 0) {
+ setOperationPosition(new DOMRefPosition(first, false));
+ } else {
+ setOperationPosition(new DOMRefPosition(last, true));
+ }
+ } else {
+ setOperationPosition(new DOMRefPosition(node.getNode(), false));
+ }
+ result = EditHelper.deleteNode(node.getNode());
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processNode(org.w3c.dom.Node,
+ * int[])
+ */
+ protected Node processNode(WorkNode node) {
+ Node result = null;
+ if (!isTableComponents(node)
+ || !new IETablePositionRule(null, null).isInValidTable(node
+ .getNode())) {
+ // it's not table components.
+ setOperationPosition(new DOMRefPosition(node.getNode(), false));
+ result = EditHelper.deleteNode(node.getNode());
+ }
+ return result;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.AbstractCopyEdit#processText(org.w3c.dom.Text,
+ * int[])
+ */
+ protected Text processText(WorkNode node) {
+ Text currentNode = (Text) node.getNode();
+ int[] offsets = node.getPosOffsets();
+ Node second = null;
+ int location1 = EditHelper.getInstance().getLocation(currentNode,
+ node.getPosOffsets()[0], true);
+ int location2 = EditHelper.getInstance().getLocation(currentNode,
+ node.getPosOffsets()[1], true);
+ // left index
+ if (currentNode.getData().length() > 0) {
+ if (location1 == EditHelper.IN_MIDDLE) {
+ IDOMPosition position = new DOMPosition(currentNode, node
+ .getPosOffsets()[0]);
+ setOperationPosition(position);
+ position = DOMPositionHelper.splitText(position);
+ Node nnode = position.getNextSiblingNode();
+ if (nnode instanceof Text) {
+ currentNode = (Text) nnode;
+ offsets[1] -= offsets[0] > 0 ? offsets[0] : 0;
+ }
+ } else {
+ // setOperationPosition(new DOMRefPosition(currentNode, false));
+ if (currentNode.getPreviousSibling() != null) {
+ setOperationPosition(new DOMRefPosition(currentNode
+ .getPreviousSibling(), true));
+ } else {
+ setOperationPosition(new DOMPosition(currentNode
+ .getParentNode(), 0));
+ }
+ }
+ // right index
+ if (location2 >= EditHelper.IN_MIDDLE) {
+ IDOMPosition position = new DOMPosition(currentNode, offsets[1]);
+ position = DOMPositionHelper.splitText(position);
+ second = position.getPreviousSiblingNode();
+ }
+ return second != null ? (Text) EditHelper.deleteNode(second) : null;
+ } else {
+ setOperationPosition(new DOMRefPosition(currentNode, false));
+ return (Text) EditHelper.deleteNode(currentNode);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DesignEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DesignEdit.java
new file mode 100644
index 000000000..ed835a984
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/DesignEdit.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.Stack;
+import java.util.Vector;
+
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.CSSUtil;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public abstract class DesignEdit {
+ public static final int DELETE_OPERATION = 1;
+
+ public static final int INSERT_OPERATION = 2;
+
+ private Stack _selections;
+
+ private DOMRange _range;
+
+ private GraphicalViewer _viewer;
+
+ private IDOMPosition _operationPosition;
+
+ protected Document _document;
+
+ protected IDOMModel _model;
+
+ protected Stack _processedResult;
+
+ public DesignEdit(DOMRange range, GraphicalViewer viewer) {
+ setRange(range);
+ _viewer = viewer;
+ _operationPosition = getRange().getStartPosition();
+ _document = ((IDOMNode) _operationPosition.getContainerNode())
+ .getModel().getDocument();
+ _model = ((IDOMNode) _operationPosition.getContainerNode()).getModel();
+ }
+
+ protected abstract boolean operate();
+
+ protected abstract Text processText(WorkNode node);
+
+ protected abstract Node processNode(WorkNode node);
+
+ protected abstract Node processContainer(WorkNode node);
+
+ public DOMRange getRange() {
+ return _range;
+ }
+
+ void setRange(DOMRange range) {
+ range = EditHelper.normal(range);
+ IDOMPosition start = EditHelper.ensureDOMPosition(range
+ .getStartPosition());
+ IDOMPosition end = EditHelper.ensureDOMPosition(range.getEndPosition());
+ _range = new DOMRange(start, end);
+ EditValidateUtil.validRange(range);
+ }
+
+ protected Clipboard getClipboard() {
+ return new Clipboard(_viewer.getControl().getDisplay());
+ }
+
+ public IDOMPosition getOperationPosition() {
+ // try
+ // {
+ // Assert.isTrue(_operationPosition != null &&
+ // _operationPosition.getContainerNode() != null &&
+ // _operationPosition.getOffset() > -1);
+ // if (_operationPosition.isText())
+ // {
+ // int length = ((Text)
+ // _operationPosition.getContainerNode()).getLength();
+ // Assert.isTrue(_operationPosition.getOffset() >= 0 &&
+ // _operationPosition.getOffset() <= length);
+ // }
+ // }
+ // catch (Exception e)
+ // {
+ // // "Error", "Error in operation location move"
+ // PDPlugin.getAlerts().confirm("Alert.DesignEdit.opLocationValidTitle",
+ // "Alert.DesignEdit.opLocationValidMessage"); //$NON-NLS-1$
+ // //$NON-NLS-2$
+ // }
+
+ return _operationPosition;
+ }
+
+ protected void setOperationPosition(IDOMPosition position) {
+ if (!EditValidateUtil.validPosition(position)) {
+ return;
+ }
+ position = EditHelper.ensureDOMPosition(position);
+ _operationPosition = position;
+ }
+
+ public boolean perform() {
+ boolean result = false;
+
+ result = operate();
+ return result;
+ }
+
+ /**
+ * @return Returns the _viewer.
+ */
+ public GraphicalViewer getViewer() {
+ return _viewer;
+ }
+
+ private Stack collectNodes() {
+ Node node;
+ Stack result = new Stack();
+ IDOMPosition start = getRange().getStartPosition(), end = getRange()
+ .getEndPosition();
+ int pos[] = new int[] { EditModelQuery.getIndexedRegionLocation(start),
+ EditModelQuery.getIndexedRegionLocation(end), };
+ if (!EditModelQuery.isSame(start, end)) {
+ Node ancestor = EditModelQuery.getInstance().getCommonAncestor(
+ start, end);
+ WorkNode rootWorkNode = new WorkNode(ancestor, pos[0], pos[1]);
+ rootWorkNode.setRoot(true);
+ result.push(rootWorkNode);
+ try {
+ // Loop all the children of the ancestor, and and the result
+ // will be collected
+ if (EditModelQuery.isText(ancestor)) {
+ Stack temp = new Stack();
+ EditHelper.getInstance().collectNodes(ancestor, pos[0],
+ pos[1], ancestor, temp);
+ WorkNode wNode = (WorkNode) temp.remove(0);
+ wNode.setParent(rootWorkNode);
+ result.push(wNode);
+ } else {
+ node = ancestor.getFirstChild();
+ Stack temp = new Stack();
+ while (node != null) {
+ EditHelper.getInstance().collectNodes(node, pos[0],
+ pos[1], ancestor, temp);
+ while (temp.size() > 0) {
+ WorkNode wNode = (WorkNode) temp.remove(0);
+ if (wNode.getNode().getParentNode() == ancestor) {
+ wNode.setParent(rootWorkNode);
+ }
+ result.push(wNode);
+ }
+ node = node.getNextSibling();
+ }
+ }
+ } catch (Exception e) {
+ result.clear();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @return Returns the result.
+ */
+ public Stack getSelections() {
+ if (_selections == null) {
+ _selections = collectNodes();
+ }
+ return _selections;
+ }
+
+ public Stack getProcessedResult() {
+ if (_processedResult == null) {
+ _processedResult = new Stack();
+ WorkNode rootNode = getRootWorkNode();
+ if (rootNode != null) {
+ processNodes(rootNode, _processedResult);
+ }
+ }
+ return _processedResult;
+ }
+
+ protected final WorkNode getRootWorkNode() {
+ WorkNode result = null;
+ if (getSelections().size() > 0) {
+ WorkNode node = (WorkNode) getSelections().get(0);
+ while (node.getParent() != null) {
+ node = node.getParent();
+ }
+ result = node;
+ Assert.isTrue(node.isRoot());
+ }
+ return result;
+ }
+
+ protected final boolean processText(WorkNode node, Stack result) {
+ boolean done = false;
+ if (EditModelQuery.isText(node.getNode())) {
+ Node text = processText(node);
+ if (text != null) {
+ result.add(text);
+ }
+ getSelections().remove(node);
+ done = true;
+ }
+ return done;
+ }
+
+ protected final boolean processContainer(WorkNode node, Stack result) {
+ processContainer(node);
+ getSelections().remove(node);
+ return true;
+ }
+
+ protected final boolean processChildren(WorkNode node, Stack result) {
+ boolean done = false;
+ if (getFirstSelectedChild(node) != null) {
+ Stack myResult = new Stack();
+ {
+ WorkNode child = null;
+ while ((child = getFirstSelectedChild(node)) != null) {
+ {
+ processNodes(child, myResult);
+ }
+ }
+ Node newParent = processContainer(node);
+ newParent = toBeParent(newParent, myResult);
+ result.push(newParent);
+ }
+ getSelections().remove(node);
+ done = true;
+ }
+ return done;
+ }
+
+ protected final boolean processChildren1(WorkNode node, Stack result) {
+ boolean done = false;
+ if (node.getNode().hasChildNodes()) {
+ Stack myResult = new Stack();
+ {
+ Node childNode = node.getNode().getFirstChild();
+ Node next = null;
+ while (childNode != null) {
+ next = childNode.getNextSibling();
+ int x1 = EditModelQuery.getNodeStartIndex(childNode) - 1;
+ int x2 = EditModelQuery.getNodeEndIndex(childNode) + 1;
+ processNodes(new WorkNode(childNode, x1, x2), myResult);
+ childNode = next;
+ }
+ Node newParent = processContainer(node);
+ newParent = toBeParent(newParent, myResult);
+ result.push(newParent);
+ }
+ getSelections().remove(node);
+ done = true;
+ }
+ return done;
+ }
+
+ /**
+ * Process the nodes that are selected, the result is a collection of nodes
+ * that either are clones or the nodes cuted.
+ *
+ * @param node
+ * @param pos
+ * @param result
+ */
+ protected final void processNodes(WorkNode node, Stack result) {
+ WorkNode child = null;
+ if (node.isRoot()) {
+ while ((child = getFirstSelectedChild(node)) != null) {
+ processNodes(child, result);
+ }
+ } else {
+ if (node.isWholeSelected()
+ || //
+ (!EditModelQuery.isText(node.getNode()) && EditModelQuery
+ .getInstance().isSingleRegionNode(node.getNode()))
+ || //
+ EditModelQuery.isWidget(node.getNode())) {
+ Node temp = processNode(node);
+ if (temp != null) {
+ result.push(temp);
+ getSelections().remove(node);
+ } else {
+ if (!processText(node, result)) {
+ if (!processChildren1(node, result)) {
+ processContainer(node, result);
+ }
+ }
+ }
+ } else {
+ if (!processText(node, result)) {
+ if (!processChildren(node, result)) {
+ processContainer(node, result);
+ }
+ }
+ }
+ }
+ }
+
+ protected void setClipboard(Stack result) {
+ Node[] nodes = (Node[]) result.toArray(new Node[result.size()]);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, size = nodes.length; i < size; i++) {
+ DOMUtil.nodeToString(nodes[i], sb);
+ }
+ getClipboard().setContents(
+ new Object[] { result, sb.toString() },
+ new Transfer[] { TemplateTransfer.getInstance(),
+ TextTransfer.getInstance() });
+ }
+
+ private Node toBeParent(Node parent, Stack children) {
+ while (children.size() > 0) {
+ parent.appendChild((Node) children.remove(0));
+ }
+ return parent;
+ }
+
+ private WorkNode getFirstSelectedChild(WorkNode node) {
+ for (int i = 0, n = getSelections().size(); i < n; i++) {
+ WorkNode wNode = (WorkNode) getSelections().get(i);
+ if (wNode.getParent() == node) {
+ return wNode;
+ }
+ }
+ return null;
+ }
+
+ public Node collectStyleNodes(Node rootNode, Vector result) {
+ Element element = null;
+ if (rootNode instanceof Element) {
+ element = (Element) rootNode;
+ } else if (rootNode.getParentNode() != null) {
+ element = (Element) rootNode.getParentNode();
+ }
+ ICSSStyle style = CSSUtil.getCSSStyle(element);
+
+ Node node = EditModelQuery.getDocumentNode(rootNode).createElement(
+ "span");
+ for (int i = 0, n = result.size(); i < n; i++) {
+ node.appendChild((Node) result.elementAt(i));
+ }
+ ((Element) node).setAttribute(IHTMLConstants.ATTR_STYLE, CSSUtil
+ .resolveCSSStyle(style));
+ result.removeAllElements();
+ result.add(node);
+ return node;
+ }
+
+ public Node collectOtherStyles(Node rootNode, Vector result) {
+ Node cur = rootNode, prev = null, appendPoint = null;
+ if (EditValidateUtil.validNode(rootNode)) {
+ while (!EditModelQuery.isDocument(cur)) {
+ if (!EditValidateUtil.validNode(cur)) {
+ return null;
+ }
+ String name = cur.getNodeName() != null ? cur.getNodeName()
+ .toLowerCase() : "";
+ if (EditModelQuery.HTML_STYLE_NODES.contains(name)) {
+ if (prev != null) {
+ Node newone = cur.cloneNode(false);
+ newone.appendChild(prev);
+ prev = newone;
+ } else {
+ prev = cur.cloneNode(false);
+ appendPoint = prev;
+ }
+ }
+ cur = cur.getParentNode();
+ }
+ if (appendPoint != null) {
+ for (int i = 0, n = result.size(); i < n; i++) {
+ appendPoint.appendChild((Node) result.elementAt(i));
+ }
+ result.removeAllElements();
+ result.add(prev);
+ }
+ }
+ return prev;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/IInputSourceProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/IInputSourceProvider.java
new file mode 100644
index 000000000..fabe0cabe
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/IInputSourceProvider.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public interface IInputSourceProvider {
+ /**
+ * @return Returns the _data.
+ */
+ public Node[] getNodes();
+
+ public String getStringData();
+
+ public Character getCharacterData();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertCommand.java
new file mode 100644
index 000000000..38d2ac769
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertCommand.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.commands.nav.ICaretPositionMover;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class InsertCommand extends RangeModeCommand implements
+ ICaretPositionMover {
+
+ private IInputSourceProvider _data;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public InsertCommand(String label, IHTMLGraphicalViewer viewer,
+ IInputSourceProvider data) {
+ super(label, viewer);
+ _data = data;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange selection) {
+ DesignEdit edit = null;
+ edit = new InsertEdit(selection, getViewer(), _data);
+ edit.perform();
+ selection = new DOMRange(edit.getOperationPosition(), edit
+ .getOperationPosition());
+ return selection;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertEdit.java
new file mode 100644
index 000000000..ff4ef2f48
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/InsertEdit.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * InsertEdit will perform action at a single location, the data souce could be
+ * clipboard or keyboard.
+ *
+ * @author mengbo
+ */
+public class InsertEdit extends DeleteEdit {
+ private IInputSourceProvider _data;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.DesignEdit#operate()
+ */
+ public boolean operate() {
+ DOMRange range = getRange();
+ if (!EditModelQuery.isSame(range.getStartPosition(), range
+ .getEndPosition())) {
+ deleteRange();
+ range = new DOMRange(getOperationPosition(), getOperationPosition());
+ setRange(range);
+ }
+ if (insertNodes()) {
+ return true;
+ } else if (insertString()) {
+ return true;
+ } else {
+ return insertChar();
+ }
+ }
+
+ /**
+ * @param range
+ * @param viewer
+ */
+ public InsertEdit(DOMRange range, GraphicalViewer viewer,
+ IInputSourceProvider data) {
+ super(range, viewer);
+ _data = data;
+ }
+
+ public InsertEdit(IDOMPosition position, GraphicalViewer viewer,
+ IInputSourceProvider data) {
+ super(new DOMRange(position, position), viewer);
+ setOperationPosition(position);
+ _data = data;
+ }
+
+ public boolean insertChar() {
+ if (_data.getStringData() == null) {
+ return false;
+ }
+ IDOMPosition position = getOperationPosition();
+ if (position.isText()) {
+ Text text = EditModelQuery.getInstance().getText(position);
+ text.insertData(getOperationPosition().getOffset(), _data
+ .getCharacterData().toString());
+ setOperationPosition(new DOMPosition(text, position.getOffset() + 1));
+ } else {
+ Node refNode = position.getNextSiblingNode();
+ Text text = _document.createTextNode(_data.getCharacterData()
+ .toString());
+ position.getContainerNode().insertBefore(text, refNode);
+ setOperationPosition(new DOMPosition(text, text.getLength()));
+ }
+ return true;
+ }
+
+ public boolean insertString() {
+ String content = _data.getStringData();
+ if (content != null) {
+ IDOMPosition position = getOperationPosition();
+ if (position.isText()) {
+ Text text = EditModelQuery.getInstance().getText(position);
+ text.insertData(getOperationPosition().getOffset(), content);
+ setOperationPosition(new DOMPosition(text, position.getOffset()
+ + content.length()));
+ } else {
+ Node refNode = position.getNextSiblingNode();
+ Text text = _document.createTextNode(content);
+ position.getContainerNode().insertBefore(text, refNode);
+ setOperationPosition(new DOMPosition(text, text.getLength()));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private boolean insertNodes() {
+ Node[] nodes = _data.getNodes();
+ if (nodes == null) {
+ return false;
+ }
+ IDOMPosition position = getOperationPosition();
+ if (position == null) {
+ return false;
+ }
+ Node refNode = null;
+ if (position.isText()) {
+ position = DOMPositionHelper.splitText(position);
+ }
+ refNode = position.getNextSiblingNode();
+ Node parent = position.getContainerNode();
+ Node node = null;
+ for (int i = 0; i < nodes.length; i++) {
+ node = DOMUtil.cloneNodeDeep(_document, nodes[i]);
+ String prefix = node.getPrefix();
+ String name = node.getLocalName();
+ if (name != null
+ && IJMTConstants.URI_JSP.equals(prefix)
+ && (node.getLocalName().startsWith(
+ IJSPCoreConstants.TAG_LEADING_DIRECTIVE)
+ || IJSPCoreConstants.TAG_DECLARATION.equals(name)
+ || IJSPCoreConstants.TAG_EXPRESSION.equals(name) || IJSPCoreConstants.TAG_SCRIPTLET
+ .equals(name))) {
+ // it is a jsp tag
+ ((IDOMElement) node).setJSPTag(true);
+ }
+ node = parent.insertBefore(node, refNode);
+ }
+
+ if (node != null) {
+ setOperationPosition(new DOMRefPosition(node, true));
+ } else if (refNode != null) {
+ setOperationPosition(new DOMRefPosition(refNode, false));
+ } else {
+ setOperationPosition(new DOMRefPosition(parent.getLastChild(), true));
+ }
+ return true;
+ }
+
+ private boolean splitNode() {
+ if ((getViewer()).getSelection() instanceof DesignRange
+ && _data.getCharacterData() != null
+ && _data.getCharacterData().charValue() == '\r') {
+ DesignRange range = (DesignRange) (getViewer()).getSelection();
+ Node node = range.getStartPosition().getContainerNode();
+ if (EditModelQuery.isText(node)) {
+ node = node.getParentNode();
+ }
+ if (EditModelQuery.isListItem(node)) {
+ IDOMPosition position = DOMPositionHelper.toDOMPosition(range
+ .getStartPosition());
+ // split text and it's parent.
+ position = EditHelper.splitNode(position);
+ position = EditHelper.splitNode(position);
+ position = EditHelper.moveInto(position.getNextSiblingNode(),
+ new InlineEditingNavigationMediator(new ActionData(
+ ActionData.INLINE_EDIT, null)), true);
+ setOperationPosition(position);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/KeyboardData.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/KeyboardData.java
new file mode 100644
index 000000000..c9213b676
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/KeyboardData.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.gef.DefaultEditDomain;
+import org.eclipse.gef.EditDomain;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class KeyboardData implements IInputSourceProvider {
+ private Character _keyCode;
+
+ private int _stateMask;
+
+ private GraphicalViewer _viewer;
+
+ public KeyboardData(char code, int mask, GraphicalViewer viewer) {
+ if ((mask & SWT.SHIFT) != 0) {
+ _keyCode = new Character(Character.toUpperCase(code));
+ } else {
+ _keyCode = new Character(code);
+ }
+ _stateMask = mask;
+ _viewer = viewer;
+ }
+
+ /**
+ * @return Returns the keyCode.
+ */
+ public int getKeyCode() {
+ return _keyCode.charValue();
+ }
+
+ /**
+ * @param keyCode
+ * The keyCode to set.
+ */
+ public void setKeyCode(char keyCode) {
+ this._keyCode = new Character(keyCode);
+ }
+
+ /**
+ * @return Returns the stateMask.
+ */
+ public int getStateMask() {
+ return _stateMask;
+ }
+
+ /**
+ * @param stateMask
+ * The stateMask to set.
+ */
+ public void setStateMask(int stateMask) {
+ this._stateMask = stateMask;
+ }
+
+ public Node getSpecialNode(KeyboardData keyCode) {
+ Object name;
+ EditDomain domain = _viewer.getEditDomain();
+ Document document = null;
+ if (domain instanceof DefaultEditDomain) {
+ document = (Document) ((HTMLEditor) (((DefaultEditDomain) domain)
+ .getEditorPart())).getDOMDocument();
+ }
+ // if ((keyCode.getStateMask() & SWT.SHIFT) != 0)
+ {
+ if ((name = EditModelQuery.CHAR_NODE_MAP.get(keyCode
+ .getCharacterData())) != null) {
+ return document.createElement((String) name);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return Returns the _data.
+ */
+ public Node[] getNodes() {
+ Node node = getSpecialNode(this);
+ if (node != null) {
+ return new Node[] { node };
+ }
+ return null;
+ }
+
+ public String getStringData() {
+ return _keyCode.toString();
+ }
+
+ // public Key
+ public Character getCharacterData() {
+ return _keyCode;
+ }
+
+ public char getChar() {
+ return _keyCode.charValue();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/Paragraph.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/Paragraph.java
new file mode 100644
index 000000000..1c879aee2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/Paragraph.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class Paragraph {
+ private DOMRange _range;
+
+ public Paragraph(IDOMPosition start, IDOMPosition end) {
+ _range = new DOMRange(start, end);
+ }
+
+ public Node getLowestContainer() {
+ return EditModelQuery.getInstance().getCommonAncestor(
+ _range.getStartPosition(), _range.getEndPosition());
+ }
+
+ /**
+ * @return Returns the _end.
+ */
+ public final IDOMPosition getStart() {
+ return _range.isOrdered() ? _range.getStartPosition() : _range
+ .getEndPosition();
+ }
+
+ /**
+ * @return Returns the _start.
+ */
+ public final IDOMPosition getEnd() {
+ return _range.isOrdered() ? _range.getEndPosition() : _range
+ .getStartPosition();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphApplyStyleCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphApplyStyleCommand.java
new file mode 100644
index 000000000..444040214
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphApplyStyleCommand.java
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.Arrays;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.actions.range.NoneParagraphStyleAction;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.dom.IDOMRefPosition;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class ParagraphApplyStyleCommand extends ApplyStyleCommand {
+ /**
+ * @param viewer
+ * @param tag
+ * @param property
+ * @param value
+ */
+ public ParagraphApplyStyleCommand(IHTMLGraphicalViewer viewer, String tag,
+ String property, String value) {
+ super(viewer, tag, property, value);
+ }
+
+ public ParagraphApplyStyleCommand(IHTMLGraphicalViewer viewer,
+ Element node, String property, String value) {
+ super(viewer, node, property, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange range) {
+ if (range != null) {
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+ Node common = null;
+ Node container = null;
+ if (EditModelQuery.isSame(range)) {
+ container = start.getContainerNode();
+ ParagraphFinder finder = new ParagraphFinder(start);
+ Paragraph p = finder.getParagraph(start);
+ start = p.getStart();
+ end = p.getEnd();
+ common = p.getLowestContainer();
+ } else {
+ common = EditModelQuery.getInstance().getCommonAncestor(start,
+ end);
+ }
+ DOMRange rt;
+ // This code is for h1-h6 only, it may need to be replaced.
+ if ((rt = replaceExistingH(start, end)) != null) {
+ return rt;
+ }
+ // replace existing p
+ if (getTag().equalsIgnoreCase(IHTMLConstants.TAG_P)) {
+ rt = replaceExistingP(start, end);
+ if (rt != null) {
+ return rt;
+ }
+ }
+ if (start.getContainerNode() == end.getContainerNode()) {
+ int offset1 = start.getOffset();
+ int offset2 = end.getOffset();
+ IDOMPosition old = start;
+ start = split(start);
+ // parent is splited
+ if (start != old) {
+ container = start.getNextSiblingNode();
+ offset2 -= offset1;
+ end = new DOMPosition(container, offset2);
+ }
+ end = split(end);
+ } else {
+ start = split(common, start);
+ end = split(common, end);
+ }
+ range = InsertStyleTag(new DOMRange(start, end));
+ }
+ return range;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#canExecute()
+ */
+ public boolean canExecute() {
+ return true;
+ }
+
+ /*
+ * Try to split the node so that we can avoid wrap its children directly.
+ * Begining from 'position' the split can reach as high as the level of
+ * 'common'.
+ */
+ private IDOMPosition split(Node common, IDOMPosition position) {
+ Assert.isTrue(EditModelQuery.isChild(common, position
+ .getContainerNode()));
+ Node container = position.getContainerNode();
+ String[] styleNodes = new String[EditModelQuery.HTML_STYLE_NODES.size()];
+ EditModelQuery.HTML_STYLE_NODES.toArray(styleNodes);
+ while (EditModelQuery.isText(container) || (container != common && //
+ EditModelQuery.containItem(styleNodes, container, true))) {
+ IDOMPosition old = position;
+ position = EditHelper.splitNode(position);
+ if (old == position) {
+ int pos = EditHelper.getLocation(position);
+ switch (pos) {
+ case -1:
+ position = new DOMRefPosition(position.getContainerNode(),
+ false);
+ break;
+ case 1:
+ position = new DOMRefPosition(position.getContainerNode(),
+ true);
+ }
+ }
+ Node containerBackup = container;
+ container = container.getParentNode();
+ if (containerBackup.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_P)) {
+ container.removeChild(containerBackup);
+ }
+ }
+ return position;
+ }
+
+ /*
+ * Split the position's container node only.
+ */
+ private IDOMPosition split(IDOMPosition position) {
+ Node container = position.getContainerNode();
+ String[] styleNodes = new String[EditModelQuery.HTML_STYLE_NODES.size()];
+ EditModelQuery.HTML_STYLE_NODES.toArray(styleNodes);
+ if (EditModelQuery.isText(container)
+ || EditModelQuery.containItem(styleNodes, container, true)) {
+ return EditHelper.splitNode(position);
+ }
+ return position;
+ }
+
+ private DOMRange replaceExistingH(IDOMPosition start, IDOMPosition end) {
+ Node common = EditModelQuery.getInstance()
+ .getCommonAncestor(start, end);
+ // Here we insert some code to avoid creating tags duplicated. but these
+ // are not the entire cases.
+ if (Arrays.asList(NoneParagraphStyleAction.HH).contains(
+ getAName(getTag()).toLowerCase())
+ && Arrays.asList(NoneParagraphStyleAction.HH).contains(
+ getAName(common.getNodeName()).toLowerCase())) {
+ // uncheck action menu
+ if (getAName(getTag()).toLowerCase().equalsIgnoreCase(
+ getAName(common.getNodeName()).toLowerCase())) {
+ NodeList nodes = common.getChildNodes();
+
+ for (int i = 0, size = nodes.getLength(); i < size; i++) {
+ common.getParentNode().insertBefore(nodes.item(i), common);
+ }
+ common.getParentNode().removeChild(common);
+ return new DOMRange(start, end);
+ }
+ start = DOMPositionHelper.toDOMRefPosition(start);
+ end = DOMPositionHelper.toDOMRefPosition(end);
+ Node newHNode = EditModelQuery.getDocumentNode(common)
+ .createElement(getTag());
+ EditModelQuery.copyChildren(common, newHNode);
+ common.getParentNode().replaceChild(newHNode, common);
+ return new DOMRange(start, end);
+ }
+ return null;
+ }
+
+ private DOMRange replaceExistingP(IDOMPosition start, IDOMPosition end) {
+ // find the selected startNode,endNode and start node's parent node
+ Node startNode = start instanceof IDOMRefPosition ? start
+ .getNextSiblingNode() : start.getContainerNode();
+ Node endNode = end instanceof IDOMRefPosition ? end
+ .getPreviousSiblingNode() : end.getContainerNode();
+ Node parentNode = startNode.getParentNode();
+
+ if (!(start.isText()) && start instanceof DOMPosition) {
+ startNode = startNode.getChildNodes().item(start.getOffset());
+ parentNode = start.getContainerNode();
+ }
+ if (!(end.isText()) && end instanceof DOMPosition) {
+ // because the offset is based on the position between nodes,so we
+ // need to reduce one from the offset
+ // in order to get the correct end node.
+ endNode = endNode.getChildNodes().item(end.getOffset() - 1);
+ }
+
+ // compute selected character number in the text or selected element
+ // number under a node
+ int len = 0;
+ if (start instanceof DOMPosition && end instanceof DOMPosition
+ || start instanceof IDOMPosition && end instanceof IDOMPosition) {
+ len = end.getOffset() - start.getOffset();
+ } else {
+ IDOMRefPosition startRef = null;
+ IDOMRefPosition endRef = null;
+ if (!(start.isText()) && start instanceof DOMPosition) {
+ startRef = new DOMRefPosition(startNode, false);
+ } else if (!(end.isText()) && end instanceof DOMPosition) {
+ endRef = new DOMRefPosition(endNode, true);
+ }
+ len = (endRef != null ? endRef.getOffset() : end.getOffset())
+ - (startRef != null ? startRef.getOffset() : start
+ .getOffset());
+ }
+
+ // if a full Text node is selected,and the Text node is the only child
+ // of its parent
+ if ((startNode == endNode) && (startNode instanceof Text)) {
+ TextEditPart part = (TextEditPart) ((INodeNotifier) startNode)
+ .getAdapterFor(EditPart.class);
+ boolean condition = false;
+ if (start instanceof IDOMRefPosition
+ || (start instanceof DOMPosition && !start.isText())) {
+ condition = parentNode.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_P)
+ && parentNode.getChildNodes().getLength() == 1;
+ } else {
+ condition = parentNode.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_P)
+ && parentNode.getChildNodes().getLength() == 1
+ && part.getTextData().length() == len;
+ }
+ if (condition) {
+ // if uncheck the align action
+ if (this._applyingNode
+ .getAttribute(IHTMLConstants.ATTR_ALIGN)
+ .equals(
+ ((Element) parentNode)
+ .getAttribute(IHTMLConstants.ATTR_ALIGN))) {
+ ((Element) parentNode)
+ .removeAttribute(IHTMLConstants.ATTR_ALIGN);
+ IDOMPosition startPos = new DOMPosition(parentNode, 0);
+ IDOMPosition endPos = new DOMRefPosition(endNode, true);
+ return new DOMRange(startPos, endPos);
+ }
+ // else replace the align attribute
+ /**
+ * this._applyingNode.appendChild(startNode);
+ * parentNode.getParentNode().replaceChild(this._applyingNode,
+ * parentNode);
+ */
+ String align = this._applyingNode
+ .getAttribute(IHTMLConstants.ATTR_ALIGN);
+ ((Element) parentNode).setAttribute(IHTMLConstants.ATTR_ALIGN,
+ align);
+
+ IDOMPosition startPos = new DOMPosition(parentNode, 0);
+ IDOMPosition endPos = new DOMRefPosition(endNode, true);
+ return new DOMRange(startPos, endPos);
+ }
+ } else {
+ if (parentNode != null
+ && parentNode.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_P)
+ && parentNode.getChildNodes().getLength() == len) {
+ if (this._applyingNode
+ .getAttribute(IHTMLConstants.ATTR_ALIGN)
+ .equals(
+ ((Element) parentNode)
+ .getAttribute(IHTMLConstants.ATTR_ALIGN))) {
+ ((Element) parentNode)
+ .removeAttribute(IHTMLConstants.ATTR_ALIGN);
+ IDOMPosition startPos = new DOMPosition(parentNode, 0);
+ IDOMPosition endPos = new DOMRefPosition(endNode, true);
+ return new DOMRange(startPos, endPos);
+ }
+
+ /**
+ * Node sibling = startNode.getNextSibling();
+ * this._applyingNode.appendChild(startNode); Node
+ * endNodeSibling = endNode.getNextSibling(); while (sibling !=
+ * null && startNode != endNode && sibling != endNodeSibling) {
+ * Node tempNode = sibling.getNextSibling();
+ * this._applyingNode.appendChild(sibling); sibling = tempNode; }
+ * parentNode.getParentNode().replaceChild(this._applyingNode,
+ * parentNode);
+ */
+ String align = this._applyingNode
+ .getAttribute(IHTMLConstants.ATTR_ALIGN);
+ ((Element) parentNode).setAttribute(IHTMLConstants.ATTR_ALIGN,
+ align);
+
+ IDOMPosition startPos = new DOMPosition(parentNode, 0);
+ IDOMPosition endPos = new DOMRefPosition(endNode, true);
+ return new DOMRange(startPos, endPos);
+ }
+ }
+ return null;
+ }
+
+ private DOMRange InsertStyleTag(DOMRange range) {
+ if (range == null || range.isEmpty()) {
+ return null;
+ }
+
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+
+ Node startContainer = start.getContainerNode();
+ Node endContainer = end.getContainerNode();
+
+ Node common = DOMUtil.findCommonAncester(start.getContainerNode(), end
+ .getContainerNode());
+ if (common == null) {
+ // should not happen.
+ return null;
+ } else {
+
+ if (startContainer instanceof Text) {
+ // if the start offset is 0,then skip split the Text
+ if (start.getOffset() > 0) {
+ startContainer = ((Text) startContainer).splitText(start
+ .getOffset());
+ start = new DOMRefPosition(startContainer, false);
+ }
+ } else {
+ startContainer = start.getNextSiblingNode();
+ }
+ if (endContainer instanceof Text) {
+ if (end.getOffset() > 0) {
+ endContainer = ((Text) endContainer).splitText(end
+ .getOffset());
+ endContainer = endContainer.getPreviousSibling();
+ } else {
+ endContainer = endContainer.getPreviousSibling();
+ }
+ } else {
+ endContainer = end.getPreviousSiblingNode();
+ }
+
+ // now the startContainer and the endContainer should share the same
+ // parent
+ Element newNode = createStyleElement();
+ startContainer.getParentNode()
+ .insertBefore(newNode, startContainer);
+
+ Node sibling = startContainer.getNextSibling();
+ newNode.appendChild(startContainer);
+ Node endNodeSibling = endContainer.getNextSibling();
+ while (sibling != null && startContainer != endContainer
+ && sibling != endNodeSibling) {
+ Node tempNode = sibling.getNextSibling();
+ newNode.appendChild(sibling);
+ sibling = tempNode;
+ }
+
+ IDOMPosition startPos = new DOMPosition(newNode, 0);
+ IDOMPosition endPos = new DOMRefPosition(endContainer, true);
+ return new DOMRange(startPos, endPos);
+ }
+ }
+
+ private static String getAName(String name) {
+ return name == null ? "" : name;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphFinder.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphFinder.java
new file mode 100644
index 000000000..af4b6c998
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphFinder.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class ParagraphFinder {
+ private IDOMPosition _position;
+
+ /**
+ * @param position
+ */
+ public ParagraphFinder(IDOMPosition position) {
+ _position = position;
+ }
+
+ public IDOMPosition getPosition() {
+ return _position;
+ }
+
+ private Node findInlineSiblings(IDOMPosition position, List result,
+ boolean forward) {
+ Node container = EditModelQuery.getInstance().getSibling(position,
+ forward);
+ if (!forward) {
+ while (container != null) {
+ if (EditModelQuery.isInline(container)) {
+ result.add(container);
+ } else {
+ return container;
+ }
+ container = container.getPreviousSibling();
+ }
+ } else {
+ while (container != null) {
+ if (EditModelQuery.isInline(container)) {
+ result.add(container);
+ } else {
+ return container;
+ }
+ container = container.getNextSibling();
+ }
+ }
+ // the result will be non-zero length.
+ return null;
+ }
+
+ private Node getParagraphNodes(IDOMPosition position, List result,
+ boolean forward) {
+ Node sResult = findInlineSiblings(position, result, forward);
+ Node container = position.getContainerNode();
+ container = position.isText() ? container.getParentNode() : container;
+ while (sResult == null) {
+ // stop at block, special container and H style nodes.
+ if (EditModelQuery.isBlockNode(container)
+ || EditModelQuery.isDocument(container)
+ || (container.getLocalName() != null && (container
+ .getLocalName().equals(IJSFConstants.TAG_VIEW) || container
+ .getLocalName().equalsIgnoreCase(
+ IHTMLConstants.TAG_HTML)))) {
+ return container;
+ }
+ position = new DOMRefPosition(container, forward);
+ sResult = findInlineSiblings(position, result, forward);
+ container = container.getParentNode();
+ }
+ return sResult;
+ }
+
+ /**
+ * Search for an area between two block nodes or within a block node, search
+ * will stop before or under a node which has block display-type, or
+ * particular container like "html", jsf "view", .etc, two positions (left
+ * and right) are returned in result.
+ *
+ * The searcher will search parent's directly children, if no block node is
+ * found, then go up the node tree to search again.
+ *
+ * @param position
+ * @param result
+ */
+ public Paragraph getParagraph(IDOMPosition position) {
+ List tempResult = new ArrayList();
+ IDOMPosition p1, p2;
+ Node r1 = getParagraphNodes(position, tempResult, true);
+ if (EditModelQuery.isChild(r1, position.getContainerNode())) {
+ p1 = new DOMPosition(r1, r1.getChildNodes().getLength());
+ } else {
+ p1 = new DOMRefPosition(r1, false);
+ }
+
+ Node r2 = getParagraphNodes(position, tempResult, false);
+ if (EditModelQuery.isChild(r2, position.getContainerNode())) {
+ p2 = new DOMPosition(r2, 0);
+ } else {
+ p2 = new DOMRefPosition(r2, true);
+ }
+ return new Paragraph(p1, p2);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphUnapplyStyleCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphUnapplyStyleCommand.java
new file mode 100644
index 000000000..a89a6ff4a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/ParagraphUnapplyStyleCommand.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class ParagraphUnapplyStyleCommand extends ApplyStyleCommand {
+ private String _groupTags[];
+
+ /**
+ * @param viewer
+ * @param tag
+ * @param property
+ * @param value
+ */
+ public ParagraphUnapplyStyleCommand(IHTMLGraphicalViewer viewer,
+ String[] tags, String property, String value) {
+ super(viewer, "", property, value);
+ _groupTags = tags;
+ }
+
+ /**
+ * @param viewer
+ * @param node
+ * @param property
+ * @param value
+ */
+ public ParagraphUnapplyStyleCommand(IHTMLGraphicalViewer viewer,
+ Element node, String property, String value) {
+ super(viewer, node, property, value);
+ // TODO Auto-generated constructor stub
+ }
+
+ private DOMRange removeExistingStyles(IDOMPosition start, IDOMPosition end) {
+ Node common = null;
+ if (EditModelQuery.isSame(start, end)) {
+ ParagraphFinder finder = new ParagraphFinder(start);
+ Paragraph p = finder.getParagraph(start);
+ start = p.getStart();
+ end = p.getEnd();
+ common = p.getLowestContainer();
+ } else {
+ common = EditModelQuery.getInstance().getCommonAncestor(start, end);
+ }
+ // Here we insert some code to avoid creating tags duplicated. but these
+ // are not the entire cases.
+ // if (Arrays.asList(_groupTags).contains(common.getNodeName()))
+ if (EditModelQuery.containItem(_groupTags, common, true)) {
+ start = DOMPositionHelper.toDOMRefPosition(start);
+ end = DOMPositionHelper.toDOMRefPosition(end);
+ Node parent = common.getParentNode();
+ EditModelQuery.copyChildren(common, parent);
+ common.getParentNode().removeChild(common);
+ return new DOMRange(start, end);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange range) {
+ return removeExistingStyles(range.getStartPosition(), range
+ .getEndPosition());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/PasteCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/PasteCommand.java
new file mode 100644
index 000000000..13ed28de1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/PasteCommand.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class PasteCommand extends RangeModeCommand {
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public PasteCommand(IHTMLGraphicalViewer viewer) {
+ super(CommandResources.getString("PasteCommand.Label.Paste"), viewer); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange selection) {
+ InsertEdit edit = new InsertEdit(selection, getViewer(),
+ new ClipboardData(getViewer().getControl()));
+ if (edit.operate()) {
+ return new DOMRange(edit.getOperationPosition(), edit
+ .getOperationPosition());
+ } else {
+ return selection;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/RangeModeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/RangeModeCommand.java
new file mode 100644
index 000000000..40f78b736
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/RangeModeCommand.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public abstract class RangeModeCommand extends DesignerCommand {
+ private static final Logger _log = PDPlugin
+ .getLogger(RangeModeCommand.class);
+
+ DOMRange _resultRange = null;
+
+ public RangeModeCommand(String label, IHTMLGraphicalViewer viewer) {
+ super(label, viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#prePreExecute()
+ */
+ protected boolean prePreExecute() {
+ int position = -1;
+ int length = -1;
+ ISelection selection = getViewer().getSelection();
+ if (selection != null) {
+ if (getViewer().isInRangeMode()) {
+ DesignRange range = (DesignRange) selection;
+ if (range.isValid()) {
+ IDOMPosition domPos = DOMPositionHelper.toDOMPosition(range
+ .getStartPosition());
+ IDOMPosition domEnd = DOMPositionHelper.toDOMPosition(range
+ .getEndPosition());
+ if (!EditValidateUtil.validPosition(domPos)
+ || !EditValidateUtil.validPosition(domEnd)) {
+ return false;
+ }
+ position = EditModelQuery.getIndexedRegionLocation(domPos);
+ int end = EditModelQuery.getIndexedRegionLocation(domEnd);
+ if (end < position) {
+ length = position - end;
+ position = end;
+ } else {
+ length = end - position;
+ }
+ }
+ } else {
+ Object object = ((IStructuredSelection) selection)
+ .getFirstElement();
+ if (object instanceof ElementEditPart) {
+ Node node = ((ElementEditPart) object).getIDOMNode();
+ position = EditModelQuery.getNodeStartIndex(node);
+ length = EditModelQuery.getNodeLenth(node);
+ } else {
+ return false;
+ }
+ }
+ if (position >= 0 && length >= 0) {
+ getModel().beginRecording(this, getLabel(), position, length);
+ } else {
+ getModel().beginRecording(this, getLabel());
+ }
+ getViewer().startSelectionChange();
+ getModel().aboutToChangeModel();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected final void doExecute() {
+ DesignRange range = getViewer().getRangeSelection();
+ if (range != null && range.isValid()) {
+ DOMRange domrange = (range == null || !range.isValid()) ? null
+ : toDOMRange(range);
+ _resultRange = doRangeExecute(domrange);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected final ISelection getAfterCommandDesignerSelection() {
+ try {
+ if (_resultRange == null) {
+ return null;
+ }
+ IDOMPosition startPos = _resultRange.getStartPosition();
+ DesignPosition start = DOMPositionHelper.toDesignPosition(startPos);
+ if (_resultRange.isEmpty()) {
+ return new DesignRange(start, start);
+ } else {
+ IDOMPosition endPos = _resultRange.getEndPosition();
+ return new DesignRange(start, DOMPositionHelper
+ .toDesignPosition(endPos));
+ }
+ } catch (Exception e) {
+ // "Selection error"
+ _log.error("Error.RangeModeCommand.SetSelection"); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ * @param range
+ * @return
+ */
+ private DOMRange toDOMRange(DesignRange range) {
+ return new DOMRange(DOMPositionHelper.toDOMPosition(range
+ .getStartPosition()), DOMPositionHelper.toDOMPosition(range
+ .getEndPosition()));
+ }
+
+ /**
+ * In the implementation of this method, should not do anything relating to
+ * EditPart. (maybe even not ICSSStyle, since not style information not
+ * refreshed yet)
+ *
+ * @return null means no change have been done to the model. In this case,
+ * system may choose to cancel undo recorrding, etc.
+ */
+ protected abstract DOMRange doRangeExecute(DOMRange selection);
+
+ protected static void appendChild(Node parent, Node ref, Node child) {
+ Node next = ref.getNextSibling();
+ if (next == null)
+ parent.appendChild(child);
+ else
+ parent.insertBefore(child, next);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/SelectAllCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/SelectAllCommand.java
new file mode 100644
index 000000000..ce6c02078
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/SelectAllCommand.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.JSFRootContainerPositionRule;
+import org.eclipse.jst.pagedesigner.validation.caret.RootContainerPositionRule;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+public class SelectAllCommand extends Command {
+ private IHTMLGraphicalViewer _viewer;
+
+ public SelectAllCommand(String label, IHTMLGraphicalViewer viewer) {
+ super(label);
+ _viewer = viewer;
+ // TODO Auto-generated constructor stub
+ }
+
+ public void execute() {
+ Node document = _viewer.getModel().getDocument();
+ IMovementMediator validator = new InlineEditingNavigationMediator(
+ new ActionData(ActionData.KEYBOARD_NAVAGATION, null));
+ Node htmlRoot = RootContainerPositionRule
+ .getBasicContainer((Document) document);
+ Node jsfRoot = JSFRootContainerPositionRule
+ .getBasicContainer((Document) document);
+ Node root;
+ if (htmlRoot != null && jsfRoot != null) {
+ if (EditModelQuery.isChild(htmlRoot, jsfRoot)) {
+ root = htmlRoot;
+ } else if (EditModelQuery.isChild(jsfRoot, htmlRoot)) {
+ root = jsfRoot;
+ } else {
+ root = htmlRoot;
+ }
+ } else {
+ if (htmlRoot != null) {
+ root = htmlRoot;
+ } else if (jsfRoot != null) {
+ root = jsfRoot;
+ } else {
+ root = document;
+ }
+ }
+ IDOMPosition position1, position2;
+ // if (root.hasChildNodes())
+ // {
+ // Node first = root.getFirstChild();
+ // position1 = new DOMRefPosition(first, false);
+ // Node last = root.getLastChild();
+ // position2 = new DOMRefPosition(last, true);
+ // }
+ // else
+ // {
+ position1 = new DOMPosition(root, 0);
+ position2 = new DOMPosition(root, root.getChildNodes().getLength());
+ // }
+ if (!validator.isValidPosition(position1)) {
+ position1 = EditHelper.moveToNextEditPosition(position1, true,
+ validator);
+ }
+ if (!validator.isValidPosition(position2)) {
+ position2 = EditHelper.moveToNextEditPosition(position2, false,
+ validator);
+ }
+ if (EditValidateUtil.validPosition(position1)
+ && EditValidateUtil.validPosition(position2)) {
+ _viewer.setRange(DOMPositionHelper.toDesignPosition(position1),
+ DOMPositionHelper.toDesignPosition(position2));
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/UnapplyStyleCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/UnapplyStyleCommand.java
new file mode 100644
index 000000000..b2c05e482
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/UnapplyStyleCommand.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class UnapplyStyleCommand extends ApplyStyleCommand {
+ /**
+ * @param viewer
+ * @param tag
+ * @param property
+ * @param value
+ */
+ public UnapplyStyleCommand(IHTMLGraphicalViewer viewer, String tag,
+ String property, String value) {
+ super(viewer, tag, property, value);
+ }
+
+ /**
+ * @param viewer
+ * @param node
+ * @param property
+ * @param value
+ */
+ public UnapplyStyleCommand(IHTMLGraphicalViewer viewer, Element node,
+ String property, String value) {
+ super(viewer, node, property, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
+ */
+ protected DOMRange doRangeExecute(DOMRange range) {
+ if (range == null || range.isEmpty()) {
+ return null;
+ }
+
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+
+ Node common = DOMUtil.findCommonAncester(start.getContainerNode(), end
+ .getContainerNode());
+ if (common == null) {
+ // should not happen.
+ return null;
+ }
+
+ if (common instanceof Text) {
+ doTextNodeStyleApply((Text) common, start.getOffset(), end
+ .getOffset());
+ }
+
+ return null;
+ }
+
+ /**
+ * @param start
+ * @param end
+ * @param common
+ */
+ private DOMRange doTextNodeStyleApply(Text textNode, int startOffset,
+ int endOffset) {
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/WorkNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/WorkNode.java
new file mode 100644
index 000000000..9613e2f96
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/range/WorkNode.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.range;
+
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class WorkNode {
+ private WorkNode parent;
+
+ private WorkNode previous;
+
+ private WorkNode next;
+
+ private Node node;
+
+ private int pos[];
+
+ private boolean isRoot;
+
+ public WorkNode(Node node, final int pos1, final int pos2) {
+ this.pos = resoveOffsets(node, pos1, pos2);
+ this.node = node;
+ }
+
+ /**
+ * @return Returns the node.
+ */
+ public Node getNode() {
+ return node;
+ }
+
+ /**
+ * @param node
+ * The node to set.
+ */
+ public void setNode(Node node) {
+ this.node = node;
+ }
+
+ public int[] getQualifiedOffsets() {
+ int result[] = new int[] { getPosOffsets()[0], getPosOffsets()[1] };
+ result[0] = result[0] < 0 ? 0 : result[0];
+ int length = EditModelQuery.getNodeLenth(node);
+ result[0] = result[0] > length ? length : result[0];
+ result[1] = result[1] < 0 ? 0 : result[1];
+ result[1] = result[1] > length ? length : result[1];
+ return result;
+ }
+
+ /**
+ * @return Returns the pos.
+ */
+ public int[] getPosOffsets() {
+ return pos;
+ }
+
+ /**
+ * @return Returns the isRoot.
+ */
+ public boolean isRoot() {
+ return isRoot;
+ }
+
+ /**
+ * @param isRoot
+ * The isRoot to set.
+ */
+ public void setRoot(boolean isRoot) {
+ this.isRoot = isRoot;
+ }
+
+ /**
+ * @return Returns the next.
+ */
+ public WorkNode getNext() {
+ return next;
+ }
+
+ /**
+ * @param next
+ * The next to set.
+ */
+ public void setNext(WorkNode next) {
+ this.next = next;
+ }
+
+ /**
+ * @return Returns the parent.
+ */
+ public WorkNode getParent() {
+ return parent;
+ }
+
+ /**
+ * @param parent
+ * The parent to set.
+ */
+ public void setParent(WorkNode parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * @return Returns the previous.
+ */
+ public WorkNode getPrevious() {
+ return previous;
+ }
+
+ /**
+ * @param previous
+ * The previous to set.
+ */
+ public void setPrevious(WorkNode previous) {
+ this.previous = previous;
+ }
+
+ private int[] resoveOffsets(Node node, int pos1, int pos2) {
+ int left = EditModelQuery.getNodeStartIndex(node);
+ return new int[] { pos1 - left, pos2 - left };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Node:").append(node).append(" pos[]:").append(pos);
+ return sb.toString();
+ }
+
+ public boolean isWholeSelected() {
+ int start = EditModelQuery.getNodeStartIndex(node);
+ int end = EditModelQuery.getNodeEndIndex(node);
+ return getQualifiedOffsets()[0] <= 0
+ && getQualifiedOffsets()[1] >= end - start;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/AddSubNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/AddSubNodeCommand.java
new file mode 100644
index 000000000..9c830e10c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/AddSubNodeCommand.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class AddSubNodeCommand extends SingleNodeCommand {
+ private IDOMElement _parent, _child;
+
+ private String _tagName;
+
+ private String _url;
+
+ private Map _attributes;
+
+ /**
+ * @param label
+ * @param node
+ */
+ public AddSubNodeCommand(String label, IDOMElement node, String name,
+ String url, Map attributs) {
+ super(label, node);
+ this._parent = node;
+ this._tagName = name;
+ this._url = url;
+ this._attributes = attributs;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ String prefix = JSPUtil.getOrCreatePrefix(_parent.getModel(), _url,
+ null);
+ _child = (IDOMElement) _parent.getOwnerDocument().createElement(
+ prefix + ":" + _tagName);
+ for (Iterator iterator = _attributes.keySet().iterator(); iterator
+ .hasNext();) {
+ String key = (String) iterator.next();
+ String value = (String) _attributes.get(key);
+ _child.setAttribute(key, value);
+ }
+ _parent.appendChild(_child);
+ }
+
+ public IDOMElement getChildNode() {
+ return _child;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeAttributeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeAttributeCommand.java
new file mode 100644
index 000000000..77fa9c028
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeAttributeCommand.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * This command is for change an single attribute of an IDOMElement. Normally
+ * used by the properties view.
+ *
+ * @author mengbo
+ */
+public class ChangeAttributeCommand extends SingleNodeCommand {
+ private IDOMElement _element;
+
+ private String _attrValue;
+
+ private String _attrName;
+
+ private Map _attributes;
+
+ private boolean _keepEmptyAttribute = false;
+
+ /**
+ *
+ * @param label
+ * @param node
+ * @param attrName
+ * @param attrValue
+ * if null means remove the specified attribute
+ */
+ public ChangeAttributeCommand(String label, IDOMElement node,
+ String attrName, String attrValue) {
+ super(label, node);
+ _element = node;
+ _attrName = attrName;
+ _attrValue = attrValue;
+ _attributes = null;
+ }
+
+ public ChangeAttributeCommand(String label, IDOMElement node, Map attributes) {
+ super(label, node);
+ _element = node;
+ _attributes = attributes;
+ _attrName = null;
+ _attrValue = null;
+ }
+
+ protected void doExecute() {
+ if (_attrName != null) {
+ updateElement(_attrName, _attrValue);
+ } else if (_attributes != null) {
+ for (Iterator iterator = _attributes.keySet().iterator(); iterator
+ .hasNext();) {
+ String name = (String) iterator.next();
+ String value = (String) _attributes.get(name);
+ if (isSameValue(value, _element.getAttribute(name))) {
+ continue;
+ }
+ updateElement(name, value);
+ }
+ }
+ }
+
+ private void updateElement(String name, String value) {
+ if (_element.hasAttribute(name) && isEmptyString(value)
+ && !_keepEmptyAttribute) {
+ _element.removeAttribute(name);
+ }
+ if (!isEmptyString(value) || _keepEmptyAttribute) {
+ _element.setAttribute(name, value);
+ }
+ }
+
+ private boolean isSameValue(String value1, String value2) {
+ value1 = value1 == null ? "" : value1;
+ value2 = value2 == null ? "" : value2;
+ return value1.equals(value2);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.equals("")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @return Returns the keepEmptyAttribute.
+ */
+ public boolean isKeepEmptyAttribute() {
+ return _keepEmptyAttribute;
+ }
+
+ /**
+ * @param keepEmptyAttribute
+ * The keepEmptyAttribute to set.
+ */
+ public void setKeepEmptyAttribute(boolean keepEmptyAttribute) {
+ this._keepEmptyAttribute = keepEmptyAttribute;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeStyleCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeStyleCommand.java
new file mode 100644
index 000000000..f8bf01246
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeStyleCommand.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import java.util.Map;
+
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.commands.CommandResources;
+import org.eclipse.jst.pagedesigner.dom.DOMStyleUtil;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclaration;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.css.ElementCSSInlineStyle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ChangeStyleCommand extends SingleNodeCommand {
+ private Map _styleProperties = null;
+
+ private CSSPropertyContext _context = null;
+
+ /**
+ * @param node
+ * @param map
+ */
+ public ChangeStyleCommand(IDOMElement node, Map map) {
+ super(CommandResources
+ .getString("ChangeStyleCommand.Label.ChangeStyle"), node); //$NON-NLS-1$
+ _styleProperties = map;
+ }
+
+ /**
+ * @param node
+ * @param map
+ */
+ public ChangeStyleCommand(IDOMElement node, CSSPropertyContext context) {
+ super(CommandResources
+ .getString("ChangeStyleCommand.Label.ChangeStyle"), node); //$NON-NLS-1$
+ _context = context;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ getOriginalElement().getModel().beginRecording(this);
+ try {
+ if (_styleProperties != null) {
+ IDOMElement original = this.getOriginalElement();
+ DOMStyleUtil.insertStyle(original, _styleProperties);
+ } else if (_context != null) {
+ ICSSStyleDeclaration styleDeclaration = (ICSSStyleDeclaration) ((ElementCSSInlineStyle) getOriginalElement())
+ .getStyle();
+
+ if (styleDeclaration == null) {
+ getOriginalElement().setAttribute(IJSFConstants.ATTR_STYLE,
+ ""); //$NON-NLS-1$
+ styleDeclaration = (ICSSStyleDeclaration) ((ElementCSSInlineStyle) getOriginalElement())
+ .getStyle();
+ }
+ _context.applyModified(styleDeclaration);
+ }
+ } finally {
+ getOriginalElement().getModel().endRecording(this);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeTagCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeTagCommand.java
new file mode 100644
index 000000000..b00030035
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/ChangeTagCommand.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This is for command that changes an element's tagname and some attributes.
+ *
+ * @author mengbo
+ */
+public class ChangeTagCommand extends SingleNodeCommand {
+ private IDOMElement _element;
+
+ private String _uri;
+
+ private String _localTag;
+
+ private Map _attributes;
+
+ private boolean _moveContent;
+
+ private String _totalTag;
+
+ public ChangeTagCommand(String label, IDOMElement node, String totaltag,
+ Map attributes, boolean movecontent) {
+ super(label, node);
+ this._element = node;
+ this._totalTag = totaltag;
+ this._attributes = attributes;
+ this._moveContent = movecontent;
+ }
+
+ /**
+ * @param label
+ * @param node
+ */
+ public ChangeTagCommand(String label, IDOMElement node, String uri,
+ String tag, Map attributes, boolean movecontent) {
+ super(label, node);
+ this._element = node;
+ this._uri = uri;
+ this._localTag = tag;
+ this._attributes = attributes;
+ this._moveContent = movecontent;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ String tag = null;
+
+ if (_totalTag != null) {
+ tag = _totalTag;
+ } else {
+ if (IJMTConstants.URI_HTML.equals(_uri)) {
+ tag = _localTag;
+ } else if (IJMTConstants.URI_JSP.equals(_uri)) {
+ tag = "jsp:" + _localTag;
+ } else {
+ tag = JSPUtil.getOrCreatePrefix(getModel(), _uri, null)
+ + _localTag;
+ }
+ }
+ // we need to remove the old element and create a new one with the new
+ // tag.
+ IDOMElement replacement = (IDOMElement) _element.getOwnerDocument()
+ .createElement(tag);
+ NamedNodeMap attrs = _element.getAttributes();
+ for (int i = 0, n = attrs.getLength(); i < n; i++) {
+ Attr a = (Attr) attrs.item(i);
+ replacement.setAttribute(a.getName(), a.getValue());
+ }
+ if (_attributes != null) {
+ for (Iterator iter = _attributes.keySet().iterator(); iter
+ .hasNext();) {
+ String name = (String) iter.next();
+ String value = (String) _attributes.get(name);
+ replacement.setAttribute(name, value);
+ }
+ }
+ if (_moveContent) {
+ NodeList nl = _element.getChildNodes();
+ ArrayList list = new ArrayList();
+ for (int i = 0, n = nl.getLength(); i < n; i++) {
+ list.add(nl.item(i));
+
+ }
+ for (int i = 0, n = list.size(); i < n; i++) {
+ replacement.appendChild((Node) list.get(i));
+ }
+ }
+ _element.getParentNode().replaceChild(replacement, _element);
+ setReplacedElement(replacement);
+ }
+
+ public IDOMElement getNewElement() {
+ return getReplacedElment();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/InsertSubNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/InsertSubNodeCommand.java
new file mode 100644
index 000000000..25f6de023
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/InsertSubNodeCommand.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class InsertSubNodeCommand extends SingleNodeCommand {
+ private IDOMElement _parent, _child, _refchild;
+
+ /**
+ * @param label
+ * @param parent
+ */
+ public InsertSubNodeCommand(String label, IDOMElement parent,
+ IDOMElement child, IDOMElement refchild) {
+ super(label, parent);
+ this._parent = parent;
+ this._child = child;
+ this._refchild = refchild;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ _parent.insertBefore(_child, _refchild);
+ }
+
+ public IDOMElement getChildNode() {
+ return _child;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/RemoveSubNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/RemoveSubNodeCommand.java
new file mode 100644
index 000000000..623a976e1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/RemoveSubNodeCommand.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RemoveSubNodeCommand extends SingleNodeCommand {
+ private IDOMElement _parent, _child;
+
+ /**
+ * @param label
+ * @param node
+ */
+ public RemoveSubNodeCommand(String label, IDOMElement parent,
+ IDOMElement child) {
+ super(label, parent);
+ _parent = parent;
+ _child = child;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
+ */
+ protected void doExecute() {
+ _parent.removeChild(_child);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/SingleNodeCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/SingleNodeCommand.java
new file mode 100644
index 000000000..f258b974c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/commands/single/SingleNodeCommand.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.commands.single;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.dom.DOMRange;
+import org.eclipse.jst.pagedesigner.dom.DOMRangeHelper;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * This is the super class for those commands that change attribute or tag name
+ * of a single element.
+ *
+ * This base class helps handles selection. As after the command, the editpart
+ * may totally change, so it tried to remember the selection before command and
+ * then restore it after the command.
+ *
+ * So the limitation to child class of this command is that: the command should
+ * only change a single element node. It could remove the node and replace with
+ * a new one, but should not touch other nodes.
+ *
+ * @author mengbo
+ */
+public abstract class SingleNodeCommand extends DesignerCommand {
+ List _structuredSelectedNodes = null;
+
+ DOMRange _rangeSelection = null;
+
+ IDOMElement _originalElement;
+
+ IDOMElement _replacement;
+
+ /**
+ * @param label
+ * @param viewer
+ */
+ public SingleNodeCommand(String label, IDOMElement node) {
+ super(label, node);
+ _originalElement = node;
+ }
+
+ protected void preExecute() {
+ super.preExecute();
+ // remember current selection
+ ISelection selection = getViewer().getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Object[] array = ((IStructuredSelection) selection).toArray();
+ _structuredSelectedNodes = new ArrayList();
+ if (array != null) {
+ for (int i = 0; i < array.length; i++) {
+ EditPart part = (EditPart) array[i];
+ _structuredSelectedNodes.add(part.getModel());
+ }
+ }
+ } else if (selection instanceof DesignRange) {
+ DesignRange range = (DesignRange) selection;
+ _rangeSelection = DOMRangeHelper.toDOMRange(range);
+ }
+ }
+
+ /**
+ * this method is to be called by child class in the doExecute() method.
+ * Telling the super class that the original element will be replaced by the
+ * specified element.
+ *
+ * @param ele
+ */
+ protected void setReplacedElement(IDOMElement ele) {
+ _replacement = ele;
+ }
+
+ protected IDOMElement getReplacedElment() {
+ return _replacement;
+ }
+
+ protected IDOMElement getOriginalElement() {
+ return _originalElement;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#getAfterCommandDesignerSelection()
+ */
+ protected final ISelection getAfterCommandDesignerSelection() {
+ if (_structuredSelectedNodes != null) {
+ // handle replacement fire.
+ if (_replacement != null && _replacement != _originalElement) {
+ int index = _structuredSelectedNodes.indexOf(_originalElement);
+ if (index >= 0) {
+ _structuredSelectedNodes.set(index, _replacement);
+ }
+ }
+
+ // as the editpart may have been refreshed, so recreated the
+ // selection
+ List parts = new ArrayList();
+ for (int i = 0, size = _structuredSelectedNodes.size(); i < size; i++) {
+ Object obj = _structuredSelectedNodes.get(i);
+ if (obj instanceof INodeNotifier) {
+ EditPart part = (EditPart) ((INodeNotifier) obj)
+ .getAdapterFor(EditPart.class);
+ if (part != null)
+ parts.add(part);
+ }
+ }
+ StructuredSelection sel = new StructuredSelection(parts);
+ return sel;
+ } else if (_rangeSelection != null) {
+ DOMRange newrange = handleReplacement(_rangeSelection,
+ _originalElement, _replacement);
+ return DOMRangeHelper.toDesignRange(newrange);
+ } else {
+ return null;
+ }
+ }
+
+ private DOMRange handleReplacement(DOMRange selection,
+ IDOMElement original, IDOMElement replacement) {
+ if (replacement == null || replacement == original)
+ return selection;
+ return DOMRangeHelper.handleReplacement(selection, original,
+ replacement);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/AbstractTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/AbstractTagConverter.java
new file mode 100644
index 000000000..8bfd3ecdd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/AbstractTagConverter.java
@@ -0,0 +1,447 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.preview.PageExpressionContext;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * This is base class for all non-hidden tag converters.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class AbstractTagConverter implements ITagConverter,
+ ITagEditInfo, INodeAdapter, IDOMFactory {
+ private IDOMDocument _targetDocument;
+
+ private Element _hostElement;
+
+ private Element _resultElement;
+
+ private List _childNodes = Collections.EMPTY_LIST;
+
+ private Map _childNodePositions = Collections.EMPTY_MAP;
+
+ private int _mode;
+
+ private int _minWidth;
+
+ private int _minHeight;
+
+ private boolean _needBorderDecorator;
+
+ /**
+ *
+ */
+ public AbstractTagConverter(Element host) {
+ _hostElement = host;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#setTargetDocument(org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument)
+ */
+ public void setDestDocument(IDOMDocument document) {
+ _targetDocument = document;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#convertRefresh(java.lang.Object)
+ */
+ public final void convertRefresh(Object context) {
+ _resultElement = null;
+ _childNodes = new ArrayList();
+ _childNodePositions = new HashMap();
+
+ _resultElement = doConvertRefresh();
+ if (_resultElement instanceof INodeNotifier) {
+ ((INodeNotifier) _resultElement).addAdapter(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ // do nothing.
+ }
+
+ /**
+ * Child class should override this method. The child class should NEVER
+ * change the host DOM structure.
+ *
+ * @return the convert result. Should be an HTML element.
+ */
+ protected abstract Element doConvertRefresh();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getHostElement()
+ */
+ public final Element getHostElement() {
+ return _hostElement;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getResultElement()
+ */
+ public final Element getResultElement() {
+ return _resultElement;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getChildModeList()
+ */
+ public final List getChildModeList() {
+ return _childNodes;
+ }
+
+ /**
+ * child class should call this method.
+ *
+ * @param childNode
+ * the childNode of the hostElement that should be futher
+ * converted.
+ * @param position
+ *
+ */
+ protected void addChild(Node childNode, ConvertPosition position) {
+ _childNodes.add(childNode);
+ _childNodePositions.put(childNode, position);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getChildVisualPosition(org.w3c.dom.Node)
+ */
+ public final ConvertPosition getChildVisualPosition(Node childModel) {
+ return (ConvertPosition) _childNodePositions.get(childModel);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isVisualByHTML()
+ */
+ public boolean isVisualByHTML() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getVisualImage()
+ */
+ public Image getVisualImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#dispose()
+ */
+ public void dispose() {
+ }
+
+ protected boolean shouldIgnore(Node node) {
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ case Node.ELEMENT_NODE:
+ return false;
+ default:
+ return true;
+ }
+
+ }
+
+ /**
+ * utility method for those converter that only converts the host tag's name
+ * and directly copy children.
+ *
+ */
+ protected void copyChildren(Element src, Element dest) {
+ Node node = src.getFirstChild();
+ int index = 0;
+ for (; node != null; node = node.getNextSibling()) {
+ if (!shouldIgnore(node)) {
+ addChild(node, new ConvertPosition(dest, index++));
+ }
+ }
+ }
+
+ /**
+ * utility method for those converter that directly copy children.
+ *
+ */
+ protected void dumCopyChildren(Element src, Element dest) {
+ Node node = src.getFirstChild();
+ Document destDoc = dest.getOwnerDocument();
+ for (; node != null; node = node.getNextSibling()) {
+ if (!shouldIgnore(node)) {
+ Node n = DOMUtil.cloneNodeDeepIgnoreError(destDoc, node);
+ dest.appendChild(n);
+ }
+ }
+ }
+
+ /**
+ * In the future, the conversion result HTML DOM tree could be in another
+ * document.
+ *
+ * @return
+ */
+ public IDOMDocument getDestDocument() {
+ if (this._targetDocument != null) {
+ return this._targetDocument;
+ } else {
+ return (IDOMDocument) _hostElement.getOwnerDocument();
+ }
+ }
+
+ /**
+ * shortcut method. Child class should always use this method to create a
+ * result element.
+ *
+ * @param tagName
+ * @return
+ */
+ public Element createElement(String tagName) {
+ return getDestDocument().createElement(tagName);
+ }
+
+ /**
+ * shortcut method. Child class should always use this method to create a
+ * text node.
+ *
+ * @param text
+ * @return
+ */
+ public Text createText(String text) {
+ return getDestDocument().createTextNode(text);
+ }
+
+ protected String mapURL(String original) {
+ // TODO: how to map URL? such as original url look like:
+ // getContext().getPath()+...
+ return original;
+ }
+
+ // TODO: FIXME: XXX:
+ // if the value is expression, we may want to do something here!!!
+ protected String mapValue(String value) {
+ if (value == null) {
+ return null;
+ }
+ if (isDesignerMode()) {
+ // if there has jsf binding expressions
+ int checkPos = value.indexOf("#{");
+ if (checkPos != -1) {
+ String mapValue = "";
+ int preferType = PreferenceReader.getMapValueType();
+ switch (preferType) {
+ case PreferenceReader.FULL_EXPRESSION_TYPE:
+ mapValue = value;
+ break;
+ case PreferenceReader.LAST_EXPRESSION_TYPE:
+ String strBackup = value;
+ StringBuffer sb = new StringBuffer();
+ while (strBackup.indexOf("#{") != -1) {
+ int pos = strBackup.indexOf("#{");
+ int endBracketPos = strBackup.indexOf("}", pos + 1);
+ if (endBracketPos != -1) {
+ sb.append(strBackup.substring(0, pos + 2));
+ String exp = strBackup.substring(pos + 2,
+ endBracketPos);
+ if (allowTrim(exp)) {
+ int lastDotPos = exp.lastIndexOf(".");
+ if (lastDotPos != -1) {
+ String convertedExp = exp
+ .substring(lastDotPos + 1);
+ sb.append(convertedExp);
+ } else {
+ sb.append(exp);
+ }
+
+ } else {
+ sb.append(exp);
+ }
+ sb.append("}");
+ } else {
+ break;
+ }
+ if (strBackup.length() > endBracketPos + 1) {
+ strBackup = strBackup.substring(endBracketPos + 1);
+ } else {
+ strBackup = "";
+ break;
+ }
+
+ }
+ sb.append(strBackup);
+ mapValue = sb.toString();
+ break;
+ case PreferenceReader.REAL_VALUE_TYPE:
+ // TODO calculate the expression value
+ default:
+ mapValue = value;
+ break;
+ }
+
+ return mapValue;
+ }
+ } else {
+ // preview mode. let's try to display the value.
+ try {
+ return (String) PageExpressionContext.getCurrent()
+ .evaluateExpression(value, String.class, null);
+ } catch (Exception ex) {
+ // can't calculate the result. ignore.
+ // ex.printStackTrace();
+ }
+ }
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#needBorderDecorator()
+ */
+ public boolean needBorderDecorator() {
+ return this._needBorderDecorator;
+ }
+
+ public void setNeedBorderDecorator(boolean b) {
+ this._needBorderDecorator = b;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#needTableDecorator()
+ */
+ public boolean needTableDecorator() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ if (type == ITagEditInfo.class) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param mode
+ */
+ public final void setMode(int mode) {
+ this._mode = mode;
+ }
+
+ public final boolean isPreviewMode() {
+ return this._mode == IConverterFactory.MODE_PREVIEW;
+ }
+
+ public final boolean isDesignerMode() {
+ return this._mode == IConverterFactory.MODE_DESIGNER;
+ }
+
+ public final int getMode() {
+ return this._mode;
+ }
+
+ /**
+ * The method is used to judge whether the value binding and method binding
+ * expression is allowed to be trimmed.Currently only expression contains
+ * only letter,digit,and '.' is allowed to be trimmed.
+ *
+ * @param expression
+ * value binding or method binding expression
+ * @return
+ */
+ private boolean allowTrim(String expression) {
+ for (int i = 0, size = expression.length(); i < size; i++) {
+ char ch = expression.charAt(i);
+ if (!Character.isLetterOrDigit(ch) && (ch != '.') && (ch != '_')) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#getMinWidth()
+ */
+ public int getMinWidth() {
+ return this._minWidth;
+ }
+
+ public void setMinWidth(int minWidth) {
+ this._minWidth = minWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#getMinHeight()
+ */
+ public int getMinHeight() {
+ return this._minHeight;
+ }
+
+ public void setMinHeight(int minHeight) {
+ this._minHeight = minHeight;
+ }
+
+ public static boolean hasAttribute(Element element, String attrname) {
+ return element.hasAttribute(attrname);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConvertPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConvertPosition.java
new file mode 100644
index 000000000..97f2ba85b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConvertPosition.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.w3c.dom.Node;
+
+/**
+ * This class is used to locate a position for child model nodes.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class ConvertPosition {
+ Node _parentNode;
+
+ int _index;
+
+ /**
+ *
+ */
+ public ConvertPosition(Node parent, int index) {
+ this._parentNode = parent;
+ this._index = index;
+ }
+
+ public Node getParentNode() {
+ return _parentNode;
+ }
+
+ public int getIndex() {
+ return _index;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java
new file mode 100644
index 000000000..21f3d889e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ConverterFacRegistryReader {
+ static IConverterFactory[] _handlers = null;
+
+ public static synchronized IConverterFactory[] getAllHandlers() {
+ if (_handlers == null) {
+ _handlers = readAllHandlers();
+ }
+ return _handlers;
+
+ }
+
+ private static IConverterFactory[] readAllHandlers() {
+ List result = new ArrayList();
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+ IExtension[] extensions = extensionPoint.getExtensions();
+
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension ext = extensions[i];
+ IConfigurationElement[] dropHandlers = ext
+ .getConfigurationElements();
+
+ for (int j = 0; j < dropHandlers.length; j++) {
+ if (dropHandlers[j].getName().equals(
+ IJMTConstants.TAG_CONVERTER_FACTORY)) {
+ dropHandlers[j].getAttribute("class");
+ Object obj;
+ try {
+ obj = dropHandlers[j]
+ .createExecutableExtension("class");
+
+ if (obj instanceof IConverterFactory) {
+ result.add(obj);
+ }
+ } catch (CoreException e) {
+ // ignore the exception
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ IConverterFactory[] ret = new IConverterFactory[result.size()];
+ result.toArray(ret);
+ return ret;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java
new file mode 100644
index 000000000..ba738678e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.converter.html.HTMLConverterFactory;
+import org.eclipse.jst.pagedesigner.converter.jsp.JSPConverterFactory;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ConverterFactoryRegistry {
+ List _factories = new ArrayList();
+
+ private static ConverterFactoryRegistry _instance;
+
+ /**
+ *
+ */
+ private ConverterFactoryRegistry() {
+ _factories.add(new JSPConverterFactory());
+ _factories.add(new HTMLConverterFactory());
+
+ IConverterFactory facs[] = ConverterFacRegistryReader.getAllHandlers();
+ if (facs != null) {
+ for (int i = 0; i < facs.length; i++) {
+ addFactory(facs[i]);
+ }
+ }
+ }
+
+ public void addFactory(IConverterFactory fac) {
+ _factories.add(fac);
+ }
+
+ public ITagConverter createTagConverter(Element ele, int mode,
+ IDOMDocument targetDocument) {
+ ITagConverter converter = internalCreateTagConverter(ele, mode);
+ if (converter != null) {
+ converter.setDestDocument(targetDocument);
+ }
+ return converter;
+ }
+
+ public ITagConverter internalCreateTagConverter(Element ele, int mode) {
+ String uri = CMUtil.getElementNamespaceURI(ele);
+ // first round, match uri
+ for (int i = 0, size = _factories.size(); i < size; i++) {
+ IConverterFactory fac = (IConverterFactory) _factories.get(i);
+ String facuri = fac.getSupportedURI();
+ if (facuri != null && facuri.equals(uri)) {
+ ITagConverter converter = fac.createConverter(ele, mode);
+ if (converter != null) {
+ return converter;
+ }
+ }
+ }
+ // second round
+ for (int i = 0, size = _factories.size(); i < size; i++) {
+ IConverterFactory fac = (IConverterFactory) _factories.get(i);
+ String facuri = fac.getSupportedURI();
+ if (facuri == null) {
+ ITagConverter converter = fac.createConverter(ele, mode);
+ if (converter != null) {
+ return converter;
+ }
+ }
+ }
+
+ // can't find. We need some default tag converter for it.
+ // if the tag is empty, show it as icon.
+ if (uri == null || IJMTConstants.URI_HTML.equals(uri)) {
+ // basically, for HTML or non JSP tag, directly renders it.
+ return new DumTagConverter(ele);
+ } else {
+ CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
+ if (decl == null) {
+ return new DumTagConverter(ele);
+ }
+ int contentType = decl.getContentType();
+ if (contentType == CMElementDeclaration.EMPTY) {
+ // if the tag is empty, show it as icon.
+ return new HiddenTagConverter(ele, getUnknownImage());
+ } else {
+ return new DefaultUnknownTagConverter(ele);
+ }
+ }
+
+ }
+
+ Image getUnknownImage() {
+ return PDPlugin.getDefault().getImage(
+ "palette/GENERIC/small/PD_Palette_Default.gif");
+ }
+
+ public static ConverterFactoryRegistry getInstance() {
+ if (_instance == null) {
+ _instance = new ConverterFactoryRegistry();
+ }
+ return _instance;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterUtil.java
new file mode 100644
index 000000000..b082303c9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterUtil.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.Set;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ConverterUtil {
+ /**
+ *
+ * @param source
+ * @param dest
+ * @param ignore
+ */
+ public static void copyAllAttributes(Element source, Element dest,
+ Set ignore) {
+ NamedNodeMap attrs = source.getAttributes();
+ for (int i = 0, size = attrs.getLength(); i < size; i++) {
+ Attr attr = (Attr) attrs.item(i);
+ if (ignore == null || !ignore.contains(attr.getName())) {
+ dest.setAttribute(attr.getName(), attr.getValue());
+ }
+ }
+ }
+
+ /**
+ * copy a single attribute (if exist)
+ *
+ * @param source
+ * @param srcattr
+ * @param dest
+ * @param destattr
+ */
+ public static void copyAttribute(Element source, String srcattr,
+ Element dest, String destattr) {
+ Attr attr = source.getAttributeNode(srcattr);
+ if (attr != null) {
+ dest.setAttribute(destattr, attr.getValue());
+ }
+ }
+
+ /**
+ * @param hostElement
+ * @return
+ */
+ public static boolean isEmptyContainer(Element hostElement) {
+ NodeList nl = hostElement.getChildNodes();
+ if (nl == null || nl.getLength() == 0) {
+ return true;
+ }
+
+ for (int i = 0, n = nl.getLength(); i < n; i++) {
+ Node node = nl.item(i);
+ if (!(node instanceof IDOMText)) {
+ return false;
+ }
+ if (!((IDOMText) node).isElementContentWhitespace()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static Element createDescriptionElement(IDOMDocument document,
+ String text) {
+ if (document == null) {
+ return null;
+ }
+ Element span = document.createElement(IHTMLConstants.TAG_SPAN); //$NON-NLS-1$
+ span.setAttribute(
+ "style", "color:gray;font-style:italic;font-size:normal;"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (text == null) {
+ span.appendChild(document.createTextNode(PDPlugin
+ .getResourceString("ConverterUtil.Description"))); //$NON-NLS-1$
+ } else {
+ span.appendChild(document.createTextNode(text));
+ }
+ return span;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DefaultUnknownTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DefaultUnknownTagConverter.java
new file mode 100644
index 000000000..d09a2fe11
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DefaultUnknownTagConverter.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * This tag converter is for those unsupported jsp tags.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class DefaultUnknownTagConverter extends AbstractTagConverter {
+
+ /**
+ * @param host
+ */
+ public DefaultUnknownTagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ Element hostEle = this.getHostElement();
+ Element divEle = createElement("div");
+ String style = DOMUtil.getAttributeIgnoreCase(hostEle, "style");
+ if (style == null) {
+ style = "";
+ }
+ if (style.length() > 0 && !style.endsWith(";")) {
+ style += ";";
+ }
+ style += "border: none; padding: 0; margin: 0";
+ divEle.setAttribute("style", style);
+ Element div2 = createElement("span");
+ div2.setAttribute("style", "background-color: cyan; border: none;");
+ Text txt = createText(hostEle.getTagName());
+ div2.appendChild(txt);
+
+ divEle.appendChild(div2);
+
+ Element div3 = createElement("div");
+ div3.setAttribute("style", "margin: 0; padding: 0");
+ divEle.appendChild(div3);
+
+ copyChildren(getHostElement(), div3);
+ return divEle;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#needBorderDecorator()
+ */
+ public boolean needBorderDecorator() {
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDeepTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDeepTagConverter.java
new file mode 100644
index 000000000..c56d0760c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDeepTagConverter.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DumDeepTagConverter extends AbstractTagConverter {
+
+ /**
+ * @param host
+ */
+ public DumDeepTagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ return (Element) DOMUtil.cloneNodeDeepIgnoreError(getDestDocument(),
+ getHostElement());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ /**
+ * @param result
+ * @return
+ */
+ private boolean internalIsWidget(Element result) {
+ String tagname = result.getTagName();
+ if (IHTMLConstants.TAG_INPUT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_SELECT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_TEXTAREA.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_IMG.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_HEAD.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_SCRIPT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_LINK.equalsIgnoreCase(tagname)) {
+ return true;
+ } else {
+
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isWidget()
+ */
+ public boolean isWidget() {
+ return true;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDescriptionTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDescriptionTagConverter.java
new file mode 100644
index 000000000..2221a5279
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumDescriptionTagConverter.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DumDescriptionTagConverter extends AbstractTagConverter {
+ /**
+ * @param host
+ */
+ public DumDescriptionTagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ Element result = createElement(getHostElement().getTagName());
+ ConverterUtil.copyAllAttributes(getHostElement(), result, null);
+ copyChildren(getHostElement(), result);
+
+ if (!this.isPreviewMode()
+ && ConverterUtil.isEmptyContainer(getHostElement())) {
+ result.appendChild(ConverterUtil.createDescriptionElement(
+ getDestDocument(), null));
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumTagConverter.java
new file mode 100644
index 000000000..6abec2f10
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/DumTagConverter.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DumTagConverter extends AbstractTagConverter {
+ /**
+ *
+ */
+ public DumTagConverter(Element host, boolean needBorder) {
+ this(host);
+ this.setNeedBorderDecorator(needBorder);
+ }
+
+ public DumTagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ Element result = createElement(getHostElement().getTagName());
+ ConverterUtil.copyAllAttributes(getHostElement(), result, null);
+ if (!internalIsWidget(result)) {
+ copyChildren(getHostElement(), result);
+ } else {
+ dumCopyChildren(getHostElement(), result);
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ if (isWidget()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param result
+ * @return
+ */
+ private boolean internalIsWidget(Element result) {
+ String tagname = result.getTagName();
+ if (IHTMLConstants.TAG_INPUT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_SELECT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_TEXTAREA.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_IMG.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_OBJECT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_HEAD.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_SCRIPT.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_LINK.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_BR.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_STYLE.equalsIgnoreCase(tagname)
+ || IHTMLConstants.TAG_HR.equalsIgnoreCase(tagname)) {
+ return true;
+ } else {
+
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isWidget()
+ */
+ public boolean isWidget() {
+ return internalIsWidget(getResultElement());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HTMLStringTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HTMLStringTagConverter.java
new file mode 100644
index 000000000..610b0c061
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HTMLStringTagConverter.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+
+/**
+ * For some tag, could generate some XML code.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class HTMLStringTagConverter extends AbstractTagConverter {
+
+ static Logger _log = PDPlugin.getLogger(HTMLStringTagConverter.class);
+
+ /**
+ * @param host
+ */
+ public HTMLStringTagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ // following are XML implementation. Assume the string is welformed HTML
+ // try
+ // {
+ // String html = getGeneratedHTML();
+ // DocumentBuilder builder =
+ // DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ // Element result = builder.parse(new InputSource(new
+ // StringReader(html))).getDocumentElement();
+ // return (Element)DOMUtil.cloneNodeDeep(this.getDestDocument(),
+ // result);
+ // }
+ // catch(Exception ex)
+ // {
+ // Element temp = createElement("div");
+ // temp.appendChild(createText("ERROR: "+ex.getMessage()));
+ // return temp;
+ // }
+ InputStream stream = null;
+ try {
+ String id = "" + System.currentTimeMillis() + ".html";
+ IModelManager manager = StructuredModelManager.getModelManager();
+ stream = new ByteArrayInputStream(getGeneratedHTML().getBytes());
+ IDOMModel model = (IDOMModel) manager.getModelForRead(id, stream,
+ null);
+ Element root = model.getDocument().getDocumentElement();
+ Element resultEle = (Element) DOMUtil.cloneNodeDeepIgnoreError(
+ getDestDocument(), root);
+ model.releaseFromRead();
+ return resultEle;
+ } catch (Throwable ex) {
+ _log.error("Log.Error.HTMLStringTagConverter.Error", ex);
+ Element temp = createElement("div");
+ temp.appendChild(createText("Error loading: " + ex.getMessage()));
+ return temp;
+ } finally {
+ ResourceUtils.ensureClosed(stream);
+ }
+ }
+
+ public abstract String getGeneratedHTML() throws Exception;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter.java
new file mode 100644
index 000000000..23714d7ad
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * This is for those tags that don't convert to HTML. So they will not display
+ * anything in preview, and will display a small icon in designer.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class HiddenTagConverter implements ITagConverter {
+ private Element _hostElement;
+
+ private Image _image;
+
+ private int _mode;
+
+ /**
+ *
+ */
+ public HiddenTagConverter(Element host, Image image) {
+ _hostElement = host;
+ _image = image;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#setDestDocument(org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument)
+ */
+ public void setDestDocument(IDOMDocument document) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#convertRefresh(java.lang.Object)
+ */
+ public void convertRefresh(Object context) {
+ // do nothing
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getHostElement()
+ */
+ public Element getHostElement() {
+ return _hostElement;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isVisualByHTML()
+ */
+ public boolean isVisualByHTML() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getVisualImage()
+ */
+ public Image getVisualImage() {
+ return _image;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getResultElement()
+ */
+ public Element getResultElement() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getChildModeList()
+ */
+ public List getChildModeList() {
+ return Collections.EMPTY_LIST;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getChildVisualPosition(org.w3c.dom.Node)
+ */
+ public ConvertPosition getChildVisualPosition(Node childModel) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isWidget()
+ */
+ public boolean isWidget() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#dispose()
+ */
+ public void dispose() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#setMode(int)
+ */
+ public void setMode(int mode) {
+ this._mode = mode;
+ }
+
+ public int getMode() {
+ return _mode;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter2.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter2.java
new file mode 100644
index 000000000..c374d21c0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/HiddenTagConverter2.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * HiddenTagConverter2 is similiar to HiddenTagConverter, with the following
+ * difference:
+ *
+ * <ol>
+ * <li>HiddenTagConverter2 will copy the DOM sub tree to the destination
+ * document.</li>
+ * </ol>
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class HiddenTagConverter2 extends AbstractTagConverter {
+
+ private Image _image;
+
+ public HiddenTagConverter2(Element host, Image image) {
+ super(host);
+ this._image = image;
+ }
+
+ protected Element doConvertRefresh() {
+ return (Element) DOMUtil.cloneNodeDeepIgnoreError(getDestDocument(),
+ getHostElement());
+ }
+
+ public boolean isVisualByHTML() {
+ return false;
+ }
+
+ public Image getVisualImage() {
+ return _image;
+ }
+
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ public boolean isWidget() {
+ return true;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IConverterFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IConverterFactory.java
new file mode 100644
index 000000000..002a7b0e0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IConverterFactory.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IConverterFactory {
+ public static final int MODE_DESIGNER = 0;
+
+ public static final int MODE_PREVIEW = 1;
+
+ /**
+ *
+ * @param element
+ * @return null if this factory don't support this element
+ */
+ public ITagConverter createConverter(Element element, int mode);
+
+ /**
+ * get the URI namespace that this factory support. "null" means this
+ * factory can be used as default factory.
+ *
+ * @return null if this factory don't have a specific URI to support.
+ */
+ public String getSupportedURI();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IDOMFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IDOMFactory.java
new file mode 100644
index 000000000..dd0748990
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/IDOMFactory.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * Factory interface. AbstractTagConverter will implement it.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IDOMFactory {
+ /**
+ * create element
+ *
+ * @param tag
+ * @return
+ */
+ public Element createElement(String tag);
+
+ /**
+ * create text node
+ *
+ * @param content
+ * @return
+ */
+ public Text createText(String content);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ITagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ITagConverter.java
new file mode 100644
index 000000000..3b504b4ef
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ITagConverter.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * ITagConverter is used to convert a custom tag to a HTML tag. Each
+ * ITagConverter instance will be dedicated to a single custom tag element.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ITagConverter {
+ /**
+ * Set the target document where the converted node should belong to.
+ *
+ * @param document
+ */
+ public void setDestDocument(IDOMDocument document);
+
+ /**
+ * refresh the internal state of this ITagConverter. This method normally is
+ * called when the host element change.
+ *
+ * @param context
+ */
+ public void convertRefresh(Object context);
+
+ /**
+ * The host element being converted.
+ *
+ * @return
+ */
+ public Element getHostElement();
+
+ /**
+ * for some tags, they don't convert to HTML. In that case, this method
+ * should return false for them. And if this method return false, then
+ * should return an image in <code>getVisualImage()</code> for displaying
+ * in the designer.
+ *
+ * @return
+ */
+ public boolean isVisualByHTML();
+
+ /**
+ * if isVisualByHTML() return false, then this method should return an image
+ * to be displayed in designer.
+ *
+ * Normally this image will be a shared image for those hidden elements. It
+ * is this class's responsibility to dispose the image if the image is not a
+ * shared one.
+ *
+ * @return
+ */
+ public Image getVisualImage();
+
+ /**
+ * the element after conversion.
+ *
+ * @return
+ */
+ public Element getResultElement();
+
+ /**
+ * get the list of children that should be continuely converted.
+ *
+ * @return
+ */
+ public List getChildModeList();
+
+ /**
+ * For child nodes that need further convert, return their position in the
+ * converted DOM tree.
+ *
+ * @param childModel
+ * @return
+ */
+ public ConvertPosition getChildVisualPosition(Node childModel);
+
+ /**
+ * When the convert result in multi-level element. If this method return
+ * false, then the caller should not use child nodes of
+ * <code>getHostElement()</code>
+ *
+ * @return
+ */
+ public boolean isMultiLevel();
+
+ /**
+ *
+ * @return
+ */
+ public boolean isWidget();
+
+ /**
+ *
+ *
+ */
+ public void dispose();
+
+ /**
+ * @param mode
+ */
+ public void setMode(int mode);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/JSFConverterUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/JSFConverterUtil.java
new file mode 100644
index 000000000..5ac56f8c7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/JSFConverterUtil.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class JSFConverterUtil {
+ private static List NamedBooleanList = Arrays.asList(new String[] {
+ "disabled", "readonly", "ismap" });
+
+ /**
+ *
+ * @param source
+ * @param dest
+ * @param ignore
+ */
+ public static void copyAllAttributes(Element source, Element dest,
+ Set ignore) {
+ NamedNodeMap attrs = source.getAttributes();
+ for (int i = 0, size = attrs.getLength(); i < size; i++) {
+ Attr attr = (Attr) attrs.item(i);
+ if (ignore == null || !ignore.contains(attr.getName())) {
+ if (NamedBooleanList.contains(attr.getName())
+ && "false".equalsIgnoreCase(attr.getValue())) {
+ continue;
+ }
+ dest.setAttribute(attr.getName(), attr.getValue());
+ }
+ }
+ }
+
+ /**
+ * copy a single attribute (if exist)
+ *
+ * @param source
+ * @param srcattr
+ * @param dest
+ * @param destattr
+ */
+ public static void copyAttribute(Element source, String srcattr,
+ Element dest, String destattr) {
+ Attr attr = source.getAttributeNode(srcattr);
+ if (attr != null) {
+ dest.setAttribute(destattr, attr.getValue());
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/PreferenceReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/PreferenceReader.java
new file mode 100644
index 000000000..71b2830c3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/PreferenceReader.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PreferenceReader {
+ public final static int FULL_EXPRESSION_TYPE = 0;
+
+ public final static int LAST_EXPRESSION_TYPE = 1;
+
+ public final static int REAL_VALUE_TYPE = 2;
+
+ public static int getMapValueType() {
+ return LAST_EXPRESSION_TYPE;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToDumBlock.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToDumBlock.java
new file mode 100644
index 000000000..619875da6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToDumBlock.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TagConverterToDumBlock extends AbstractTagConverter {
+
+ /**
+ * @param host
+ */
+ public TagConverterToDumBlock(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ Element result = createElement(IHTMLConstants.TAG_DIV);
+ copyChildren(getHostElement(), result);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToInlineBlock.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToInlineBlock.java
new file mode 100644
index 000000000..3e4a41400
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToInlineBlock.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.w3c.dom.Element;
+
+/**
+ * This converter can be used simply convert the tag to inline div, and copy all
+ * the children
+ *
+ * NOTE: It behave almost same as "span". In fact, we may remove this later, if
+ * our css engine support "minWidth"/"minHeight" for inline element.
+ *
+ * NOTE: it will not copy attributes!
+ *
+ * @author mengbo
+ * @version 1.5
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#getMinHeight()
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#getMinWidth()
+ */
+public class TagConverterToInlineBlock extends AbstractTagConverter {
+ private int model;
+
+ /**
+ * @param host
+ */
+ public TagConverterToInlineBlock(Element host, int model) {
+ super(host);
+ this.model = model;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ Element result = null;
+ if (model == IConverterFactory.MODE_PREVIEW) {
+ result = createElement("span");
+ copyChildren(getHostElement(), result);
+ } else {
+ result = createElement("div");
+ result
+ .setAttribute(
+ "style",
+ "display:inline-block; border-width:0; margin:0; min-width:1.2em;min-height:1.2em;");
+ copyChildren(getHostElement(), result);
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToSpan.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToSpan.java
new file mode 100644
index 000000000..5dfa8006f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/TagConverterToSpan.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter;
+
+import org.w3c.dom.Element;
+
+/**
+ * This converter can be used simply convert the tag to span, and copy all the
+ * children
+ *
+ * NOTE: it will not copy attributes!
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class TagConverterToSpan extends AbstractTagConverter {
+
+ /**
+ * @param host
+ */
+ public TagConverterToSpan(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ // Register a named facet on the UIComponent associated with the
+ // closest parent UIComponent custom action.
+ // we'll render facet as a inline flow figure. so treat it as simple
+ // <span> here.
+ Element result = createElement("span");
+ copyChildren(getHostElement(), result);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/ATagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/ATagConverter.java
new file mode 100644
index 000000000..ab9708102
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/ATagConverter.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter.html;
+
+import org.eclipse.jst.pagedesigner.converter.ConverterUtil;
+import org.eclipse.jst.pagedesigner.converter.DumTagConverter;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ATagConverter extends DumTagConverter {
+ private boolean _emptyContainer = false;
+
+ /**
+ * @param host
+ */
+ public ATagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ _emptyContainer = ConverterUtil.isEmptyContainer(getHostElement());
+ if (_emptyContainer) {
+ Element resultEle = createElement("a");
+ ConverterUtil.copyAllAttributes(getHostElement(), resultEle, null);
+ Text fakedNode = createText("link");
+ resultEle.appendChild(fakedNode);
+ return resultEle;
+ } else {
+ return super.doConvertRefresh();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#needBorderDecorator()
+ */
+ public boolean needBorderDecorator() {
+ return _emptyContainer;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return _emptyContainer;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return _emptyContainer;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/HTMLConverterFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/HTMLConverterFactory.java
new file mode 100644
index 000000000..b17a6c65b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/HTMLConverterFactory.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter.html;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.converter.AbstractTagConverter;
+import org.eclipse.jst.pagedesigner.converter.DumDescriptionTagConverter;
+import org.eclipse.jst.pagedesigner.converter.DumTagConverter;
+import org.eclipse.jst.pagedesigner.converter.HiddenTagConverter2;
+import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
+import org.eclipse.jst.pagedesigner.converter.ITagConverter;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class HTMLConverterFactory implements IConverterFactory {
+
+ /**
+ * the constructor
+ */
+ public HTMLConverterFactory() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.IConverterFactory#createConverter(org.w3c.dom.Element)
+ */
+ public ITagConverter createConverter(Element element, int mode) {
+ String tagName = element.getLocalName();
+
+ if (mode == MODE_PREVIEW) {
+ return new DumTagConverter(element);
+ }
+ if (!HTMLUtil.isVisualHtmlElement(tagName)) {
+ return new HiddenTagConverter2(element, getUnknownImage());
+ }
+
+ AbstractTagConverter c;
+ if (IHTMLConstants.TAG_TABLE.equalsIgnoreCase(tagName)) {
+ c = new TableTagConverter(element);
+ } else if (IHTMLConstants.TAG_A.equalsIgnoreCase(tagName)) {
+ c = new ATagConverter(element);
+ } else if (IHTMLConstants.TAG_FORM.equalsIgnoreCase(tagName)) {
+ // for those HTML tag that we want to build a border decorator,
+ // should
+ // go there.
+ c = new DumTagConverter(element, true);
+ } else if (IHTMLConstants.TAG_HTML.equalsIgnoreCase(tagName)
+ || IHTMLConstants.TAG_BODY.equalsIgnoreCase(tagName)) {
+ c = new DumDescriptionTagConverter(element);
+ c.setNeedBorderDecorator(true);
+ } else {
+ c = new DumTagConverter(element);
+ }
+ c.setMode(mode);
+ return c;
+ }
+
+ private static Image getUnknownImage() {
+ return PDPlugin.getDefault().getImage(
+ "palette/GENERIC/small/PD_Palette_Default.gif");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.IConverterFactory#getSupportedURI()
+ */
+ public String getSupportedURI() {
+ return IJMTConstants.URI_HTML;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/TableTagConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/TableTagConverter.java
new file mode 100644
index 000000000..eaf192863
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/html/TableTagConverter.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter.html;
+
+import org.eclipse.jst.pagedesigner.converter.AbstractTagConverter;
+import org.eclipse.jst.pagedesigner.converter.ConverterUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class TableTagConverter extends AbstractTagConverter {
+ /**
+ * @param host
+ */
+ public TableTagConverter(Element host) {
+ super(host);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ Element result = createElement(getHostElement().getTagName());
+ ConverterUtil.copyAllAttributes(getHostElement(), result, null);
+ copyChildren(getHostElement(), result);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#needTableDecorator()
+ */
+ public boolean needTableDecorator() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#needBorderDecorator()
+ */
+ public boolean needBorderDecorator() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/IncludeTagConverterPreview.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/IncludeTagConverterPreview.java
new file mode 100644
index 000000000..00c0f9909
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/IncludeTagConverterPreview.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter.jsp;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.converter.AbstractTagConverter;
+import org.eclipse.jst.pagedesigner.jsp.core.internal.pagevar.DocumentPageVariableAdapter;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.adapter.PageVariableAdapterFactory;
+import org.eclipse.jst.pagedesigner.preview.PageExpressionContext;
+import org.eclipse.jst.pagedesigner.preview.PreviewConvertContext;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * This is the tag converter for preview.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class IncludeTagConverterPreview extends AbstractTagConverter {
+ private static Logger _log = PDPlugin
+ .getLogger(IncludeTagConverterPreview.class);
+
+ private String _fileAttrName;
+
+ /**
+ * @param host
+ */
+ public IncludeTagConverterPreview(Element host, String fileAttrname) {
+ super(host);
+ this._fileAttrName = fileAttrname;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#doConvertRefresh()
+ */
+ protected Element doConvertRefresh() {
+ String fileName = getResolvedURL(getHostElement(), this._fileAttrName);
+ if (fileName == null || fileName.length() == 0) {
+ return null;
+ } else {
+ IPath includedPath = new Path(fileName);
+ includedPath.makeAbsolute();
+
+ IFile file = getFile(includedPath);
+ if (file == null) {
+ return null;
+ } else {
+ return previewFile(file);
+ }
+ }
+ }
+
+ public IFile getFile(IPath includedPath) {
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ IProject[] projects = workspaceRoot.getProjects();
+
+ for (int i = 0, length = projects.length; i < length; i++) {
+ IPath path = projects[i].getLocation();
+ path = path.makeAbsolute();
+ if (path != null && path.isPrefixOf(includedPath)) {
+ // -1 so we still have the project path
+ includedPath = includedPath.removeFirstSegments(path
+ .segmentCount() - 1);
+ return ResourcesPlugin.getWorkspace().getRoot().getFile(
+ includedPath);
+ }
+ }
+ return null;
+ }
+
+ public Element previewFile(IFile file) {
+ IDOMModel xmlModel = null;
+ DocumentPageVariableAdapter provider = null;
+ boolean pushedPageVarProvider = false;
+ try {
+
+ xmlModel = (IDOMModel) PDPlugin.getModelManager().getModelForRead(
+ file);
+ if (xmlModel != null) {
+ IDOMDocument doc = xmlModel.getDocument();
+
+ // XXX: need to also register page variable adapters. In the
+ // future, this should go to some
+ // SSE system registry mechanism.
+ xmlModel.getFactoryRegistry().addFactory(
+ new PageVariableAdapterFactory());
+ provider = new DocumentPageVariableAdapter(doc);
+ doc.addAdapter(provider);
+
+ provider.refresh();
+ PageExpressionContext.getCurrent()
+ .pushPageVarProvider(provider);
+
+ Node child = xmlModel.getDocument().getFirstChild();
+ PreviewConvertContext context = new PreviewConvertContext(this
+ .getDestDocument());
+ List results = new ArrayList();
+ while (child != null) {
+ Node node = context.previewConvert(child);
+ if (node != null) {
+ results.add(node);
+ }
+ child = child.getNextSibling();
+ }
+
+ if (results.size() == 0) {
+ return null;
+ } else if (results.size() == 1
+ && results.get(0) instanceof Element) {
+ return (Element) results.get(0);
+ } else {
+ Element ret = createElement(IHTMLConstants.TAG_SPAN);
+ for (int i = 0, n = results.size(); i < n; i++) {
+ ret.appendChild((Node) results.get(i));
+ }
+ return ret;
+ }
+ }
+ } catch (CoreException e) {
+ _log.error("PreviewUtil.previewFile.CoreException", e);
+ } catch (IOException e) {
+ _log.error("PreviewUtil.previewFile.IOException", e);
+ } catch (Exception ex) {
+ _log.error("PreviewUtil.previewFile.CoreException", ex);
+ } finally {
+ if (pushedPageVarProvider) {
+ PageExpressionContext.getCurrent().popPageVarProvider(provider);
+ }
+ if (xmlModel != null) {
+ xmlModel.releaseFromRead();
+ }
+ }
+ return null;
+ }
+
+ static String getResolvedURL(Element element, String attrName) {
+ URIResolver resolver = null;
+ if (element instanceof IDOMNode) {
+ resolver = ((IDOMNode) element).getModel().getResolver();
+ }
+ if (null == resolver) {
+ return null;
+ }
+ String src = element.getAttribute(attrName);
+ if (src != null && src.length() > 0) {
+ return resolver.getLocationByURI(src);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#isMultiLevel()
+ */
+ public boolean isMultiLevel() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/JSPConverterFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/JSPConverterFactory.java
new file mode 100644
index 000000000..9931241f4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/jsp/JSPConverterFactory.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.converter.jsp;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.converter.HiddenTagConverter;
+import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
+import org.eclipse.jst.pagedesigner.converter.ITagConverter;
+import org.eclipse.jst.pagedesigner.converter.TagConverterToDumBlock;
+import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class JSPConverterFactory implements IConverterFactory {
+ /**
+ *
+ */
+ public JSPConverterFactory() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.IConverterFactory#createConverter(org.w3c.dom.Element)
+ */
+ public ITagConverter createConverter(Element element, int mode) {
+ String tagName = element.getLocalName();
+ Image image = getJSPSharedImage(tagName);
+
+ if (mode == IConverterFactory.MODE_PREVIEW) {
+ // we want to generate the included page in preview, so
+ // handle differently
+ if (IJSPCoreConstants.TAG_INCLUDE.equalsIgnoreCase(tagName)) {
+ IncludeTagConverterPreview c = new IncludeTagConverterPreview(
+ element, "page");
+ c.setMode(mode);
+ return c;
+ } else if (IJSPCoreConstants.TAG_DIRECTIVE_INCLUDE
+ .equalsIgnoreCase(tagName)) {
+ IncludeTagConverterPreview c = new IncludeTagConverterPreview(
+ element, "file");
+ c.setMode(mode);
+ return c;
+ } else if (IJSPCoreConstants.TAG_ROOT.equalsIgnoreCase(tagName)) {
+ TagConverterToDumBlock c = new TagConverterToDumBlock(element);
+ c.setNeedBorderDecorator(true);
+ c.setMode(mode);
+ return c;
+ } else {
+ return new HiddenTagConverter(element, image);
+ }
+ } else {
+ if (IJSPCoreConstants.TAG_ROOT.equalsIgnoreCase(tagName)) {
+ TagConverterToDumBlock c = new TagConverterToDumBlock(element);
+ c.setNeedBorderDecorator(true);
+ c.setMode(mode);
+ return c;
+ }
+ return new HiddenTagConverter(element, image);
+ }
+ }
+
+ /**
+ * @param tagName
+ * @return
+ */
+ private Image getJSPSharedImage(String tagName) {
+ Image image = PDPlugin.getDefault().getImage(
+ "palette/JSP/small/JSP_" + tagName.toUpperCase() + ".gif");
+ return image;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.converter.IConverterFactory#getSupportedURI()
+ */
+ public String getSupportedURI() {
+ return IJMTConstants.URI_JSP;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSTempUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSTempUtil.java
new file mode 100644
index 000000000..38310c30a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSTempUtil.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetAdapter;
+import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetListAdapter;
+import org.eclipse.wst.html.core.internal.provisional.HTML40Namespace;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.stylesheets.StyleSheet;
+import org.w3c.dom.stylesheets.StyleSheetList;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSTempUtil {
+ /**
+ * the default implementation of (IStyleSheetListAdapter)
+ * docnotifier.getAdapterFor(IStyleSheetListAdapter.class) will only get
+ * those style tags under certain tags like "html", "head", etc.
+ *
+ * But datawindow is generating style tag and is not putting them into
+ * "head". So we can't handle them using the default SSE mechanism.
+ *
+ * We have another problem: currently the converted element is also using
+ * the original document, not generating another document, and these
+ * elements is not really adding into the document, so they can't be reached
+ * from the document.
+ *
+ * @param ele
+ * @return
+ * @see org.eclipse.wst.html.core.htmlcss.HTMLDocumentAdapter#addStyleSheet(org.w3c.dom.Element)
+ */
+ public static List getStyleSheets(Element element) {
+ List styleSheets = new ArrayList();
+ INodeNotifier docnotifier = (INodeNotifier) element.getOwnerDocument();
+ IStyleSheetListAdapter adapter = (IStyleSheetListAdapter) docnotifier
+ .getAdapterFor(IStyleSheetListAdapter.class);
+
+ StyleSheetList ssl = (adapter == null ? null : adapter.getStyleSheets());
+
+ if (ssl != null) {
+ for (int i = 0, numStyles = ssl.getLength(); i < numStyles; i++) {
+ // loop for styles (<style> and <link>)
+ org.w3c.dom.stylesheets.StyleSheet ss = ssl.item(i);
+ styleSheets.add(ss);
+ }
+ }
+
+ // now is our work-around part for support datawindow.
+ Node parent = element.getParentNode();
+ Element rootEle = element;
+ while (parent != null && parent instanceof Element) {
+ rootEle = (Element) parent;
+ parent = parent.getParentNode();
+ }
+ addStyleSheet(rootEle, styleSheets);
+ return styleSheets;
+ }
+
+ /**
+ */
+ private static void addStyleSheet(Element node, List result) {
+ IDOMElement element = (IDOMElement) node;
+ String tagName = element.getTagName();
+ if (tagName == null) {
+ return;
+ }
+ boolean isContainer = false;
+
+ if (element.isCommentTag()) {
+ Node parent = element.getParentNode();
+ if (parent == element.getOwnerDocument()) {
+ // This condition is too severe, actually do not work for JSF
+ // template.
+ // But above (! globalTag() && isContainer()) cover JSF template
+ // + tpl template
+ isContainer = true;
+ } else if (parent.getNodeType() == Node.ELEMENT_NODE) {
+ tagName = ((Element) parent).getTagName();
+ if (tagName != null
+ && tagName
+ .equalsIgnoreCase(HTML40Namespace.ElementName.HEAD)) {
+ isContainer = true;
+ }
+ }
+ } else {
+ INodeNotifier notifier = element;
+
+ // (lium) Increase performance: since this method is called tooooo
+ // many times,
+ // and getAdapterFor() is slow, so add a check on the tagName to
+ // filter
+ // those stylesheet stuff first.
+ if (IHTMLConstants.TAG_LINK.equalsIgnoreCase(tagName)
+ || IHTMLConstants.TAG_STYLE.equalsIgnoreCase(tagName)) {
+ INodeAdapter adapter = notifier
+ .getAdapterFor(IStyleSheetAdapter.class);
+ if (adapter != null && adapter instanceof IStyleSheetAdapter) {
+ StyleSheet sheet = ((IStyleSheetAdapter) adapter)
+ .getSheet();
+ result.add(sheet);
+ }
+ }
+
+ isContainer = true;
+ }
+ if (isContainer) {
+ for (Node child = element.getFirstChild(); child != null; child = child
+ .getNextSibling()) {
+ if (child.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+ addStyleSheet((Element) child, result);
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSUtil.java
new file mode 100644
index 000000000..d20a2b3a7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/CSSUtil.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.css2.font.CSSFont;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetListAdapter;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
+import org.eclipse.wst.css.core.internal.util.CSSClassTraverser;
+import org.eclipse.wst.html.core.internal.htmlcss.CSSQueryTraverser;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.stylesheets.StyleSheet;
+import org.w3c.dom.stylesheets.StyleSheetList;
+
+/**
+ * @author mengbo
+ */
+public class CSSUtil {
+ private static StyleSheet _userAgentDefault;
+
+ public static String[] getCSSClasses(Document doc) {
+ Collection c = Collections.EMPTY_SET;
+ if (doc instanceof INodeNotifier) {
+ IStyleSheetListAdapter adapter = (IStyleSheetListAdapter) ((INodeNotifier) doc)
+ .getAdapterFor(IStyleSheetListAdapter.class);
+ StyleSheetList ssl = (adapter == null ? null : adapter
+ .getStyleSheets());
+
+ CSSClassTraverser traverser = new CSSClassTraverser();
+ if (ssl != null) {
+ for (int i = 0, numStyles = ssl.getLength(); i < numStyles; i++) {
+ // loop for styles (<style> and <link>)
+ org.w3c.dom.stylesheets.StyleSheet ss = ssl.item(i);
+
+ try {
+ traverser.apply((ICSSNode) ss);
+ } catch (ClassCastException ex) {
+ Logger log = PDPlugin
+ .getLogger(CSSStyleDeclaration.class);
+ log.error("Error.CSSUtil.0", ex); //$NON-NLS-1$
+ // FIXME: should this continue to be processed?
+ }
+ }
+ c = traverser.getClassNames();
+ }
+ }
+ String[] result = new String[c.size()];
+ c.toArray(result);
+ return result;
+ }
+
+ /**
+ * Get the css style of a node.
+ *
+ * @param node
+ * @return
+ */
+ public static ICSSStyle getCSSStyle(Element node) {
+ ICSSStyle style = null;
+ if (node instanceof IDOMElement) {
+ style = (ICSSStyle) ((IDOMElement) node)
+ .getAdapterFor(ICSSStyle.class);
+ }
+ if (style == null) {
+ return DefaultStyle.getInstance();
+ } else {
+ return style;
+ }
+ }
+
+ /**
+ * Resolve the css style string from css style elements.
+ *
+ * @param node
+ * @return
+ */
+ public static String resolveCSSStyle(ICSSStyle style) {
+ StringBuffer sb = new StringBuffer();
+ Object object1 = style.getColor();
+ if (object1 instanceof Color) {
+ sb.append("color:");
+
+ sb.append("#").append(
+ Integer.toHexString(((Color) object1).getRed()));
+ sb.append("#").append(
+ Integer.toHexString(((Color) object1).getGreen()));
+ sb.append("#").append(
+ Integer.toHexString(((Color) object1).getBlue()));
+ sb.append(";");
+ }
+ Object object2 = style.getCSSFont();
+ if (object2 instanceof CSSFont) {
+ sb.append(((CSSFont) object2).getCSSString());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Many of this method implementation copied from HTMLDocumentAdapter,
+ * mainly add support for user agent default style sheet.
+ *
+ * @param element
+ * the element.
+ * @param pseudoName
+ * the pseudoname of the element
+ * @return
+ */
+ public static CSSStyleDeclaration getCSSDeclaration(Element element,
+ String pseudoName) {
+ // please reference comments in CSSTempUtil.
+ List styleSheets = CSSTempUtil.getStyleSheets(element);
+ // INodeNotifier docnotifier = (INodeNotifier)
+ // element.getOwnerDocument();
+ // IStyleSheetListAdapter adapter = (IStyleSheetListAdapter)
+ // docnotifier.getAdapterFor(IStyleSheetListAdapter.class);
+ //
+ // StyleSheetList ssl = (adapter == null ? null :
+ // adapter.getStyleSheets());
+
+ CSSQueryTraverser query = new CSSQueryTraverser();
+ query.setTraverseImported(true);
+ query.setTraverseImportFirst(true);
+ query.setElement(element, pseudoName);
+
+ // if (ssl != null)
+ // {
+ // for (int i = 0, numStyles = ssl.getLength(); i < numStyles; i++)
+ // {
+ // // loop for styles (<style> and <link>)
+ // org.w3c.dom.stylesheets.StyleSheet ss = ssl.item(i);
+ if (styleSheets != null) {
+ for (int i = 0, numStyles = styleSheets.size(); i < numStyles; i++) {
+ StyleSheet ss = (StyleSheet) styleSheets.get(i);
+ try {
+ query.apply((ICSSNode) ss);
+ } catch (ClassCastException ex) {
+ Logger log = PDPlugin.getLogger(CSSStyleDeclaration.class);
+ log.error("Error.CSSUtil.0", ex); //$NON-NLS-1$
+ // FIXME: should this continue to be processed?
+ }
+ }
+ }
+ CSSStyleDeclaration declare = query.getDeclaration();
+ // FIXME: when do we need to apply the user agent style sheet?
+ return declare;
+ }
+
+ /**
+ * Many of this method implementation copied from HTMLDocumentAdapter,
+ * mainly add support for user agent default style sheet.
+ *
+ * @param element
+ * the element.
+ * @param pseudoName
+ * the pseudoname of the element
+ * @return
+ */
+ public static CSSStyleDeclaration getDefaultCSSDeclaration(Element element,
+ String pseudoName) {
+ CSSQueryTraverser query = new CSSQueryTraverser();
+ query.setTraverseImported(true);
+ query.setTraverseImportFirst(true);
+
+ query.setElement(element, pseudoName);
+
+ // FIXME: when do we need to apply the user agent style sheet?
+ try {
+ getUserAgentDefaultStyleSheet(element);
+ } catch (UnsupportedEncodingException e) {
+ Logger log = PDPlugin.getLogger(CSSStyleDeclaration.class);
+ log.error("Error.CSSUtil.1", e); //$NON-NLS-1$
+ } catch (IOException e) {
+ Logger log = PDPlugin.getLogger(CSSStyleDeclaration.class);
+ log.error("Error.CSSUtil.2", e); //$NON-NLS-1$
+ }
+ if (_userAgentDefault != null) {
+ try {
+ query.apply((ICSSNode) _userAgentDefault);
+ } catch (ClassCastException ex) {
+ Logger log = PDPlugin.getLogger(CSSStyleDeclaration.class);
+ log.error("Error.CSSUtil.3", ex); //$NON-NLS-1$
+ }
+ }
+ CSSStyleDeclaration declare = query.getDeclaration();
+ return declare;
+ }
+
+ /**
+ * Get the user agent default style sheet.
+ *
+ * @param element
+ * @return
+ * @throws IOException
+ * @throws UnsupportedEncodingException
+ */
+ // XXX: in the future, we may get user agent default style sheet based on
+ // device type.
+ private static StyleSheet getUserAgentDefaultStyleSheet(Element element)
+ throws UnsupportedEncodingException, IOException {
+ if (_userAgentDefault == null) {
+ InputStream input = CSSUtil.class
+ .getResourceAsStream(IJMTConstants.USERAGENT);
+ IStructuredModel model = StructuredModelManager.getModelManager()
+ .getModelForEdit(IJMTConstants.USERAGENT, input, null);
+ ICSSModel cssmodel = (ICSSModel) model;
+ _userAgentDefault = (StyleSheet) cssmodel.getDocument();
+
+ ResourceUtils.ensureClosed(input);
+ }
+
+ return _userAgentDefault;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/ICSSStyle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/ICSSStyle.java
new file mode 100644
index 000000000..190d5ee70
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/ICSSStyle.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+
+/**
+ * The style declaration for an element can be cached.
+ *
+ * @author mengbo
+ */
+public interface ICSSStyle extends INodeAdapter, IAdaptable {
+ public static final int INHERIT = Integer.MIN_VALUE;
+
+ public static final String TOP = "top";
+
+ public static final String RIGHT = "right";
+
+ public static final String LEFT = "left";
+
+ public static final String BOTTOM = "bottom";
+
+ public void reset();
+
+ public ICSSFont getCSSFont();
+
+ public Object getStyleProperty(String property);
+
+ public Insets getMarginInsets();
+
+ public Insets getBorderInsets();
+
+ public Insets getPaddingInsets();
+
+ /**
+ * shortcut method to get the CSS display.
+ *
+ * @see http://www.w3.org/TR/REC-CSS2/visuren.html#propdef-display
+ * @return
+ */
+ public String getDisplay();
+
+ /**
+ * null means transparent.
+ *
+ * @return
+ */
+ public Object getBackgroundColor();
+
+ public Object getColor();
+
+ /**
+ * @return
+ */
+ public boolean isSizeIncludeBorderPadding();
+
+ public void dispose();
+
+ /**
+ * @return
+ */
+ public ICSSStyle getParentStyle();
+
+ /**
+ * Get counters declared on this style. the counters are either created by
+ * counter-reset or refered by counter-increment
+ *
+ * @return
+ */
+ public Map getCounters();
+
+ /**
+ * Search a named counter declared on this style or its ancestors' styles
+ *
+ * @param name
+ * @param must
+ * @return
+ */
+ public ICounterValueGenerator findCounter(String name, boolean must);
+
+ /**
+ * Currently, rowspan and colspan are not CSS property. But based on the CSS
+ * specification, it is expected in the future this two will be added as CSS
+ * property, so we also include them into ICSSStyle
+ *
+ * @return
+ */
+ public int getRowSpan();
+
+ /**
+ * @return
+ */
+ public int getColSpan();
+
+ /**
+ * Normally, when layout a figure and its children. We'll reset the counters
+ * declared on this style. And if there are "counter-increment" on this
+ * style, they'll also be processed.
+ *
+ */
+ public void processCounters();
+
+ /**
+ * Whether the corresponding figure should be draw in selected mode. This is
+ * not a real CSS property. This is a shortcut method. implemented through
+ * getAdapter() on IRangeSelectionProxy
+ *
+ * @return
+ */
+ public boolean isInSelection();
+
+ public Object getHTMLelementInitValue(String propertyName);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/border/CSSBorder.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/border/CSSBorder.java
new file mode 100644
index 000000000..a8e8934f6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/border/CSSBorder.java
@@ -0,0 +1,535 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.border;
+
+import java.util.Arrays;
+
+import org.eclipse.draw2d.AbstractBorder;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.MessageFormater;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ */
+public class CSSBorder extends AbstractBorder {
+
+ private static final String BODER_QUERY_TEMPLETE = "border-{0}-style";
+
+ private static final String COLOR_QUERY_TEMPLETE = "border-{0}-color";
+
+ private ICSSStyle _style;
+
+ protected Rectangle _innerRect = new Rectangle();
+
+ public CSSBorder(ICSSStyle style) {
+ this._style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Border#getInsets(org.eclipse.draw2d.IFigure)
+ */
+ public Insets getInsets(IFigure figure) {
+ return _style.getBorderInsets();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Border#paint(org.eclipse.draw2d.IFigure,
+ * org.eclipse.draw2d.Graphics, org.eclipse.draw2d.geometry.Insets)
+ */
+ public void paint(IFigure figure, Graphics graphics, Insets insets) {
+ tempRect.setBounds(getPaintRectangle(figure, insets));
+ _innerRect.setBounds(tempRect);
+ _innerRect.crop(_style.getBorderInsets());
+ paintEdge(graphics, tempRect, _innerRect, ICSSStyle.LEFT);
+ paintEdge(graphics, tempRect, _innerRect, ICSSStyle.RIGHT);
+ paintEdge(graphics, tempRect, _innerRect, ICSSStyle.TOP);
+ paintEdge(graphics, tempRect, _innerRect, ICSSStyle.BOTTOM);
+ }
+
+ /**
+ * @param style
+ * @return
+ */
+ private boolean shouldDraw(String style) {
+ return style != null && !ICSSPropertyID.VAL_NONE.equals(style)
+ && !ICSSPropertyID.VAL_HIDDEN.equals(style);
+ }
+
+ /**
+ * Fetchs the color array used to draw the given edge under the given style
+ *
+ * @param graphics
+ * @param style
+ * @param edge
+ * @return
+ */
+ private RGB[] getEdgeColors(Graphics graphics, String style, String edge) {
+ String property = MessageFormater.format(COLOR_QUERY_TEMPLETE, edge);
+ Object obj = _style.getStyleProperty(property);
+ if (obj instanceof RGB) {
+ return getCustomColors(graphics, style, edge, (RGB) obj);
+ } else if (obj instanceof Color) {
+ return getCustomColors(graphics, style, edge, ((Color) obj)
+ .getRGB());
+ } else {
+ return getDefaultColors(graphics, style, edge);
+ }
+ }
+
+ private RGB[] getDefaultColors(Graphics graphics, String style, String edge) {
+ if (ICSSPropertyID.VAL_OUTSET.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] { ColorConstants.button.getRGB(),
+ ColorConstants.buttonLightest.getRGB() };
+ } else {
+ return new RGB[] { ColorConstants.buttonDarkest.getRGB(),
+ ColorConstants.buttonDarker.getRGB() };
+ }
+ } else if (ICSSPropertyID.VAL_INSET.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] { ColorConstants.buttonDarker.getRGB(),
+ ColorConstants.buttonDarkest.getRGB() };
+ } else {
+ return new RGB[] { ColorConstants.buttonLightest.getRGB(),
+ ColorConstants.button.getRGB() };
+ }
+ } else if (ICSSPropertyID.VAL_TDBORDERSTYLE.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] { ColorConstants.buttonDarker.getRGB() };
+ } else {
+ return new RGB[] { ColorConstants.button.getRGB() };
+ }
+ } else if (ICSSPropertyID.VAL_RIDGE.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] { ColorConstants.button.getRGB(),
+ ColorConstants.buttonDarkest.getRGB() };
+ } else {
+ return new RGB[] { ColorConstants.buttonDarkest.getRGB(),
+ ColorConstants.button.getRGB() };
+ }
+ } else if (ICSSPropertyID.VAL_GROOVE.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] { ColorConstants.buttonDarker.getRGB(),
+ ColorConstants.buttonLightest.getRGB() };
+ } else {
+ return new RGB[] { ColorConstants.buttonLightest.getRGB(),
+ ColorConstants.buttonDarker.getRGB(), };
+ }
+ } else if (ICSSPropertyID.VAL_DOUBLE.equals(style)) {
+ return new RGB[] { ColorConstants.buttonDarkest.getRGB(),
+ graphics.getBackgroundColor().getRGB(),
+ ColorConstants.buttonDarkest.getRGB() };
+ } else if (ICSSPropertyID.VAL_SOLID.equals(style)) {
+ return new RGB[] { ColorConstants.black.getRGB() };
+ }
+
+ return new RGB[] { ColorConstants.black.getRGB() };
+ }
+
+ private RGB[] getCustomColors(Graphics graphics, String style, String edge,
+ RGB baseColor) {
+ if (ICSSPropertyID.VAL_OUTSET.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] {
+ new RGB((int) baseColor.red * 3 / 4,
+ (int) baseColor.green * 3 / 4,
+ (int) baseColor.blue * 3 / 4),
+ new RGB(baseColor.red, baseColor.green, baseColor.blue) };
+ } else {
+ return new RGB[] {
+ new RGB((int) baseColor.red / 2,
+ (int) baseColor.green / 2,
+ (int) baseColor.blue / 2),
+ new RGB((int) baseColor.red / 4,
+ (int) baseColor.green / 4,
+ (int) baseColor.blue / 4) };
+ }
+ } else if (ICSSPropertyID.VAL_INSET.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] {
+ new RGB((int) baseColor.red / 4,
+ (int) baseColor.green / 4,
+ (int) baseColor.blue / 4),
+ new RGB((int) baseColor.red / 2,
+ (int) baseColor.green / 2,
+ (int) baseColor.blue / 2) };
+ } else {
+ return new RGB[] {
+ new RGB(baseColor.red, baseColor.green, baseColor.blue),
+ new RGB((int) baseColor.red * 3 / 4,
+ (int) baseColor.green * 3 / 4,
+ (int) baseColor.blue * 3 / 4), };
+ }
+ } else if (ICSSPropertyID.VAL_TDBORDERSTYLE.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] { new RGB((int) baseColor.red / 4,
+ (int) baseColor.green / 4, (int) baseColor.blue / 4) };
+ } else {
+ return new RGB[] { new RGB(baseColor.red, baseColor.green,
+ baseColor.blue) };
+ }
+ } else if (ICSSPropertyID.VAL_RIDGE.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] {
+ new RGB((int) baseColor.red * 3 / 4,
+ (int) baseColor.green * 3 / 4,
+ (int) baseColor.blue * 3 / 4),
+ new RGB((int) baseColor.red / 2,
+ (int) baseColor.green / 2,
+ (int) baseColor.blue / 2) };
+ } else {
+ return new RGB[] {
+ new RGB((int) baseColor.red / 2,
+ (int) baseColor.green / 2,
+ (int) baseColor.blue / 2),
+ new RGB((int) baseColor.red * 3 / 4,
+ (int) baseColor.green * 3 / 4,
+ (int) baseColor.blue * 3 / 4) };
+ }
+ } else if (ICSSPropertyID.VAL_GROOVE.equals(style)) {
+ if (ICSSStyle.TOP.equals(edge) || ICSSStyle.LEFT.equals(edge)) {
+ return new RGB[] {
+ new RGB((int) baseColor.red / 4,
+ (int) baseColor.green / 4,
+ (int) baseColor.blue / 4),
+ new RGB(baseColor.red, baseColor.green, baseColor.blue) };
+
+ } else {
+ return new RGB[] {
+ new RGB(baseColor.red, baseColor.green, baseColor.blue),
+ new RGB((int) baseColor.red / 4,
+ (int) baseColor.green / 4,
+ (int) baseColor.blue / 4) };
+ }
+ } else if (ICSSPropertyID.VAL_DOUBLE.equals(style)) {
+ return new RGB[] {
+ new RGB(baseColor.red, baseColor.green, baseColor.blue),
+ graphics.getBackgroundColor().getRGB(),
+ new RGB(baseColor.red, baseColor.green, baseColor.blue) };
+ } else if (ICSSPropertyID.VAL_SOLID.equals(style)) {
+ return new RGB[] { new RGB(baseColor.red, baseColor.green,
+ baseColor.blue) };
+ }
+ return new RGB[] { new RGB(baseColor.red, baseColor.green,
+ baseColor.blue) };
+ }
+
+ public void paintEdge(Graphics graphics, Rectangle rect,
+ Rectangle innerRect, String edge, String style) {
+ if (!shouldDraw(style)) {
+ return;
+ }
+ RGB[] rgbs = getEdgeColors(graphics, style, edge);
+
+ if (ICSSStyle.TOP.equals(edge)) {
+ paintTopEdge(graphics, rgbs, style, rect, innerRect);
+ } else if (ICSSStyle.BOTTOM.equals(edge)) {
+ paintBottomEdge(graphics, rgbs, style, rect, innerRect);
+ } else if (ICSSStyle.LEFT.equals(edge)) {
+ paintLeftEdge(graphics, rgbs, style, rect, innerRect);
+ } else if (ICSSStyle.RIGHT.equals(edge)) {
+ paintRightEdge(graphics, rgbs, style, rect, innerRect);
+ }
+ }
+
+ protected void paintEdge(Graphics graphics, Rectangle rect,
+ Rectangle innerRect, String edge) {
+ String property = MessageFormater.format(BODER_QUERY_TEMPLETE, edge);
+ Object obj = _style.getStyleProperty(property);
+ String style = obj.toString();
+ paintEdge(graphics, rect, innerRect, edge, style);
+ }
+
+ private void paintTopEdge(Graphics graphics, RGB[] rgbs, String style,
+ Rectangle rect, Rectangle innerRect) {
+ int leftX = rect.x;
+ int rightX = rect.right() - 1;
+ int y = rect.y;
+ int width = innerRect.y - rect.y;
+
+ if (ICSSPropertyID.VAL_DOTTED.equals(style)) {
+ drawDottedBorder(graphics, rgbs, ICSSStyle.TOP, rect, width);
+ } else if (ICSSPropertyID.VAL_DASHED.equals(style)) {
+ drawDashedBorder(graphics, rgbs, ICSSStyle.TOP, rect, width);
+ } else {
+ double xLeftRate = ((double) (innerRect.x - rect.x)) / width;
+ double xRightRate = ((double) (rect.right() - innerRect.right()))
+ / width;
+ graphics.pushState();
+ for (int i = 0; i < width; i++) {
+ Color color = new Color(Display.getCurrent(), rgbs[rgbs.length
+ * i / width]);
+ graphics.setForegroundColor(color);
+ graphics.drawLine((int) (leftX + i * xLeftRate), y + i,
+ (int) (rightX - i * xRightRate), y + i);
+ color.dispose();
+ }
+ graphics.popState();
+ }
+ }
+
+ private void paintBottomEdge(Graphics graphics, RGB[] rgbs, String style,
+ Rectangle rect, Rectangle innerRect) {
+ int leftX = rect.x;
+ int rightX = rect.right() - 1;
+ int y = rect.bottom() - 1;
+ int width = rect.bottom() - innerRect.bottom();
+
+ if (ICSSPropertyID.VAL_DOTTED.equals(style)) {
+ drawDottedBorder(graphics, rgbs, ICSSStyle.BOTTOM, rect, width);
+ } else if (ICSSPropertyID.VAL_DASHED.equals(style)) {
+ drawDashedBorder(graphics, rgbs, ICSSStyle.BOTTOM, rect, width);
+ } else {
+ double xLeftRate = ((double) (innerRect.x - rect.x)) / width;
+ double xRightRate = ((double) (rect.right() - innerRect.right()))
+ / width;
+ graphics.pushState();
+ for (int i = 0; i < width; i++) {
+ Color color = new Color(Display.getCurrent(), rgbs[rgbs.length
+ * i / width]);
+ graphics.setForegroundColor(color);
+ graphics.drawLine(leftX + (int) (i * xLeftRate), y - i, rightX
+ - (int) (i * xRightRate), y - i);
+ color.dispose();
+ }
+ graphics.popState();
+ }
+ }
+
+ private void paintLeftEdge(Graphics graphics, RGB[] rgbs, String style,
+ Rectangle rect, Rectangle innerRect) {
+ int x = rect.x;
+ int topY = rect.y;
+ int bottomY = rect.bottom() - 1;
+ int width = innerRect.x - rect.x;
+
+ if (ICSSPropertyID.VAL_DOTTED.equals(style)) {
+ drawDottedBorder(graphics, rgbs, ICSSStyle.LEFT, rect, width);
+ } else if (ICSSPropertyID.VAL_DASHED.equals(style)) {
+ drawDashedBorder(graphics, rgbs, ICSSStyle.LEFT, rect, width);
+ } else {
+ double yTopRate = ((double) (innerRect.y - rect.y)) / width;
+ double yBottomRate = ((double) (rect.bottom() - innerRect.bottom()))
+ / width;
+ graphics.pushState();
+ for (int i = 0; i < width; i++) {
+ Color color = new Color(Display.getCurrent(), rgbs[rgbs.length
+ * i / width]);
+ graphics.setForegroundColor(color);
+ graphics.drawLine(x + i, topY + (int) (i * yTopRate), x + i,
+ bottomY - (int) (i * yBottomRate));
+ color.dispose();
+ }
+ graphics.popState();
+ }
+
+ }
+
+ private void paintRightEdge(Graphics graphics, RGB[] rgbs, String style,
+ Rectangle rect, Rectangle innerRect) {
+ int x = rect.right() - 1;
+ int topY = rect.y;
+ int bottomY = rect.bottom() - 1;
+ int width = rect.right() - innerRect.right();
+
+ if (ICSSPropertyID.VAL_DOTTED.equals(style)) {
+ drawDottedBorder(graphics, rgbs, ICSSStyle.RIGHT, rect, width);
+ } else if (ICSSPropertyID.VAL_DASHED.equals(style)) {
+ drawDashedBorder(graphics, rgbs, ICSSStyle.RIGHT, rect, width);
+ } else {
+ graphics.pushState();
+ for (int i = 0; i < width; i++) {
+ double yTopRate = ((double) (innerRect.y - rect.y)) / width;
+ double yBottomRate = ((double) (rect.bottom() - innerRect
+ .bottom()))
+ / width;
+ Color color = new Color(Display.getCurrent(), rgbs[rgbs.length
+ * i / width]);
+ graphics.setForegroundColor(color);
+ graphics.drawLine(x - i, topY + (int) (i * yTopRate), x - i,
+ bottomY - (int) (i * yBottomRate));
+ color.dispose();
+ }
+ graphics.popState();
+ }
+ }
+
+ private void drawDottedBorder(Graphics graphics, RGB[] rgbs, String style,
+ Rectangle rect, int width) {
+ if (width == 0 || 3 * width > rect.width) {
+ return;
+ }
+
+ int beginX = 0;
+ int beginY = 0;
+ int xRate = 0;
+ int yRate = 0;
+ int span = 0;
+
+ if (ICSSStyle.TOP.equals(style)) {
+ beginX = rect.x;
+ beginY = rect.y;
+ xRate = 1;
+ yRate = 0;
+ span = rect.width;
+ } else if (ICSSStyle.LEFT.equals(style)) {
+ beginX = rect.x;
+ beginY = rect.y;
+ xRate = 0;
+ yRate = 1;
+ span = rect.height;
+ } else if (ICSSStyle.BOTTOM.equals(style)) {
+ beginX = rect.x;
+ beginY = rect.y + rect.height - width;
+ xRate = 1;
+ yRate = 0;
+ span = rect.width;
+ } else if (ICSSStyle.RIGHT.equals(style)) {
+ beginX = rect.x + rect.width - width;
+ beginY = rect.y;
+ xRate = 0;
+ yRate = 1;
+ span = rect.height;
+ }
+
+ int dottedCount = (span + width) / (2 * width);
+ if (dottedCount < 2) {
+ dottedCount = 2;
+ }
+ int averagePad = (span - dottedCount * width) / (dottedCount - 1);
+ int leftPad = (span - dottedCount * width) % (dottedCount - 1);
+ int[] paddings = new int[dottedCount - 1];
+ Arrays.fill(paddings, averagePad);
+ for (int i = 0; i < leftPad; i++) {
+ paddings[i] = paddings[i] + 1;
+ }
+
+ int pad = 0;
+ Color color = new Color(Display.getCurrent(), rgbs[0]);
+ graphics.pushState();
+ graphics.setBackgroundColor(color);
+ for (int i = 0; i < dottedCount; i++) {
+ graphics.fillOval(beginX + (pad + width * i) * xRate, beginY
+ + (pad + width * i) * yRate, width, width);
+ if (i != dottedCount - 1) {
+ pad += paddings[i];
+ }
+ }
+ graphics.popState();
+ color.dispose();
+
+ }
+
+ private void drawDashedBorder(Graphics graphics, RGB[] rgbs, String style,
+ Rectangle rect, int borderThick) {
+ if (borderThick == 0 || 5 * borderThick > rect.width) {
+ return;
+ }
+
+ if ((5 * borderThick > rect.height)
+ && (ICSSStyle.LEFT.equals(style) || ICSSStyle.RIGHT
+ .equals(style))) {
+ return;
+ }
+
+ int width = 0;
+ int height = 0;
+ int edgeLength = 0;
+ int beginX = 0;
+ int beginY = 0;
+ int xRate = 0;
+ int yRate = 0;
+ int span = 0;
+
+ if (ICSSStyle.TOP.equals(style)) {
+ width = borderThick * 2;
+ height = borderThick;
+ beginX = rect.x;
+ beginY = rect.y;
+ xRate = 1;
+ yRate = 0;
+
+ span = rect.width;
+ edgeLength = width;
+ } else if (ICSSStyle.LEFT.equals(style)) {
+ width = borderThick;
+ height = borderThick * 2;
+ beginX = rect.x;
+ beginY = rect.y;
+ xRate = 0;
+ yRate = 1;
+
+ span = rect.height;
+ edgeLength = height;
+ } else if (ICSSStyle.BOTTOM.equals(style)) {
+ width = borderThick * 2;
+ height = borderThick;
+ beginX = rect.x;
+ beginY = rect.y + rect.height - height;
+ xRate = 1;
+ yRate = 0;
+
+ span = rect.width;
+ edgeLength = width;
+ } else if (ICSSStyle.RIGHT.equals(style)) {
+ width = borderThick;
+ height = borderThick * 2;
+ beginX = rect.x + rect.width - width;
+ beginY = rect.y;
+ xRate = 0;
+ yRate = 1;
+
+ span = rect.height;
+ edgeLength = height;
+ }
+
+ int dottedCount = (span + borderThick) / (edgeLength + borderThick);
+ if (dottedCount < 2) {
+ dottedCount = 2;
+ }
+ int averagePad = (span - dottedCount * edgeLength) / (dottedCount - 1);
+ int leftPad = (span - dottedCount * edgeLength) % (dottedCount - 1);
+ int[] paddings = new int[dottedCount - 1];
+ Arrays.fill(paddings, averagePad);
+ for (int i = 0; i < leftPad; i++) {
+ paddings[i] = paddings[i] + 1;
+ }
+
+ int pad = 0;
+ graphics.pushState();
+ Color color = new Color(Display.getCurrent(), rgbs[0]);
+ graphics.setBackgroundColor(color);
+ for (int i = 0; i < dottedCount; i++) {
+ graphics.fillRectangle(beginX + (pad + width * i) * xRate, beginY
+ + (pad + height * i) * yRate, width, height);
+ if (i != dottedCount - 1) {
+ pad += paddings[i];
+ }
+ }
+ graphics.popState();
+ color.dispose();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorConverter.java
new file mode 100644
index 000000000..f493a893e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorConverter.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.color;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * @author mengbo
+ */
+public class CSSColorConverter {
+ private static final String PREFIX_RGB = "rgb"; //$NON-NLS-1$
+
+ private static Logger _log = PDPlugin.getLogger(CSSColorConverter.class);
+
+ private static CSSColorConverter _instance = new CSSColorConverter();
+
+ public static CSSColorConverter getInstantce() {
+ if (_instance == null) {
+ _instance = new CSSColorConverter();
+ }
+ return _instance;
+ }
+
+ protected Object getCSSColor(String CSSText) {
+ if (CSSText == null) {
+ return null;
+ }
+ ;
+ CSSText = CSSText.trim().toLowerCase();
+ if (CSSText.length() == 0) {
+ return null;
+ }
+ if (CSSColorDefaults.SYSTEM_DEFAULT_COLORS.containsKey(CSSText)) {
+ Object result = null;
+ result = CSSColorDefaults.SYSTEM_DEFAULT_COLORS.get(CSSText);
+ return result;
+ } else if (CSSColorDefaults.EXTENDED_COLORS.containsKey(CSSText)) {
+ Object result = null;
+ result = CSSColorDefaults.EXTENDED_COLORS.get(CSSText);
+ return result;
+ } else {
+ return convertStringToRGB(CSSText);
+ }
+ }
+
+ private RGB convertStringToRGB(String CSSText) {
+ StringBuffer sb = new StringBuffer(CSSText);
+ int value;
+ try {
+ if (sb.indexOf("#") == 0) //$NON-NLS-1$
+ {
+ if (sb.length() == 4) {
+ sb.insert(1, sb.charAt(1));
+ sb.insert(3, sb.charAt(3));
+ sb.insert(5, sb.charAt(5));
+ value = Integer.parseInt(sb.substring(1, sb.length())
+ .toString(), 16);
+ return new RGB(value >>> 16 & 0xff, value >>> 8 & 0xff,
+ value & 0xff);
+ } else if (sb.length() == 7) {
+ value = Integer.parseInt(sb.substring(1, sb.length()), 16);
+ return new RGB(value >>> 16 & 0xff, value >>> 8 & 0xff,
+ value & 0xff);
+ }
+ } else if (CSSText.startsWith(PREFIX_RGB)) {
+ return convertRgbToRGB(sb.substring(
+ sb.indexOf("(") + 1, sb.indexOf(")"))); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } catch (Exception e) {
+ _log.info("CSSColorConverter.0", CSSText, null); //$NON-NLS-1$
+ return null;
+ }
+ return null;
+ }
+
+ private RGB convertRgbToRGB(String text) {
+ text = text.trim();
+ try {
+ StringTokenizer tokenizer = new StringTokenizer(text, ",");//$NON-NLS-1$
+
+ if (tokenizer.countTokens() != 3) {
+ return null;
+ }
+ String[] rgbText = new String[3];
+ for (int i = 0; i < 3; i++) {
+ rgbText[i] = tokenizer.nextToken();
+ }
+
+ int[] intRGB = new int[] { 0, 0, 0 };
+ for (int i = 0; i < 3; i++) {
+ int intValue = -1;
+ String textValue = rgbText[i].trim();
+
+ if (textValue.endsWith("%"))//$NON-NLS-1$
+ {
+ textValue = textValue.substring(0, textValue.length() - 1);
+
+ intValue = Integer.parseInt(textValue) * 255 / 100;
+ } else {
+ intValue = Integer.parseInt(textValue);
+ }
+ if (intValue < 0) {
+ intValue = 0;
+ } else if (intValue > 255) {
+ intValue = 255;
+ }
+ intRGB[i] = intValue;
+ }
+ return new RGB(intRGB[0], intRGB[1], intRGB[2]);
+ } catch (Exception e) {
+ // notify
+ _log.info("CSSColorConverter.1", text, null); //$NON-NLS-1$
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorDefaults.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorDefaults.java
new file mode 100644
index 000000000..4e3f477e0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorDefaults.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.color;
+
+import java.util.HashMap;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ */
+public class CSSColorDefaults {
+ public static final HashMap SYSTEM_DEFAULT_COLORS = new HashMap(20);
+
+ public static final HashMap EXTENDED_COLORS = new HashMap(20);
+
+ static {
+ SYSTEM_DEFAULT_COLORS.put("black", ColorConstants.black);
+ SYSTEM_DEFAULT_COLORS.put("blue", ColorConstants.blue);
+ SYSTEM_DEFAULT_COLORS.put("gray", ColorConstants.gray);
+ SYSTEM_DEFAULT_COLORS.put("green", new Color(null, 0, 128, 0));
+ SYSTEM_DEFAULT_COLORS.put("orange", ColorConstants.orange);
+ SYSTEM_DEFAULT_COLORS.put("red", ColorConstants.red);
+ SYSTEM_DEFAULT_COLORS.put("white", ColorConstants.white);
+ SYSTEM_DEFAULT_COLORS.put("yellow", new Color(null, 255, 255, 0));
+ SYSTEM_DEFAULT_COLORS.put("aqua", ColorConstants.cyan);
+ SYSTEM_DEFAULT_COLORS.put("fuchsia", new Color(null, 255, 0, 255));
+ SYSTEM_DEFAULT_COLORS.put("lime", ColorConstants.green);
+ SYSTEM_DEFAULT_COLORS.put("maroon", new Color(null, 128, 0, 0));
+ SYSTEM_DEFAULT_COLORS.put("navy", new Color(null, 0, 0, 128));
+ SYSTEM_DEFAULT_COLORS.put("olive", new Color(null, 128, 128, 0));
+ SYSTEM_DEFAULT_COLORS.put("purple", new Color(null, 128, 0, 128));
+ SYSTEM_DEFAULT_COLORS.put("silver", ColorConstants.lightGray);
+ SYSTEM_DEFAULT_COLORS.put("teal", new Color(null, 0, 128, 128));
+
+ SYSTEM_DEFAULT_COLORS.put("activeborder", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_BORDER));
+ // Active window border.
+ SYSTEM_DEFAULT_COLORS.put("activecaption",
+ ColorConstants.titleBackground);
+ // Active window caption.
+ SYSTEM_DEFAULT_COLORS
+ .put("appworkspace", ColorConstants.listBackground);
+ // Background color of multiple document interface.
+ SYSTEM_DEFAULT_COLORS.put("background", ColorConstants.listBackground);
+ // Desktop background.
+ SYSTEM_DEFAULT_COLORS.put("buttonface", ColorConstants.button);
+ // Face color for three-dimensional display elements.
+ SYSTEM_DEFAULT_COLORS.put("buttonhighlight",
+ ColorConstants.buttonLightest);
+ // Dark shadow for three-dimensional display elements (for edges facing
+ // away from the light source).
+ SYSTEM_DEFAULT_COLORS.put("buttonshadow", ColorConstants.buttonDarker);
+ // Shadow color for three-dimensional display elements.
+ SYSTEM_DEFAULT_COLORS.put("buttontext", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
+ // Text on push buttons.
+ SYSTEM_DEFAULT_COLORS
+ .put("captiontext", ColorConstants.titleForeground);
+ // Text in caption, size box, and scrollbar arrow box.
+ SYSTEM_DEFAULT_COLORS.put("graytext",
+ ColorConstants.titleInactiveForeground);
+ // Grayed (disabled) text. This color is set to #000 if the current
+ // display driver does not support a solid gray color.
+ SYSTEM_DEFAULT_COLORS.put("highlight",
+ ColorConstants.menuBackgroundSelected);
+ // Item(s) selected in a control.
+ SYSTEM_DEFAULT_COLORS.put("highlighttext",
+ ColorConstants.menuForegroundSelected);
+ // Text of item(s) selected in a control.
+ SYSTEM_DEFAULT_COLORS.put("inactiveborder", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
+ // Inactive window border.
+ SYSTEM_DEFAULT_COLORS.put("inactivecaption",
+ ColorConstants.titleInactiveBackground);
+ // Inactive window caption.
+ SYSTEM_DEFAULT_COLORS.put("inactivecaptiontext",
+ ColorConstants.titleInactiveForeground);
+ // Color of text in an inactive caption.
+ SYSTEM_DEFAULT_COLORS.put("infobackground",
+ ColorConstants.tooltipBackground);
+ // Background color for tooltip controls.
+ SYSTEM_DEFAULT_COLORS.put("infotext", ColorConstants.tooltipForeground);
+ // Text color for tooltip controls.
+ SYSTEM_DEFAULT_COLORS.put("menu", ColorConstants.menuBackground);
+ // Menu background.
+ SYSTEM_DEFAULT_COLORS.put("menutext", ColorConstants.menuForeground);
+ // Text in menus.
+ SYSTEM_DEFAULT_COLORS.put("scrollbar", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ // Scroll bar gray area.
+ SYSTEM_DEFAULT_COLORS.put("threeddarkshadow", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+ // Dark shadow for three-dimensional display elements.
+ SYSTEM_DEFAULT_COLORS.put("threedface", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ // Face color for three-dimensional display elements.
+ SYSTEM_DEFAULT_COLORS.put("threedhighlight", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+ // Highlight color for three-dimensional display elements.
+ SYSTEM_DEFAULT_COLORS.put("threedlightshadow", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
+ // Light color for three-dimensional display elements (for edges facing
+ // the light source).
+ SYSTEM_DEFAULT_COLORS.put("threedshadow", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+ // Dark shadow for three-dimensional display elements.
+ SYSTEM_DEFAULT_COLORS.put("window", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ // Window background.
+ SYSTEM_DEFAULT_COLORS.put("windowframe", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_WIDGET_BORDER));
+ // Window frame.
+ SYSTEM_DEFAULT_COLORS.put("windowtext", Display.getCurrent()
+ .getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ // Window text
+ SYSTEM_DEFAULT_COLORS.put("hyperlink", ColorConstants.blue);
+ }
+
+ static {
+ EXTENDED_COLORS.put("aliceblue", new Color(null, 240, 248, 255));
+ EXTENDED_COLORS.put("antiquewhite", new Color(null, 250, 235, 215));
+ EXTENDED_COLORS.put("aqua", new Color(null, 0, 255, 255));
+ EXTENDED_COLORS.put("aquamarine", new Color(null, 127, 255, 212));
+ EXTENDED_COLORS.put("azure", new Color(null, 240, 255, 255));
+ EXTENDED_COLORS.put("beige", new Color(null, 245, 245, 220));
+ EXTENDED_COLORS.put("bisque", new Color(null, 255, 228, 196));
+ EXTENDED_COLORS.put("black", new Color(null, 0, 0, 0));
+ EXTENDED_COLORS.put("blanchedalmond", new Color(null, 255, 235, 205));
+ EXTENDED_COLORS.put("blue", new Color(null, 0, 0, 255));
+ EXTENDED_COLORS.put("blueviolet", new Color(null, 138, 43, 226));
+ EXTENDED_COLORS.put("brown", new Color(null, 165, 42, 42));
+ EXTENDED_COLORS.put("burlywood", new Color(null, 222, 184, 135));
+ EXTENDED_COLORS.put("cadetblue", new Color(null, 95, 158, 160));
+ EXTENDED_COLORS.put("chartreuse", new Color(null, 127, 255, 0));
+ EXTENDED_COLORS.put("chocolate", new Color(null, 210, 105, 30));
+ EXTENDED_COLORS.put("coral", new Color(null, 255, 127, 80));
+ EXTENDED_COLORS.put("cornflowerblue", new Color(null, 100, 149, 237));
+ EXTENDED_COLORS.put("cornsilk", new Color(null, 255, 248, 220));
+ EXTENDED_COLORS.put("crimson", new Color(null, 220, 20, 60));
+ EXTENDED_COLORS.put("cyan", new Color(null, 0, 255, 255));
+ EXTENDED_COLORS.put("darkblue", new Color(null, 0, 0, 139));
+ EXTENDED_COLORS.put("darkcyan", new Color(null, 0, 139, 139));
+ EXTENDED_COLORS.put("darkgoldenrod", new Color(null, 184, 134, 11));
+ EXTENDED_COLORS.put("darkgray", new Color(null, 169, 169, 169));
+ EXTENDED_COLORS.put("darkgreen", new Color(null, 0, 100, 0));
+ EXTENDED_COLORS.put("darkkhaki", new Color(null, 189, 183, 107));
+ EXTENDED_COLORS.put("darkmagenta", new Color(null, 139, 0, 139));
+ EXTENDED_COLORS.put("darkolivegreen", new Color(null, 85, 107, 47));
+ EXTENDED_COLORS.put("darkorange", new Color(null, 255, 140, 0));
+ EXTENDED_COLORS.put("darkorchid", new Color(null, 153, 50, 204));
+ EXTENDED_COLORS.put("darkred", new Color(null, 139, 0, 0));
+ EXTENDED_COLORS.put("darksalmon", new Color(null, 233, 150, 122));
+ EXTENDED_COLORS.put("darkseagreen", new Color(null, 143, 188, 143));
+ EXTENDED_COLORS.put("darkslateblue", new Color(null, 72, 61, 139));
+ EXTENDED_COLORS.put("darkslategray", new Color(null, 47, 79, 79));
+ EXTENDED_COLORS.put("darkturquoise", new Color(null, 0, 206, 209));
+ EXTENDED_COLORS.put("darkviolet", new Color(null, 148, 0, 211));
+ EXTENDED_COLORS.put("deeppink", new Color(null, 255, 20, 147));
+ EXTENDED_COLORS.put("deepskyblue", new Color(null, 0, 191, 255));
+ EXTENDED_COLORS.put("dimgray", new Color(null, 105, 105, 105));
+ EXTENDED_COLORS.put("dodgerblue", new Color(null, 30, 144, 255));
+ EXTENDED_COLORS.put("feldspar", new Color(null, 209, 146, 117));
+ EXTENDED_COLORS.put("firebrick", new Color(null, 178, 34, 34));
+ EXTENDED_COLORS.put("floralwhite", new Color(null, 255, 250, 240));
+ EXTENDED_COLORS.put("forestgreen", new Color(null, 34, 139, 34));
+ EXTENDED_COLORS.put("fuchsia", new Color(null, 255, 0, 255));
+ EXTENDED_COLORS.put("gainsboro", new Color(null, 220, 220, 220));
+ EXTENDED_COLORS.put("ghostwhite", new Color(null, 248, 248, 255));
+ EXTENDED_COLORS.put("gold", new Color(null, 255, 215, 0));
+ EXTENDED_COLORS.put("goldenrod", new Color(null, 218, 165, 32));
+ EXTENDED_COLORS.put("gray", new Color(null, 128, 128, 128));
+ EXTENDED_COLORS.put("green", new Color(null, 0, 128, 0));
+ EXTENDED_COLORS.put("greenyellow", new Color(null, 173, 255, 47));
+ EXTENDED_COLORS.put("honeydew", new Color(null, 240, 255, 240));
+ EXTENDED_COLORS.put("hotpink", new Color(null, 255, 105, 180));
+ EXTENDED_COLORS.put("indianred", new Color(null, 205, 92, 92));
+ EXTENDED_COLORS.put("indigo", new Color(null, 75, 0, 130));
+ EXTENDED_COLORS.put("ivory", new Color(null, 255, 255, 240));
+ EXTENDED_COLORS.put("khaki", new Color(null, 240, 230, 140));
+ EXTENDED_COLORS.put("lavender", new Color(null, 230, 230, 250));
+ EXTENDED_COLORS.put("lavenderblush", new Color(null, 255, 240, 245));
+ EXTENDED_COLORS.put("lawngreen", new Color(null, 124, 252, 0));
+ EXTENDED_COLORS.put("lemonchiffon", new Color(null, 255, 250, 205));
+ EXTENDED_COLORS.put("lightblue", new Color(null, 173, 216, 230));
+ EXTENDED_COLORS.put("lightcoral", new Color(null, 240, 128, 128));
+ EXTENDED_COLORS.put("lightcyan", new Color(null, 224, 255, 255));
+ EXTENDED_COLORS.put("lightgoldenrodyellow", new Color(null, 250, 250,
+ 210));
+ EXTENDED_COLORS.put("lightgrey", new Color(null, 211, 211, 211));
+ EXTENDED_COLORS.put("lightgreen", new Color(null, 144, 238, 144));
+ EXTENDED_COLORS.put("lightpink", new Color(null, 255, 182, 193));
+ EXTENDED_COLORS.put("lightsalmon", new Color(null, 255, 160, 122));
+ EXTENDED_COLORS.put("lightseagreen", new Color(null, 32, 178, 170));
+ EXTENDED_COLORS.put("lightskyblue", new Color(null, 135, 206, 250));
+ EXTENDED_COLORS.put("lightslateblue", new Color(null, 132, 112, 255));
+ EXTENDED_COLORS.put("lightslategray", new Color(null, 119, 136, 153));
+ EXTENDED_COLORS.put("lightsteelblue", new Color(null, 176, 196, 222));
+ EXTENDED_COLORS.put("lightyellow", new Color(null, 255, 255, 224));
+ EXTENDED_COLORS.put("lime", new Color(null, 0, 255, 0));
+ EXTENDED_COLORS.put("limegreen", new Color(null, 50, 205, 50));
+ EXTENDED_COLORS.put("linen", new Color(null, 250, 240, 230));
+ EXTENDED_COLORS.put("magenta", new Color(null, 255, 0, 255));
+ EXTENDED_COLORS.put("maroon", new Color(null, 128, 0, 0));
+ EXTENDED_COLORS.put("mediumaquamarine", new Color(null, 102, 205, 170));
+ EXTENDED_COLORS.put("mediumblue", new Color(null, 0, 0, 205));
+ EXTENDED_COLORS.put("mediumorchid", new Color(null, 186, 85, 211));
+ EXTENDED_COLORS.put("mediumpurple", new Color(null, 147, 112, 216));
+ EXTENDED_COLORS.put("mediumseagreen", new Color(null, 60, 179, 113));
+ EXTENDED_COLORS.put("mediumslateblue", new Color(null, 123, 104, 238));
+ EXTENDED_COLORS.put("mediumspringgreen", new Color(null, 0, 250, 154));
+ EXTENDED_COLORS.put("mediumturquoise", new Color(null, 72, 209, 204));
+ EXTENDED_COLORS.put("mediumvioletred", new Color(null, 199, 21, 133));
+ EXTENDED_COLORS.put("midnightblue", new Color(null, 25, 25, 112));
+ EXTENDED_COLORS.put("mintcream", new Color(null, 245, 255, 250));
+ EXTENDED_COLORS.put("mistyrose", new Color(null, 255, 228, 225));
+ EXTENDED_COLORS.put("moccasin", new Color(null, 255, 228, 181));
+ EXTENDED_COLORS.put("navajowhite", new Color(null, 255, 222, 173));
+ EXTENDED_COLORS.put("navy", new Color(null, 0, 0, 128));
+ EXTENDED_COLORS.put("oldlace", new Color(null, 253, 245, 230));
+ EXTENDED_COLORS.put("olive", new Color(null, 128, 128, 0));
+ EXTENDED_COLORS.put("olivedrab", new Color(null, 107, 142, 35));
+ EXTENDED_COLORS.put("orange", new Color(null, 255, 165, 0));
+ EXTENDED_COLORS.put("orangeted", new Color(null, 255, 69, 0));
+ EXTENDED_COLORS.put("orchid", new Color(null, 218, 112, 214));
+ EXTENDED_COLORS.put("ralegoldenrod", new Color(null, 238, 232, 170));
+ EXTENDED_COLORS.put("palegreen", new Color(null, 152, 251, 152));
+ EXTENDED_COLORS.put("paleturquoise", new Color(null, 175, 238, 238));
+ EXTENDED_COLORS.put("palevioletred", new Color(null, 216, 112, 147));
+ EXTENDED_COLORS.put("papayawhip", new Color(null, 255, 239, 213));
+ EXTENDED_COLORS.put("peachpuff", new Color(null, 255, 218, 185));
+ EXTENDED_COLORS.put("peru", new Color(null, 205, 133, 63));
+ EXTENDED_COLORS.put("pink", new Color(null, 255, 192, 203));
+ EXTENDED_COLORS.put("plum", new Color(null, 221, 160, 221));
+ EXTENDED_COLORS.put("powderblue", new Color(null, 176, 224, 230));
+ EXTENDED_COLORS.put("purple", new Color(null, 128, 0, 128));
+ EXTENDED_COLORS.put("red", new Color(null, 255, 0, 0));
+ EXTENDED_COLORS.put("rosybrown", new Color(null, 188, 143, 143));
+ EXTENDED_COLORS.put("royalblue", new Color(null, 65, 105, 225));
+ EXTENDED_COLORS.put("saddlebrown", new Color(null, 139, 69, 19));
+ EXTENDED_COLORS.put("salmon", new Color(null, 250, 128, 114));
+ EXTENDED_COLORS.put("sandybrown", new Color(null, 244, 164, 96));
+ EXTENDED_COLORS.put("seagreen", new Color(null, 46, 139, 87));
+ EXTENDED_COLORS.put("seashell", new Color(null, 255, 245, 238));
+ EXTENDED_COLORS.put("sienna", new Color(null, 160, 82, 45));
+ EXTENDED_COLORS.put("silver", new Color(null, 192, 192, 192));
+ EXTENDED_COLORS.put("skyblue", new Color(null, 135, 206, 235));
+ EXTENDED_COLORS.put("slateblue", new Color(null, 106, 90, 205));
+ EXTENDED_COLORS.put("slategray", new Color(null, 112, 128, 144));
+ EXTENDED_COLORS.put("snow", new Color(null, 255, 250, 250));
+ EXTENDED_COLORS.put("springgreen", new Color(null, 0, 255, 127));
+ EXTENDED_COLORS.put("steelblue", new Color(null, 70, 130, 180));
+ EXTENDED_COLORS.put("tan", new Color(null, 210, 180, 140));
+ EXTENDED_COLORS.put("teal", new Color(null, 0, 128, 128));
+ EXTENDED_COLORS.put("thistle", new Color(null, 216, 191, 216));
+ EXTENDED_COLORS.put("tomato", new Color(null, 255, 99, 71));
+ EXTENDED_COLORS.put("turquoise", new Color(null, 64, 224, 208));
+ EXTENDED_COLORS.put("violet", new Color(null, 238, 130, 238));
+ EXTENDED_COLORS.put("violetred", new Color(null, 208, 32, 144));
+ EXTENDED_COLORS.put("wheat", new Color(null, 245, 222, 179));
+ EXTENDED_COLORS.put("white", new Color(null, 255, 255, 255));
+ EXTENDED_COLORS.put("whitesmoke", new Color(null, 245, 245, 245));
+ EXTENDED_COLORS.put("yellow", new Color(null, 255, 255, 0));
+ EXTENDED_COLORS.put("yellowgreen", new Color(null, 154, 205, 50));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorManager.java
new file mode 100644
index 000000000..ec3542ada
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/color/CSSColorManager.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.color;
+
+/**
+ * @author mengbo
+ */
+public class CSSColorManager {
+ private static CSSColorManager _instance;
+
+ private CSSColorManager() {
+ }
+
+ public static CSSColorManager getInstance() {
+ if (_instance == null) {
+ _instance = new CSSColorManager();
+ }
+ return _instance;
+ }
+
+ /**
+ * return Color or RGB. If return color, then the returned color is system
+ * color, caller should NOT dispose the returned color
+ *
+ * @param cssText
+ * @return
+ */
+ public Object getColor(String cssText) {
+ return CSSColorConverter.getInstantce().getCSSColor(cssText);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFont.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFont.java
new file mode 100644
index 000000000..504fd4288
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFont.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.font;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * @author mengbo
+ */
+public class CSSFont implements ICSSFont {
+ private String _family;
+
+ private int _size;
+
+ private int _style;
+
+ private int _weight;
+
+ private String _cssString;
+
+ /**
+ *
+ */
+ public CSSFont(String family, int size, int style, int weight,
+ String cssString) {
+ this._family = family;
+ this._size = size;
+ this._style = style;
+ this._weight = weight;
+ _cssString = cssString;
+ }
+
+ public String getFontFamily() {
+ return _family;
+ }
+
+ public int getFontSize() {
+ return _size;
+ }
+
+ public int getFontStyle() {
+ return _style;
+ }
+
+ public String getCSSString() {
+ return _cssString;
+ }
+
+ public int getWeight() {
+ return _weight;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof CSSFont) {
+ CSSFont fd = (CSSFont) obj;
+ return this._family.equals(fd._family) && this._size == fd._size
+ && this._style == fd._style && this._weight == fd._weight;
+ } else
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return _family.hashCode() + _size + _style + _weight;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.font.ICSSFont#getSwtFont()
+ */
+ public Font getSwtFont() {
+ // return FontPoolManager.getInstance().getFont(this);
+ return CSSFontManager.getInstance().getSwtFont(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.font.ICSSFont#getXHeight()
+ */
+ public int getXHeight() {
+ return getFontSize();
+ }
+
+ /**
+ * @return
+ */
+ public int getSwtFontStyle() {
+ int style = SWT.NONE;
+ // see:http://www.htmlhelp.com/reference/css/font/font-weight.html
+ if (getWeight() >= 600)
+ style |= SWT.BOLD;
+ style |= getFontStyle();
+ return style;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFontManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFontManager.java
new file mode 100644
index 000000000..3034ed8e3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/CSSFontManager.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.font;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.FontFamilyMeta;
+import org.eclipse.jst.pagedesigner.css2.property.FontSizeMeta;
+import org.eclipse.jst.pagedesigner.css2.property.FontWeightMeta;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.utils.CacheManager;
+import org.eclipse.jst.pagedesigner.utils.ICacheEntryCreator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ */
+public class CSSFontManager implements ICSSFontManager {
+ private static CSSFontManager _instance;
+
+ private static final boolean DEBUG = false;
+
+ private int _totalFont = 0;
+
+ // private static FontPoolManager _fontPoolManager;
+ // Map _cache = new HashMap();
+
+ private static final int CACHESIZE = 100; // we cache 100 font.
+
+ // the scale to convert the px to pt.
+ private final static double FONT_SCALE = ((double) Display.getCurrent()
+ .getDPI().x) / 72;
+
+ static String cssFontToLocalFont(String original) {
+ if ("serif".equalsIgnoreCase(original)) {
+ return "Georgia";
+ } else if ("sans-serif".equalsIgnoreCase(original)) {
+ return "Arial";
+ } else if ("cursive".equalsIgnoreCase(original)) {
+ // FIXME: MS windows does not support the alternative fonts that
+ // match cursive defined at
+ // http://www.w3.org/TR/REC-CSS2/fonts.html#generic-font-families,
+ // We use Comic Sans MS font family
+ // because it is MS alternative.
+ return "Comic Sans MS";
+ } else if ("fantasy".equalsIgnoreCase(original)) {
+ return cssFontToLocalFont("serif");
+ } else if ("monospace".equalsIgnoreCase(original)) {
+ return "Courier New";
+ } else {
+ return original;
+ }
+ }
+
+ private CacheManager _cacheManager = new CacheManager(
+ new ICacheEntryCreator() {
+ public Object createEntry(Object key) {
+ if (DEBUG) {
+ _totalFont++;
+ System.out.println("TotalFont++: " + _totalFont);
+ }
+ CSSFont cssfont = (CSSFont) key;
+
+ Font font = new Font(null, cssFontToLocalFont(cssfont
+ .getFontFamily()), (int) Math.round(cssfont
+ .getFontSize()
+ / FONT_SCALE), cssfont.getSwtFontStyle());
+ return font;
+ }
+
+ public void dispose(Object key, Object entry) {
+ if (DEBUG) {
+ _totalFont--;
+ System.out.println("TotalFont--: " + _totalFont);
+ }
+ ((Font) entry).dispose();
+
+ }
+ }, CACHESIZE);
+
+ /**
+ * constructor
+ */
+ private CSSFontManager() {
+ super();
+ }
+
+ private String resolveFontStyleString(ICSSStyle style) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(ICSSPropertyID.ATTR_FONT_FAMILY).append(":");
+ sb.append("'").append(
+ (String) style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_FAMILY))
+ .append("'");
+ sb.append(";");
+ sb.append(ICSSPropertyID.ATTR_FONT_STYLE).append(":");
+ sb
+ .append(
+ (String) style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_STYLE))
+ .append(";");
+ sb.append(ICSSPropertyID.ATTR_FONT_WEIGHT).append(":");
+ sb.append(
+ ((Integer) style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_WEIGHT))
+ .toString()).append(";");
+ sb.append(ICSSPropertyID.ATTR_FONT_SIZE).append(":");
+ int fontSize = getFontSize(style, style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_SIZE));
+ sb.append(Integer.toString(fontSize));
+ return sb.toString();
+ }
+
+ public ICSSFont createFont(ICSSStyle style) {
+ String fontfamily = (String) style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_FAMILY);
+ Object fontsizeobj = style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_SIZE);
+ int fontsize;
+ fontsize = getFontSize(style, fontsizeobj);
+ int fontstyle = getFontStyle(style);
+ int fontweight = ((Integer) style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_WEIGHT)).intValue();
+
+ return new CSSFont(fontfamily, fontsize, fontstyle, fontweight,
+ resolveFontStyleString(style));
+ }
+
+ private int getFontSize(ICSSStyle style, Object fontsizeobj) {
+ int fontsize;
+ if (fontsizeobj instanceof Length) {
+ fontsize = ((Length) fontsizeobj).getValue();
+ } else {
+ fontsize = style.getParentStyle().getCSSFont().getFontSize();
+ }
+ return fontsize;
+ }
+
+ /**
+ * @param style
+ */
+ private int getFontStyle(ICSSStyle style) {
+ int fontstyle;
+ String fontstylestr = (String) style
+ .getStyleProperty(ICSSPropertyID.ATTR_FONT_STYLE);
+ if (ICSSPropertyID.VAL_ITALIC.equals(fontstylestr)
+ || ICSSPropertyID.VAL_OBLIQUE.equals(fontstylestr)) {
+ fontstyle = SWT.ITALIC;
+ } else {
+ fontstyle = SWT.NORMAL;
+ }
+ return fontstyle;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.font.ICSSFontManager#dispose()
+ */
+ public void dispose() {
+ _cacheManager.disposeAll();
+ }
+
+ public ICSSFont createDefaultFont() {
+ CSSFont result = new CSSFont(FontFamilyMeta.DEFAULT_FONT,
+ (int) FontSizeMeta.MEDIUM_VAL_INT, SWT.NORMAL,
+ FontWeightMeta.NORMAL_WEIGHT.intValue(), "");
+ return result;
+ }
+
+ public Font getSwtFont(CSSFont f) {
+ return (Font) _cacheManager.getEntry(f);
+ }
+
+ /**
+ * @return
+ */
+ public static CSSFontManager getInstance() {
+ if (_instance == null) {
+ _instance = new CSSFontManager();
+ }
+ return _instance;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFont.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFont.java
new file mode 100644
index 000000000..1dff0bc9b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFont.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.font;
+
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * XXX: this class should be renamed to CSSFontDescriptor. Since now it is only
+ * used to describe a CSSFont.
+ *
+ * @author mengbo
+ */
+public interface ICSSFont {
+ /**
+ * Will get a Font system resource from a pool.
+ *
+ * The caller should NOT dispose the returned Font object.
+ *
+ * The caller should not hold reference on the returned Font object, since
+ * system may dispose it at any time.
+ *
+ * @return
+ */
+ public Font getSwtFont();
+
+ public String getFontFamily();
+
+ /**
+ * get font size in pixel
+ *
+ * @return
+ */
+ public int getFontSize();
+
+ /**
+ * get font x height in pixel
+ *
+ * @return
+ */
+ public int getXHeight();
+
+ /**
+ * @return
+ */
+ public int getWeight();
+
+ /**
+ *
+ * @return could be SWT.NONE or SWT.ITALIC
+ */
+ public int getFontStyle();
+
+ public String getCSSString();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFontManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFontManager.java
new file mode 100644
index 000000000..2d0720412
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/font/ICSSFontManager.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.font;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+
+/**
+ * @author mengbo
+ */
+public interface ICSSFontManager {
+ public ICSSFont createFont(ICSSStyle style);
+
+ public void dispose();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/html4.css b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/html4.css
new file mode 100644
index 000000000..e91e5de0d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/html4.css
@@ -0,0 +1,155 @@
+/*
+ * Basic HTML style information.
+ */
+html,
+address,
+blockquote,listing,
+body, dd, div,
+dl, dt, fieldset, legend,form,
+frame, frameset,
+h1, h2, h3, h4,
+h5, h6, noframes,noscript,
+ol, p, ul, center,
+dir, hr, menu, pre, plaintext, xmp { display: block }
+
+ol {counter-reset: _anonymous; list-style-type: decimal}
+ul,dir,menu {counter-reset: _anonymous; list-style-type: disc}
+li {display: list-item}
+li {counter-increment: _anonymous}
+
+head { display: none }
+table { display: table }
+tr { display: table-row }
+thead { display: table-header-group }
+tbody { display: table-row-group }
+tfoot { display: table-footer-group }
+col { display: table-column }
+colgroup { display: table-column-group }
+td, th { display: table-cell; }
+caption { display: table-caption }
+th { font-weight: bolder;}
+caption { text-align: center;horizontal-align:top }
+button, textarea,
+input, object,
+select, img { display:inline-block; }
+pre,plaintext, xmp { white-space: pre }
+h1, h2, h3, h4,
+h5, h6, b,
+strong { font-weight: bold }
+i, cite, em,dfn,
+var, address { font-style: italic }
+pre, tt, code,plaintext, xmp,
+kbd, samp { font-family: monospace }
+ol { list-style-type: decimal }
+br:before { content: "\A" }
+center { text-align: center }
+sub { vertical-align: sub }
+sup { vertical-align: super }
+u, ins { text-decoration: underline }
+input { text-decoration: none }
+button { white-space: nowrap }
+a[href] { text-decoration: underline }
+
+/*
+ * styles that may be different for different user agent.
+ * This part may need to move out and put into different css files.
+ */
+body { line-height: 1.12em }
+h1 { font-size: 2em; margin: .67em 0 }
+h2 { font-size: 1.5em; margin: .75em 0 }
+h3 { font-size: 1.17em; margin: .83em 0 }
+h4, p,ul,
+fieldset, form,
+ol, dl, dir,
+menu { margin: 1.12em 0 }
+blockquote { margin: 1em 40px }
+h5 { font-size: .83em; margin: 1.5em 0 }
+h6 { font-size: .75em; margin: 1.67em 0 }
+blockquote { margin-left: 40px; margin-right: 40px }
+big { font-size: larger }
+small, sub, sup { font-size: smaller }
+s, strike, del { text-decoration: line-through }
+hr { border: 1px inset }
+ol, ul, dir,
+menu, dd { margin-left: 40px;border:0px }
+ol ul, ul ol,
+ul ul, ol ol { margin-top: 0; margin-bottom: 0 }
+abbr, acronym { font-variant: small-caps; letter-spacing: 0.1em }
+a[href] { color:blue;}
+select {background-color: window;font-family:sans-serif;font-size:13px;font-weight: normal;}
+textarea {border: 2px inset;font-size:13px;font-family:monospace}
+textarea,
+input {background-color: window}
+input,
+input[type=text],
+input[type=password] {border: 2px inset;font-size:13px;font-family:sans-serif;font-weight: normal;}
+/* following upcased TYPE is for workaround the WTP M2 bug of not setting default content type */
+input[TYPE=submit],input[TYPE=reset],input[TYPE=button],input[TYPE=cancel],
+button,
+input[type=button],
+input[type=reset],
+input[type=cancel],
+input[type=submit] {background-color: ButtonFace; border: 2px outset; font-size:13px;
+ font-family:sans-serif;text-align: center;font-weight: normal;}
+input[type=image],
+input[type=checkbox],
+input[type=radio] {border: none }
+input[type=hidden] {border: none }
+img {border: 0px none}
+listing {font-family:monospace;font-size: medium;white-space: pre; margin: 1em 0;}
+tbody,thead,tfoot {vertical-align: middle;}
+blink {text-decoration: blink;}
+
+hr {margin: 0.5em auto 0.5em auto;}
+caption {border: 0px none;margin: 0px; padding:0px 0px 4px 0px;}
+td, th,
+table {border: 4px none;}
+button {padding: 3px 5px;text-align: center;vertical-align: middle;}
+button,textarea,input {vertical-align: text-bottom;color:black;font-style:none;}
+select {vertical-align: text-bottom;}
+input[type=image] {vertical-align: baseline;}
+li {min-height:1.2em}
+button {min-height:1.8em}
+div,tr,form {min-height:1.2em}
+table,td {min-width:1.2em;min-height:1.2em}
+
+/* nested lists have no top/bottom margins */
+ul ul, ul ol, ul dir, ul menu, ul dl,
+ol ul, ol ol, ol dir, ol menu, ol dl,
+dir ul, dir ol, dir dir, dir menu, dir dl,
+menu ul, menu ol, menu dir, menu menu, menu dl,
+dl ul, dl ol, dl dir, dl menu, dl dl {margin-top: 0; margin-bottom: 0;}
+
+/* 2 deep unordered lists use a circle */
+ol ul, ul ul, menu ul, dir ul,
+ol menu, ul menu, menu menu, dir menu,
+ol dir, ul dir, menu dir, dir dir {list-style-type: circle;}
+
+/* 3 deep (or more) unordered lists use a square */
+ol ol ul, ol ul ul, ol menu ul, ol dir ul,
+ol ol menu, ol ul menu, ol menu menu, ol dir menu,
+ol ol dir, ol ul dir, ol menu dir, ol dir dir,
+ul ol ul, ul ul ul, ul menu ul, ul dir ul,
+ul ol menu, ul ul menu, ul menu menu, ul dir menu,
+ul ol dir, ul ul dir, ul menu dir, ul dir dir,
+menu ol ul, menu ul ul, menu menu ul, menu dir ul,
+menu ol menu, menu ul menu, menu menu menu, menu dir menu,
+menu ol dir, menu ul dir, menu menu dir, menu dir dir,
+dir ol ul, dir ul ul, dir menu ul, dir dir ul,
+dir ol menu, dir ul menu, dir menu menu, dir dir menu,
+dir ol dir, dir ul dir, dir menu dir, dir dir dir { list-style-type: square;}
+
+/**
+ * We do not write codes to support some elements. This part defines properties for them
+ * to improve the look of these elements.
+ */
+applet {border: 1px solid;}
+fieldset {border: 2px groove;}
+applet,iframe {display:inline-block; border:3px inset; }
+object {display:inline-block;border:0px none;}
+
+
+/*
+ * Sets right margin to have gap between widgets.
+ */
+input,textarea,button { margin-right: 2px;} \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockBox.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockBox.java
new file mode 100644
index 000000000..7c635a59c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockBox.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A CompositeBox suitable for containing multiple LineBox fragments. Based on
+ * BlockBox of draw2d.
+ *
+ * @author mengbo
+ */
+public class BlockBox extends CompositeBox {
+ // internalContent dimension is for the closure of the FlowBox(es) added
+ // into the BlockBox.
+ private int _internalContentWidth = -1;
+
+ private int _internalContentHeight = -1;
+
+ Rectangle toRectangle() {
+ return new Rectangle(_x, _y, Math.max(_width, _recommendedWidth),
+ _height);
+ }
+
+ /**
+ * Sets the height.
+ *
+ * @param h
+ * The height
+ */
+ public void setHeight(int h) {
+ _height = h;
+ }
+
+ /**
+ * Unions the dimensions of this with the dimensions of the passed FlowBox.
+ * For BlockBox, each time unionInfo is called, the passed in object
+ * represents a line.
+ *
+ * @param box
+ * The FlowBox to union this with
+ */
+ protected void unionInfo(FlowBox box) {
+ _width = Math.max(_width, box._width + this.getBorderPaddingWidth());
+ _height = Math.max(_height, box._y + box._height
+ + this.getBorderPaddingHeight());
+
+ _internalContentWidth = Math.max(_internalContentWidth, box._width);
+ _internalContentHeight = Math.max(_internalContentHeight, box._y
+ + box._height);
+ }
+
+ public int getInternalContentWidth() {
+ return _internalContentWidth;
+ }
+
+ public int getInternalContentHeight() {
+ return _internalContentHeight;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowBox#getAscent()
+ */
+ public int getAscent() {
+ // XXX: some hard coded things here. If the blockbox is only for a
+ // single widget, and if that widget support ascent, then we'll
+ // delegate to that widget for ascent support.
+ // if (_fragments.size()==1)
+ // {
+ // FlowBox box = (FlowBox) _fragments.get(0);
+ // if (box instanceof LineBox)
+ // {
+ // List linecomponents = ((LineBox) box).getFragments();
+ // if (linecomponents != null && linecomponents.size() == 1)
+ // {
+ // FlowBox box2 = (FlowBox) linecomponents.get(0);
+ // if (box2 instanceof WidgetBox)
+ // {
+ // WidgetBox widgetBox = (WidgetBox) box2;
+ // if (widgetBox.supportAscent())
+ // {
+ // return widgetBox.getAscent() + this.getBorderPaddingInsets().top;
+ // }
+ // }
+ // }
+ // }
+ // }
+ return super.getAscent();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlow.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlow.java
new file mode 100644
index 000000000..35eb4c7c2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlow.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.PositionConstants;
+
+/**
+ * A <code>FlowFigure</code> represented by a single {@link BlockBox}fragment
+ * containing one or more lines. A BlockFlow is a creator of LineBoxes, which
+ * its children require during layout. A BlockFlow can be thought of as a
+ * paragraph.
+ * <P>
+ * BlockFlows should be nested inside other BlockFlows, but it is also valid to
+ * place them in InlineFlows. {@link FlowPage}can be used as a "root" block and
+ * can be added to normal draw2d Figures.
+ * <P>
+ * Only {@link FlowFigure}s can be added to a BlockFlow.
+ */
+public class BlockFlow extends FlowFigure {
+
+ final BlockBox _blockBox;
+
+ private int _aligment;
+
+ /**
+ * Constructs a new BlockFlow.
+ */
+ public BlockFlow() {
+ setLayoutManager(createDefaultFlowLayout());
+ _blockBox = createBlockBox();
+ }
+
+ BlockBox createBlockBox() {
+ return new BlockBox();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#createDefaultFlowLayout()
+ */
+ protected FlowFigureLayout createDefaultFlowLayout() {
+ return new BlockFlowLayout(this);
+ }
+
+ /**
+ * Returns the BlockBox associated with this.
+ *
+ * @return This BlockFlow's BlockBox
+ */
+ protected BlockBox getBlockBox() {
+ return _blockBox;
+ }
+
+ /**
+ * Returns the horizontal aligment.
+ *
+ * @return the hotizontal aligment
+ */
+ public int getHorizontalAligment() {
+ return _aligment & PositionConstants.LEFT_CENTER_RIGHT;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#postValidate()
+ */
+ public void postValidate() {
+ setBounds(getBlockBox().toRectangle().expand(getInsets()));
+ List v = getChildren();
+ for (int i = 0, n = v.size(); i < n; i++) {
+ ((FlowFigure) v.get(i)).postValidate();
+ }
+ }
+
+ /**
+ * Sets the horitontal aligment of the block. Valid values are:
+ * <UL>
+ * <LI>{@link org.eclipse.draw2d.PositionConstants#LEFT}
+ * <LI>{@link org.eclipse.draw2d.PositionConstants#RIGHT}
+ * <LI>{@link org.eclipse.draw2d.PositionConstants#CENTER}
+ *
+ * @param value
+ * the aligment
+ */
+ public void setHorizontalAligment(int value) {
+ if (!(value == PositionConstants.LEFT
+ || value == PositionConstants.RIGHT || value == PositionConstants.CENTER)) {
+ throw new IllegalArgumentException(
+ "Horizontal Aligment must be one of: LEFT, CENTER, RIGHT");
+ }
+ this._aligment &= ~PositionConstants.LEFT_CENTER_RIGHT;
+ this._aligment |= value;
+ revalidate();
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#useLocalCoordinates()
+ */
+ protected boolean useLocalCoordinates() {
+ return true;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowContext.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowContext.java
new file mode 100644
index 000000000..55faec578
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowContext.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+
+/**
+ * When doing absolute positioning, we need to create a block. But that block
+ * don't have a corresponding figure. So we need a block without corresponding
+ * figure.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class BlockFlowContext implements FlowContext {
+ protected LineBox _currentLine;
+
+ private LineBox _previousLine = null;
+
+ protected BlockBox _blockBox;
+
+ protected FlowContext _originalContext;
+
+ protected ICSSStyle _style;
+
+ /**
+ *
+ */
+ public BlockFlowContext(FlowContext originalContext, ICSSStyle style) {
+ this._originalContext = originalContext;
+ this._style = style;
+ setup();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
+ */
+ public int getContainerWidth() {
+
+ return _originalContext.getContainerWidth();
+ }
+
+ public void setup() {
+ _blockBox = new BlockBox();
+ _blockBox.setRecommendedWidth(getRecommendedWidth());
+ _currentLine = this.getCurrentLine();
+ _previousLine = null;
+ }
+
+ private int getRecommendedWidth() {
+ int containerWidth = getContainerWidth();
+ Object leftObj = _style.getStyleProperty(ICSSPropertyID.ATTR_LEFT);
+ if (leftObj != null && leftObj instanceof Length) {
+ Length left = (Length) leftObj;
+ int intLeft = left.getValue();
+ if (left.isPercentage()) {
+ intLeft = containerWidth * intLeft / 100;
+ }
+ if (intLeft < containerWidth) {
+ return containerWidth - intLeft;
+ }
+ }
+ return containerWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#addToCurrentLine(org.eclipse.jst.pagedesigner.css2.layout.FlowBox)
+ */
+ public void addToCurrentLine(FlowBox block) {
+ getCurrentLine().add(block);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#endLine()
+ */
+ public void endLine() {
+ // this is called from child layouts.
+ // If there is no current line, state is equivalent to new line
+ if (_currentLine == null)
+ return;
+ if (_currentLine.isOccupied())
+ layoutLine(); // finalize the current line layout
+ else
+ return;
+
+ LineBox box = _currentLine;
+ // _currentLine = _previousLine; //XXX: ???? why (yang)
+ _previousLine = box;
+
+ _currentLine = null;
+ // setupLine(getCurrentLine());
+
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine()
+ */
+ public LineBox getCurrentLine() {
+ if (_currentLine == null)
+ createNewLine();
+ return _currentLine;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine(int)
+ */
+ public LineBox getCurrentLine(int topMargin) {
+ if (_currentLine == null)
+ createNewLine(topMargin);
+ return _currentLine;
+ }
+
+ /**
+ * @param topMargin
+ */
+ private void createNewLine(int topMargin) {
+ createNewLine();
+ }
+
+ protected void createNewLine() {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, Integer.MIN_VALUE);
+ }
+
+ /**
+ * Override to setup the line's x, remaining, and available width.
+ *
+ * @param line
+ * the LineBox to set up
+ */
+ protected void setupLine(LineBox line, int topMargin) {
+ line.clear();
+
+ // the caller of getCurrentLine() may add leftMargin and leftPadding and
+ // leftBorder to line.x
+ line._x = _blockBox._borderInsets.left + _blockBox._paddingInsets.left;
+
+ // FIXME: here should check the floating boxes, and minus the width of
+ // them from
+ // current line.
+ // XXX: the RecommendedContentWidth is related with the RecommendedWidth
+ // of container that
+ // usually larger than it needed.here we do not set the RecommendedWidth
+ // for the sake of
+ // layouting right absolute position.
+ // /shortcoming:the box will break into multi-line after every white
+ // space.
+ // line.setRecommendedWidth(_blockBox.getRecommendedContentWidth());
+ if (_previousLine == null) {
+ line._y = _blockBox._borderInsets.top
+ + _blockBox._paddingInsets.top;
+ if (topMargin != Integer.MIN_VALUE)
+ line._y += topMargin;
+ } else {
+ if (topMargin == Integer.MIN_VALUE)
+ line._y = _previousLine._y + _previousLine.getHeight()
+ + getLinePadding() + _previousLine._marginInsets.bottom; // XXX:
+ // should
+ // add
+ // previous
+ // margin
+ // bottom?
+ else
+ line._y = _previousLine._y
+ + _previousLine.getHeight()
+ + Math.max(topMargin,
+ _previousLine._marginInsets.bottom);
+ }
+ // line.validate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
+ */
+ public int getCurrentY() {
+ return getCurrentLine()._y; // FIXME: margin of previous block?
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCurrentLineOccupied()
+ */
+ public boolean isCurrentLineOccupied() {
+ return _currentLine != null && _currentLine.isOccupied();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getLastMarginRight()
+ */
+ public int getLastMarginRight() {
+ if (_currentLine == null || !_currentLine.isOccupied()) {
+ return 0;
+ }
+ FlowBox box = (FlowBox) _currentLine.getFragments().get(
+ _currentLine.getFragments().size() - 1);
+ if (box != null) {
+ return box._marginInsets.right;
+ } else {
+ return 0;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCalculatingMaxWidth()
+ */
+ public boolean isCalculatingMaxWidth() {
+ return false;
+ }
+
+ /**
+ * Adjust all fragments in the current line to have the same baseline. Do
+ * any additional adjustments, such as horizontal alignment.
+ */
+ protected void layoutLine() {
+ // currentLine.x = 0; //XXX: comment out, don't understand why set to 0,
+ // because it has already
+ // been set when setupLine(). And if do need, should
+ // set to getBorderPaddingInsets().left
+ // if (!isInlineBlock() && shouldExpand())
+ // {
+ // // FIXME: currently we are using getRecommendedContentWidth,
+ // // what happen if after adding the new line, the new width is bigger
+ // than
+ // // recommendedContentWidth? should we use getWidth() instead of
+ // // recommendedcontentWidth?
+ //
+ // Object textalign =
+ // (getCSSStyle().getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN));
+ // if (textalign == ICSSPropertyID.VAL_RIGHT)
+ // {
+ // _currentLine._x = _blockBox.getRecommendedContentWidth() +
+ // _blockBox.getBorderPaddingInsets().left - _currentLine.getWidth();
+ // }
+ // else if (textalign == ICSSPropertyID.VAL_CENTER)
+ // {
+ //
+ // _currentLine._x = _blockBox.getBorderPaddingInsets().left +
+ // (_blockBox.getRecommendedContentWidth() - _currentLine.getWidth()) /
+ // 2;
+ // }
+ // if (_currentLine._x < 0)
+ // _currentLine._x = 0;
+ // }
+
+ // FIXME: should check vertical alignment here?
+ _currentLine.commit();
+ _blockBox.add(_currentLine);
+ }
+
+ public void endBlock() {
+ endLine();
+ }
+
+ int getLinePadding() {
+ return 0;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowLayout.java
new file mode 100644
index 000000000..8647f293c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BlockFlowLayout.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Insets;
+
+/**
+ * The layout for {@link BlockFlow}figures.
+ * <P>
+ * WARNING: This class is not intended to be subclassed by clients.
+ *
+ * @author mengbo
+ * @since 2.1
+ */
+public class BlockFlowLayout extends FlowContainerLayout {
+ private LineBox _previousLine = null;
+
+ BlockBox _blockBox;
+
+ /**
+ * Creates a new BlockFlowLayout with the given BlockFlow.
+ *
+ * @param blockFlow
+ * the BlockFlow
+ */
+ public BlockFlowLayout(BlockFlow blockFlow) {
+ super(blockFlow);
+ }
+
+ /**
+ * @see FlowContainerLayout#cleanup()
+ */
+ protected void cleanup() {
+ _currentLine = _previousLine = null;
+ }
+
+ /**
+ * @see FlowContainerLayout#createNewLine()
+ */
+ protected void createNewLine() {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, Integer.MIN_VALUE);
+ }
+
+ protected void createNewLine(int topmargin) {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, topmargin);
+ }
+
+ /**
+ * Override to setup the line's x, remaining, and available width.
+ *
+ * @param line
+ * the LineBox to set up
+ */
+ protected void setupLine(LineBox line, int topMargin) {
+ line.clear();
+
+ // the caller of getCurrentLine() may add leftMargin and leftPadding and
+ // leftBorder to line.x
+ line._x = 0;
+
+ // FIXME: here should check the floating boxes, and minus the width of
+ // them from
+ // current line.
+ line.setRecommendedWidth(_blockBox.getRecommendedContentWidth());
+ if (_previousLine == null) {
+ line._y = 0;
+ if (topMargin != Integer.MIN_VALUE) {
+ line._y += topMargin;
+ }
+ } else {
+ if (topMargin == Integer.MIN_VALUE) {
+ line._y = _previousLine._y + _previousLine.getHeight()
+ + getLinePadding() + _previousLine._marginInsets.bottom; // XXX:
+ // should
+ // add
+ // previous
+ // margin
+ // bottom?
+ } else {
+ line._y = _previousLine._y
+ + _previousLine.getHeight()
+ + Math.max(topMargin,
+ _previousLine._marginInsets.bottom);
+ }
+ }
+ // line.validate();
+ }
+
+ /**
+ * Called by flush(), adds the BlockBox associated with this BlockFlowLayout
+ * to the current line and then ends the line.
+ */
+ protected void endBlock() {
+ getFlowContext().addToCurrentLine(_blockBox);
+
+ // FIXME: here should tell the context the bottom margin.
+ getFlowContext().endLine();
+ }
+
+ /**
+ * @see FlowContext#endLine()
+ */
+ public void endLine() {
+ // this is called from child layouts.
+ // If there is no current line, state is equivalent to new line
+ if (_currentLine == null) {
+ return;
+ }
+ if (_currentLine.isOccupied()) {
+ layoutLine(); // finalize the current line layout
+ } else {
+ _currentLine = null;
+ return;
+ }
+ LineBox box = _currentLine;
+ _previousLine = box;
+ _currentLine = null;// _previousLine; //XXX: ???? why (yang)
+
+ // setupLine(getCurrentLine());
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
+ */
+ public int getCurrentY() {
+ return getCurrentLine()._y; // FIXME: margin of previous block?
+ }
+
+ /**
+ * Returns the BlockFlow associated with this BlockFlowLayout
+ *
+ * @return the BlockFlow
+ */
+ protected final BlockFlow getBlockFlow() {
+ return (BlockFlow) getFlowFigure();
+ }
+
+ /**
+ * Adjust all fragments in the current line to have the same baseline. Do
+ * any additional adjustments, such as horizontal alignment.
+ */
+ protected void layoutLine() {
+ // currentLine.x = 0; //XXX: comment out, don't understand why set to 0,
+ // because it has already
+ // been set when setupLine(). And if do need, should
+ // set to getBorderPaddingInsets().left
+ switch (getBlockFlow().getHorizontalAligment()) {
+ case PositionConstants.RIGHT:
+ _currentLine._x = _blockBox.getContentWidth()
+ - getBorderPaddingInsets().right - _currentLine.getWidth();
+ break;
+ case PositionConstants.CENTER:
+ _currentLine._x = (_blockBox.getContentWidth()
+ + getBorderPaddingInsets().left
+ - getBorderPaddingInsets().right - _currentLine.getWidth()) / 2;
+ break;
+ }
+ // FIXME: should check vertical alignment here?
+ _currentLine.commit();
+ _blockBox.add(_currentLine);
+ }
+
+ /**
+ * @see FlowContainerLayout#flush()
+ */
+ protected void flush() {
+ if (_currentLine != null)
+ layoutLine();
+ endBlock();
+ }
+
+ /**
+ * @see FlowContainerLayout#preLayout()
+ */
+ protected void preLayout() {
+ _blockBox = getBlockFlow().getBlockBox();
+ setupBlock();
+ // Probably could setup current and previous line here, or just previous
+ }
+
+ /**
+ * sets up the single block that contains all of the lines.
+ */
+ protected void setupBlock() {
+ // Ask for a new line, in case we are in the middle of a line
+
+ // FIXME: the endLine() should tell context the top margin of this
+ // block.
+ getFlowContext().endLine();
+
+ LineBox line = getFlowContext().getCurrentLine();
+ // int recommended = line.getAvailableWidth();
+ // if (recommended != previousRecommendedWidth)
+ // Remove all current Fragments
+ _blockBox.clear();
+
+ // Setup the one fragment for this Block with the correct X and
+ // available width
+
+ // FIXME: here should check whether the CSS already set recommended
+ // width for this
+ // block.
+ _blockBox.setRecommendedWidth(line.getAvailableWidth());
+
+ _blockBox._y = getFlowContext().getCurrentY();
+
+ // FIXME: blockBox.x should be context.getBorderPaddingInsets().left
+ // or just line.x ?
+ _blockBox._x = 0;
+ }
+
+ Insets getBorderPaddingInsets() {
+ // FIXME:
+ return new Insets();
+ }
+
+ int getLinePadding() {
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#dispose()
+ */
+ public void dispose() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
+ */
+ public int getContainerWidth() {
+ int width = Math.max(0, Math.max(_blockBox.getWidth(), _blockBox
+ .getRecommendedWidth()));
+ return width;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BoxUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BoxUtil.java
new file mode 100644
index 000000000..54978d145
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/BoxUtil.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * @author mengbo
+ */
+public class BoxUtil {
+ /**
+ * @param box
+ * @param style
+ */
+ public static void setupBorderPaddingMargin(FlowBox box, ICSSStyle style) {
+ box._marginInsets = new Insets(style.getMarginInsets());
+ box._borderInsets = new Insets(style.getBorderInsets());
+ box._paddingInsets = new Insets(style.getPaddingInsets());
+
+ if (box.getBorderPaddingHeight() > box.getHeight()) {
+ box.setHeight(box.getBorderPaddingHeight());
+ }
+ if (box.getBorderPaddingWidth() > box.getWidth()) {
+ box.setWidth(box.getBorderPaddingWidth());
+ }
+ }
+
+ /**
+ * Debug code.
+ *
+ * @param g
+ * @param box
+ */
+ public static void drawBox(Graphics g, FlowBox box) {
+ Color color = null;
+ if (box instanceof BlockBox) {
+ // color = ColorConstants.red;
+ } else if (box instanceof LineBox) {
+ color = ColorConstants.blue;
+ } else if (box instanceof TextFragmentBox) {
+ color = ColorConstants.green;
+ } else {
+ color = ColorConstants.darkGreen;
+ }
+ if (color != null) {
+ g.setForegroundColor(color);
+ g.setLineStyle(Graphics.LINE_DASH);
+ g.setLineWidth(1);
+ g.drawRectangle(box._x, box._y, box.getWidth(), box.getHeight());
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBlockFlowLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBlockFlowLayout.java
new file mode 100644
index 000000000..6460f5ffd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBlockFlowLayout.java
@@ -0,0 +1,723 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.css2.widget.BorderUtil;
+import org.eclipse.swt.graphics.FontMetrics;
+
+/**
+ * The block layout for {@link CSSFigure}figures. Basic code structure is from
+ * BlockFlowLayout.
+ *
+ * @author mengbo
+ */
+public class CSSBlockFlowLayout extends CSSLayout implements ICSSPainter2 {
+ private LineBox _previousLine = null;
+
+ protected BlockBox _blockBox = null;
+
+ protected FontMetrics _fontMetrices;
+
+ int _userSpecifiedWidth;
+
+ int _userSpecifiedHeight;
+
+ /*
+ * whether we need HScroll and VScroll when overflow is set to "scroll".
+ * will be updated in "endBlock" and used in "paintFigurePostClientArea"
+ */
+ boolean _needHScroll = false;
+
+ boolean _needVScroll = false;
+
+ /**
+ * Creates a new CSSBlockFlowLayout with the given BlockFlow.
+ */
+ public CSSBlockFlowLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ protected boolean hasMoreThanOneLine() {
+ return _previousLine != null;
+ }
+
+ public boolean isInlineBlock() {
+ String obj = getCSSStyle().getDisplay();
+ return ICSSPropertyID.VAL_INLINE_BLOCK.equals(obj)
+ || ICSSPropertyID.VAL_INLINE_TABLE.equals(obj);
+ }
+
+ /**
+ * whether should expand the width to all available width.
+ *
+ * @return
+ */
+ public boolean shouldExpand() {
+ ICSSStyle style = getCSSStyle();
+ if (style == null) {
+ return false;
+ } else {
+ return "block".equalsIgnoreCase(style.getDisplay())
+ || "list-item".equalsIgnoreCase(style.getDisplay());
+ }
+ }
+
+ // ---------------------------------------------------------------------------------------------------
+ // preLayout stage. Major job is get the top-left corner information of the
+ // new block.
+
+ /**
+ * sets up the single block that contains all of the lines.
+ */
+ protected void setupBlock() {
+ // int recommended = line.getAvailableWidth();
+ // if (recommended != previousRecommendedWidth)
+ // Remove all current Fragments
+ _blockBox.clear();
+ // Ask for a new line, in case we are in the middle of a line
+
+ if (!isInlineBlock()) {
+ LineBox lineBox = getFlowContext().getCurrentLine();
+ if (lineBox != null && !lineBox.isEmptyStringLine()) {
+ getFlowContext().endLine();
+ }
+ }
+
+ ICSSStyle style = getCSSStyle();
+
+ // endLine will result in context create a new line, so we are in the
+ // new line now.
+ // passing in the top margin, and context will consider that when create
+ // the new line.
+ int marginTop = style.getMarginInsets().top;
+ LineBox line = getFlowContext().getCurrentLine(marginTop);
+
+ // Setup the one fragment for this Block with the correct X and
+ // available width
+
+ // FIXME: according to spec, when using percentage width/height, should
+ // percentage to
+ // the "containing block". But we don't have very good "containing
+ // block" resolution
+ // implementation yet.
+
+ // calculate the min size
+ // int minWidth = 0;
+ // int minHeight = 0;
+ // if (style != null)
+ // {
+ // // try to see whether there is any designer specified min size
+ // ITagEditInfo info = (ITagEditInfo)
+ // style.getAdapter(ITagEditInfo.class);
+ // if (info != null)
+ // {
+ // minWidth = info.getMinWidth();
+ // minHeight = info.getMinHeight();
+ // }
+ //
+ // // CSS also has the min-width/min-height property. We should also get
+ // that,
+ // // and using the max of the "min-width" css property and the designer
+ // specified min size.
+ // int height = getLengthValue(style,ICSSPropertyID.ATTR_MIN_HEIGHT);
+ // if(height > minHeight)
+ // {
+ // minHeight = height;
+ // }
+ // int width = getLengthValue(style,ICSSPropertyID.ATTR_MIN_WIDTH);
+ // if(width > minWidth)
+ // {
+ // minWidth = width;
+ // }
+ // }
+
+ // keep track of user specified size, this will be used when handling
+ // the "overflow" CSS property.
+ _userSpecifiedWidth = 0;
+ _userSpecifiedHeight = 0;
+
+ {
+ int width = getLengthValue(style, ICSSPropertyID.ATTR_WIDTH);
+
+ int availableWidth = line.getAvailableWidth()
+ - style.getMarginInsets().getWidth();
+ if (width <= 0) {
+ // no width setting
+ if (isCalculatingMaxWidth()) {
+ _blockBox.setRecommendedWidth(Integer.MAX_VALUE);
+ // _blockBox.setWidth( (minWidth>0?minWidth:0));
+ } else {
+ _blockBox.setRecommendedWidth(availableWidth);
+ if (shouldExpand()) {
+ _blockBox.setWidth(availableWidth);
+ } else {
+ // _blockBox.setWidth( (minWidth>0?minWidth:0));
+ }
+ }
+ } else {
+ int w = width;
+ if (!style.isSizeIncludeBorderPadding()) {
+ w += style.getBorderInsets().getWidth()
+ + style.getPaddingInsets().getWidth();
+ }
+ // XXX: should we use minWidth or follow user's choice?
+ // if (w < minWidth)
+ // {
+ // w = minWidth;
+ // }
+ _userSpecifiedWidth = w;
+ _blockBox.setWidth(w);
+ _blockBox.setRecommendedWidth(w);
+ }
+ }
+
+ {
+ int height = getLengthValue(style, ICSSPropertyID.ATTR_HEIGHT);
+ // Object height =
+ // style.getStyleProperty(ICSSPropertyID.ATTR_HEIGHT);
+ // Length heightLength = (height instanceof Length) ? (Length)
+ // height : null;
+
+ if (height <= 0) {
+ // if (minHeight > 0)
+ // {
+ // // _blockBox.setHeight(minHeight);
+ // _blockBox.setRecommendedHeight(minHeight);
+ // }
+ // else
+ {
+ _blockBox.setHeight(0);
+ _blockBox.setRecommendedHeight(0);
+ }
+ } else {
+ int h = height;
+ if (handlingBorderForBlock()
+ && !style.isSizeIncludeBorderPadding()) {
+ h += style.getBorderInsets().getHeight()
+ + style.getPaddingInsets().getHeight();
+ }
+ // XXX: should we follow minHeight or user's choice?
+ // if (minHeight > h)
+ // {
+ // h = minHeight;
+ // }
+ _userSpecifiedHeight = h;
+ _blockBox.setHeight(h);
+ _blockBox.setRecommendedHeight(h);
+ }
+ }
+ _blockBox._marginInsets = new Insets(style.getMarginInsets());
+ if (handlingBorderForBlock()) {
+ BoxUtil.setupBorderPaddingMargin(_blockBox, getCSSStyle());
+ }
+
+ // as in designer, we don't want to the element to have zero size, so
+ // set a minimun size here.
+ // _blockBox.setWidth(Math.max(20, _blockBox.getWidth()));
+ // int minHeight = getCSSStyle().getCSSFont().getFontSize() +
+ // _blockBox.getBorderPaddingHeight();
+ // _blockBox.setHeight(Math.max(minHeight, _blockBox.getHeight()));
+
+ _blockBox._y = line._y;
+ _blockBox._x = line._x;
+
+ setBlockVerticalAlign(_blockBox);
+ }
+
+ protected int getLengthValue(ICSSStyle style, String property) {
+ int lengthValue = 0;
+ if (style != null) {
+ Object object = style.getStyleProperty(property);
+ Length lengthObj = (object instanceof Length) ? (Length) object
+ : null;
+
+ if (lengthObj != null) {
+ lengthValue = lengthObj.getValue();
+ if (lengthObj.isPercentage()) {
+ if (ICSSPropertyID.ATTR_WIDTH.equalsIgnoreCase(property)
+ || ICSSPropertyID.ATTR_MIN_WIDTH
+ .equalsIgnoreCase(property)) {
+ lengthValue = this.getFlowContext().getContainerWidth()
+ * lengthValue / 100;
+ } else if (ICSSPropertyID.ATTR_HEIGHT
+ .equalsIgnoreCase(property)
+ || ICSSPropertyID.ATTR_MIN_HEIGHT
+ .equalsIgnoreCase(property)) {
+ // XXX: we should omit it because we don't support
+ // percentage height now.
+ lengthValue = 0;
+ }
+ }
+ }
+ }
+ return lengthValue;
+ }
+
+ private void setBlockVerticalAlign(BlockBox box) {
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ box.setVerticalAlignData(style
+ .getStyleProperty(ICSSPropertyID.ATTR_VERTICAL_ALIGN));
+ }
+ }
+
+ /**
+ * @see FlowContainerLayout#preLayout()
+ */
+ protected void preLayout() {
+ super.preLayout();
+ _blockBox = new BlockBox();
+ setupBlock();
+ // Probably could setup current and previous line here, or just previous
+ }
+
+ // -------------------------------------------------------------------------------------------------------
+ protected void layoutLines() {
+ List lines = _blockBox.getFragments();
+ if (lines != null) {
+ for (int i = 0; i < lines.size(); i++) {
+ if (lines.get(i) instanceof LineBox) {
+ layoutLine((LineBox) lines.get(i));
+ }
+ }
+ }
+ }
+
+ /**
+ * Called by flush(), adds the BlockBox associated with this BlockFlowLayout
+ * to the current line and then ends the line.
+ */
+ protected void endBlock() {
+ layoutLines();
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ int minWidth = 0;
+ int minHeight = 0;
+ // try to see whether there is any designer specified min size
+ ITagEditInfo info = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (info != null) {
+ minWidth = info.getMinWidth();
+ minHeight = info.getMinHeight();
+ }
+
+ // CSS also has the min-width/min-height property. We should also
+ // get that,
+ // and using the max of the "min-width" css property and the
+ // designer specified min size.
+ int height = getLengthValue(style, ICSSPropertyID.ATTR_MIN_HEIGHT);
+ if (height > minHeight) {
+ minHeight = height;
+ }
+ int width = getLengthValue(style, ICSSPropertyID.ATTR_MIN_WIDTH);
+ if (width > minWidth) {
+ minWidth = width;
+ }
+ if (minHeight > _blockBox.getHeight()) {
+ _blockBox.setHeight(minHeight);
+ }
+ if (minWidth > _blockBox.getWidth()) {
+ _blockBox.setWidth(minWidth);
+ }
+ }
+
+ // reset scroll information.
+ this._needHScroll = this._needVScroll = false;
+
+ // ok, now we need to adjust the _blockBox's size according to the
+ // "overflow" setting.
+ // depends on different "overflow" style of this block, different sizing
+ // policy may apply.
+ // ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ Object overflow = style
+ .getStyleProperty(ICSSPropertyID.ATTR_OVERFLOW);
+ if (ICSSPropertyID.VAL_HIDDEN.equals(overflow)) {
+ if (_userSpecifiedWidth > 0) {
+ _blockBox.setWidth(_userSpecifiedWidth);
+ }
+ if (_userSpecifiedHeight > 0) {
+ _blockBox.setHeight(_userSpecifiedHeight);
+ }
+ } else if (ICSSPropertyID.VAL_SCROLL.equals(overflow)
+ || ICSSPropertyID.VAL_AUTO.equals(overflow)) {
+ // adjust _needHScroll and _needVScroll
+ if (_userSpecifiedWidth > 0
+ && _userSpecifiedWidth < _blockBox.getWidth()) {
+ _needHScroll = true;
+ }
+ if (_userSpecifiedHeight > 0
+ && _userSpecifiedHeight < _blockBox.getHeight()) {
+ _needVScroll = true;
+ }
+ if (_needHScroll && !_needVScroll) {
+ if (_userSpecifiedHeight > 0
+ && _blockBox.getInternalContentHeight() >= 0
+ && _userSpecifiedHeight < _blockBox
+ .getInternalContentHeight()
+ + _blockBox._paddingInsets.getHeight()
+ + BorderUtil.SCROLL_WIDTH) {
+ _needVScroll = true;
+ }
+ }
+ if (!_needHScroll && _needVScroll) {
+ if (_userSpecifiedWidth > 0
+ && _blockBox.getInternalContentWidth() >= 0
+ && _userSpecifiedWidth < _blockBox
+ .getInternalContentWidth()
+ + _blockBox._paddingInsets.getWidth()
+ + BorderUtil.SCROLL_WIDTH) {
+ _needHScroll = true;
+ }
+ }
+
+ if (_userSpecifiedWidth > 0) {
+ _blockBox.setWidth(_userSpecifiedWidth);
+ }
+ if (_userSpecifiedHeight > 0) {
+ _blockBox.setHeight(_userSpecifiedHeight);
+ }
+ }
+ }
+
+ if (getFlowContext().isCurrentLineOccupied()
+ && getFlowContext().getCurrentLine().getAvailableWidth() < _blockBox._width
+ + _blockBox._marginInsets.getWidth()) {
+ getFlowContext().endLine();
+ }
+ if (!isInlineBlock()) {
+ LineBox line = getFlowContext().getCurrentLine();
+ line.setHorizonalData(getCSSStyle().getStyleProperty(
+ ICSSPropertyID.ATTR_HORIZONTAL_ALIGN));
+ line.setHtmlInitData(getCSSStyle().getHTMLelementInitValue(
+ ICSSPropertyID.ATTR_HORIZONTAL_ALIGN));
+ line.add(_blockBox);
+ // getFlowContext().addToCurrentLine(_blockBox);
+ } else {
+ getFlowContext().addToCurrentLine(_blockBox);
+ }
+ getFlowContext().getCurrentLine()._marginInsets.bottom = getCSSStyle()
+ .getMarginInsets().bottom;
+
+ if (!isInlineBlock()) {
+ getFlowContext().endLine();
+ }
+ }
+
+ protected void layoutLine(LineBox line) {
+ // currentLine.x = 0; //XXX: comment out, don't understand why set to 0,
+ // because it has already
+ // been set when setupLine(). And if do need, should
+ // set to getBorderPaddingInsets().left
+ // if (!isInlineBlock() && shouldExpand())
+ // {
+ // FIXME: currently we are using getRecommendedContentWidth,
+ // what happen if after adding the new line, the new width is bigger
+ // than
+ // recommendedContentWidth? should we use getWidth() instead of
+ // recommendedcontentWidth?
+ Object textalign = line.getHorizonalData();
+ if (textalign == null
+ || ICSSPropertyMeta.NOT_SPECIFIED.equals(textalign)) {
+ textalign = (getCSSStyle()
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN));
+ }
+ if (textalign == null
+ || ICSSPropertyMeta.NOT_SPECIFIED.equals(textalign)) {
+ textalign = line.getHtmlInitData();
+ }
+ if (ICSSPropertyID.VAL_RIGHT.equals(textalign)) {
+ line._x = _blockBox.getContentWidth() - line.getWidth();
+ } else if (ICSSPropertyID.VAL_CENTER.equals(textalign)) {
+ line._x = (_blockBox.getContentWidth() - line.getWidth()) / 2;
+ }
+
+ if (line._x < 0) {
+ line._x = 0;
+ }
+ line.commit();
+ }
+
+ /**
+ * Adjust all fragments in the current line to have the same baseline. Do
+ * any additional adjustments, such as horizontal alignment.
+ */
+ protected void addCurrentLine() {
+ // The follow code is commented out, and moved into layoutLine(line)
+ // called by endBlock().
+ // since only when endBlock is called we really know how big is this
+ // block box, and then can
+ // do horizontal alignment.
+ // // currentLine.x = 0; //XXX: comment out, don't understand why set to
+ // 0, because it has already
+ // // been set when setupLine(). And if do need, should
+ // // set to getBorderPaddingInsets().left
+ // if (!isInlineBlock() && shouldExpand())
+ // {
+ // // FIXME: currently we are using getRecommendedContentWidth,
+ // // what happen if after adding the new line, the new width is bigger
+ // than
+ // // recommendedContentWidth? should we use getWidth() instead of
+ // // recommendedcontentWidth?
+ //
+ // Object textalign =
+ // (getCSSStyle().getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN));
+ // if (textalign == ICSSPropertyID.VAL_RIGHT)
+ // {
+ // _currentLine._x = _blockBox.getContentWidth() +
+ // _blockBox.getBorderPaddingInsets().left - _currentLine.getWidth();
+ // }
+ // else if (textalign == ICSSPropertyID.VAL_CENTER)
+ // {
+ //
+ // _currentLine._x = _blockBox.getBorderPaddingInsets().left +
+ // (_blockBox.getContentWidth() - _currentLine.getWidth()) / 2;
+ // }
+ // if (_currentLine._x < 0)
+ // _currentLine._x = 0;
+ // }
+ //
+ // // FIXME: should check vertical alignment here?
+ // _currentLine.commit();
+
+ // layoutLine(_currentLine);
+ _blockBox.add(_currentLine);
+ }
+
+ /**
+ * @see FlowContainerLayout#flush()
+ */
+ protected void flush() {
+ if (_currentLine != null && _currentLine.isOccupied()) {
+ addCurrentLine();
+ }
+ endBlock();
+ }
+
+ /**
+ * @see FlowContainerLayout#cleanup()
+ */
+ protected void cleanup() {
+ _currentLine = _previousLine = null;
+ _fontMetrices = null;
+ }
+
+ // ----------------------------------------------------------------------------------
+
+ /**
+ * Override to setup the line's x, remaining, and available width.
+ *
+ * @param line
+ * the LineBox to set up
+ */
+ protected void setupLine(LineBox line, int topMargin) {
+ line.clear();
+
+ // the caller of getCurrentLine() may add leftMargin and leftPadding and
+ // leftBorder to line.x
+ line._x = 0;
+
+ // FIXME: here should check the floating boxes, and minus the width of
+ // them from
+ // current line.
+ line.setRecommendedWidth(_blockBox.getRecommendedContentWidth());
+ if (_previousLine == null) {
+ line._y = 0;
+ if (topMargin != Integer.MIN_VALUE) {
+ line._y += topMargin;
+ }
+ } else {
+ if (topMargin == Integer.MIN_VALUE) {
+ line._y = _previousLine._y + _previousLine.getHeight()
+ + getLinePadding() + _previousLine._marginInsets.bottom; // XXX:
+ // should
+ // add
+ // previous
+ // margin
+ // bottom?
+ } else {
+ line._y = _previousLine._y
+ + _previousLine.getHeight()
+ + Math.max(topMargin,
+ _previousLine._marginInsets.bottom);
+ }
+ }
+ setFontinfoForLine(line);
+ // line.validate();
+ }
+
+ private void setFontinfoForLine(LineBox line) {
+
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ if (_fontMetrices == null) {
+ // as getSwtFont is resource consuming, so we cache the
+ // _fontMetrics.
+ _fontMetrices = FigureUtilities.getFontMetrics(style
+ .getCSSFont().getSwtFont());
+ }
+ line.setFontMetrics(_fontMetrices);
+ }
+ }
+
+ /**
+ * @see FlowContainerLayout#createNewLine()
+ */
+ protected void createNewLine() {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, Integer.MIN_VALUE);
+ }
+
+ protected void createNewLine(int topmargin) {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, topmargin);
+ }
+
+ /**
+ * @see FlowContext#endLine()
+ */
+ public void endLine() {
+ // this is called from child layouts.
+ // If there is no current line, state is equivalent to new line
+ if (_currentLine == null) {
+ return;
+ }
+ if (_currentLine.isOccupied()) {
+ addCurrentLine(); // finalize the current line layout
+ } else {
+ _currentLine = null;
+ return;
+ }
+
+ LineBox box = _currentLine;
+ // _currentLine = _previousLine; //XXX: ???? why (yang)
+ _previousLine = box;
+
+ _currentLine = null;
+ // setupLine(getCurrentLine());
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
+ */
+ public int getCurrentY() {
+ return getCurrentLine()._y; // FIXME: margin of previous block?
+ }
+
+ int getLinePadding() {
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSLayout#useLocalCoordinates()
+ */
+ public boolean useLocalCoordinates() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#dispose()
+ */
+ public void dispose() {
+ //
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSLayout#getFragmentsForRead()
+ */
+ public List getFragmentsForRead() {
+ List r = new ArrayList(1);
+ r.add(_blockBox);
+ return r;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSLayout#postValidate()
+ */
+ public void postValidate() {
+
+ Rectangle r = new Rectangle(_blockBox._x, _blockBox._y, _blockBox
+ .getWidth(), _blockBox.getHeight());
+ getCSSFigure().setBounds(r);
+ List list = getCSSFigure().getChildren();
+ for (int i = 0; i < list.size(); i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
+ */
+ public int getContainerWidth() {
+ int width = Math.max(0, Math.max(_blockBox.getWidth(), _blockBox
+ .getRecommendedWidth()));
+ return width;
+ }
+
+ /**
+ * when the "overflow" is "scroll", we need to paint the scrollbar
+ */
+ public void paintFigurePostClientArea(Graphics g) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ Object overflow = style
+ .getStyleProperty(ICSSPropertyID.ATTR_OVERFLOW);
+ if (ICSSPropertyID.VAL_SCROLL.equals(overflow)
+ || ICSSPropertyID.VAL_AUTO.equals(overflow)) {
+ if (this._needHScroll || this._needVScroll) {
+ // as this is using localCoordinate, so translate to
+ // relative to left/up corder of whole
+ // blockbox.
+ g.translate(-_blockBox.getBorderPaddingInsets().left,
+ -_blockBox.getBorderPaddingInsets().top);
+
+ Rectangle rect = new Rectangle(0, 0, _blockBox.getWidth(),
+ _blockBox.getHeight());
+ rect.crop(_blockBox._borderInsets);
+
+ if (this._needHScroll && this._needVScroll) {
+ BorderUtil.drawScrollBar(g, BorderUtil.SCROLL_WIDTH,
+ rect, BorderUtil.BOTH);
+ } else if (this._needHScroll) {
+ BorderUtil.drawScrollBar(g, BorderUtil.SCROLL_WIDTH,
+ rect, BorderUtil.HORIZONTAL_BAR);
+ } else if (this._needVScroll) {
+ BorderUtil.drawScrollBar(g, BorderUtil.SCROLL_WIDTH,
+ rect, BorderUtil.VERTICAL_BAR);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBrFlowLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBrFlowLayout.java
new file mode 100644
index 000000000..b343aaea9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSBrFlowLayout.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author mengbo
+ */
+public class CSSBrFlowLayout extends CSSInlineFlowLayout implements ICSSPainter {
+ /**
+ * @param flow
+ */
+ public CSSBrFlowLayout(CSSFigure flow) {
+ super(flow);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSInlineFlowLayout#flush()
+ */
+ protected void flush() {
+ FlowBox forcedBox = new FlowBox();
+ forcedBox.setWidth(16);
+ forcedBox.setHeight(getCSSStyle().getCSSFont().getXHeight());
+ addToCurrentLine(forcedBox);
+ endLine();
+
+ FlowBox flowbox = new FlowBox();
+ flowbox.setHeight(getCSSStyle().getCSSFont().getFontSize());
+ getCurrentLine().add(flowbox);
+
+ super.flush();
+ }
+
+ public void paintFigure(Graphics g) {
+ List fragments = getFragmentsForRead();
+ if (!fragments.isEmpty()) {
+ FlowBox box = (FlowBox) fragments.get(0);
+ g.drawImage(getSharedHTMLImage(), new Point(box._x, box._y));
+ }
+ }
+
+ private static Image getSharedHTMLImage() {
+ return PDPlugin.getDefault().getImage("palette/HTML/small/HTML_BR.gif");
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSFigure.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSFigure.java
new file mode 100644
index 000000000..60580d2bb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSFigure.java
@@ -0,0 +1,518 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Border;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.border.CSSBorder;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.VisibilityMeta;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
+import org.eclipse.jst.pagedesigner.css2.widget.BorderUtil;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Normally a CSSFigure is a container. It's layout will be driven by different
+ * display type information from the style.
+ *
+ * Each CSSFigure will be driven by ICSSStyle, the display type of the ICSSStyle
+ * will decide the layout to be used for the figure.
+ *
+ * @author mengbo
+ */
+public class CSSFigure extends FlowFigure implements ICSSFigure {
+ private static Logger _log = PDPlugin.getLogger(CSSFigure.class);
+
+ private static final Rectangle PRIVATE_RECT = new Rectangle();
+
+ ICSSStyle _style;
+
+ // NOTE: here keep the element is only for debug use. CSSFigure shouldn't
+ // require an element.
+ // Element _element;
+
+ // if this field is set, then regetLayout() will still return this layout,
+ // without going through the CSS resolution
+ CSSLayout _fixedLayout;
+
+ public CSSFigure() {
+ _style = DefaultStyle.getInstance();
+ invalidateCSS();
+ }
+
+ public CSSFigure(ICSSStyle style) {
+ _style = style;
+ // _element = element;
+ invalidateCSS();
+ }
+
+ public ICSSStyle getCSSStyle() {
+ return _style;
+ }
+
+ public void setCSSStyle(ICSSStyle style) {
+ _style = style;
+ invalidateCSS();
+ }
+
+ public void revalidate() {
+ CSSLayout layout = (CSSLayout) getLayoutManager();
+ layout.figureRevalidate();
+ super.revalidate();
+ }
+
+ /**
+ * this method is called when the css source noticed style change. So tell
+ * the figure should invalidate its cached data.
+ */
+ public void invalidateCSS() {
+ // maybe we changed from inline to block or block to inline
+ // XXX: or even to table?
+ CSSLayout layout = regetLayout(getLayoutManager());
+ this.setLayoutManager(layout);
+ }
+
+ public void setFixedLayoutManager(CSSLayout layout) {
+ this._fixedLayout = layout;
+ this.setLayoutManager(regetLayout(getLayoutManager()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#setLayoutManager(org.eclipse.draw2d.LayoutManager)
+ */
+ public void setLayoutManager(LayoutManager manager) {
+ LayoutManager old = getLayoutManager();
+ if (old != manager) {
+ FlowContext context = null;
+ if (old instanceof FlowFigureLayout) {
+ context = ((FlowFigureLayout) old).getOriginalFlowContext();
+ }
+ if (manager instanceof FlowFigureLayout) {
+ ((FlowFigureLayout) manager).setOriginalFlowContext(context);
+ }
+
+ if (manager instanceof FlowContext) {
+ List list = getChildren();
+ for (int i = 0, size = list.size(); i < size; i++) {
+ try {
+ ((FlowFigure) list.get(i))
+ .setOriginalFlowContext((FlowContext) manager);
+ } catch (ClassCastException classcastexception) {
+ // Error in flowContext setting.
+ _log.error("Error.CSSFigure.0", classcastexception); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ super.setLayoutManager(manager);
+ }
+
+ protected CSSLayout regetLayout(LayoutManager old) {
+ if (_fixedLayout != null) {
+ return _fixedLayout;
+ }
+ CSSLayout layout = DisplayToLayout.displayToLayout(this, getCSSStyle()
+ .getDisplay(), old);
+ if (layout != null) {
+ return layout;
+ } else {
+ return new CSSInlineFlowLayout(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#containsPoint(int, int)
+ */
+ public boolean containsPoint(int x, int y) {
+ // check whether any float figure contains it.
+ // FIXME: need check floating figure here!!!
+ if (!super.containsPoint(x, y)) {
+ return false;
+ }
+ List frags = getFragmentsForRead();
+ // Here we should not get void pointer.
+ if (frags != null) {
+ for (int i = 0; i < frags.size(); i++) {
+ FlowBox box = (FlowBox) frags.get(i);
+ if (box != null && box.containsPoint(x, y)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure#getFragmentsForRead()
+ */
+ public List getFragmentsForRead() {
+ CSSLayout layout = (CSSLayout) getLayoutManager();
+ return layout.getFragmentsForRead();
+ }
+
+ /**
+ * this method is a shortcut to getFragmentsForRead
+ *
+ * @return
+ */
+ public Rectangle[] getFragmentsBounds() {
+ List list = getFragmentsForRead();
+ if (list == null || list.size() == 0) {
+ // should not happen. but still handle it.
+ return new Rectangle[] { getBounds() };
+ } else {
+ Rectangle[] ret = new Rectangle[list.size()];
+ for (int i = 0, size = list.size(); i < size; i++) {
+ FlowBox box = (FlowBox) list.get(i);
+ ret[i] = new Rectangle(box._x, box._y, box.getWidth(), box
+ .getHeight());
+ }
+ return ret;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#setBounds(org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void setBounds(Rectangle r) {
+ if (getBounds().equals(r)) {
+ return;
+ }
+ boolean invalidate = getBounds().width != r.width
+ || getBounds().height != r.height;
+ super.setBounds(r);
+
+ CSSLayout layout = (CSSLayout) this.getLayoutManager();
+ layout.setBoundsCalled(r, invalidate);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#postValidate()
+ */
+ public void postValidate() {
+ CSSLayout layout = (CSSLayout) getLayoutManager();
+ layout.postValidateForAbsolute();
+ layout.postValidate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#validate()
+ */
+ public void validate() {
+ super.validate();
+ // should not call this.postValidate() here. PostValidate() should
+ // only be started from the FlowPage. Otherwise it will be called
+ // multiple times on a figure.
+ // this.postValidate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#useLocalCoordinates()
+ */
+ protected boolean useLocalCoordinates() {
+ CSSLayout layout = (CSSLayout) getLayoutManager();
+ if (layout == null) {
+ return false;
+ } else {
+ return layout.useLocalCoordinates();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#paint(org.eclipse.draw2d.Graphics)
+ */
+ public void paint(Graphics graphics) {
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ Object visibility = style
+ .getStyleProperty(ICSSPropertyID.ATTR_VISIBILITY);
+ // handle visibility: hidden here.
+ // TODO: "collapse" is not supported yet!
+ if (VisibilityMeta.HIDDEN.equals(visibility)) {
+ return;
+ }
+ }
+
+ CSSLayout layout = (CSSLayout) this.getLayoutManager();
+ graphics.pushState();
+ try {
+ paintFigure(graphics);
+ graphics.restoreState();
+ paintClientArea(graphics);
+ if (layout instanceof ICSSPainter2) {
+ if (useLocalCoordinates()) {
+ graphics.translate(getBounds().x + getInsets().left,
+ getBounds().y + getInsets().top);
+ ((ICSSPainter2) layout).paintFigurePostClientArea(graphics);
+ graphics.restoreState();
+ } else {
+ ((ICSSPainter2) layout).paintFigurePostClientArea(graphics);
+ }
+ }
+ paintBorder(graphics);
+ } finally {
+ graphics.popState();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#paintFigure(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintFigure(Graphics g) {
+ Color rgbColor = null;
+ boolean fillArea = false;
+ Object bg = getCSSStyle().getBackgroundColor();
+ if (bg instanceof RGB) {
+ rgbColor = new Color(null, (RGB) bg);
+ g.setBackgroundColor(rgbColor);
+ fillArea = true;
+ } else if (bg instanceof Color) {
+ g.setBackgroundColor((Color) bg);
+ fillArea = true;
+ }
+ if (fillArea) {
+ List fragments = getFragmentsForRead();
+
+ for (int i = 0, n = fragments.size(); i < n; i++) {
+ Object obj = fragments.get(i);
+ if (obj instanceof FlowBox) {
+ FlowBox box = (FlowBox) obj;
+ g.fillRectangle(box._x, box._y, box.getWidth(), box
+ .getHeight());
+ }
+ }
+ }
+ if (rgbColor != null) {
+ rgbColor.dispose();
+ }
+ g.restoreState();
+
+ LayoutManager layout = getLayoutManager();
+ if (layout instanceof ICSSPainter) {
+ if (useLocalCoordinates()) {
+ g.translate(getBounds().x + getInsets().left, getBounds().y
+ + getInsets().top);
+ ((ICSSPainter) layout).paintFigure(g);
+ g.restoreState();
+ } else {
+ ((ICSSPainter) layout).paintFigure(g);
+ }
+ }
+
+ // paint selected mode here.
+ paintSelection(g);
+
+ if (Debug.DEBUG_BOX) {
+ // draw two levels of boxes. Since normally each figure will only
+ // have two levels of boxes.
+ List fragments = this.getFragmentsForRead();
+ for (int i = 0, size = fragments.size(); i < size; i++) {
+ FlowBox box = (FlowBox) fragments.get(i);
+ BoxUtil.drawBox(g, box);
+ if (box instanceof BlockBox) {
+ BlockBox compositeBox = (BlockBox) box;
+ List list = compositeBox.getFragments();
+ for (int j = 0; j < list.size(); j++) {
+ g.translate(this.getInsets().left,
+ this.getInsets().right);
+ BoxUtil.drawBox(g, (FlowBox) list.get(j));
+ g.restoreState();
+ }
+ }
+ }
+ }
+ if (Debug.DEBUG_BASELINE) {
+ List fragments = this.getFragmentsForRead();
+ for (int i = 0, size = fragments.size(); i < size; i++) {
+ Object obj = fragments.get(i);
+ if (obj instanceof LineBox) {
+ LineBox linebox = (LineBox) obj;
+ g.setForegroundColor(ColorConstants.red);
+ g.drawLine(linebox._x, linebox._y + linebox.getAscent(),
+ linebox._x + linebox.getWidth(), linebox._y
+ + linebox.getAscent());
+ }
+ }
+ }
+
+ if (Debug.DEBUG_BORDERPADDING) {
+ if (this.getLayoutManager() instanceof CSSBlockFlowLayout) {
+ g.setLineWidth(1);
+ Rectangle rect = getBounds().getCopy().crop(getInsets());
+ g.setForegroundColor(ColorConstants.green);
+ g.drawRectangle(rect);
+ g.setForegroundColor(ColorConstants.red);
+ g.drawRectangle(getBounds());
+ }
+ }
+
+ if (Debug.DEBUG_BOX) {
+ CSSLayout csslayout = (CSSLayout) this.getLayoutManager();
+ if (csslayout._absoluteContext != null) {
+ BlockBox blockbox = csslayout._absoluteContext._blockBox;
+ g.setLineWidth(1);
+ g.setForegroundColor(ColorConstants.green);
+ g.drawRectangle(blockbox._x, blockbox._y, blockbox.getWidth(),
+ blockbox.getHeight());
+ }
+ }
+ }
+
+ /**
+ * Paints this Figure's client area. The client area is typically defined as
+ * the anything inside the Figure's {@link Border} or {@link Insets}, and
+ * by default includes the children of this Figure. On return, this method
+ * must leave the given Graphics in its initial state.
+ *
+ * @param graphics
+ * The Graphics used to paint
+ * @since 2.0
+ */
+ protected void paintClientArea(Graphics graphics) {
+ if (this.getChildren().isEmpty()) {
+ return;
+ }
+
+ Object overflow = ICSSPropertyID.VAL_VISIBLE;
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ overflow = style.getStyleProperty(ICSSPropertyID.ATTR_OVERFLOW);
+ }
+
+ boolean optimizeClip = ICSSPropertyID.VAL_VISIBLE.equals(overflow);
+
+ if (useLocalCoordinates()) {
+ graphics.translate(getBounds().x + getInsets().left, getBounds().y
+ + getInsets().top);
+ if (!optimizeClip) {
+ graphics.clipRect(getClientArea(PRIVATE_RECT));
+ }
+ graphics.pushState();
+ paintChildren(graphics);
+ graphics.popState();
+ graphics.restoreState();
+ } else {
+ if (optimizeClip) {
+ paintChildren(graphics);
+ } else {
+ graphics.clipRect(getClientArea(PRIVATE_RECT));
+ graphics.pushState();
+ paintChildren(graphics);
+ graphics.popState();
+ graphics.restoreState();
+ }
+ }
+ }
+
+ /**
+ * @param g
+ */
+ protected void paintSelection(Graphics g) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ if (style.isInSelection()) {
+ ITagEditInfo editInfo = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (editInfo != null && editInfo.isWidget()) {
+ BorderUtil.maskFigure(this, g);
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#paintBorder(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintBorder(Graphics graphics) {
+ CSSLayout layout = (CSSLayout) getLayoutManager();
+ if (layout != null && !layout.handlingBorderForBlock()) {
+ return;
+ }
+
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ CSSBorder border = new CSSBorder(this.getCSSStyle());
+ border.paint(this, graphics, NO_INSETS);
+
+ // draw a border for those special elements like <h:form>, etc.
+ ITagEditInfo editInfo = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (editInfo != null && editInfo.needBorderDecorator()) {
+ BorderUtil.drawBorderDecorator(this, graphics);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#getInsets()
+ */
+ public Insets getInsets() {
+ CSSLayout layout = (CSSLayout) getLayoutManager();
+ if (layout != null && !layout.handlingBorderForBlock()) {
+ return new Insets();
+ }
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ return style.getBorderInsets().getAdded(style.getPaddingInsets());
+ }
+ return new Insets();
+ }
+
+ /**
+ * FIXME: need trace the implementation of Figure.invalidate() We want to
+ * just mark this figure as invalid, but don't want to the layout get
+ * invalidated.
+ *
+ */
+ public void invalidate2() {
+ if (!isValid())
+ return;
+ // if (getLayoutManager() != null)
+ // getLayoutManager().invalidate();
+ setValid(false);
+
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSInlineFlowLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSInlineFlowLayout.java
new file mode 100644
index 000000000..97f4571c0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSInlineFlowLayout.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
+
+/**
+ * The layout manager for {@link CSSFigure}figures. This class is based on
+ * InlineFlowLayout of draw2d.
+ *
+ * @author mengbo
+ */
+public class CSSInlineFlowLayout extends CSSLayout {
+ List _fragments = new ArrayList();
+
+ /**
+ * Creates a new InlineFlowLayout with the given FlowFigure.
+ *
+ * @param flow
+ * The FlowFigure
+ */
+ public CSSInlineFlowLayout(CSSFigure flow) {
+ super(flow);
+ }
+
+ /**
+ * Clears out all fragments prior to the call to layoutChildren().
+ */
+ public void preLayout() {
+ super.preLayout();
+ _fragments.clear();
+ // force creating of the first line. avoid empty element don't have
+ // fragments.
+ // createFirstLine();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#layoutChildren()
+ */
+ protected void layoutChildren() {
+ // For designer, to make it to have some size. otherwise can't
+ // be found on screen.
+ // List children = getCSSFigure().getChildren();
+ // if (children.size() == 0)
+ // {
+ // FlowBox box = new FlowBox();
+ // box._height = getCSSStyle().getCSSFont().getFontSize();
+ // box._width = 2;
+ // addToCurrentLine(box);
+ //
+ // }
+ super.layoutChildren();
+ }
+
+ /**
+ * Adds the given FlowBox to the current line of this InlineFlowLayout.
+ *
+ * @param block
+ * the FlowBox to add to the current line
+ */
+ public void addToCurrentLine(FlowBox block) {
+ getCurrentLine().add(block);
+ // XXX: ???: will currentLine be added multiple times to fragments?
+ // (yang)
+ // _fragments.add(_currentLine);
+ }
+
+ private void createFirstLine() {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, true);
+ _fragments.add(_currentLine);
+ }
+
+ /**
+ * @see FlowContainerLayout#createNewLine()
+ */
+ protected void createNewLine() {
+ _currentLine = new LineBox();
+ setupLine(_currentLine, false);
+ _fragments.add(_currentLine);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#createNewLine(int)
+ */
+ protected void createNewLine(int topMargin) {
+ // inline flow don't support vertical margin.
+ createNewLine();
+ }
+
+ /**
+ * @see FlowContainerLayout#cleanup()
+ */
+ protected void cleanup() {
+ _currentLine = null;
+ }
+
+ /**
+ * @see FlowContainerLayout#flush()
+ */
+ protected void flush() {
+ if (_fragments.isEmpty()) {
+ createFirstLine();
+ } else if (_fragments.size() == 1) {
+
+ ICSSStyle style = getCSSStyle();
+ int minWidth = 0, minHeight = 0;
+ // try to see whether there is any designer specified min size
+ ITagEditInfo info = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (info != null) {
+ minWidth = info.getMinWidth();
+ minHeight = info.getMinHeight();
+ }
+ FlowBox box = (FlowBox) _fragments.get(0);
+ if (minWidth > box._width) {
+ box._width = minWidth;
+ }
+ if (minHeight > box._height) {
+ box._height = minHeight;
+ }
+ }
+
+ if (_currentLine != null /* && _currentLine.isOccupied() */) {
+ _currentLine._marginInsets.right = getCSSStyle().getMarginInsets().right;
+ getFlowContext().addToCurrentLine(_currentLine);
+ }
+
+ }
+
+ /**
+ * @see FlowContext#endLine()
+ */
+ public void endLine() {
+ if (_currentLine == null) {
+ getFlowContext().endLine();
+ return;
+ }
+ // If nothing was ever placed in the line, ignore it. and if the line is
+ // the first line, just remove it.
+ if (_currentLine.isOccupied()) {
+ getFlowContext().addToCurrentLine(_currentLine);
+ } else if (_fragments.size() == 1) {
+ _fragments.remove(0);
+ }
+ getFlowContext().endLine();
+ _currentLine = null;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
+ */
+ public int getCurrentY() {
+ return getCurrentLine()._y;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#isCurrentLineOccupied()
+ */
+ public boolean isCurrentLineOccupied() {
+ if (_currentLine == null) {
+ return getFlowContext().isCurrentLineOccupied();
+ } else if (_currentLine.getFragments().isEmpty()) {
+ return getFlowContext().isCurrentLineOccupied();
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Initializes the given LineBox. Called by createNewLine().
+ *
+ * @param line
+ * The LineBox to initialize.
+ */
+ protected void setupLine(LineBox line, boolean firstline) {
+ LineBox parent = getFlowContext().getCurrentLine();
+ line._x = 0;
+ line._y = getFlowContext().getCurrentY();
+
+ line.setRecommendedWidth(parent.getAvailableWidth());
+
+ setLineVerticalAlign(line);
+ setFontinfoForLine(line);
+
+ if (firstline && getCSSStyle() != null) {
+ ICSSStyle style = getCSSStyle();
+ int minWidth = 0, minHeight = 0;
+ // try to see whether there is any designer specified min size
+ ITagEditInfo info = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (info != null) {
+ minWidth = info.getMinWidth();
+ minHeight = info.getMinHeight();
+ }
+
+ // // CSS also has the min-width/min-height property. We should also
+ // get that,
+ // // and using the max of the "min-width" css property and the
+ // designer specified min size.
+ // int height =
+ // getLengthValue(style,ICSSPropertyID.ATTR_MIN_HEIGHT);
+ // if(height > minHeight)
+ // {
+ // minHeight = height;
+ // }
+ // int width = getLengthValue(style,ICSSPropertyID.ATTR_MIN_WIDTH);
+ // if(width > minWidth)
+ // {
+ // minWidth = width;
+ // }
+ if (minWidth > 0) {
+ line.setWidth(minWidth);
+ }
+ int fontHeight = this.getCSSStyle().getCSSFont().getXHeight();
+ if (minHeight > 0 && minHeight > fontHeight) {
+ line.setHeight(minHeight);
+ } else {
+ line.setHeight(fontHeight);
+ }
+ }
+ }
+
+ private void setLineVerticalAlign(LineBox box) {
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ box.setVerticalAlignData(style
+ .getStyleProperty(ICSSPropertyID.ATTR_VERTICAL_ALIGN));
+ }
+ }
+
+ private void setFontinfoForLine(LineBox line) {
+
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ line.setFontMetrics(FigureUtilities.getFontMetrics(style
+ .getCSSFont().getSwtFont()));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#dispose()
+ */
+ public void dispose() {
+ //
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSLayout#getFragmentsForRead()
+ */
+ public List getFragmentsForRead() {
+ return _fragments;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSLayout#postValidate()
+ */
+ public void postValidate() {
+ List list = _fragments;
+
+ FlowBox box;
+ int left = Integer.MAX_VALUE, top = left;
+ int right = Integer.MIN_VALUE, bottom = right;
+ for (int i = 0; i < list.size(); i++) {
+ box = (FlowBox) list.get(i);
+ // if (box instanceof LineBox && !((LineBox) box).isOccupied())
+ // {
+ // continue; // skip unoccupied line
+ // }
+ left = Math.min(left, box._x);
+ right = Math.max(right, box._x + box._width);
+ top = Math.min(top, box._y);
+ bottom = Math.max(bottom, box._y + box._height);
+ }
+ getCSSFigure().setBounds(
+ new Rectangle(left, top, right - left, bottom - top));
+ list = getCSSFigure().getChildren();
+ for (int i = 0; i < list.size(); i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
+ */
+ public int getContainerWidth() {
+ // FIXME: don't really understand what means for inline
+ return this.getFlowContext().getContainerWidth();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSLayout.java
new file mode 100644
index 000000000..c38052946
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSLayout.java
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.PositionMeta;
+import org.eclipse.jst.pagedesigner.css2.property.VerticalAlignMeta;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+
+/**
+ * CSSLayout is the base layout manager for different CSS layouts, such as block
+ * layout, inline layout (possible in the future table layout, etc)
+ *
+ * @author mengbo
+ */
+public abstract class CSSLayout extends FlowFigureLayout implements FlowContext {
+ protected BlockFlowContext _absoluteContext;
+
+ // when doing absolute layout, and if top/left are both "auto", it will be
+ // relating to the normaly flow position. The following two fields try to
+ // catch normal flow layout position.
+ // int _xForAbsolute;
+ // int _yForAbsolute;
+ private FlowBox _boxForAbsolute;
+
+ /**
+ * the current line
+ */
+ protected LineBox _currentLine;
+
+ private boolean _calculatingMaxWidth = false;
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#FlowFigureLayout(FlowFigure)
+ */
+ protected CSSLayout(CSSFigure flowFigure) {
+ super(flowFigure);
+ }
+
+ /**
+ * a shortcut method to get the style associated with the figure.
+ *
+ * @return
+ */
+ public ICSSStyle getCSSStyle() {
+ return getCSSFigure().getCSSStyle();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#addToCurrentLine(FlowBox)
+ */
+ public void addToCurrentLine(FlowBox block) {
+ getCurrentLine().add(block);
+ }
+
+ /**
+ * Used by getCurrentLine().
+ */
+ protected abstract void createNewLine();
+
+ /**
+ * Used by getCurrentLine(int topmargin)
+ *
+ * @param topMargin
+ */
+ protected void createNewLine(int topMargin) {
+ createNewLine();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine()
+ */
+ public LineBox getCurrentLine() {
+ if (_currentLine == null) {
+ createNewLine();
+ }
+ return _currentLine;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine(int)
+ */
+ public LineBox getCurrentLine(int topMargin) {
+ if (_currentLine == null) {
+ createNewLine(topMargin);
+ }
+ // if the current line only contains an empty string, reset the current
+ // line using the given margin.
+ else if (_currentLine.isEmptyStringLine()) {
+ List list = _currentLine.getFragments();
+ createNewLine(topMargin);
+ _currentLine._fragments.addAll(list);
+ }
+ return _currentLine;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCurrentLineOccupied
+ */
+ public boolean isCurrentLineOccupied() {
+ return _currentLine != null && _currentLine.isOccupied();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#layout()
+ */
+ protected void layout() {
+ preLayout();
+ layoutChildren();
+ flush();
+ cleanup();
+ }
+
+ protected boolean isAbsolutePosition() {
+ ICSSStyle style = getCSSStyle();
+
+ // FIXME: Some layout don't support absolute, need check here
+ if (style != null) {
+ Object obj = style.getStyleProperty(ICSSPropertyID.ATTR_POSITION);
+ if (PositionMeta.ABSOLUTE.equals(obj)
+ || PositionMeta.FIXED.equals(obj)) {
+ return supportAbsolutePosition();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Child class could override this method.
+ *
+ * @return
+ */
+ protected boolean supportAbsolutePosition() {
+ if (findContainingPositionedFigure() == null) {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#preLayout()
+ */
+ protected void preLayout() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ style.processCounters();
+ }
+
+ if (isAbsolutePosition()) {
+ FlowContext parentFigureContext = getParentFigureContext();
+ _absoluteContext = new BlockFlowContext(parentFigureContext, style);
+ _boxForAbsolute = new FlowBox();// size is 0. Just as a flag, so
+ // later we
+ // could figure out where will this figure be
+ // be put in case of not absolute
+ _boxForAbsolute.setVerticalAlignData(VerticalAlignMeta.TOP);
+ parentFigureContext.addToCurrentLine(_boxForAbsolute);
+ } else {
+ _absoluteContext = null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#getFlowContext()
+ */
+ public FlowContext getFlowContext() {
+ if (_absoluteContext != null) {
+ return _absoluteContext;
+ } else {
+ return getOriginalFlowContext();
+ }
+ }
+
+ public FlowContext getParentFigureContext() {
+ return super.getFlowContext();
+ }
+
+ public void postValidateForAbsolute() {
+ if (_absoluteContext != null) {
+ ICSSStyle style = this.getCSSStyle();
+
+ _absoluteContext.endBlock();
+
+ int xOffset;
+ int yOffset;
+
+ ICSSFigure containingPositionedFigure = findContainingPositionedFigure();
+ IFigure parentFigure = this.getCSSFigure().getParent();
+
+ xOffset = calculatePositionRelativeToParent(style,
+ containingPositionedFigure, parentFigure, true);
+ yOffset = calculatePositionRelativeToParent(style,
+ containingPositionedFigure, parentFigure, false);
+ move(_absoluteContext._blockBox, xOffset, yOffset);
+ }
+ }
+
+ /**
+ * @param style
+ * @param containingPositionedFigure
+ * @param parentFigure
+ * @return
+ */
+ private int calculatePositionRelativeToParent(ICSSStyle style,
+ ICSSFigure containingPositionedFigure, IFigure parentFigure,
+ boolean horizontal) {
+ int xOffset;
+ Object left = horizontal ? style
+ .getStyleProperty(ICSSPropertyID.ATTR_LEFT) : style
+ .getStyleProperty(ICSSPropertyID.ATTR_TOP);
+ Object right = horizontal ? style
+ .getStyleProperty(ICSSPropertyID.ATTR_RIGHT) : style
+ .getStyleProperty(ICSSPropertyID.ATTR_BOTTOM);
+
+ if (!(left instanceof Length) && !(right instanceof Length)) {
+ // _boxForAbsolute partipated the layout of the parent figure, and
+ // is already relative to parent.
+ return horizontal ? _boxForAbsolute._x : _boxForAbsolute._y;
+ }
+
+ // ok, user specified left or right. let's calculate the left
+ int leftValue;
+ if (left instanceof Length) {
+ Length leftLength = (Length) left;
+ leftValue = leftLength.getValue();
+ if (leftLength.isPercentage()) {
+ leftValue = (horizontal ? containingPositionedFigure
+ .getBounds().width : containingPositionedFigure
+ .getBounds().height)
+ * leftValue / 100;
+ }
+ } else {
+ Length rightLength = (Length) right;
+ int lengthValue = rightLength.getValue();
+ if (rightLength.isPercentage()) {
+ lengthValue = (horizontal ? containingPositionedFigure
+ .getBounds().width : containingPositionedFigure
+ .getBounds().height)
+ * lengthValue / 100;
+ }
+
+ if (horizontal) {
+ leftValue = containingPositionedFigure.getBounds().width
+ - _absoluteContext._blockBox.getWidth() - lengthValue;
+ } else {
+ leftValue = containingPositionedFigure.getBounds().height
+ - _absoluteContext._blockBox.getHeight() - lengthValue;
+ }
+
+ }
+
+ // xOffset is relative to the first box of the containing figure
+ List fragments = ((ICSSFigure) containingPositionedFigure)
+ .getFragmentsForRead();
+ if (fragments.size() > 0) {
+ FlowBox box = (FlowBox) fragments.get(0);
+ // box._x is the x location relative to containingPositionedFigure's
+ // parent.
+ // so now xOffset is relative to containingPositionedFigure's
+ // parent.
+ xOffset = (horizontal ? box._x : box._y) + leftValue;
+ } else {
+ xOffset = leftValue; // should not happen.
+ }
+ Point p;
+ if (horizontal) {
+ p = new Point(xOffset, 0);
+ } else {
+ p = new Point(0, xOffset);
+ }
+ containingPositionedFigure.translateFromParent(p);
+ containingPositionedFigure.translateToAbsolute(p);
+ parentFigure.translateToRelative(p);
+ return horizontal ? p.x : p.y;
+ }
+
+ /**
+ * @return
+ */
+ private ICSSFigure findContainingPositionedFigure() {
+ IFigure figure = this.getCSSFigure().getParent();
+ while (figure instanceof ICSSFigure) {
+ return (ICSSFigure) figure;
+ // ICSSStyle style = ((ICSSFigure) figure).getCSSStyle();
+ // if (DisplayToLayout.isPositioned(style))
+ // {
+ // return (ICSSFigure) figure;
+ // }
+ // figure = figure.getParent();
+ }
+ return null;
+
+ }
+
+ /**
+ * @param resultBox
+ * @param x
+ * @param y
+ */
+ private void move(CompositeBox compBox, int x, int y) {
+ compBox._x += x;
+ compBox._y += y;
+ List list = compBox.getFragments();
+ for (int i = 0; i < list.size(); i++) {
+ FlowBox box = (FlowBox) list.get(i);
+
+ if (box instanceof CompositeBox && !(box instanceof BlockBox)) {
+ move((CompositeBox) box, x, y);
+ } else {
+ box._x += x;
+ box._y += y;
+ }
+ }
+ }
+
+ /**
+ * Layout all children.
+ */
+ protected void layoutChildren() {
+ List children = getFlowFigure().getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ Figure f = (Figure) children.get(i);
+ f.invalidate();
+ f.validate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getLastMarginRight()
+ */
+ public int getLastMarginRight() {
+ if (_currentLine == null || !_currentLine.isOccupied()) {
+ return 0;
+ }
+ FlowBox box = (FlowBox) _currentLine.getFragments().get(
+ _currentLine.getFragments().size() - 1);
+ if (box != null) {
+ return box._marginInsets.right;
+ } else {
+ return 0;
+ }
+ }
+
+ public void setCalculatingMaxWidth(boolean c) {
+ _calculatingMaxWidth = c;
+ }
+
+ public boolean getCalcuatingMaxWidth() {
+ return _calculatingMaxWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCalculatingMaxWidth()
+ */
+ public boolean isCalculatingMaxWidth() {
+ if (_calculatingMaxWidth) {
+ return true;
+ } else if (this.getFlowContext() == null) {
+ return false;
+ } else {
+ return this.getFlowContext().isCalculatingMaxWidth();
+ }
+ }
+
+ /**
+ * Called after {@link #layoutChildren()}when all children have been laid
+ * out. This method exists to flush the last line.
+ */
+ protected abstract void flush();
+
+ /**
+ * Flush anything pending and free all temporary data used during layout.
+ */
+ protected abstract void cleanup();
+
+ // ------------------------------------------------------------------------------------
+
+ public CSSFigure getCSSFigure() {
+ return (CSSFigure) getFlowFigure();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public abstract List getFragmentsForRead();
+
+ /**
+ * postValidate the child figures of this CSSFigure. Normally layout fall
+ * into the first category need implement this method.
+ */
+ public abstract void postValidate();
+
+ /**
+ * setBounds is called on the CSSFigure. Normally layout fall into the
+ * second category need implement this method.
+ *
+ * @param rect
+ * @param invalidate
+ */
+ public void setBoundsCalled(Rectangle rect, boolean invalidate) {
+ }
+
+ /**
+ * Child class can override this. Normally block figure will return true.
+ *
+ * @return
+ */
+ public boolean useLocalCoordinates() {
+ return false;
+ }
+
+ /**
+ * If CSSLayout will call paint rountine to draw Border for its box, this
+ * method will return true, else return false, for example,the input file
+ * will return false.
+ *
+ * @return
+ */
+ public boolean handlingBorderForBlock() {
+ return true;
+ }
+
+ /**
+ * This method is called when the corresponding figure is revalidated.
+ *
+ */
+ public void figureRevalidate() {
+ // child class can override.
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSListItemLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSListItemLayout.java
new file mode 100644
index 000000000..a3608ddad
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSListItemLayout.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.list.CounterHelper;
+import org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator;
+import org.eclipse.jst.pagedesigner.css2.marker.CounterUtil;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ */
+public class CSSListItemLayout extends CSSBlockFlowLayout implements
+ ICSSPainter {
+ private static final String DEFAULT_LIST_COUNTER = "_anonymous";
+
+ private static final int CIRCLE_DIAMETER = 6;
+
+ private static final int DISC_DIAMETER = 5;
+
+ private static final int ROUNDRECT_ARC = 2;
+
+ private static final int TEXT_PADDING = 16;
+
+ private int _count;
+
+ /**
+ * @param cssfigure
+ */
+ public CSSListItemLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter#paintFigure(org.eclipse.draw2d.Graphics)
+ */
+ public void paintFigure(Graphics g) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+
+ Rectangle drawArea = null;
+ Font font = getCSSStyle().getCSSFont().getSwtFont();
+
+ // draw the marker box
+ Object styleType = style
+ .getStyleProperty(ICSSPropertyID.ATTR_LIST_STYLE_TYPE);
+
+ g.pushState();
+
+ Color newColor = null;
+ Object color = style.getColor();
+ if (color instanceof Color) {
+ g.setForegroundColor((Color) color);
+ g.setBackgroundColor((Color) color);
+ } else if (color instanceof RGB) {
+ newColor = new Color(Display.getCurrent(), (RGB) color);
+ g.setForegroundColor(newColor);
+ g.setBackgroundColor(newColor);
+ }
+
+ if (styleType instanceof String) {
+ int type = CounterHelper.toTypeInt((String) styleType);
+ switch (type) {
+ case CounterHelper.LIST_T_UPPER_ALPHA:
+ case CounterHelper.LIST_T_LOWER_ALPHA:
+ case CounterHelper.LIST_T_LOWER_ROMAN:
+ case CounterHelper.LIST_T_UPPER_ROMAN:
+ case CounterHelper.LIST_T_DECIMAL:
+ g.setFont(font);
+ String displayString = CounterUtil.convertCount(_count, type);
+ Point point = getDrawPointForText(displayString);
+ g.drawString(displayString, point);
+ break;
+ case CounterHelper.LIST_T_CIRCLE:
+ drawArea = getDrawAreaForGraph(CIRCLE_DIAMETER, CIRCLE_DIAMETER);
+ g.drawArc(drawArea, 0, 360);
+ break;
+ case CounterHelper.LIST_T_SQUARE:
+ drawArea = getDrawAreaForGraph(DISC_DIAMETER, DISC_DIAMETER);
+ g.fillRectangle(drawArea);
+ case CounterHelper.LIST_T_DECIMAL_LEADING_ZERO:
+ case CounterHelper.LIST_T_LOWER_GREEK:
+ case CounterHelper.LIST_T_ARMENIAN:
+ case CounterHelper.LIST_T_GEORGIAN:
+ case CounterHelper.LIST_T_IMAGE:
+ case CounterHelper.LIST_T_NONE:
+ default:
+ drawArea = getDrawAreaForGraph(DISC_DIAMETER, DISC_DIAMETER);
+ g.fillRoundRectangle(drawArea, ROUNDRECT_ARC, ROUNDRECT_ARC);
+ break;
+ }
+ }
+ g.popState();
+
+ if (newColor != null) {
+ newColor.dispose();
+ }
+ }
+
+ /**
+ * @param g
+ * @return
+ */
+ private Rectangle getDrawAreaForGraph(int width, int height) {
+ Rectangle drawArea;
+
+ int x = 0;
+ int y = 0;
+
+ List list = _blockBox.getFragments();
+ Rectangle box = _blockBox.toRectangle().getCopy().expand(
+ _blockBox.getBorderPaddingInsets().getAdded(
+ _blockBox._marginInsets));
+ if (list != null && !list.isEmpty()) {
+ LineBox line = (LineBox) list.get(0);
+ y = line.getBaseline() - CIRCLE_DIAMETER;
+ x = box.x;
+ } else {
+ x = box.x;
+ y = box.height / 2 - CIRCLE_DIAMETER;
+ }
+ drawArea = new Rectangle(x - CIRCLE_DIAMETER * 5 / 2, y, width, height);
+ return drawArea;
+ }
+
+ private Point getDrawPointForText(String displayString) {
+ Font font = getCSSStyle().getCSSFont().getSwtFont();
+
+ int x = 0;
+ int y = 0;
+
+ Rectangle box = _blockBox.toRectangle().getCopy().expand(
+ _blockBox.getBorderPaddingInsets().getAdded(
+ _blockBox._marginInsets));
+
+ x = box.x - FigureUtilities.getTextWidth(displayString, font);
+ x = x
+ - (TEXT_PADDING - FigureUtilities.getFontMetrics(font)
+ .getDescent());
+
+ return new Point(x, y);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#layoutChildren()
+ */
+ protected void layoutChildren() {
+ ICounterValueGenerator counter = this.getCSSStyle().findCounter(
+ DEFAULT_LIST_COUNTER, true);
+ if (counter != null) {
+ _count = counter.getCurrentCount();
+ } else {
+ // should not happen.
+ _count = 1; // use 1 as the default value
+ }
+ super.layoutChildren();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSPageFlowLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSPageFlowLayout.java
new file mode 100644
index 000000000..c74963a58
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSPageFlowLayout.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * This layout if for those thigns that it's parent will decide its size. Such
+ * as table cell.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSPageFlowLayout extends CSSBlockFlowLayout {
+ private Dimension _pageSize = new Dimension();
+
+ private int _recommendedWidth;
+
+ private int _pageSizeCacheKeys[] = new int[4];
+
+ private Dimension _pageSizeCacheValues[] = new Dimension[4];
+
+ private Dimension _cacheMaxWidthSize = null;
+
+ /**
+ * @param cssfigure
+ */
+ public CSSPageFlowLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#invalidate()
+ */
+ public void invalidate() {
+ super.invalidate();
+ _pageSizeCacheKeys = new int[4];
+ _pageSizeCacheValues = new Dimension[4];
+ _pageSize = new Dimension();
+ _recommendedWidth = 0;
+ _cacheMaxWidthSize = null;
+ }
+
+ protected void endBlock() {
+ layoutLines();
+ }
+
+ /**
+ * TODO: This method is not being called.
+ */
+ public void postValidate() {
+ Rectangle r = new Rectangle(_blockBox._x, _blockBox._y, _blockBox
+ .getWidth(), _blockBox.getHeight());
+ r = r.expand(getCSSFigure().getInsets());
+ _pageSize.width = r.width;
+ _pageSize.height = r.height;
+
+ List list = getCSSFigure().getChildren();
+ for (int i = 0; i < list.size(); i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+
+ }
+
+ /**
+ * Setup blockBox to the initial bounds of the Page
+ */
+ protected void setupBlock() {
+ // Remove all current Fragments
+ _blockBox.clear();
+
+ // Setup the one fragment for this Block with the correct X and
+ // available width
+ int recommendedWidth = getRecommendedWidth();
+ _blockBox.setRecommendedWidth(recommendedWidth);
+
+ if (recommendedWidth > 0 && recommendedWidth != Integer.MAX_VALUE) {
+ _blockBox.setWidth(recommendedWidth);
+ }
+
+ _blockBox._x = 0;
+ }
+
+ public int getRecommendedWidth() {
+ return _recommendedWidth;
+ }
+
+ private void setRecommendedWidth(int width) {
+ if (_recommendedWidth == width) {
+ return;
+ }
+ _recommendedWidth = width;
+ getCSSFigure().invalidate2();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSLayout#setBoundsCalled(org.eclipse.jst.pagedesigner.css2.layout.CSSFigure,
+ * org.eclipse.draw2d.geometry.Rectangle, boolean)
+ */
+ public void setBoundsCalled(Rectangle r, boolean invalidate) {
+ super.setBoundsCalled(r, invalidate);
+ CSSFigure figure = getCSSFigure();
+ int newWidth = r.width - figure.getInsets().getWidth();
+ if (invalidate || getRecommendedWidth() != newWidth) {
+ setRecommendedWidth(newWidth);
+ figure.getUpdateManager().addInvalidFigure(figure);
+ }
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
+ */
+ public Dimension getPreferredSize(IFigure container, int width, int h) {
+ if (width >= 0) {
+ width = Math.max(0, width - container.getInsets().getWidth());
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if (_pageSizeCacheKeys[i] == width
+ && _pageSizeCacheValues[i] != null) {
+ return _pageSizeCacheValues[i];
+ }
+ }
+
+ _pageSizeCacheKeys[3] = _pageSizeCacheKeys[2];
+ _pageSizeCacheKeys[2] = _pageSizeCacheKeys[1];
+ _pageSizeCacheKeys[1] = _pageSizeCacheKeys[0];
+ _pageSizeCacheKeys[0] = width;
+
+ _pageSizeCacheValues[3] = _pageSizeCacheValues[2];
+ _pageSizeCacheValues[2] = _pageSizeCacheValues[1];
+ _pageSizeCacheValues[1] = _pageSizeCacheValues[0];
+
+ // Flowpage must temporarily layout to determine its preferred size
+ int oldWidth = getRecommendedWidth();
+ setRecommendedWidth(width);
+ container.validate();
+ _pageSizeCacheValues[0] = _pageSize.getExpanded(container.getInsets()
+ .getWidth(), container.getInsets().getHeight());
+
+ if (width != oldWidth) {
+ setRecommendedWidth(oldWidth);
+ container.getUpdateManager().addInvalidFigure(container);
+ }
+ return _pageSizeCacheValues[0];
+ }
+
+ public Dimension getMaxContentWidthSize(IFigure container) {
+ if (this._cacheMaxWidthSize == null) {
+ boolean b = getCalcuatingMaxWidth();
+ setCalculatingMaxWidth(true);
+
+ // Flowpage must temporarily layout to determine its preferred size
+ int oldWidth = getRecommendedWidth();
+ setRecommendedWidth(Integer.MAX_VALUE);
+ container.validate();
+ _cacheMaxWidthSize = _pageSize.getExpanded(container.getInsets()
+ .getWidth(), container.getInsets().getHeight());
+
+ if (0 != oldWidth) {
+ setRecommendedWidth(oldWidth);
+ container.getUpdateManager().addInvalidFigure(container);
+ }
+
+ setCalculatingMaxWidth(b);
+ }
+ return _cacheMaxWidthSize;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextFigure.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextFigure.java
new file mode 100644
index 000000000..a5a2871d1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextFigure.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.jst.pagedesigner.css2.style.StyleUtil;
+import org.eclipse.jst.pagedesigner.viewer.CaretPositionResolver;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * @author mengbo
+ */
+public class CSSTextFigure extends FlowFigure implements ICSSFigure {
+ private ICSSTextProvider _provider;
+
+ private List _fragments = new ArrayList(1);
+
+ public CSSTextFigure(ICSSTextProvider provider) {
+ _provider = provider;
+ this.setLayoutManager(createDefaultFlowLayout());
+ }
+
+ public ICSSStyle getCSSStyle() {
+ IFigure parentFigure = this.getParent();
+ if (parentFigure instanceof ICSSFigure) {
+ ICSSStyle style = ((ICSSFigure) parentFigure).getCSSStyle();
+ if (style != null) {
+ return style;
+ }
+ }
+ return DefaultStyle.getInstance();
+ }
+
+ /**
+ * @see org.eclipse.draw2d.IFigure#containsPoint(int, int)
+ */
+ public boolean containsPoint(int x, int y) {
+ if (!super.containsPoint(x, y)) {
+ return false;
+ }
+ List frags = getFragments();
+ for (int i = 0, n = frags.size(); i < n; i++) {
+ if (((FlowBox) frags.get(i)).containsPoint(x, y)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see FlowFigure#createDefaultFlowLayout()
+ */
+ protected FlowFigureLayout createDefaultFlowLayout() {
+ return new CSSTextLayout(this);
+ }
+
+ /**
+ * Returns the <code>LineBox</code> fragments contained in this InlineFlow
+ *
+ * @return The fragments
+ */
+ public List getFragments() {
+ return _fragments;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure#getFragmentsForRead()
+ */
+ public List getFragmentsForRead() {
+ return getFragments();
+ }
+
+ public String getText() {
+ return _provider.getTextData();
+ }
+
+ /**
+ * @see FlowFigure#postValidate()
+ */
+ public void postValidate() {
+ List list = getFragments();
+ FlowBox box;
+ int left = Integer.MAX_VALUE, top = left;
+ int right = Integer.MIN_VALUE, bottom = right;
+ for (int i = 0, n = list.size(); i < n; i++) {
+ box = (FlowBox) list.get(i);
+ left = Math.min(left, box._x);
+ right = Math.max(right, box._x + box._width);
+ top = Math.min(top, box._y);
+ bottom = Math.max(bottom, box._y + box._height);
+ }
+ setBounds(new Rectangle(left, top, right - left, bottom - top));
+ list = getChildren();
+ for (int i = 0, n = list.size(); i < n; i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#paintBorder(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintBorder(Graphics graphics) {
+ if (Debug.DEBUG_TEXTBORDER) {
+ if (_fragments != null) {
+ graphics.setForegroundColor(ColorConstants.darkBlue);
+ for (int i = 0, size = _fragments.size(); i < size; i++) {
+ FlowBox box = (FlowBox) _fragments.get(i);
+ BoxUtil.drawBox(graphics, box);
+ }
+ graphics.restoreState();
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#paintFigure(Graphics)
+ */
+ protected void paintFigure(Graphics g) {
+ Object result = this.getCSSStyle().getColor();
+ Color color;
+ if (result instanceof Color) {
+ color = (Color) result;
+ } else if (result instanceof RGB) {
+ color = new Color(null, (RGB) result);
+ } else {
+ color = null;
+ }
+ int[] range = null;
+ if (!StyleUtil.isInWidget(this.getCSSStyle())) {
+ range = _provider.getSelectedRange();
+ }
+ if (range == null || range[0] == range[1]) {
+ // we are not in selection
+ TextLayoutSupport.paintTextFigure(g, _fragments, getCSSStyle()
+ .getCSSFont().getSwtFont(), color, ((Integer) getCSSStyle()
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTDECORATION))
+ .intValue());
+ } else {
+ TextLayoutSupport.paintTextFigureWithSelection(g, _fragments,
+ _provider.getTextData(), getCSSStyle().getCSSFont()
+ .getSwtFont(), color, ((Integer) getCSSStyle()
+ .getStyleProperty(
+ ICSSPropertyID.ATTR_TEXTDECORATION))
+ .intValue(), range[0], range[1],
+ ColorConstants.white, ColorConstants.blue);
+ }
+ if (color != result && color != null) {
+ color.dispose();
+ }
+ }
+
+ /**
+ * Find out lines which has closer y coordinate to point, and then line
+ * which has closer x coordinate.
+ *
+ * @param relative
+ * @return
+ */
+ public int getNewInsertionOffset(Point relative) {
+ TextFragmentBox closestBox = null;
+ // if there is one which are at the same line with relative, calculate
+ // that line first;
+ for (int i = 0, n = _fragments.size(); i < n; i++) {
+ TextFragmentBox box = (TextFragmentBox) _fragments.get(i);
+ if (box.containsPoint(relative.x, relative.y)) {
+ int index = FlowUtilities.getTextInWidth(box.getTextData(),
+ getCSSStyle().getCSSFont().getSwtFont(), relative.x
+ - box._x, TextLayoutSupport
+ .getAverageCharWidth(box));
+ return box._offset + index;
+ } else {
+ if (closestBox == null) {
+ closestBox = box;
+ } else {
+ // box is above point
+ TextFragmentBox tempBox = box;
+ int offset1 = Math
+ .abs(CaretPositionResolver.getYDistance(
+ new Rectangle(tempBox._x, tempBox._y,
+ tempBox._width, tempBox._height),
+ relative));
+ tempBox = closestBox;
+ int offset2 = Math
+ .abs(CaretPositionResolver.getYDistance(
+ new Rectangle(tempBox._x, tempBox._y,
+ tempBox._width, tempBox._height),
+ relative));
+ if (offset1 < offset2) {
+ closestBox = box;
+ }
+ }
+ // at the same line
+ if (box.containsPoint(box._x, relative.y)) {
+ TextFragmentBox tempBox = box;
+ int offset1 = Math
+ .abs(CaretPositionResolver.getXDistance(
+ new Rectangle(tempBox._x, tempBox._y,
+ tempBox._width, tempBox._height),
+ relative));
+ tempBox = closestBox;
+ int offset2 = Math
+ .abs(CaretPositionResolver.getXDistance(
+ new Rectangle(tempBox._x, tempBox._y,
+ tempBox._width, tempBox._height),
+ relative));
+ if (offset1 < offset2) {
+ closestBox = box;
+ }
+ }
+ }
+ }
+
+ if (closestBox.containsPoint(closestBox._x, relative.y)
+ || closestBox.containsPoint(relative.x, closestBox._y)) {
+ int offset = relative.x - closestBox._x;
+ int index = FlowUtilities.getTextInWidth(closestBox.getTextData(),
+ getCSSStyle().getCSSFont().getSwtFont(), offset,
+ TextLayoutSupport.getAverageCharWidth(closestBox));
+ return closestBox._offset + index;
+ } else {
+ return -1;
+ }
+ }
+
+ public int getInsertionOffset(Point relative) {
+ for (int i = 0, n = _fragments.size(); i < n; i++) {
+ TextFragmentBox box = (TextFragmentBox) _fragments.get(i);
+ if (box.containsPoint(relative.x, relative.y)) {
+ int index = FlowUtilities.getTextInWidth(box.getTextData(),
+ getCSSStyle().getCSSFont().getSwtFont(), relative.x
+ - box._x, TextLayoutSupport
+ .getAverageCharWidth(box));
+ return box._offset + index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * the returned rectangle will be relative to this text figure.
+ *
+ * @param offset
+ * @return
+ */
+ public Rectangle calculateCaretPosition(int offset) {
+ // search reverse order, find the latest box that has _offset small than
+ // the specified one
+ if (offset > 0) {
+ for (int i = _fragments.size() - 1; i >= 0; i--) {
+ TextFragmentBox box = (TextFragmentBox) _fragments.get(i);
+ if (box._offset <= offset) {
+ // ok, we find the box.
+ if (box._offset + box._length < offset) {
+ return new Rectangle(box._x + box._width, box._y, 1,
+ box._height);
+ } else {
+ String s = box.getTextData().substring(0,
+ offset - box._offset);
+ int width = FlowUtilities.getTextExtents(s,
+ getCSSStyle().getCSSFont().getSwtFont()).width;
+ return new Rectangle(box._x + width, box._y, 1,
+ box._height);
+ }
+ }
+ }
+ } else {
+ if (_fragments.size() > 0) {
+ TextFragmentBox box = (TextFragmentBox) _fragments.get(0);
+ return new Rectangle(box._x, box._y, 1, box._height);
+ }
+ }
+ // should only reach here when there is no fragments.
+ Rectangle bounds = this.getBounds();
+ return new Rectangle(bounds.x, bounds.y, 1, bounds.height);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextLayout.java
new file mode 100644
index 000000000..b61a37a94
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSTextLayout.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * @author mengbo
+ */
+// NOTE: CSSTextLayout does not extends CSSFlowLayout. Since text is a little
+// special,
+// we don't want to do things like "preLayout()" as in CSSFlowLayout.
+public class CSSTextLayout extends FlowFigureLayout {
+ /**
+ * Wrapping will ONLY occur at valid line breaks
+ */
+ public static final int WORD_WRAP_HARD = 0;
+
+ /**
+ * Wrapping will always occur at the end of the available space, breaking in
+ * the middle of a word.
+ */
+ public static final int WORD_WRAP_SOFT = 1;
+
+ /**
+ * Wrapping will always occur at the end of available space, truncating a
+ * word if it doesn't fit.
+ */
+ // don't support this flag
+ // public static final int WORD_WRAP_TRUNCATE = 2;
+ private int _wrappingStyle = WORD_WRAP_HARD;
+
+ public CSSTextLayout(CSSTextFigure textfigure) {
+ super(textfigure);
+ }
+
+ // --------------------------------------------------------------------------------------------------
+ FlowBox findLastNonLineBox(LineBox box) {
+ List fragments = box.getFragments();
+ for (int i = fragments.size() - 1; i >= 0; i--) {
+ FlowBox item = (FlowBox) fragments.get(i);
+ if (item instanceof LineBox) {
+ FlowBox found = findLastNonLineBox((LineBox) item);
+ if (found != null) {
+ return found;
+ }
+ } else {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ // boolean isElementContentWhitespaceEnding()
+ // {
+ // if (!this._context.isCurrentLineOccupied())
+ // return true;
+ // LineBox line = this._context.getCurrentLine();
+ // FlowBox lastNoneLinebox = findLastNonLineBox(line);
+ // if (lastNoneLinebox instanceof TextFragmentBox)
+ // return ((TextFragmentBox) lastNoneLinebox)._isLastCharWhitespace;
+ // else
+ // return true;
+ // }
+ //
+ // String normalize(String text)
+ // {
+ // text = EntityMap.translateAndCompact(text);
+ // if (text.length() > 0 &&
+ // Character.isElementContentWhitespace(text.charAt(0)) &&
+ // isElementContentWhitespaceEnding())
+ // return text.substring(1);
+ // else
+ // return text;
+ // }
+
+ private void layoutEmptyString(List fragments, Font font) {
+ // empty node! we want to create a fake fragment, so things can be
+ // consistent
+ // that all the CSSTextFigure will have something inside, also in this
+ // way, even
+ // empty text node will have a position, thus we can support showing
+ // caret associated
+ // with this text figure.
+ fragments.clear();
+ TextFragmentBox box = TextLayoutSupport.getFragment(0, fragments);
+ box._length = 0;
+ box._offset = 0;
+ box._height = 0;
+ box._width = 0;
+ box.setTextData("");
+
+ // {following comments deprecated XXX: If is empty string, we only want
+ // to this figure to have a size, but don't
+ // want to it to be added into current line. Otherwise, a line with only
+ // a empty string
+ // will also take a line's space.}
+
+ // please reference LineBox.isOccupied()
+ // now we treat a line with only an empty text as not occupied.
+ getFlowContext().getCurrentLine().add(box);
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#layout()
+ */
+ protected void layout() {
+ CSSTextFigure flowFigure = (CSSTextFigure) getFlowFigure();
+
+ List fragments = flowFigure.getFragments();// Reuse the previous List
+ // of fragments
+ String text = flowFigure.getText();
+ Font font = flowFigure.getCSSStyle().getCSSFont().getSwtFont();
+ Object whitespace = flowFigure.getCSSStyle().getStyleProperty(
+ ICSSPropertyID.ATTR_WHITESPACE);
+
+ if (whitespace == ICSSPropertyID.VAL_PRE) {
+ if (text == null || text.length() == 0)
+ layoutEmptyString(fragments, font);
+ else
+ TextLayoutSupport.layoutNoWrap(getFlowContext(), text,
+ fragments, font);
+ } else if (whitespace == ICSSPropertyID.VAL_NOWRAP) {
+ if (text == null || text.length() == 0)
+ layoutEmptyString(fragments, font);
+ else
+ TextLayoutSupport.layoutNoWrap(getFlowContext(), text,
+ fragments, font);
+ } else {
+ if (text == null || text.length() == 0)
+ layoutEmptyString(fragments, font);
+ else {
+ boolean trimLeadingChar = (text.charAt(0) == ' ' && shouldTrimLeadingWhitespace(getFlowContext()));
+ TextLayoutSupport.layoutNormal(getFlowContext(), text,
+ fragments, font, _wrappingStyle, trimLeadingChar);
+ }
+ }
+ }
+
+ // XXX: maybe should move to TextSupport later.
+ public boolean shouldTrimLeadingWhitespace(FlowContext context) {
+ if (!context.isCurrentLineOccupied()) {
+ return true;
+ }
+ while (context instanceof CSSInlineFlowLayout) {
+ context = ((CSSInlineFlowLayout) context).getFlowContext();
+ }
+ LineBox line = context.getCurrentLine();
+ if (line == null || !line.isOccupied()) {
+ return true;
+ }
+ FlowBox lastNoneLinebox = findLastNonLineBox(line);
+ if (lastNoneLinebox == null || lastNoneLinebox.getWidth() == 0) {
+ return true;
+ } else if (lastNoneLinebox instanceof TextFragmentBox) {
+ return ((TextFragmentBox) lastNoneLinebox)._isLastCharWhitespace;
+ } else {
+ return false;
+ }
+ }
+
+ public void dispose() {
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSWidgetLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSWidgetLayout.java
new file mode 100644
index 000000000..1c83653d2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CSSWidgetLayout.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+
+/**
+ * @author mengbo
+ */
+public class CSSWidgetLayout extends CSSBlockFlowLayout implements ICSSPainter {
+ private WidgetBox _widgetBox;
+
+ private ICSSWidgetProvider _provider;
+
+ /**
+ * @param flowfigure
+ */
+ public CSSWidgetLayout(CSSFigure flowfigure, ICSSWidgetProvider provider) {
+ super(flowfigure);
+ _provider = provider;
+ }
+
+ /**
+ * normally this method is called directly after constructor
+ *
+ * @param provider
+ */
+ public void setProvider(ICSSWidgetProvider provider) {
+ _provider = provider;
+ }
+
+ public ICSSWidgetProvider getProvider() {
+ // return ((CSSWidgetFigure)this.getFlowFigure()).getProvider();
+ return _provider;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#isInlineBlock()
+ */
+ public boolean isInlineBlock() {
+ ICSSWidgetProvider provider = getProvider();
+ return provider.isInline();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#layout()
+ */
+ protected void layoutChildren() {
+ ICSSWidgetProvider provider = getProvider();
+
+ // if we did endLine, then will result in context create a new line, so
+ // we may in the new line now.
+ // passing in the top margin, and context will consider that when
+ // creating the new line.
+
+ int suggestedWith = _blockBox.getContentWidth();
+ int suggestedHeight = _blockBox.getContentHeight();
+ // int suggestedWith = getSuggestedWidth(line, style, provider);
+ // int suggestedHeight = getSuggestedHeight(line, style, provider);
+
+ DimensionInfo resultInfo = provider.getPreferredDimension(
+ suggestedWith, suggestedHeight);
+ Dimension resultSize = resultInfo.getDimension();
+
+ _widgetBox = new WidgetBox(); // ((CSSWidgetFigure)getFlowFigure()).getWidgetBox();
+ // if (provider.isHandlingBorder() || style == null)
+ // {
+ _widgetBox.setWidth(resultSize.width);
+ _widgetBox.setHeight(resultSize.height);
+ _widgetBox.setAscent(resultInfo.getAscent());
+ // }
+ // else
+ // {
+ // widgetBox.setWidth(resultSize.width +
+ // style.getBorderInsets().getWidth());
+ // widgetBox.setHeight(resultSize.height +
+ // style.getBorderInsets().getHeight());
+ // widgetBox.setAscent(resultInfo.getAscent()+style.getBorderInsets().top);
+ // }
+ this.addToCurrentLine(_widgetBox);
+ // if (!provider.isInline())
+ // {
+ // context.endLine();
+ // }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#dispose()
+ */
+ public void dispose() {
+ }
+
+ // public int getSuggestedWidth(LineBox line, ICSSStyle style,
+ // ICSSWidgetProvider provider)
+ // {
+ // if (style == null) return -1;
+ //
+ // Object width = style.getStyleProperty(ICSSPropertyID.ATTR_WIDTH);
+ // Length recommendedWidth = (width instanceof Length) ? (Length) width :
+ // null;
+ //
+ // int rw = 0;
+ // if (recommendedWidth == null || recommendedWidth.getValue() <= 0)
+ // {
+ // return -1;
+ // }
+ // else
+ // {
+ // if (recommendedWidth.isPercentage())
+ // {
+ // rw = line.getAvailableWidth() * recommendedWidth.getValue() / 100;
+ // }
+ // else
+ // {
+ // rw = recommendedWidth.getValue();
+ // }
+ //
+ // if (!style.isSizeIncludeBorderPadding() && provider.isHandlingBorder())
+ // {
+ // rw += style.getBorderInsets().getWidth() +
+ // style.getPaddingInsets().getWidth();
+ // }
+ // else if (style.isSizeIncludeBorderPadding() &&
+ // !provider.isHandlingBorder())
+ // {
+ // rw -= style.getBorderInsets().getWidth() +
+ // style.getPaddingInsets().getWidth();
+ // }
+ // }
+ //
+ // return rw;
+ // }
+ //
+ // public int getSuggestedHeight(LineBox line, ICSSStyle style,
+ // ICSSWidgetProvider provider)
+ // {
+ // if (style == null) return -1;
+ //
+ // Object height = style.getStyleProperty(ICSSPropertyID.ATTR_HEIGHT);
+ // Length recommendedHeight = (height instanceof Length) ? (Length) height :
+ // null;
+ //
+ // int rh = 0;
+ // if (recommendedHeight == null || recommendedHeight.getValue() <= 0)
+ // {
+ // return -1;
+ // }
+ // else
+ // {
+ // if (recommendedHeight.isPercentage())
+ // {
+ // // we don't support percentage height for this version, ignore
+ // return -1;
+ // }
+ // else
+ // {
+ // rh = recommendedHeight.getValue();
+ // }
+ //
+ // if (!style.isSizeIncludeBorderPadding() && provider.isHandlingBorder())
+ // {
+ // rh += style.getBorderInsets().getHeight() +
+ // style.getPaddingInsets().getHeight();
+ // }
+ // else if (style.isSizeIncludeBorderPadding() &&
+ // !provider.isHandlingBorder())
+ // {
+ // rh -= style.getBorderInsets().getHeight() +
+ // style.getPaddingInsets().getHeight();
+ // }
+ // }
+ //
+ // return rh;
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter#paintFigure(org.eclipse.draw2d.Graphics)
+ */
+ public void paintFigure(Graphics g) {
+ ICSSWidgetProvider provider = this.getProvider();
+ if (provider != null && _widgetBox != null) {
+ provider.paintFigure(g, new Rectangle(_widgetBox._x, _widgetBox._y,
+ _widgetBox.getWidth(), _widgetBox.getHeight()));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSLayout#handlingBorderForBlock()
+ */
+ public boolean handlingBorderForBlock() {
+ ICSSWidgetProvider provider = this.getProvider();
+ if (provider != null) {
+ return provider.isHandlingBorder();
+ }
+ return super.handlingBorderForBlock();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CompositeBox.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CompositeBox.java
new file mode 100644
index 000000000..6cce9545a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/CompositeBox.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A FlowBox that can contain other BlockInfos. The contained BlockInfos are
+ * called <i>fragments </i>.
+ *
+ * @author mengbo
+ * @since 2.1
+ */
+public abstract class CompositeBox extends FlowBox {
+
+ /**
+ * The contained fragments.
+ */
+ protected List _fragments = new ArrayList();
+
+ int _recommendedWidth;
+
+ int _recommendedHeight;
+
+ /**
+ * Adds the specified FlowBox. Updates the width, height, and ascent
+ * properties.
+ *
+ * @param block
+ * the FlowBox being added
+ */
+ public void add(FlowBox block) {
+ // The order is critical.see the first "if" block in the unionInfo()
+ // method.
+ unionInfo(block);
+ _fragments.add(block);
+ }
+
+ /**
+ * Removes all owned fragments and invalidates this CompositeBox.
+ */
+ public void clear() {
+ _fragments.clear();
+ resetInfo();
+ }
+
+ /**
+ * Overridden to ensure that the CompositeBox is valid.
+ *
+ * @see FlowBox#getBounds()
+ */
+ // public Rectangle getBounds() {
+ // validate();
+ // return this;
+ // }
+ /**
+ * @return the List of fragments
+ */
+ public List getFragments() {
+ return _fragments;
+ }
+
+ /**
+ * Returns the recommended width for this CompositeBox.
+ *
+ * @return the recommended width
+ */
+ public int getRecommendedWidth() {
+ return _recommendedWidth;
+ }
+
+ /**
+ * Returns the recommended height for this compositebox.
+ *
+ * @return
+ */
+ public int getRecommendedHeight() {
+ return _recommendedHeight;
+ }
+
+ // public int getInnerTop() {
+ // validate();
+ // return y;
+ // }
+
+ /**
+ * resets fields before unioning the data from the fragments.
+ */
+ protected void resetInfo() {
+ _width = _height = 0;
+ }
+
+ /**
+ * Sets the recommended width for this CompositeBox.
+ *
+ * @param w
+ * the width
+ */
+ public void setRecommendedWidth(int w) {
+ _recommendedWidth = w;
+ }
+
+ public void setRecommendedHeight(int h) {
+ _recommendedHeight = h;
+ }
+
+ /**
+ * unions the fragment's width, height, and ascent into this composite.
+ *
+ * @param box
+ * the fragment
+ */
+ protected void unionInfo(FlowBox box) {
+ int right = Math.max(_x + _width, box._x + box._width);
+ int bottom = Math.max(_y + _height, box._y + box._height);
+ _x = Math.min(_x, box._x);
+ _y = Math.min(_y, box._y);
+ _width = right - _x;
+ _height = bottom - _y;
+ }
+
+ public int getContentWidth() {
+ return getWidth() - getBorderPaddingWidth();
+ }
+
+ public int getContentHeight() {
+ return getHeight() - getBorderPaddingHeight();
+ }
+
+ public int getRecommendedContentWidth() {
+ return Math.max(0, getRecommendedWidth() - getBorderPaddingWidth());
+ }
+ //
+ // public int getRecommendedContentHeight()
+ // {
+ // return Math.max(0, getRecommendedHeight() - getBorderPaddingHeight());
+ // }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/Debug.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/Debug.java
new file mode 100644
index 000000000..c15f21da0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/Debug.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+/**
+ * Debug constants.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class Debug {
+ public static final boolean DEBUG_BASELINE = false;
+
+ public static final boolean DEBUG_BOX = false;
+
+ public static final boolean DEBUG_BORDERPADDING = false;
+
+ public static final boolean DEBUG_TEXTBORDER = false;
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/DisplayToLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/DisplayToLayout.java
new file mode 100644
index 000000000..de2eaa8d9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/DisplayToLayout.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTRGroupLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTRLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableCaptionLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableCellLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableLayout2;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.PositionMeta;
+
+/**
+ * @author mengbo
+ */
+public class DisplayToLayout {
+ /**
+ * @param figure
+ * @param display
+ * @param old
+ * @return
+ */
+ public static CSSLayout displayToLayout(CSSFigure figure, String display,
+ LayoutManager old) {
+ if ("block".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ return new CSSBlockFlowLayout(figure);
+ } else if ("inline".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ return new CSSInlineFlowLayout(figure);
+ } else if ("table".equalsIgnoreCase(display) || "inline-table".equalsIgnoreCase(display)) //$NON-NLS-1$ $NON-NLS-2$
+ {
+ return new CSSTableLayout2(figure);
+ } else if ("table-row".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ return new CSSTRLayout(figure);
+ } else if ("table-row-group".equalsIgnoreCase(display) //$NON-NLS-1$
+ || "table-header-group".equalsIgnoreCase(display) //$NON-NLS-1$
+ || "table-footer-group".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ return new CSSTRGroupLayout(figure);
+ } else if ("table-cell".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ return new CSSTableCellLayout(figure);
+ } else if (display.equalsIgnoreCase("table-caption")) //$NON-NLS-1$
+ {
+ return new CSSTableCaptionLayout(figure);
+ } else if ("inline-block".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ return new CSSBlockFlowLayout(figure) {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#isInlineBlock()
+ */
+ public boolean isInlineBlock() {
+ return true;
+ }
+ };
+ } else if (ICSSPropertyID.VAL_LIST_ITEM.equalsIgnoreCase(display)) {
+ return new CSSListItemLayout(figure);
+ }
+ return null;
+ }
+
+ /**
+ * @param figure
+ * @param display
+ * @param old
+ * @return
+ */
+ public static boolean isInline(String display) {
+ return "inline".equalsIgnoreCase(display) //$NON-NLS-1$
+ || "inline-block".equalsIgnoreCase(display); //$NON-NLS-1$
+ }
+
+ /**
+ * @param style
+ * @return
+ */
+ public static boolean isPositioned(ICSSStyle style) {
+ Object position = style.getStyleProperty(ICSSPropertyID.ATTR_POSITION);
+ if (PositionMeta.STATIC.equalsIgnoreCase((String) position)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FigureUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FigureUtil.java
new file mode 100644
index 000000000..60e3f6fcb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FigureUtil.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Translatable;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class FigureUtil {
+ // XXX:
+ // seemed Figure.translateToRelative is bug?
+ public static final void translateToRelative(IFigure figure, Translatable t) {
+ if (figure.getParent() != null) {
+ translateToRelative(figure.getParent(), t);
+ // figure.getParent().translateToRelative(t);
+ figure.translateFromParent(t);
+ }
+ }
+
+ // XXX:
+ // seemed Figure.translateToAbsolute is bug?
+ public static final void translateToAbsolute(IFigure figure, Translatable t) {
+ if (figure.getParent() != null) {
+ figure.translateToParent(t);
+ translateToAbsolute(figure.getParent(), t);
+ // figure.getParent().translateToAbsolute(t);
+ }
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowBox.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowBox.java
new file mode 100644
index 000000000..149fbd9a4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowBox.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * This class represents the CSS box model. See chapter 8 of CSS2 spec.
+ *
+ * @see http://www.w3.org/TR/REC-CSS2/box.html
+ */
+public class FlowBox {
+ private Object _verticalAlignData = null;
+
+ /**
+ * The x location
+ */
+ public int _x;
+
+ /**
+ * The y location
+ */
+ public int _y;
+
+ int _width;
+
+ int _height;
+
+ public Insets _marginInsets = new Insets();
+
+ public Insets _borderInsets = new Insets();
+
+ public Insets _paddingInsets = new Insets();
+
+ /**
+ * This method must be called on a block that is completely positioned and
+ * committed.
+ *
+ * @param x
+ * X
+ * @param y
+ * Y
+ * @return <code>true</code> if the FlowBox contains the point
+ */
+ public boolean containsPoint(int x, int y) {
+ return x >= this._x && y >= this._y && x < this._x + this._width
+ && y < this._y + this._height;
+ }
+
+ /**
+ * By default, a FlowBox is all ascent, and no descent, so the height is
+ * returned.
+ *
+ * @return the <i>ascent </i> in pixels above the baseline
+ */
+ public int getAscent() {
+ return getHeight();
+ }
+
+ /**
+ * By default, a simple FlowBox is all ascent, and no descent. Zero is
+ * returned.
+ *
+ * @return the <i>descent </i> in pixels below the baseline
+ */
+ public final int getDescent() {
+ return getHeight() - getAscent();
+ }
+
+ /**
+ * Returns the height
+ *
+ * @return height
+ */
+ public int getHeight() {
+ return _height;
+ }
+
+ /**
+ * Returns the width
+ *
+ * @return width
+ */
+ public int getWidth() {
+ return _width;
+ }
+
+ public void setWidth(int w) {
+ _width = w;
+ }
+
+ public void setHeight(int h) {
+ _height = h;
+ }
+
+ /**
+ * Used to set the baseline of this FlowBox to the specified value.
+ *
+ * @param value
+ * the new baseline
+ */
+ public void makeBaseline(int value) {
+ _y = (value - getAscent());
+ }
+
+ public int getBorderPaddingWidth() {
+ return _borderInsets.getWidth() + _paddingInsets.getWidth();
+ }
+
+ /**
+ * @return
+ */
+ public int getBorderPaddingHeight() {
+ return _borderInsets.getHeight() + _paddingInsets.getHeight();
+ }
+
+ /**
+ * @return
+ */
+ public Insets getBorderPaddingInsets() {
+ Insets temp = new Insets(_borderInsets);
+ return temp.add(_paddingInsets);
+ }
+
+ public void setXYWidthHeight(Rectangle rect) {
+ this._x = rect.x;
+ this._y = rect.y;
+ this.setWidth(rect.width);
+ this.setHeight(rect.height);
+ }
+
+ /**
+ * @return Returns the _verticalAlignData.
+ */
+ public Object getVerticalAlignData() {
+ return _verticalAlignData;
+ }
+
+ /**
+ * @param alignData
+ * The _verticalAlignData to set.
+ */
+ public void setVerticalAlignData(Object alignData) {
+ _verticalAlignData = alignData;
+ }
+
+ public Rectangle getRectangle() {
+ return new Rectangle(this._x, this._y, this.getWidth(), this
+ .getHeight());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContainerLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContainerLayout.java
new file mode 100644
index 000000000..b53cf7f2c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContainerLayout.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Figure;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+
+/**
+ * A layout for FlowFigures with children.
+ * <P>
+ * WARNING: This class is not intended to be subclassed by clients.
+ *
+ * @author mengbo
+ * @since 2.1
+ */
+public abstract class FlowContainerLayout extends FlowFigureLayout implements
+ FlowContext {
+ private static Logger _log = PDPlugin.getLogger(FlowContainerLayout.class);
+
+ /**
+ * the current line
+ */
+ protected LineBox _currentLine;
+
+ private boolean _calculatingMaxWidth = false;
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#FlowFigureLayout(FlowFigure)
+ */
+ protected FlowContainerLayout(FlowFigure flowFigure) {
+ super(flowFigure);
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#addToCurrentLine(FlowBox)
+ */
+ public void addToCurrentLine(FlowBox block) {
+ getCurrentLine().add(block);
+ }
+
+ /**
+ * Used by getCurrentLine().
+ */
+ protected abstract void createNewLine();
+
+ /**
+ * Used by getCurrentLine(int topmargin)
+ *
+ * @param topMargin
+ */
+ protected void createNewLine(int topMargin) {
+ createNewLine();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine()
+ */
+ public LineBox getCurrentLine() {
+ if (_currentLine == null)
+ createNewLine();
+ return _currentLine;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine(int)
+ */
+ public LineBox getCurrentLine(int topMargin) {
+ if (_currentLine == null) {
+ createNewLine(topMargin);
+ }
+ // if the current line only contains an empty string, reset the current
+ // line using the given margin.
+ else if (_currentLine.isEmptyStringLine()) {
+ List list = _currentLine.getFragments();
+ createNewLine(topMargin);
+ _currentLine._fragments.addAll(list);
+ }
+ return _currentLine;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCurrentLineOccupied
+ */
+ public boolean isCurrentLineOccupied() {
+ return _currentLine != null && _currentLine.isOccupied();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#layout()
+ */
+ protected void layout() {
+ preLayout();
+ layoutChildren();
+ flush();
+ cleanup();
+ }
+
+ /**
+ * Layout all children.
+ */
+ protected void layoutChildren() {
+ List children = getFlowFigure().getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ Figure f = (Figure) children.get(i);
+ f.invalidate();
+ f.validate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getLastMarginRight()
+ */
+ public int getLastMarginRight() {
+ if (_currentLine == null || !_currentLine.isOccupied()) {
+ return 0;
+ }
+ FlowBox box = (FlowBox) _currentLine.getFragments().get(
+ _currentLine.getFragments().size() - 1);
+ if (box != null) {
+ return box._marginInsets.right;
+ } else {
+ return 0;
+ }
+ }
+
+ public void setCalculatingMaxWidth(boolean c) {
+ _calculatingMaxWidth = c;
+ }
+
+ public boolean getCalcuatingMaxWidth() {
+ return _calculatingMaxWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCalculatingMaxWidth()
+ */
+ public boolean isCalculatingMaxWidth() {
+ if (_calculatingMaxWidth) {
+ return true;
+ } else if (this.getFlowContext() == null) {
+ return false;
+ } else {
+ return this.getFlowContext().isCalculatingMaxWidth();
+ }
+ }
+
+ /**
+ * Called before layoutChildren() to setup any necessary state.
+ */
+ protected abstract void preLayout();
+
+ /**
+ * Called after {@link #layoutChildren()}when all children have been laid
+ * out. This method exists to flush the last line.
+ */
+ protected abstract void flush();
+
+ /**
+ * Flush anything pending and free all temporary data used during layout.
+ */
+ protected abstract void cleanup();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContext.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContext.java
new file mode 100644
index 000000000..dbca0dd53
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowContext.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+/**
+ * Copied from draw2d. Enhanced to meet page designer's needs. The context that
+ * a {@link FlowFigureLayout}uses to perform its layout.
+ * <P>
+ * WARNING: This interface is not intended to be implemented by clients. It
+ * exists to define the API between the layout and its context.
+ */
+public interface FlowContext {
+
+ /**
+ * Adds the given box into the current line.
+ *
+ * @param box
+ * the FlowBox to add
+ */
+ void addToCurrentLine(FlowBox box);
+
+ /**
+ * The current line should be committed if it is occupied, and then set to
+ * <code>null</code>. Otherwise, do nothing.
+ */
+ void endLine();
+
+ /**
+ * Obtains the current line, creating a new line if there is no current
+ * line. if create a new line, the new line's x will be set correctly
+ * without considering the new element's left margin. Also, if create new
+ * line, it will treat as the new line's top margin is 0.
+ *
+ * @return the current line
+ */
+ LineBox getCurrentLine();
+
+ /**
+ * if create a new line, the new line's x will be set correctly without
+ * considering the new element's left margin.
+ *
+ * @param topMargin
+ * @return
+ */
+ LineBox getCurrentLine(int topMargin);
+
+ /**
+ * Returns the current Y value.
+ *
+ * @return the current Y value
+ */
+ int getCurrentY();
+
+ /**
+ * @return <code>true</code> if the current line contains any fragments
+ */
+ boolean isCurrentLineOccupied();
+
+ /**
+ * @return
+ */
+ int getLastMarginRight();
+
+ /**
+ * when layout table, we need to calculate max width of a cell. This is done
+ * by don't break line (other than explicit required). Currently, the
+ * solution is to make the recommended width to be very big, and when create
+ * block element we don't set the block element's size to be recommended
+ * width. Please see CSSBlockFlowLayout
+ *
+ * @return
+ */
+ boolean isCalculatingMaxWidth();
+
+ /**
+ * when calculating percentage width, we need the container width
+ *
+ * @return
+ */
+ int getContainerWidth();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigure.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigure.java
new file mode 100644
index 000000000..7c15e1278
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigure.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * The base implementation for text flow figures. A flow figure is used to
+ * render a document in which elements are laid out horizontally within a "line"
+ * until that line is filled. Layout continues on the next line.
+ * <p>
+ * WARNING: This class is not intended to be subclassed by clients. Future
+ * versions may contain additional abstract methods.
+ *
+ * @author mengbo
+ * @since 2.1
+ */
+public abstract class FlowFigure extends Figure {
+
+ // static final boolean SHOW_BASELINE = true;
+
+ /**
+ * Constructs a new FlowFigure.
+ */
+ public FlowFigure() {
+ // setLayoutManager(createDefaultFlowLayout());
+ }
+
+ /**
+ * If the child is a <code>FlowFigure</code>, its FlowContext is passed
+ * to it.
+ *
+ * @see org.eclipse.draw2d.IFigure#add(IFigure, Object, int)
+ */
+ public void add(IFigure child, Object constraint, int index) {
+ super.add(child, constraint, index);
+ if (child instanceof FlowFigure) {
+ FlowFigure ff = (FlowFigure) child;
+ if (getLayoutManager() instanceof FlowContext) {
+ ff.setOriginalFlowContext((FlowContext) getLayoutManager());
+ } else {
+ // should not happen
+ // FIXME: logging
+ System.err.println("layout is not FlowContext");
+ }
+ }
+ }
+
+ /**
+ * Creates the default layout manager
+ *
+ * @return The default layout
+ */
+ // protected abstract FlowFigureLayout createDefaultFlowLayout();
+ /**
+ * @see Figure#paintFigure(Graphics)
+ */
+ protected void paintFigure(Graphics g) {
+ super.paintFigure(g);
+ // g.drawRectangle(getBounds().getResized(-1,-1));
+ }
+
+ /**
+ * Called after validate has occurred. This is used to update the bounds of
+ * the FlowFigure to encompass its new flow boxed created during validate.
+ */
+ public abstract void postValidate();
+
+ /**
+ * FlowFigures override setBounds() to prevent translation of children.
+ * "bounds" is a derived property for FlowFigures, calculated from the
+ * fragments that make up the FlowFigure.
+ *
+ * @see Figure#setBounds(Rectangle)
+ */
+ public void setBounds(Rectangle r) {
+ if (getBounds().equals(r))
+ return;
+ erase();
+ bounds.x = r.x;
+ bounds.y = r.y;
+ bounds.width = r.width;
+ bounds.height = r.height;
+ fireFigureMoved();
+ repaint();
+ }
+
+ /**
+ * Sets the flow context.
+ *
+ * @param flowContext
+ * the flow context for this flow figure
+ */
+ public void setOriginalFlowContext(FlowContext flowContext) {
+ ((FlowFigureLayout) getLayoutManager())
+ .setOriginalFlowContext(flowContext);
+ }
+
+ public void setDisplayString(String s) {
+ _displayString = s;
+ }
+
+ public String toString() {
+ if (_displayString == null)
+ return super.toString();
+ else
+ return _displayString + " " + getClass().getName();
+ }
+
+ String _displayString; // for debug
+
+ /**
+ * @return
+ */
+ public FlowContext getFlowContext() {
+ return ((FlowFigureLayout) getLayoutManager()).getFlowContext();
+ }
+
+ // ----------------------------------------------------------------------
+ // as absolute positioning and relative positioning may have children
+ // out-side
+ // of parent bounds, so we want to disable clipping when drawing figures
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#paintChildren(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintChildren(Graphics graphics) {
+ IFigure child;
+
+ Rectangle clip = Rectangle.SINGLETON;
+ List children = this.getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ child = (IFigure) children.get(i);
+ if (child.isVisible() && child.intersects(graphics.getClip(clip))) {
+ // graphics.clipRect(child.getBounds());
+ child.paint(graphics);
+ graphics.restoreState();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#paintClientArea(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintClientArea(Graphics graphics) {
+ if (this.getChildren().isEmpty())
+ return;
+
+ // boolean optimizeClip = getBorder() == null || getBorder().isOpaque();
+
+ if (useLocalCoordinates()) {
+ graphics.translate(getBounds().x + getInsets().left, getBounds().y
+ + getInsets().top);
+ // if (!optimizeClip)
+ // graphics.clipRect(getClientArea(PRIVATE_RECT));
+ graphics.pushState();
+ paintChildren(graphics);
+ graphics.popState();
+ graphics.restoreState();
+ } else {
+ // if (optimizeClip)
+ paintChildren(graphics);
+ // else {
+ // graphics.clipRect(getClientArea(PRIVATE_RECT));
+ // graphics.pushState();
+ // paintChildren(graphics);
+ // graphics.popState();
+ // graphics.restoreState();
+ // }
+ }
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigureLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigureLayout.java
new file mode 100644
index 000000000..3f80478cf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowFigureLayout.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.AbstractLayout;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+
+public abstract class FlowFigureLayout extends AbstractLayout {
+
+ /**
+ * <code>true</code> if the context has changed, and a layout is needed.
+ */
+ protected boolean _invalid = true;
+
+ /**
+ * The flow context in which this LayoutManager exists.
+ */
+ private FlowContext _context;
+
+ /**
+ * The figure passed by layout(Figure) is held for convenience.
+ */
+ private final FlowFigure _flowFigure;
+
+ /**
+ * Constructs a new FlowFigureLayout with the given FlowFigure.
+ *
+ * @param flowfigure
+ * the FlowFigure
+ */
+ protected FlowFigureLayout(FlowFigure flowfigure) {
+ this._flowFigure = flowfigure;
+ }
+
+ /**
+ * TextFlowLayouts do not calculate a preferred size because it is too
+ * expensive. {@link FlowPage}will actually layout itself in order to
+ * calculate preferredSize.
+ *
+ * @see AbstractLayout#calculatePreferredSize(IFigure)
+ */
+ public Dimension calculatePreferredSize(IFigure f, int w, int h) {
+ return null;
+ }
+
+ /**
+ * @return the FlowFigure
+ */
+ protected FlowFigure getFlowFigure() {
+ return _flowFigure;
+ }
+
+ /**
+ * Marks this layout as invalid.
+ *
+ * @see org.eclipse.draw2d.LayoutManager#invalidate()
+ */
+ public void invalidate() {
+ _invalid = true;
+ super.invalidate();
+ }
+
+ /**
+ * @see org.eclipse.draw2d.LayoutManager#layout(IFigure)
+ */
+ public final void layout(IFigure figure) {
+ layout();
+ _invalid = false;
+ }
+
+ /**
+ * Called during {@link #layout(IFigure)}. The {@link #_invalid}flag is
+ * reset after this method is called.
+ */
+ protected abstract void layout();
+
+ /**
+ * Sets the context for this layout manager.
+ *
+ * @param flowContext
+ * the context of this layout
+ */
+ public void setOriginalFlowContext(FlowContext flowContext) {
+ _context = flowContext;
+ }
+
+ public FlowContext getOriginalFlowContext() {
+ return _context;
+ }
+
+ /**
+ * get flow context.
+ *
+ * @return
+ */
+ public FlowContext getFlowContext() {
+ return _context;
+ }
+
+ public String toString() {
+ // for debug purpose.
+ return _flowFigure.toString();
+ }
+
+ abstract public void dispose();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowPage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowPage.java
new file mode 100644
index 000000000..31d44de44
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowPage.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * The root of a Flow hierarchy. A flow page can be treated as a normal figure,
+ * but contains FlowFigures.
+ * <P>
+ * A FlowPage will not have a defined width unless it is inside a figure whose
+ * layout provides width hints when calling
+ * {@link org.eclipse.draw2d.IFigure#getPreferredSize(int, int)}.
+ * <P>
+ * WARNING: This class is not intended to be subclassed by clients.
+ */
+public class FlowPage extends BlockFlow {
+
+ private Dimension _pageSize = new Dimension();
+
+ private int _recommendedWidth;
+
+ private int _pageSizeCacheKeys[] = new int[4];
+
+ private Dimension _pageSizeCacheValues[] = new Dimension[4];
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.BlockFlow#createDefaultFlowLayout()
+ */
+ protected FlowFigureLayout createDefaultFlowLayout() {
+ return new PageFlowLayout(this);
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#getMinimumSize()
+ */
+ public Dimension getMinimumSize(int w, int h) {
+ return getPreferredSize(w, h);
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#invalidate()
+ */
+ public void invalidate() {
+ _pageSizeCacheValues = new Dimension[4];
+ super.invalidate();
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
+ */
+ public Dimension getPreferredSize(int width, int h) {
+ if (width >= 0)
+ width = Math.max(0, width - getInsets().getWidth());
+
+ for (int i = 0; i < 4; i++) {
+ if (_pageSizeCacheKeys[i] == width
+ && _pageSizeCacheValues[i] != null)
+ return _pageSizeCacheValues[i];
+ }
+
+ _pageSizeCacheKeys[3] = _pageSizeCacheKeys[2];
+ _pageSizeCacheKeys[2] = _pageSizeCacheKeys[1];
+ _pageSizeCacheKeys[1] = _pageSizeCacheKeys[0];
+ _pageSizeCacheKeys[0] = width;
+
+ _pageSizeCacheValues[3] = _pageSizeCacheValues[2];
+ _pageSizeCacheValues[2] = _pageSizeCacheValues[1];
+ _pageSizeCacheValues[1] = _pageSizeCacheValues[0];
+
+ // Flowpage must temporarily layout to determine its preferred size
+ int oldWidth = getRecommendedWidth();
+ setRecommendedWidth(width);
+ validate();
+ _pageSizeCacheValues[0] = _pageSize.getExpanded(getInsets().getWidth(),
+ getInsets().getHeight());
+
+ if (width != oldWidth) {
+ setRecommendedWidth(oldWidth);
+ getUpdateManager().addInvalidFigure(this);
+ }
+ return _pageSizeCacheValues[0];
+ }
+
+ int getRecommendedWidth() {
+ return _recommendedWidth;
+ }
+
+ /**
+ * @see BlockFlow#postValidate()
+ */
+ public void postValidate() {
+ Rectangle r = getBlockBox().toRectangle();
+ _pageSize.width = r.width;
+ _pageSize.height = r.height;
+ List v = getChildren();
+ for (int i = 0; i < v.size(); i++)
+ ((FlowFigure) v.get(i)).postValidate();
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#setBounds(Rectangle)
+ */
+ public void setBounds(Rectangle r) {
+ if (getBounds().equals(r))
+ return;
+ boolean invalidate = getBounds().width != r.width
+ || getBounds().height != r.height;
+ super.setBounds(r);
+ int newWidth = r.width - getInsets().getWidth();
+ if (invalidate || getRecommendedWidth() != newWidth) {
+ setRecommendedWidth(newWidth);
+ getUpdateManager().addInvalidFigure(this);
+ }
+ }
+
+ private void setRecommendedWidth(int width) {
+ if (_recommendedWidth == width)
+ return;
+ _recommendedWidth = width;
+ super.invalidate();
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#validate()
+ */
+ public void validate() {
+ if (isValid())
+ return;
+ super.validate();
+ postValidate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#setValid(boolean)
+ */
+ public void setValid(boolean value) {
+ super.setValid(value);
+ }
+
+ public Insets getInsets() {
+ return new Insets(8);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowUtilities.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowUtilities.java
new file mode 100644
index 000000000..5ebde828b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/FlowUtilities.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.text.BreakIterator;
+
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+
+/**
+ * Utility class for FlowFigures.
+ *
+ */
+public class FlowUtilities extends FigureUtilities {
+ /**
+ * Returns the number of characters from the specified String that will fit
+ * in the available amount of space. An average character width can be
+ * provided as a hint for faster calculation.
+ *
+ * @param frag
+ * the TextFragmentBox
+ * @param string
+ * the String
+ * @param font
+ * the Font used for measuring
+ * @param availableWidth
+ * the available width in pixels
+ * @param avg
+ * 0.0, or an avg character width to use during calculation
+ * @param wrapping
+ * the word wrap style
+ * @return the number of characters that will fit in the space
+ */
+ public static int setupFragmentBasedOnTextSpace(TextFragmentBox frag,
+ String string, Font font, int availableWidth, float avg,
+ int wrapping) {
+ int result = getTextForSpace(string, font, availableWidth, avg,
+ wrapping);
+ frag._length = result;
+ setupFragment(frag, font, string);
+ return result;
+ }
+
+ /**
+ * given the text string, font and available width and wrapping mode.
+ * Calculate how much text can fit into.
+ *
+ * @param string
+ * @param font
+ * @param availableWidth
+ * @param avg
+ * @param wrapping
+ * @return
+ */
+ public static int getTextForSpace(String string, Font font,
+ int availableWidth, float avg, int wrapping) {
+ if (string.length() == 0) {
+ return 0;
+ }
+
+ FontMetrics metrics = getFontMetrics(font);
+ BreakIterator breakItr = BreakIterator.getLineInstance();
+ breakItr.setText(string);
+ int MIN, min, max;
+ if (avg == 0.0) {
+ avg = metrics.getAverageCharWidth();
+ }
+
+ int firstBreak = breakItr.next();
+
+ int winNL = string.indexOf("\r\n"); //$NON-NLS-1$
+ int macNL = string.indexOf('\r');
+ int unixNL = string.indexOf('\n');
+
+ MIN = min = (wrapping == CSSTextLayout.WORD_WRAP_HARD) ? firstBreak : 1;
+ if (macNL == winNL) {
+ macNL = -1; // If the Mac newline is just the prefix to the win NL,
+ // ignore it
+ }
+
+ max = string.length() + 1;
+
+ if (winNL != -1) {
+ max = Math.min(max, winNL);
+ min = Math.min(min, winNL);
+ }
+ if (unixNL != -1) {
+ max = Math.min(max, unixNL);
+ min = Math.min(min, unixNL);
+ }
+ if (macNL != -1) {
+ max = Math.min(max, macNL);
+ min = Math.min(min, macNL);
+ }
+
+ int origMax = max;
+ // The size of the current guess
+ int guess = 0, guessSize = 0;
+
+ while ((max - min) > 1) {
+ // Pick a new guess size
+ // New guess is the last guess plus the missing width in pixels
+ // divided by the average character size in pixels
+ guess = guess + (int) ((availableWidth - guessSize) / avg);
+
+ if (guess >= max) {
+ guess = max - 1;
+ }
+ if (guess <= min) {
+ guess = min + 1;
+ }
+
+ // Measure the current guess
+ guessSize = getStringExtents2(string.substring(0, guess), font).width;
+
+ if (guessSize <= availableWidth) {
+ // We did not use the available width
+ min = guess;
+ } else {
+ // We exceeded the available width
+ max = guess;
+ }
+ }
+
+ int result = string.length();
+ switch (wrapping) {
+ case CSSTextLayout.WORD_WRAP_HARD:
+ if (min == string.length() || min == winNL || min == unixNL
+ || min == macNL) {
+ result = min;
+ } else if (max == origMax
+ && getStringExtents2(string.substring(0, max), font).width <= availableWidth) {
+ result = max;
+ } else {
+ result = Math.max(MIN, breakItr.preceding(Math.min(max, string
+ .length() - 1)));
+ }
+ break;
+
+ case CSSTextLayout.WORD_WRAP_SOFT:
+ if (min == string.length() || min == winNL || min == unixNL
+ || min == macNL) {
+ result = min;
+ } else if (max == origMax
+ && getStringExtents2(string.substring(0, max), font).width <= availableWidth) {
+ result = max;
+ } else if (breakItr.isBoundary(min)) {
+ result = min;
+ } else if (breakItr.isBoundary(Math.min(max, string.length() - 1))) {
+ result = max;
+ } else {
+ result = breakItr.preceding(Math.min(max, string.length() - 1));
+ }
+ if (result <= 0) {
+ result = min;
+ }
+ break;
+ // case CSSTextLayout.WORD_WRAP_TRUNCATE:
+ // if (min == string.length() || min == winNL || min == unixNL || min ==
+ // macNL)
+ // {
+ // result = frag._length = min;
+ // setupFragment(frag, font, string);
+ // if (frag.getWidth() <= availableWidth)
+ // return result;
+ // min -= 1;
+ // }
+ // else if (max == origMax && getStringExtents(string.substring(0, max),
+ // font).width <= availableWidth)
+ // {
+ // result = frag._length = max;
+ // setupFragment(frag, font, string);
+ // return result;
+ // }
+ // result = breakItr.preceding(Math.min(max + 1, string.length() - 1));
+ // if (result <= 0)
+ // {
+ // ELLIPSIS_SIZE =
+ // FigureUtilities.getStringExtents(CSSTextFigure.ELLIPSIS, font);
+ // getTextForSpace(frag, string, font, availableWidth -
+ // ELLIPSIS_SIZE.width, avg, CSSTextLayout.WORD_WRAP_SOFT);
+ // //frag.length = min;
+ // frag._truncated = true;
+ // result = breakItr.following(min);
+ // if (result == BreakIterator.DONE)
+ // result = string.length();
+ // }
+ // else
+ // {
+ // frag._length = result;
+ // }
+ }
+
+ return result;
+ }
+
+ public static int getTextInWidth(String string, Font font,
+ int availableWidth, float avg) {
+ if (string.length() == 0) {
+ return 0;
+ }
+ int guess = 0;
+ while (true) {
+ Dimension a = getTextExtents(string.substring(0, guess), font);
+ if (a.width >= availableWidth) {
+ return guess;
+ }
+ guess++;
+ if (guess == string.length()) {
+ return guess;
+ }
+ }
+ }
+
+ /**
+ * change the parent implementation of getStringExtents(). Don't expend the
+ * 1 width. So empty string will not have any width.
+ *
+ * @param s
+ * @param f
+ * @return
+ */
+ public static Dimension getStringExtents2(String s, Font f) {
+ return new Dimension(getStringDimension(s, f));
+ }
+
+ static void setupFragment(TextFragmentBox frag, Font f, String s) {
+ // if (frag.length != s.length())
+ // we don't skip whitespace here. since already truncated in
+ // CSSTextLayout
+
+ // while (frag.length > 0 &&
+ // Character.isElementContentWhitespace(s.charAt(frag.length - 1)))
+ // frag.length--;
+ frag.setTextData(s.substring(0, frag._length));
+ Dimension d = getStringExtents2(s.substring(0, frag._length), f);
+ FontMetrics fm = getFontMetrics(f);
+ frag.setHeight(fm.getHeight());
+ frag.setAscent(fm.getAscent() + fm.getLeading());
+ if (frag._length > 0
+ && Character.isWhitespace(s.charAt(frag._length - 1))) {
+ frag._isLastCharWhitespace = true;
+ } else {
+ frag._isLastCharWhitespace = false;
+ }
+ frag.setWidth(d.width);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSFigure.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSFigure.java
new file mode 100644
index 000000000..b0a193562
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSFigure.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+
+/**
+ * @author mengbo
+ */
+public interface ICSSFigure extends IFigure {
+ /**
+ * get fragments of this figure. Each item of the list will be a FlowBox.
+ * Note, this method is for read only, caller should not change the returned
+ * list and items in the returned list.
+ *
+ * @return
+ */
+ public List getFragmentsForRead();
+
+ /**
+ * get the CSSStyle of this CSS figure.
+ *
+ * @return
+ */
+ public ICSSStyle getCSSStyle();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSLayout.java
new file mode 100644
index 000000000..1320103f3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSLayout.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.LayoutManager;
+
+/**
+ * There are several kinds of layout involved. 1. the layout need let the child
+ * figures do certain layouting of themselves first, then decide the final
+ * result based on child information. 2. the layout could decide the size
+ * information of this figure without child information.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ICSSLayout extends LayoutManager {
+ /**
+ * Each ICSSLayout is dedicated to a single CSSFigure.
+ *
+ * @return
+ */
+ public ICSSFigure getICSSFigure();
+
+ /**
+ *
+ * @return
+ */
+ // public List getFragmentsForRead();
+ /**
+ * postValidate the child figures of this CSSFigure. Normally layout fall
+ * into the first category need implement this method.
+ */
+ // public void postValidate();
+ /**
+ * setBounds is called on the CSSFigure. Normally layout fall into the
+ * second category need implement this method.
+ *
+ * @param rect
+ * @param invalidate
+ */
+ // public void setBoundsCalled(Rectangle rect, boolean invalidate);
+ /**
+ * @return
+ */
+ // public boolean useLocalCoordinates();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter.java
new file mode 100644
index 000000000..5f83cb868
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.Graphics;
+
+/**
+ * @author mengbo
+ */
+public interface ICSSPainter {
+ /**
+ * this method is called in the figure's <code>paintFigure</code> method,
+ * before <code>paintClientArea</code>. So it is called before children.
+ * Thus, children may override its effects.
+ *
+ * @param g
+ */
+ public void paintFigure(Graphics g);
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter2.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter2.java
new file mode 100644
index 000000000..f93fb8447
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/ICSSPainter2.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.Graphics;
+
+/**
+ * If the layout implements this interface, then it will have chance to paint
+ * something to override children effect.
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSFigure
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ICSSPainter2 {
+ /**
+ * this method is called after <code>paintClientArea</code>. So it is
+ * called after children. Thus, it could override some children effects.
+ *
+ * @param g
+ */
+ public void paintFigurePostClientArea(Graphics g);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/LineBox.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/LineBox.java
new file mode 100644
index 000000000..5ab842f2f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/LineBox.java
@@ -0,0 +1,414 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.jst.pagedesigner.css2.property.VerticalAlignMeta;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.swt.graphics.FontMetrics;
+
+/**
+ * A composite box representing a single line. LineBox calculates its ascent and
+ * descent from the child boxes it contains. Clients can call
+ * {@link #getAscent()}or {@link#getHeight()}at any time and expect valid
+ * values. The child boxes that are added to a line have unspecied locations
+ * until {@link #commit()}is called, at which time the child boxes are layed
+ * out in left-to-right order, and their baselines are all aligned vertically.
+ *
+ */
+public class LineBox extends CompositeBox {
+ private final static int BASELINE = 0;
+
+ private final static int MIDDLE = 1;
+
+ private final static int SUB = 2;
+
+ private final static int SUPER = 3;
+
+ private final static int TEXT_TOP = 4;
+
+ private final static int TEXT_BOTTOM = 5;
+
+ private final static int TOP = 6;
+
+ private final static int BOTTOM = 7;
+
+ private final static int LENGTH = 8;
+
+ private int _ascent = 0;
+
+ private int _descent = 0;
+
+ private int _fontAscent = 0;
+
+ private int _fontDescent = 0;
+
+ private int _fontLeading = 0;
+
+ private Object _horizonalData = null;
+
+ private Object _htmlInitData = null;
+
+ private int _accumlatedWidth = 0;
+
+ /**
+ * Removes all owned fragments and invalidates this CompositeBox.
+ */
+ public void clear() {
+ super.clear();
+ _horizonalData = null;
+ _htmlInitData = null;
+ }
+
+ /**
+ * Committing a LineBox will position its children correctly. All children
+ * boxes are made to have the same baseline, and are layed out from
+ * left-to-right.
+ */
+ public void commit() {
+ int baseline = getBaseline();
+ int xLocation = _x;
+ for (int i = 0; i < _fragments.size(); i++) {
+ FlowBox block = (FlowBox) _fragments.get(i);
+ block._x = xLocation + block._marginInsets.left;
+ xLocation = block._x + block._width + block._marginInsets.right;
+
+ if (_fragments.size() > 1 && block instanceof TextFragmentBox) {
+ TextFragmentBox textBox = (TextFragmentBox) block;
+ if (textBox.getTextData().length() == 0) {
+ textBox._height = _fontAscent + _fontDescent + _fontLeading;
+ textBox.setAscent(_fontAscent + _fontLeading);
+ block._y = this._y;
+ continue;
+ }
+ }
+
+ switch (getVerticalAlignType(block)) {
+ case TOP:
+ block._y = this._y;
+ break;
+ case BOTTOM:
+ block._y = this.getBaseline() - (block.getHeight() - _descent);
+ break;
+ case MIDDLE:
+ int halfXHeight = getHalfXHeight();
+ block._y = this.getBaseline() - halfXHeight
+ - (block.getHeight() + 1) / 2;
+ break;
+ case TEXT_TOP:
+ block._y = this.getBaseline() - _fontAscent - _fontLeading;
+ break;
+ case TEXT_BOTTOM:
+ block._y = this.getBaseline() - (block._height - _fontDescent);
+ break;
+ case LENGTH:
+ block._y = this.getBaseline() + getIncrement(block);
+ break;
+ case SUPER:
+ block._y = this.getBaseline() - getHalfXHeight() * 2
+ - block._height;
+ break;
+ case SUB:
+ block._y = this.getBaseline() - block._height * _fontLeading
+ / getFontHeight();
+ break;
+ case BASELINE:
+ default:
+ block.makeBaseline(baseline);
+ break;
+ }
+ if (block instanceof LineBox) {
+ ((LineBox) block).commit();
+ }
+ }
+ }
+
+ protected int getVerticalAlignType(FlowBox box) {
+ Object data = box.getVerticalAlignData();
+
+ if (data != null) {
+ if (data instanceof Length) {
+ return LENGTH;
+ } else if (VerticalAlignMeta.BASELINE.equals(data)) {
+ return BASELINE;
+ } else if (VerticalAlignMeta.MIDDLE.equals(data)) {
+ return MIDDLE;
+ } else if (VerticalAlignMeta.SUB.equals(data)) {
+ return SUB;
+ } else if (VerticalAlignMeta.SUPER.equals(data)) {
+ return SUPER;
+ } else if (VerticalAlignMeta.TEXT_TOP.equals(data)) {
+ return TEXT_TOP;
+ } else if (VerticalAlignMeta.TEXT_BOTTOM.equals(data)) {
+ return TEXT_BOTTOM;
+ } else if (VerticalAlignMeta.TOP.equals(data)) {
+ return TOP;
+ } else if (VerticalAlignMeta.BOTTOM.equals(data)) {
+ return BOTTOM;
+ }
+ return BASELINE;
+ }
+ return BASELINE;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowBox#getAscent()
+ */
+ public int getAscent() {
+ // because at initial, ascent is 0. And the linebox
+ // could have some size setting without children. In
+ // that case, we need handle differently.
+ if (_ascent == 0 && _fragments.isEmpty()) {
+ return getHeight();
+ }
+ return _ascent;
+ }
+
+ /**
+ * Returns the width available to child fragments.
+ *
+ * @return the width in pixels
+ */
+ public int getAvailableWidth() {
+ if (_recommendedWidth < 0) {
+ return Integer.MAX_VALUE;
+ }
+ int availableWidth = _recommendedWidth - _accumlatedWidth;
+ if (availableWidth < 0) {
+ availableWidth = 0;
+ }
+ return availableWidth;
+ }
+
+ /**
+ * Returns the baseline of this LineBox, which is the y value plus the
+ * ascent.
+ *
+ * @return the baseline value.
+ */
+ public int getBaseline() {
+ return _y + getAscent();
+ }
+
+ /**
+ * @see CompositeBox#resetInfo()
+ */
+ protected void resetInfo() {
+ super.resetInfo();
+ _accumlatedWidth = 0;
+ _ascent = 0;
+ }
+
+ /**
+ * @see CompositeBox#unionInfo(FlowBox)
+ */
+ protected void unionInfo(FlowBox blockInfo) {
+ if (blockInfo instanceof TextFragmentBox) {
+ if (((TextFragmentBox) blockInfo).getTextData().length() == 0) {
+ return;
+ }
+ }
+
+ if (_fragments == null || _fragments.isEmpty()) {
+ this._ascent = 0;
+ this._descent = 0;
+ this._height = 0;
+ }
+
+ int valign = getVerticalAlignType(blockInfo);
+
+ if (valign == BASELINE) {
+ _ascent = Math.max(_ascent, blockInfo.getAscent());
+ if (blockInfo instanceof WidgetBox) {
+ _descent = 0;
+ } else {
+ _descent = Math.max(_descent, blockInfo.getDescent());
+ }
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == MIDDLE) {
+ int halfXHeight = getHalfXHeight();
+ _ascent = Math.max(_ascent, (blockInfo.getHeight() + 1) / 2
+ + halfXHeight);
+ _descent = Math.max(_descent, blockInfo.getHeight() / 2
+ - halfXHeight);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == TEXT_TOP) {
+ _ascent = Math.max(_ascent, _fontAscent + _fontLeading);
+ _descent = Math.max(_descent, blockInfo.getHeight() - _fontAscent
+ - _fontLeading);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == TEXT_BOTTOM) {
+ _ascent = Math.max(_ascent, blockInfo.getHeight() - _fontDescent);
+ _descent = Math.max(_descent, _fontDescent);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == SUB) {
+ int blockTop = blockInfo._height * _fontLeading / getFontHeight();
+ _ascent = Math.max(_ascent, blockTop);
+ _descent = Math.max(_descent, blockInfo.getHeight() - blockTop);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == SUPER) {
+ int blockTop = blockInfo._height;
+ _ascent = Math.max(_ascent, getHalfXHeight() * 2 + blockTop);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == LENGTH) {
+ int increment = getIncrement(blockInfo);
+ _ascent = Math.max(_ascent, blockInfo.getAscent() + increment);
+ _descent = Math.max(_descent, blockInfo.getDescent() - increment);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == TOP) {
+ _descent = Math.max(_descent, blockInfo.getHeight() - _ascent);
+ _height = Math.max(_height, _ascent + _descent);
+ } else if (valign == BOTTOM) {
+ // XXX:the render of IE is not consistent with spec, mozilla is. so
+ // we follow mozilla's implementation.
+ _ascent = Math.max(_ascent, blockInfo.getHeight() - _descent);
+ _height = Math.max(_height, _ascent + _descent);
+ } else {
+ _ascent = Math.max(_ascent, blockInfo.getAscent());
+ _descent = Math.max(_descent, blockInfo.getDescent());
+ _height = Math.max(_height, blockInfo.getHeight());
+ }
+
+ _accumlatedWidth += blockInfo._width
+ + blockInfo._marginInsets.getWidth();
+ if (_accumlatedWidth > _width) {
+ _width = _accumlatedWidth;
+ }
+ }
+
+ private int getIncrement(FlowBox blockInfo) {
+ int valign = getVerticalAlignType(blockInfo);
+ if (valign == LENGTH) {
+ int increment = 0;
+ Length length = (Length) blockInfo.getVerticalAlignData();
+ if (length.isPercentage()) {
+ increment = length.getValue() * getFontHeight() / 100;
+ } else {
+ increment = length.getValue();
+ }
+ return increment;
+ }
+ return 0;
+ }
+
+ /**
+ * @see org.eclipse.draw2d.geometry.Rectangle#isEmpty()
+ */
+ public boolean isOccupied() {
+ if (_width > 0) {
+ return true;
+ }
+
+ if (_fragments.isEmpty()) {
+ return false;
+ }
+ // int size = _fragments.size();
+ // if (size > 1)
+ // {
+ // return true;
+ // }
+ // ok, we have one segment
+ // FlowBox box = (FlowBox) _fragments.get(0);
+ // if (box instanceof TextFragmentBox)
+ // {
+ // if (((TextFragmentBox) box).getTextData().length() == 0)
+ // {
+ // // this is an empty string text box.
+ // return false;
+ // }
+ // }
+ return true;
+ }
+
+ public boolean isEmptyStringLine() {
+ // if(this.getWidth() == 0)
+ // {
+ // return true;
+ // }
+ // else
+ // {
+ // return false;
+ // }
+ if (_fragments.size() == 1) {
+ FlowBox box = (FlowBox) _fragments.get(0);
+ if (box instanceof TextFragmentBox) {
+ if (box instanceof TextFragmentBox) {
+ if (((TextFragmentBox) box).getTextData().length() == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param fontMetrics
+ */
+ public void setFontMetrics(FontMetrics fontMetrics) {
+ if (fontMetrics != null) {
+ _fontAscent = fontMetrics.getAscent();
+ _fontDescent = fontMetrics.getDescent();
+ _fontLeading = fontMetrics.getLeading();
+ // if (_fragments == null || _fragments.isEmpty())
+ // {
+ // this._ascent = _fontAscent + _fontLeading;
+ // this._descent = _fontDescent;
+ // if (this._height < this._ascent + this._descent)
+ // {
+ // this._height = this._ascent + this._descent;
+ // }
+ // }
+ } else {
+ _fontAscent = 0;
+ _fontDescent = 0;
+ _fontLeading = 0;
+ }
+ }
+
+ private int getHalfXHeight() {
+ return (_fontAscent + _fontDescent + _fontLeading) / 5;
+ }
+
+ private int getFontHeight() {
+ return _fontAscent + _fontDescent + _fontLeading;
+ }
+
+ /**
+ * @return Returns the horizonalData.
+ */
+ public Object getHorizonalData() {
+ return _horizonalData;
+ }
+
+ /**
+ * @param horizonalData
+ * The horizonalData to set.
+ */
+ public void setHorizonalData(Object horizonalData) {
+ this._horizonalData = horizonalData;
+ }
+
+ /**
+ * @return Returns the htmlInitData.
+ */
+ public Object getHtmlInitData() {
+ return _htmlInitData;
+ }
+
+ /**
+ * @param htmlInitData
+ * The htmlInitData to set.
+ */
+ public void setHtmlInitData(Object htmlInitData) {
+ this._htmlInitData = htmlInitData;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/MultiLineLabel.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/MultiLineLabel.java
new file mode 100644
index 000000000..24ed25588
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/MultiLineLabel.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+
+public class MultiLineLabel extends Label {
+ private static String ELLIPSIS = "..."; //$NON-NLS-1$
+
+ protected void paintFigure(Graphics graphics) {
+ if (isOpaque()) {
+ graphics.fillRectangle(getBounds());
+ }
+ Rectangle bounds = getBounds();
+ graphics.translate(bounds.x, bounds.y);
+ drawText(graphics);
+ graphics.translate(-bounds.x, -bounds.y);
+ }
+
+ private void drawText(Graphics graphics) {
+ String[] strings = splitString(getText());
+ int y = 0;
+ int lineHeight = FigureUtilities.getFontMetrics(getFont()).getHeight();
+ for (int i = 0; i < strings.length; i++) {
+ graphics.drawText(getSubStringText(strings[i]), 0, y);
+ y += lineHeight;
+ }
+
+ }
+
+ private String[] splitString(String text) {
+ String[] lines = new String[1];
+ int start = 0, pos;
+ do {
+ pos = text.indexOf('\n', start);
+ if (pos == -1) {
+ lines[lines.length - 1] = text.substring(start);
+ } else {
+ boolean crlf = (pos > 0) && (text.charAt(pos - 1) == '\r');
+ lines[lines.length - 1] = text.substring(start, pos
+ - (crlf ? 1 : 0));
+ start = pos + 1;
+ String[] newLines = new String[lines.length + 1];
+ System.arraycopy(lines, 0, newLines, 0, lines.length);
+ lines = newLines;
+ }
+ } while (pos != -1);
+ return lines;
+ }
+
+ public String getSubStringText(String text) {
+ String subStringText = text;
+
+ Font currentFont = getFont();
+ int textWidth = FigureUtilities.getTextWidth(text, currentFont);
+ if (textWidth - getSize().width <= 0) {
+ return subStringText;
+ }
+
+ Dimension effectiveSize = new Dimension(getSize().width, 0);
+
+ int dotsWidth = FigureUtilities.getTextWidth(ELLIPSIS, currentFont);
+
+ if (effectiveSize.width < dotsWidth) {
+ effectiveSize.width = dotsWidth;
+ }
+
+ int subStringLength = getLargestSubstringConfinedTo(text, currentFont,
+ effectiveSize.width - dotsWidth);
+ subStringText = new String(text.substring(0, subStringLength)
+ + ELLIPSIS);
+ return subStringText;
+ }
+
+ int getLargestSubstringConfinedTo(String s, Font f, int availableWidth) {
+ FontMetrics metrics = FigureUtilities.getFontMetrics(f);
+ int min, max;
+ float avg = metrics.getAverageCharWidth();
+ min = 0;
+ max = s.length() + 1;
+
+ // The size of the current guess
+ int guess = 0, guessSize = 0;
+ while ((max - min) > 1) {
+ // Pick a new guess size
+ // New guess is the last guess plus the missing width in pixels
+ // divided by the average character size in pixels
+ guess = guess + (int) ((availableWidth - guessSize) / avg);
+
+ if (guess >= max) {
+ guess = max - 1;
+ }
+ if (guess <= min) {
+ guess = min + 1;
+ }
+
+ // Measure the current guess
+ guessSize = FigureUtilities
+ .getTextExtents(s.substring(0, guess), f).width;
+
+ if (guessSize < availableWidth) {
+ // We did not use the available width
+ min = guess;
+ } else {
+ // We exceeded the available width
+ max = guess;
+ }
+ }
+ return min;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/PageFlowLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/PageFlowLayout.java
new file mode 100644
index 000000000..54dedbfaf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/PageFlowLayout.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.jst.pagedesigner.css2.font.CSSFont;
+import org.eclipse.jst.pagedesigner.css2.font.CSSFontManager;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * A block layout which requires no FlowContext to perform its layout. This
+ * class is used by {@link FlowPage}.
+ * <p>
+ * WARNING: This class is not intended to be subclassed by clients.
+ */
+public class PageFlowLayout extends BlockFlowLayout {
+
+ /**
+ * Creates a new PageFlowLayout with the given FlowPage
+ *
+ * @param page
+ * the FlowPage
+ */
+ public PageFlowLayout(FlowPage page) {
+ super(page);
+ }
+
+ /**
+ * @see BlockFlowLayout#endBlock()
+ */
+ protected void endBlock() {
+ }
+
+ /**
+ * TODO: This method is not being called.
+ */
+ public void postValidate() {
+ }
+
+ protected void setupLine(LineBox line, int topMargin) {
+ super.setupLine(line, topMargin);
+
+ CSSFontManager fontManager = CSSFontManager.getInstance();
+ Font font = fontManager.getSwtFont((CSSFont) fontManager
+ .createDefaultFont());
+ line.setFontMetrics(FigureUtilities.getFontMetrics(font));
+ }
+
+ /**
+ * Setup blockBox to the initial bounds of the Page
+ */
+ protected void setupBlock() {
+ // Remove all current Fragments
+ _blockBox.clear();
+
+ // Setup the one fragment for this Block with the correct X and
+ // available width
+ _blockBox.setRecommendedWidth(((FlowPage) getFlowFigure())
+ .getRecommendedWidth());
+ _blockBox._x = 0;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextFragmentBox.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextFragmentBox.java
new file mode 100644
index 000000000..00b181da8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextFragmentBox.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+/**
+ * A Geometric object for representing a TextFragment region on a line of Text.
+ */
+public class TextFragmentBox extends FlowBox {
+
+ /** The offset in pixels * */
+ public int _offset;
+
+ /** The length in pixels * */
+ public int _length;
+
+ private int _ascent;
+
+ // boolean _truncated;
+
+ public boolean _isLastCharWhitespace = false;
+
+ private String _textData;
+
+ /**
+ * Creates a new TextFragmentBox
+ */
+ public TextFragmentBox() {
+ }
+
+ /**
+ * Returns the ascent of this TextFragmentBox
+ *
+ * @return the ascent
+ */
+ public int getAscent() {
+ return _ascent;
+ }
+
+ /**
+ * Sets the ascent of this TextFragmentBox to the given value
+ *
+ * @param a
+ * the ascent
+ */
+ public void setAscent(int a) {
+ _ascent = a;
+ }
+
+ /**
+ * Sets the height of this TextFragmentBox to the given value
+ *
+ * @param h
+ * the height
+ */
+ public void setHeight(int h) {
+ _height = h;
+ }
+
+ /**
+ * Sets the width of this TextFragmentBox to the given value
+ *
+ * @param w
+ * the width
+ */
+ public void setWidth(int w) {
+ _width = w;
+ }
+
+ public String getTextData() {
+ return _textData;
+ }
+
+ public void setTextData(String txt) {
+ _textData = txt;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextLayoutSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextLayoutSupport.java
new file mode 100644
index 000000000..008d7369b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/TextLayoutSupport.java
@@ -0,0 +1,386 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.property.TextDecorationMeta;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * @author mengbo
+ */
+public class TextLayoutSupport {
+ private static final Logger _log = PDPlugin
+ .getLogger(TextLayoutSupport.class);
+
+ private static final String[] DELIMITERS = { "\r\n", //$NON-NLS-1$
+ "\n", //$NON-NLS-1$
+ "\r" //$NON-NLS-1$
+ }; //$NON-NLS-1$
+
+ static private int delimeterLength;
+
+ /**
+ * Reuses an existing <code>TextFragmentBox</code>, or creates a new one.
+ *
+ * @param i
+ * the index
+ * @param fragments
+ * the original list of fragments
+ * @return a TextFragmentBox
+ */
+ // copied from TextLayout
+ protected static TextFragmentBox getFragment(int i, List fragments) {
+ if (fragments.size() > i) {
+ return (TextFragmentBox) fragments.get(i);
+ }
+ TextFragmentBox box = new TextFragmentBox();
+ fragments.add(box);
+ return box;
+ }
+
+ /**
+ * Returns the average character width of given TextFragmentbox
+ *
+ * @param fragment
+ * the TextFragmentBox
+ * @return the average character width
+ */
+ public static float getAverageCharWidth(TextFragmentBox fragment) {
+ if (fragment._width != 0 && fragment._length != 0) {
+ return fragment._width / (float) fragment._length;
+ }
+ return 0.0f;
+ }
+
+ // ----------------------------------------------------------------------------------------
+ /**
+ * this method will create a set of TextFragment. Each fragment will offset
+ * to the original text (whole text for the text figure).
+ */
+ public static void layoutNormal(FlowContext context, String text,
+ List fragments, Font font, int wrappingStyle, boolean trimLeading) {
+ int i = 0; // The index of the current fragment;
+ int offset = 0;
+ if (trimLeading) {
+ offset = 1;
+ text = text.substring(1);
+ }
+
+ int length = 0; // The length of the current fragment
+ float prevAvgCharWidth;
+ LineBox currentLine;
+ TextFragmentBox fragment;
+
+ while (text.length() > 0) {
+ fragment = null;
+ prevAvgCharWidth = 0f;
+ fragment = getFragment(i, fragments);
+ prevAvgCharWidth = getAverageCharWidth(fragment);
+
+ // Check for newline, if it exists, call context.endLine and skip
+ // over the newline
+ // Exccept for first time through, don't do this.
+ if (i != 0) {
+ boolean changed = false;
+ if (text.charAt(0) == '\r') {
+ text = text.substring(1);
+ changed = true;
+ offset += 1;
+ }
+ if (text.length() != 0 && text.charAt(0) == '\n') {
+ text = text.substring(1);
+ changed = true;
+ offset += 1;
+ }
+ if (changed) {
+ context.endLine();
+ }
+ }
+
+ fragment._offset = offset;
+
+ // This loop is done at most twice.
+ // The second time through, a context.endLine()
+ // was requested, and the loop will break.
+ while (true) {
+ currentLine = context.getCurrentLine();
+ length = FlowUtilities.setupFragmentBasedOnTextSpace(fragment,
+ text, font, currentLine.getAvailableWidth(),
+ prevAvgCharWidth, wrappingStyle);
+
+ if (fragment._width <= currentLine.getAvailableWidth()
+ || !context.isCurrentLineOccupied()) {
+ break;
+ }
+ context.endLine();
+ }
+ // fragment.x = context.getCurrentX();
+ context.addToCurrentLine(fragment);
+ text = text.substring(length);
+ offset += length;
+ if (text.length() > 0) {
+ context.endLine();
+ }
+ i++;
+ }
+
+ // Remove the remaining unused fragments.
+ while (i < fragments.size()) {
+ fragments.remove(fragments.size() - 1);
+ }
+ }
+
+ public static void layoutNoWrap(FlowContext context, String text,
+ List fragments, Font font) {
+ TextFragmentBox fragment;
+ int i = 0;
+ int offset = 0;
+
+ while (offset < text.length()) {
+ int result = nextLineBreak(text, offset);
+ fragment = getFragment(i++, fragments);
+ fragment._length = result - offset;
+ fragment._offset = offset;
+ FlowUtilities.setupFragment(fragment, font, text.substring(offset));
+ context.getCurrentLine().add(fragment);
+ offset = result + delimeterLength;
+ if (delimeterLength != 0) {
+ // in nextLineBreak we fo
+ context.endLine();
+ }
+
+ }
+ // Remove the remaining unused fragments.
+ while (i < fragments.size()) {
+ fragments.remove(i++);
+ }
+ }
+
+ private static int nextLineBreak(String text, int offset) {
+ int result = text.length();
+ delimeterLength = 0;
+ int current;
+ for (int i = 0; i < DELIMITERS.length; i++) {
+ current = text.indexOf(DELIMITERS[i], offset);
+ if (current != -1 && current < result) {
+ result = current;
+ delimeterLength = DELIMITERS[i].length();
+ }
+ }
+ return result;
+ }
+
+ public static void paintTextFigure(Graphics g, List fragments, Font font,
+ int textDecoration) {
+ paintTextFigure(g, fragments, font, null, textDecoration);
+ }
+
+ public static void paintTextDecoration(Graphics g, Rectangle rect,
+ int textDecoration) {
+ if ((textDecoration & TextDecorationMeta.UNDERLINE) != 0) {
+ g.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width
+ - 1, rect.y + rect.height - 1);
+ }
+ if ((textDecoration & TextDecorationMeta.OVERLINE) != 0) {
+ g.drawLine(rect.x, rect.y + 1, rect.x + rect.width - 1, rect.y + 1);
+ }
+ if ((textDecoration & TextDecorationMeta.LINETHROUGH) != 0) {
+ g.drawLine(rect.x, rect.y + rect.height / 2, rect.x + rect.width
+ - 1, rect.y + rect.height / 2);
+ }
+ }
+
+ public static void paintTextFigure(Graphics g, List fragments, Font font,
+ Color color, int textDecoration) {
+ // FIXME: It happens there is problem in this method's parameters. what
+ // exception should be catched?
+ try {
+ TextFragmentBox frag;
+ // XXX: adjust font. Here is not using setFont(), because that will
+ // result in revalidate
+ g.setFont(font);
+
+ for (int i = 0; i < fragments.size(); i++) {
+ frag = (TextFragmentBox) fragments.get(i);
+ // if (!g.getClip(Rectangle.SINGLETON).intersects(frag))
+ // continue;
+ String draw;
+ draw = frag.getTextData();
+
+ if (color != null) {
+ g.setForegroundColor(color);
+ }
+ g.drawText(draw, frag._x, frag._y);
+ if ((textDecoration & TextDecorationMeta.UNDERLINE) != 0) {
+ g.drawLine(frag._x, frag._y + frag.getHeight() - 1, frag._x
+ + frag.getWidth(), frag._y + frag.getHeight() - 1);
+ }
+ if ((textDecoration & TextDecorationMeta.OVERLINE) != 0) {
+ g.drawLine(frag._x, frag._y, frag._x + frag.getWidth(),
+ frag._y);
+ }
+ if ((textDecoration & TextDecorationMeta.LINETHROUGH) != 0) {
+ g.drawLine(frag._x, frag._y + frag.getHeight() / 2, frag._x
+ + frag.getWidth(), frag._y + frag.getHeight() / 2);
+ }
+
+ if (Debug.DEBUG_BASELINE) {
+ g.drawLine(frag._x, frag._y + frag.getAscent(), frag._x
+ + frag.getWidth(), frag._y + frag.getAscent());
+ }
+ }
+ } catch (Exception e) {
+ // "Error in text painting:"
+ _log.info("TextLayoutSupport.Info.1", e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ *
+ * @param g
+ * @param fragments
+ * @param text
+ * all the text in the Text figure.
+ * @param font
+ * @param color
+ * @param textDecoration
+ * @param start
+ * @param end
+ * @param selectionForeColor
+ * @param selectionBackColor
+ */
+ public static void paintTextFigureWithSelection(Graphics g, List fragments,
+ String text, Font font, Color color, int textDecoration, int start,
+ int end, Color selectionForeColor, Color selectionBackColor) {
+ // FIXME: It happens there is problem in this method's parameters. what
+ // exception should be catched?
+ try {
+ TextFragmentBox frag;
+
+ Color originalForeground = g.getForegroundColor();
+ Color originalBackgroud = g.getBackgroundColor();
+
+ // XXX: adjust font. Here is not using setFont(), because that will
+ // result in revalidate
+ g.setFont(font);
+
+ for (int i = 0, n = fragments.size(); i < n; i++) {
+ frag = (TextFragmentBox) fragments.get(i);
+
+ // to make things simpler, we always draw the line using default
+ // color
+ if (color != null) {
+ g.setForegroundColor(color);
+ }
+
+ // if (!g.getClip(Rectangle.SINGLETON).intersects(frag))
+ // continue;
+ String draw;
+ draw = frag.getTextData();
+ if (frag._offset >= end || frag._offset + frag._length <= start) {
+ // we are not in selection. no need to change color
+ g.drawText(draw, frag._x, frag._y);
+ paintTextDecoration(g, frag.getRectangle(), textDecoration);
+ } else if (frag._offset >= start
+ && frag._offset + frag._length <= end) {
+ // we are fully in selection
+ g.setForegroundColor(selectionForeColor);
+ g.setBackgroundColor(selectionBackColor);
+ g
+ .fillRectangle(frag._x, frag._y, FlowUtilities
+ .getTextExtents(draw, font).width, frag
+ .getHeight());
+ g.drawText(draw, frag._x, frag._y);
+ paintTextDecoration(g, frag.getRectangle(), textDecoration);
+ } else {
+ // partial of the fragment's text is in selection.
+
+ // draw the original string first
+ g.drawText(draw, frag._x, frag._y);
+ // then override with the selected parts.
+ g.setForegroundColor(selectionForeColor);
+ g.setBackgroundColor(selectionBackColor);
+ int partialStart = frag._offset > start ? frag._offset
+ : start;
+ int partialEnd = (frag._offset + frag._length > end) ? end
+ : (frag._offset + frag._length);
+ int x = 0;
+ String skip = text.substring(frag._offset, partialStart);
+ x = FlowUtilities.getTextExtents(skip, font).width;
+ String todraw = text.substring(partialStart, partialEnd);
+ if (todraw.length() > 0) {
+ Dimension dimension = FlowUtilities.getTextExtents(skip
+ + todraw, font);
+ g.fillRectangle(frag._x + x, frag._y, dimension.width
+ - x, dimension.height);
+ g.drawText(skip + todraw, frag._x, frag._y);
+ if (color != null) {
+ g.setForegroundColor(color);
+ } else {
+ g.setForegroundColor(originalForeground);
+ }
+ g.drawText(skip, frag._x, frag._y);
+ paintTextDecoration(g, frag.getRectangle(),
+ textDecoration);
+ g.setForegroundColor(selectionForeColor);
+ paintTextDecoration(g,
+ new Rectangle(frag._x + x, frag._y,
+ dimension.width - x, dimension.height),
+ textDecoration);
+ }
+ }
+
+ // we do this in each loop, to make sure we are using correct
+ // color
+ g.setForegroundColor(originalForeground);
+ g.setBackgroundColor(originalBackgroud);
+
+ }
+ } catch (Exception e) {
+ // "Error in text painting:"
+ _log.info("TextLayoutSupport.Info.1", e); //$NON-NLS-1$
+ }
+ }
+
+ public static int getBeginX(Object textAlign, Rectangle rect, int textWidth) {
+ int x = rect.x;
+ if (textAlign != null) {
+ String align = textAlign.toString();
+ if ("left".equalsIgnoreCase(align)) //$NON-NLS-1$
+ {
+ x = rect.x + 1;
+ } else if ("right".equalsIgnoreCase(align)) //$NON-NLS-1$
+ {
+ x = rect.x + rect.width - textWidth - 1;
+ if (x < 1) {
+ x = 1;
+ }
+ } else if ("center".equalsIgnoreCase(align)) //$NON-NLS-1$
+ {
+ int offset = (rect.width - textWidth) / 2;
+ if (offset <= 0) {
+ offset = 0;
+ }
+ x = x + offset + 1;
+ }
+ }
+ return x;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/WidgetBox.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/WidgetBox.java
new file mode 100644
index 000000000..7143e83d2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/WidgetBox.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout;
+
+/**
+ * Simple box support ascent.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class WidgetBox extends FlowBox {
+ private int _ascent = -1;
+
+ public int getAscent() {
+ if (_ascent < 0) {
+ return super.getAscent();
+ } else {
+ return _ascent;
+ }
+ }
+
+ public void setAscent(int ascent) {
+ _ascent = ascent;
+ }
+
+ /**
+ * @return
+ */
+ public boolean supportAscent() {
+ return _ascent > 0;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRGroupLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRGroupLayout.java
new file mode 100644
index 000000000..814c7026a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRGroupLayout.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSTRGroupLayout extends CSSBlockFlowLayout {
+
+ /**
+ * @param cssfigure
+ */
+ public CSSTRGroupLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /**
+ * the parent figure of TRGroup should be table figure. If so, return the
+ * corresponding table layout.
+ *
+ * @return
+ */
+ public CSSTableLayout2 getTableLayoutContext() {
+ IFigure parent = getCSSFigure().getParent();
+ if (parent != null) {
+ LayoutManager parentLayout = parent.getLayoutManager();
+ if (parentLayout instanceof CSSTableLayout2) {
+ return (CSSTableLayout2) parentLayout;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#postValidate()
+ */
+ public void postValidate() {
+ CSSTableLayout2 tableLayout = getTableLayoutContext();
+ if (tableLayout == null) {
+ super.postValidate();
+ } else {
+ Rectangle r = getTRGroupRect(tableLayout);
+ if (r != null) {
+ _blockBox.setXYWidthHeight(r);
+ getCSSFigure().setBounds(r);
+ List list = getCSSFigure().getChildren();
+ for (int i = 0; i < list.size(); i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+ } else {
+ super.postValidate();
+ }
+ }
+ }
+
+ /**
+ * @return
+ */
+ private Rectangle getTRGroupRect(CSSTableLayout2 tableLayout) {
+ TableRowGroupInfo groupinfo = tableLayout.getGroupInfo(this
+ .getCSSFigure());
+ int rowIndex = groupinfo.getRowIndex();
+ int rowCount = groupinfo.getRowCount();
+ int y = (rowIndex + 1) * tableLayout.getVSpacing();
+ for (int k = 0; k < rowIndex; k++) {
+ y += tableLayout.getRowHeights()[k];
+ }
+ if (tableLayout.getCaptionInfo() != null
+ && "top".equalsIgnoreCase(tableLayout.getCaptionInfo().getAlign())) //$NON-NLS-1$
+ {
+ y += tableLayout.getCaptionSize().height;
+ }
+
+ int height = (rowCount - 1) * tableLayout.getVSpacing();
+ for (int k = 0; k < rowCount; k++) {
+ height += tableLayout.getRowHeights()[rowIndex + k];
+ }
+ ICSSFigure figure = groupinfo.getFigure();
+ return new Rectangle(tableLayout.getRowX(), y, tableLayout
+ .getRowWidth(), height);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#useLocalCoordinates()
+ */
+ public boolean useLocalCoordinates() {
+ // if is in table, we don't use local coordinates.
+ return getTableLayoutContext() == null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#endBlock()
+ */
+ protected void endBlock() {
+ if (getTableLayoutContext() == null) {
+ super.endBlock();
+ } else {
+ layoutLines();
+ }
+ }
+
+ // /* (non-Javadoc)
+ // * @see
+ // org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#layout()
+ // */
+ // protected void layout()
+ // {
+ // CSSTableLayout2 tableLayout = getTableLayoutContext();
+ // if (tableLayout == null)
+ // {
+ // // we are not in table? treat as block.
+ // super.layout();
+ // }
+ // else
+ // {
+ // // ok, we are in table. we need to layout our children.
+ // TableRowGroupInfo groupInfo =
+ // tableLayout.getGroupInfo(this.getCSSFigure());
+ // int[] rowHeights = tableLayout.getRowHeights();
+ // int vspacing = tableLayout.getVSpacing();
+ // int rowwidth = getCSSFigure().getBounds().width;// XXX: get from table
+ // layout?
+ // int grouprowindex = groupInfo.getRowIndex();
+ // List rows = groupInfo.getRowList();
+ // for (int i=0, size=rows.size(); i<size; i++)
+ // {
+ // TableRowInfo rowinfo = (TableRowInfo) rows.get(i);
+ // ICSSFigure figure = rowinfo.getFigure();
+ //
+ // int y = 0;
+ // int rowindex = rowinfo.getRowIndex();
+ // for (int row=grouprowindex; row<rowindex; row++)
+ // {
+ // y += rowHeights[row];
+ // y += vspacing;
+ // }
+ // int height = rowHeights[rowindex];
+ // Rectangle rect = new Rectangle(0, y, rowwidth, height);
+ // figure.setBounds(rect);
+ // }
+ // }
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSLayout#handlingBorderForBlock()
+ */
+ public boolean handlingBorderForBlock() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRLayout.java
new file mode 100644
index 000000000..d29fdfcf4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTRLayout.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSTRLayout extends CSSBlockFlowLayout {
+ /**
+ * @param cssfigure
+ */
+ public CSSTRLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /**
+ * the parent figure of TRGroup should be table figure. If so, return the
+ * corresponding table layout.
+ *
+ * @return
+ */
+ public CSSTableLayout2 getTableLayoutContext() {
+ IFigure parent = getCSSFigure().getParent();
+ if (parent != null) {
+ LayoutManager parentLayout = parent.getLayoutManager();
+ if (parentLayout instanceof CSSTableLayout2) {
+ return (CSSTableLayout2) parentLayout;
+ } else if (parentLayout instanceof CSSTRGroupLayout) {
+ return ((CSSTRGroupLayout) parentLayout)
+ .getTableLayoutContext();
+ }
+ }
+
+ return null;
+ }
+
+ public CSSTRGroupLayout getTRGroupLayout() {
+ IFigure parent = getCSSFigure().getParent();
+ if (parent != null) {
+ LayoutManager parentLayout = parent.getLayoutManager();
+ if (parentLayout instanceof CSSTRGroupLayout) {
+ return ((CSSTRGroupLayout) parentLayout);
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#postValidate()
+ */
+ public void postValidate() {
+ CSSTableLayout2 tableLayout = getTableLayoutContext();
+ if (tableLayout == null) {
+ // we are not in table? treat as block.
+ super.postValidate();
+ } else {
+ Rectangle r = getTRRect(tableLayout, getTRGroupLayout());
+ if (r != null) {
+ _blockBox.setXYWidthHeight(r);
+ getCSSFigure().setBounds(r);
+ List list = getCSSFigure().getChildren();
+ for (int i = 0; i < list.size(); i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+ } else {
+ super.postValidate();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#endBlock()
+ */
+ protected void endBlock() {
+ if (this.getTableLayoutContext() == null) {
+ super.endBlock();
+ } else {
+ layoutLines();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#useLocalCoordinates()
+ */
+ public boolean useLocalCoordinates() {
+ return this.getTableLayoutContext() == null;
+ }
+
+ private Rectangle getTRRect(CSSTableLayout2 tableLayout,
+ CSSTRGroupLayout groupLayout) {
+ TableRowInfo rowinfo = tableLayout.getRowInfo(this.getCSSFigure());
+ int rowIndex = rowinfo.getRowIndex();
+ int y = (rowIndex + 1) * tableLayout.getVSpacing();
+ for (int k = 0; k < rowIndex; k++) {
+ y += tableLayout.getRowHeights()[k];
+ }
+ if (tableLayout.getCaptionInfo() != null
+ && "top".equalsIgnoreCase(tableLayout.getCaptionInfo().getAlign())) //$NON-NLS-1$
+ {
+ y += tableLayout.getCaptionSize().height;
+ }
+
+ int height = tableLayout.getRowHeights()[rowIndex];
+ ICSSFigure figure = rowinfo.getFigure();
+ return new Rectangle(tableLayout.getRowX(), y, tableLayout
+ .getRowWidth(), height);
+ }
+
+ /**
+ * @param tableLayout
+ * @param groupLayout
+ * @return
+ */
+ // private Rectangle getTRRect(CSSTableLayout2 tableLayout, CSSTRGroupLayout
+ // groupLayout)
+ // {
+ // TableRowGroupInfo groupInfo = null;
+ // if (groupLayout != null)
+ // {
+ // groupInfo = tableLayout.getGroupInfo(groupLayout.getCSSFigure());
+ // }
+ // if (groupInfo != null)
+ // {
+ // // This TR is in tr group
+ // int[] rowHeights = tableLayout.getRowHeights();
+ // int vspacing = tableLayout.getVSpacing();
+ // int rowwidth = tableLayout.getRowWidth();
+ // int grouprowindex = groupInfo.getRowIndex();
+ // TableRowInfo rowinfo = tableLayout.getRowInfo(this.getCSSFigure());
+ // ICSSFigure figure = rowinfo.getFigure();
+ //
+ // int y = 0;
+ // int rowindex = rowinfo.getRowIndex();
+ // for (int row = grouprowindex; row < rowindex; row++)
+ // {
+ // y += rowHeights[row];
+ // y += vspacing;
+ // }
+ // int height = rowHeights[rowindex];
+ // Rectangle rect = new Rectangle(0, y, rowwidth, height);
+ // return rect;
+ // }
+ // else
+ // {
+ // TableRowInfo rowinfo = tableLayout.getRowInfo(this.getCSSFigure());
+ // int rowIndex = rowinfo.getRowIndex();
+ // int y = (rowIndex+1) * tableLayout.getVSpacing();
+ // int rowHeights[] = tableLayout.getRowHeights();
+ // for (int k=0; k<rowIndex; k++)
+ // {
+ // y += rowHeights[k];
+ // }
+ // int height = rowHeights[rowIndex];
+ // return new Rectangle(tableLayout.getRowX(), y, tableLayout.getRowWidth(),
+ // height);
+ // }
+ // }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSLayout#handlingBorderForBlock()
+ */
+ public boolean handlingBorderForBlock() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCaptionLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCaptionLayout.java
new file mode 100644
index 000000000..27d15717c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCaptionLayout.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSTableCaptionLayout extends CachedTableCellLayout {
+ private CSSTableLayout2 _tableLayout;
+
+ private TableCaptionInfo _caption;
+
+ /**
+ * @param cssfigure
+ */
+ public CSSTableCaptionLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#invalidate()
+ */
+ public void invalidate() {
+ super.invalidate();
+
+ _tableLayout = null;
+ _caption = null;
+ }
+
+ public Rectangle getCellRect() {
+ int x = 0;
+
+ int[] rowHeights = _tableLayout.getRowHeights();
+ int vspacing = _tableLayout.getVSpacing();
+ int y = vspacing;
+ if (_caption != null && "bottom".equalsIgnoreCase(_caption.getAlign())) //$NON-NLS-1$
+ {
+ for (int row = 0; row < rowHeights.length; row++) {
+ y += rowHeights[row];
+ y += vspacing;
+ }
+ }
+
+ int height = 0;
+ height = _tableLayout.getCaptionSize().height;
+ int width = _tableLayout.getCaptionSize().width;
+ Rectangle rect = new Rectangle(x, y, width, height);
+ return rect;
+ }
+
+ /**
+ * the parent figure of TRGroup should be table figure. If so, return the
+ * corresponding table layout.
+ *
+ * @return
+ */
+ public CSSTableLayout2 getTableLayoutContext() {
+ IFigure parent = getCSSFigure().getParent();
+ if (parent != null) {
+ LayoutManager parentLayout = parent.getLayoutManager();
+ if (parentLayout instanceof CSSTableLayout2) {
+ return (CSSTableLayout2) parentLayout;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return
+ */
+ public boolean initializeTableInfo() {
+ _caption = null;
+ _tableLayout = getTableLayoutContext();
+ if (_tableLayout != null) {
+ _caption = _tableLayout.getCaptionInfo();
+ return _caption != null;
+ }
+ return false;
+ }
+
+ public CSSTableLayout2 getTableLayout() {
+ return _tableLayout;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSLayout#isCalculatingMaxWidth()
+ */
+ public boolean isCalculatingMaxWidth() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCellLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCellLayout.java
new file mode 100644
index 000000000..f09529ef0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableCellLayout.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowBox;
+import org.eclipse.jst.pagedesigner.css2.layout.LineBox;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.VerticalAlignMeta;
+
+/**
+ * This layout is for those thigns that it's parent will decide its size. Such
+ * as table cell.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSTableCellLayout extends CachedTableCellLayout {
+ private CSSTableLayout2 _tableLayout;
+
+ private TableRowInfo _rowinfo;
+
+ private TableCellInfo _cellinfo;
+
+ /**
+ * @param cssfigure
+ */
+ public CSSTableCellLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#invalidate()
+ */
+ public void invalidate() {
+ super.invalidate();
+
+ _tableLayout = null;
+ _rowinfo = null;
+ _cellinfo = null;
+ }
+
+ protected void endBlock() {
+ if (isTable()) {
+ verticalLayoutLines();
+ layoutLines();
+ } else {
+ super.endBlock();
+ }
+ }
+
+ protected void verticalLayoutLines() {
+ List lines = _blockBox.getFragments();
+
+ String verticalStyle = getVerticalAlign();
+ int linesHeight = 0;
+
+ if (lines != null && !lines.isEmpty()) {
+ FlowBox bottomBox = ((FlowBox) lines.get(lines.size() - 1));
+ FlowBox topBox = ((FlowBox) lines.get(0));
+ linesHeight = bottomBox._y + bottomBox.getHeight() - topBox._y;
+ }
+ int movement = 0;
+ if (VerticalAlignMeta.BOTTOM.equals(verticalStyle)) {
+ movement = _blockBox.getHeight() - linesHeight
+ - _blockBox.getBorderPaddingHeight() / 2;
+ } else if (VerticalAlignMeta.TOP.equals(verticalStyle)) {
+ movement = 0;
+ }
+ // else if (VerticalAlignMeta.BASELINE.equals(verticalStyle))
+ // {
+ // movement = _blockBox.getHeight() - linesHeight;
+ // }
+ else // if (VerticalAlignMeta.MIDDLE.equals(verticalStyle))
+ {
+ movement = (_blockBox.getHeight() - linesHeight - _blockBox
+ .getBorderPaddingHeight()) / 2;
+ }
+ // VerticalAlignMeta.TOP, ICSSPropertyID.VAL_AUTO and others
+ // else
+ // {
+ // movement = 0;
+ // }
+ if (lines != null) {
+ for (int i = 0, n = lines.size(); i < n; i++) {
+ if (lines.get(i) instanceof LineBox) {
+ LineBox lineBox = (LineBox) lines.get(i);
+ int LineMovement = Math.max(lineBox._marginInsets
+ .getHeight(), movement);
+ lineBox._y = lineBox._y + LineMovement
+ - lineBox._marginInsets.getHeight();
+ }
+ }
+ }
+ }
+
+ private String getVerticalAlign() {
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ return style.getStyleProperty(ICSSPropertyID.ATTR_VERTICAL_ALIGN)
+ .toString();
+ }
+ return VerticalAlignMeta.MIDDLE;
+ }
+
+ public Rectangle getCellRect() {
+ int columnIndex = _cellinfo.getColumnIndex();
+ int rowIndex = _cellinfo.getRowIndex();
+ int[] columnWidths = _tableLayout.getColumnWidths();
+ int hspacing = _tableLayout.getHSpacing();
+ int x = hspacing;
+ for (int col = 0; col < columnIndex; col++) {
+ x += columnWidths[col];
+ x += hspacing;
+ }
+
+ int[] rowHeights = _tableLayout.getRowHeights();
+ int vspacing = _tableLayout.getVSpacing();
+ int y = vspacing;
+ for (int row = 0; row < rowIndex; row++) {
+ y += rowHeights[row];
+ y += vspacing;
+ }
+ if (_tableLayout.getCaptionInfo() != null
+ && "top".equalsIgnoreCase(_tableLayout.getCaptionInfo().getAlign())) //$NON-NLS-1$
+ {
+ y += _tableLayout.getCaptionSize().height;
+ }
+
+ int width = _tableLayout.getCellWidth(_cellinfo, columnWidths);
+ int height = _tableLayout.getCellHeight(_cellinfo, rowHeights);
+
+ Rectangle rect = new Rectangle(x, y, width, height);
+ return rect;
+ }
+
+ /**
+ * the parent figure of TRGroup should be table figure. If so, return the
+ * corresponding table layout.
+ *
+ * @return
+ */
+ public CSSTableLayout2 getTableLayoutContext() {
+ IFigure parent = getCSSFigure().getParent();
+ if (parent != null) {
+ LayoutManager parentLayout = parent.getLayoutManager();
+ if (parentLayout instanceof CSSTRLayout) {
+ return ((CSSTRLayout) parentLayout).getTableLayoutContext();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @return
+ */
+ public boolean initializeTableInfo() {
+ _rowinfo = null;
+ _cellinfo = null;
+ _tableLayout = getTableLayoutContext();
+ if (_tableLayout != null) {
+ _rowinfo = _tableLayout.getRowInfo((CSSFigure) this.getCSSFigure()
+ .getParent());
+ if (_rowinfo != null) {
+ _cellinfo = _rowinfo.getCellInfo(this.getCSSFigure());
+ if (_cellinfo != null) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public CSSTableLayout2 getTableLayout() {
+ return _tableLayout;
+ }
+
+ public TableCellInfo getTableCellInfo() {
+ return _cellinfo;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableLayout2.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableLayout2.java
new file mode 100644
index 000000000..5acdfb1af
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CSSTableLayout2.java
@@ -0,0 +1,628 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
+import org.eclipse.swt.SWT;
+
+/**
+ * @see http://www.w3.org/TR/REC-CSS2/tables.html
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSTableLayout2 extends CSSBlockFlowLayout implements ICSSPainter {
+ static Logger _log = PDPlugin.getLogger(CSSTableLayout2.class);
+
+ int _hspacing;
+
+ int _vspacing;
+
+ int[] _columnWidths;
+
+ int[] _rowHeights;
+
+ Dimension _captionSize;
+
+ // _tableInfo will be initialized in preLayout
+ TableInfo _tableInfo;
+
+ private int _internalTableWidth;
+
+ private int _internalTableHeight;
+
+ private int _rowx;
+
+ private int _rowwidth;
+
+ /**
+ * @param flowfigure
+ */
+ public CSSTableLayout2(CSSFigure flowfigure) {
+ super(flowfigure);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#preLayout()
+ */
+ protected void preLayout() {
+ // super.preLayout will setup the block box.
+ super.preLayout();
+
+ ICSSStyle style = this.getCSSStyle();
+
+ _hspacing = _vspacing = 3; // default value
+
+ if (style != null) {
+ Object borderspacing = style
+ .getStyleProperty(ICSSPropertyID.ATTR_BORDER_SPACING);
+ if (borderspacing instanceof int[]) {
+ int[] intvalues = (int[]) borderspacing;
+ _hspacing = intvalues[0];
+ _vspacing = intvalues[1];
+ } else {
+ ITagEditInfo info = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (info != null && info.needTableDecorator()) {
+ // default decorating value. to make things look more
+ // separated.
+ if (_hspacing < 5) {
+ _hspacing = 5;
+ }
+ if (_vspacing < 5) {
+ _vspacing = 5;
+ }
+ }
+ }
+ }
+
+ // TODO: support caption
+ _tableInfo = new TableInfo(getCSSFigure());
+
+ // construct the table structure.
+ _tableInfo.constructTable();
+
+ // calculate the user specified width/height for table and cells.
+ // contentWidth is the user specified content width. If <= 0 means no
+ // user
+ // specification.
+ int contentWidth = this._blockBox.getContentWidth();
+ int availableWidth = this._blockBox.getRecommendedContentWidth();
+ int contentHeight = this._blockBox.getContentHeight();
+
+ _tableInfo.calculateWidth(contentWidth, availableWidth);
+ _tableInfo.calculateHeight(contentHeight);
+
+ int columnCount = _tableInfo.getColumnCount();
+
+ int columnMinWidths[] = new int[columnCount];
+ int columnMaxWidths[] = new int[columnCount];
+
+ // For each column, determine a maximum and minimum column width from
+ // the cells that span only that column. The minimum is that required by
+ // the cell with the largest minimum cell width (or the column 'width',
+ // whichever is larger). The maximum is that required by the cell with
+ // the
+ // largest maximum cell width (or the column 'width', whichever is
+ // larger).
+ List cells = _tableInfo.getCells();
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
+ if (cellinfo.getColSpan() == 1) {
+ int column = cellinfo.getColumnIndex();
+ Dimension mincw = cellinfo.getMinCWDimension();
+ Dimension maxcw = cellinfo.getMaxCWDimension();
+ if (maxcw.width < mincw.width) {
+ maxcw.width = mincw.width;
+ }
+ if (mincw.width > columnMinWidths[column]) {
+ columnMinWidths[column] = mincw.width;
+ }
+ if (maxcw.width > columnMaxWidths[column]) {
+ columnMaxWidths[column] = maxcw.width;
+ }
+ }
+ }
+ // For caption, determine a maximum and minimum width from it.
+ int captionWidth = 0;
+ if (_tableInfo._caption != null) {
+ captionWidth = _tableInfo._caption.getDimension().width;
+ }
+
+ // For each cell that spans more than one column, increase the
+ // minimum widths of the columns it spans so that together, they
+ // are at least as wide as the cell. Do the same for the maximum
+ // widths. If possible, widen all spanned columns by approximately
+ // the same amount.
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
+ int colspan = cellinfo.getColSpan();
+ if (colspan > 1) {
+ int column = cellinfo.getColumnIndex();
+ Dimension mincw = cellinfo.getMinCWDimension();
+ Dimension maxcw = cellinfo.getMaxCWDimension();
+
+ adjustWidth(column, colspan, mincw.width, columnMinWidths);
+ adjustWidth(column, colspan, maxcw.width, columnMaxWidths);
+ }
+ }
+
+ int sigmaMinWidth = 0;
+ int sigmaMaxWidth = 0;
+ for (int i = 0; i < columnMinWidths.length; i++) {
+ sigmaMinWidth += columnMinWidths[i];
+ if (columnMaxWidths[i] == Integer.MAX_VALUE) {
+ sigmaMaxWidth = Integer.MAX_VALUE;
+ } else if (sigmaMaxWidth != Integer.MAX_VALUE) {
+ sigmaMaxWidth += columnMaxWidths[i];
+ if (sigmaMaxWidth < 0) {
+ sigmaMaxWidth = Integer.MAX_VALUE;
+ }
+ }
+ }
+ int spacingall = (columnMinWidths.length + 1) * _hspacing;
+ sigmaMinWidth += spacingall;
+ if (sigmaMaxWidth != Integer.MAX_VALUE) {
+ sigmaMaxWidth += spacingall;
+ if (sigmaMaxWidth < 0) {
+ sigmaMaxWidth = Integer.MAX_VALUE;
+ }
+ }
+
+ int tableWidth = _tableInfo.getTableWidth();
+ if (tableWidth > 0) {
+ // If the 'table' or 'inline-table' element's 'width' property has a
+ // specified value (W) other than 'auto', the property's computed
+ // value
+ // is the greater of W and the minimum width required by all the
+ // columns
+ // plus cell spacing or borders (MIN). If W is greater than MIN, the
+ // extra
+ // width should be distributed over the columns.
+ int maxMin = Math.max(captionWidth, sigmaMinWidth);
+ if (maxMin >= tableWidth) {
+ tableWidth = maxMin;
+ }
+ distribute(tableWidth - sigmaMinWidth, columnMinWidths,
+ columnMaxWidths);
+ } else {
+ // If the 'table' or 'inline-table' element has 'width: auto', the
+ // computed
+ // table width is the greater of the table's containing block width
+ // and MIN.
+ // However, if the maximum width required by the columns plus cell
+ // spacing or
+ // borders (MAX) is less than that of the containing block, use MAX.
+ // int availableWidth = this.getCurrentLine().getAvailableWidth();
+ int maxMin = Math.max(captionWidth, sigmaMaxWidth);
+ if (maxMin <= availableWidth) {
+ // TODO: if _tableInfo.hasWidthPercentage, then we need take
+ // that into consideration
+ // to distribute the column width. Left to next version.
+ tableWidth = maxMin;
+ // columnMinWidths = columnMaxWidths;
+ } else {
+ tableWidth = availableWidth;
+ }
+ distribute(tableWidth - sigmaMinWidth, columnMinWidths,
+ columnMaxWidths);
+ }
+
+ // now columnMinWidths contains width for each column
+ _columnWidths = columnMinWidths;
+
+ // ok, we have finished calculating column width.
+ // next we need to find out row heights.
+ _rowHeights = new int[_tableInfo.getRowCount()];
+
+ // first find out those TR that has height settings and use them.
+ List rows = _tableInfo.getRows();
+ for (int i = 0, size = rows.size(); i < size && i < _rowHeights.length; i++) {
+ TableRowInfo rowInfo = (TableRowInfo) rows.get(i);
+ if (rowInfo.getSpecifiedRowHeight() > 0) {
+ _rowHeights[i] = rowInfo.getSpecifiedRowHeight();
+ }
+ }
+
+ // First the cells don't span multiple rows.
+ cells = _tableInfo.getCells();
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
+ IFigure figure = cellinfo.getFigure();
+ int rowspan = cellinfo.getRowSpan();
+ if (rowspan == 1) {
+ int cellWidth = getCellWidth(cellinfo, _columnWidths);
+ Dimension d = figure.getPreferredSize(cellWidth, cellinfo
+ .getHeight());
+ if (d.height > _rowHeights[cellinfo.getRowIndex()]) {
+ _rowHeights[cellinfo.getRowIndex()] = d.height;
+ }
+ }
+ }
+
+ // Next those cells span multiple rows.
+ cells = _tableInfo.getCells();
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
+ IFigure figure = cellinfo.getFigure();
+ int rowspan = cellinfo.getRowSpan();
+ if (rowspan > 1) {
+ int cellWidth = getCellWidth(cellinfo, _columnWidths);
+ Dimension d = figure.getPreferredSize(cellWidth, cellinfo
+ .getHeight());
+ if (d.height > getCellHeight(cellinfo, _rowHeights)) {
+ adjustHeight(cellinfo.getRowIndex(), rowspan, d.height,
+ _rowHeights);
+ }
+ }
+ }
+
+ // Next we may need distribute height.
+ int sigmaHeight = (_tableInfo.getRowCount() + 1) * _vspacing;
+ for (int i = 0; i < _rowHeights.length; i++) {
+ sigmaHeight += _rowHeights[i];
+ }
+ if (sigmaHeight < contentHeight) {
+ distributeHeights(contentHeight - sigmaHeight, _rowHeights);
+ }
+
+ // now we have calculated the width and height of all cells.
+ // FIXME: border?
+ Insets insets = (style == null ? new Insets() : style.getBorderInsets()
+ .getAdded(style.getPaddingInsets()));
+ _internalTableWidth = (_tableInfo.getColumnCount() + 1) * _hspacing;
+ for (int i = 0; i < _columnWidths.length; i++) {
+ _internalTableWidth += _columnWidths[i];
+ }
+ int minWidth = getLengthValue(style, ICSSPropertyID.ATTR_MIN_WIDTH);
+ _internalTableWidth = _internalTableWidth > minWidth ? _internalTableWidth
+ : minWidth;
+
+ _blockBox.setWidth(_internalTableWidth + insets.getWidth());
+ _internalTableHeight = (_tableInfo.getRowCount() + 1) * _vspacing;
+ for (int i = 0; i < _rowHeights.length; i++) {
+ _internalTableHeight += _rowHeights[i];
+ }
+ int minHeight = getLengthValue(style, ICSSPropertyID.ATTR_MIN_HEIGHT);
+ _internalTableHeight = _internalTableHeight > minHeight ? _internalTableHeight
+ : minHeight;
+
+ int captionHeight = 0;
+ if (_tableInfo._caption != null) {
+ _captionSize = _tableInfo._caption.getFigure().getPreferredSize(
+ _internalTableWidth, SWT.DEFAULT);
+ captionHeight = _captionSize.height;
+ } else {
+ _captionSize = null;
+ }
+ _internalTableHeight += captionHeight;
+
+ _blockBox.setHeight(_internalTableHeight + insets.getHeight());
+
+ _rowwidth = _internalTableWidth - 2 * _hspacing;
+ _rowx = _hspacing; // XXX: table border width left?
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#endBlock()
+ */
+ protected void endBlock() {
+ _blockBox.setWidth(_internalTableWidth
+ + _blockBox.getBorderPaddingWidth());
+ _blockBox.setHeight(_internalTableHeight
+ + _blockBox.getBorderPaddingHeight());
+ super.endBlock();
+ }
+
+ //
+ // /**
+ // * when some of the column has percentage width, and sigmaMax smaller than
+ // container,
+ // * @param containerWidth
+ // * @param columnMinWidths
+ // * @param columnMaxWidths
+ // * @return
+ // */
+ // private int distribute2(int containerWidth, int[] columnMinWidths, int[]
+ // columnMaxWidths)
+ // {
+ //
+ // }
+ //
+ /**
+ * Distribute the additional width to columnMinWidths, using max width as a
+ * possible reference on how to distribute.
+ *
+ * @param toDistribute
+ * @param columnMinWidths
+ * @param columnMaxWidths
+ */
+ private void distribute(int toDistribute, int[] columnMinWidths,
+ int[] columnMaxWidths) {
+ if (toDistribute <= 0)
+ return;
+ if (columnMinWidths.length == 0)
+ return;
+
+ int[] delta = new int[columnMinWidths.length];
+ int sigmaDelta = 0;
+ for (int i = 0; i < columnMinWidths.length && toDistribute > 0; i++) {
+ if (_tableInfo._widthSpecified[i]) {
+ delta[i] = 0;
+ } else {
+ delta[i] = columnMaxWidths[i] - columnMinWidths[i];
+ if (delta[i] <= 0) {
+ delta[i] = 0;
+ }
+ sigmaDelta += delta[i];
+ }
+ }
+ if (sigmaDelta == 0) {
+ // should not happen, but anyway, distribute all to the last column
+ // columnMinWidths[columnMinWidths.length-1] += toDistribute;
+ averageDeltaToCell(columnMinWidths, toDistribute);
+ } else {
+ int left = toDistribute;
+ for (int i = 0; i < columnMinWidths.length - 1; i++) {
+ if (delta[i] > 0) {
+ int add = delta[i] * toDistribute / sigmaDelta;
+ left -= add;
+ columnMinWidths[i] += add;
+ }
+ }
+ columnMinWidths[columnMinWidths.length - 1] += left;
+ }
+ }
+
+ private void averageDeltaToCell(int[] columnMinWidths, int toDistribute) {
+
+ if (toDistribute <= 0) {
+ return;
+ }
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < columnMinWidths.length; i++) {
+ if (!_tableInfo._widthSpecified[i]) {
+ list.add(new Integer(i));
+ }
+ }
+ if (list.size() == 0) {
+ for (int i = 0; i < columnMinWidths.length; i++) {
+ list.add(new Integer(i));
+ }
+ }
+ int padding = toDistribute / list.size();
+ int left = toDistribute % list.size();
+ for (int i = 0, n = list.size(); i < n; i++) {
+ columnMinWidths[((Integer) list.get(i)).intValue()] += padding;
+ }
+ if (left > 0) {
+ for (int i = 0; i < left; i++) {
+ columnMinWidths[((Integer) list.get(i)).intValue()] += 1;
+ }
+ }
+ }
+
+ /**
+ * @param i
+ * @param heights
+ */
+ private void distributeHeights(int toDistribute, int[] heights) {
+ if (heights.length == 0)
+ return;
+ int eachDelta = toDistribute / heights.length;
+ for (int i = 0; i < heights.length - 1; i++) {
+ heights[i] += eachDelta;
+ }
+ heights[heights.length - 1] += toDistribute - (heights.length - 1)
+ * eachDelta;
+ }
+
+ /**
+ * @param cellinfo
+ * @param heights
+ * @return
+ */
+ public int getCellHeight(TableCellInfo cellinfo, int[] heights) {
+ int rowIndex = cellinfo.getRowIndex();
+ int rowspan = cellinfo.getRowSpan();
+ int h = 0;
+ for (int i = 0; i < rowspan; i++) {
+ h += heights[rowIndex + i];
+ }
+ h += (rowspan - 1) * _vspacing;
+ return h;
+ }
+
+ /**
+ * @param cellinfo
+ * @param widths
+ * @return
+ */
+ public int getCellWidth(TableCellInfo cellinfo, int[] widths) {
+ int columnIndex = cellinfo.getColumnIndex();
+ int colspan = cellinfo.getColSpan();
+ int w = 0;
+ for (int i = 0; i < colspan; i++) {
+ w += widths[columnIndex + i];
+ }
+ w += (colspan - 1) * _hspacing;
+ return w;
+ }
+
+ /**
+ * @param column
+ * the start column
+ * @param colspan
+ * number of columns
+ * @param width
+ * desired width
+ * @param columnWidths
+ * current columns widths. After the adjust, need make sure the
+ * columnWidths to be bigger than desired width
+ */
+ private void adjustWidth(int column, int colspan, int width,
+ int[] columnWidths) {
+ adjustSpan(column, colspan, width, columnWidths, _hspacing);
+ }
+
+ /**
+ * @see #adjustWidth(int, int, int, int[])
+ */
+ private void adjustHeight(int rowIndex, int rowspan, int height,
+ int[] heights) {
+ adjustSpan(rowIndex, rowspan, height, heights, _vspacing);
+ }
+
+ static private void adjustSpan(int column, int colspan, int width,
+ int[] columnWidths, int spacing) {
+ int spanwidth = 0;
+ for (int i = 0; i < colspan; i++) {
+ spanwidth += columnWidths[column + i];
+ }
+ // XXX: vspacing here?
+ spanwidth += (colspan - 1) * spacing;
+
+ if (spanwidth >= width) {
+ return;
+ } else {
+ int delta = width - spanwidth;
+ int deltaeach = delta / colspan;
+ for (int i = 0; i < colspan - 1; i++) {
+ columnWidths[column + i] += deltaeach;
+ }
+ columnWidths[column + colspan - 1] += (delta - (colspan - 1)
+ * deltaeach);
+ }
+ }
+
+ /**
+ * @return
+ */
+ public int[] getRowHeights() {
+ return _rowHeights;
+ }
+
+ /**
+ * @return
+ */
+ public int[] getColumnWidths() {
+ return _columnWidths;
+ }
+
+ /**
+ * @return
+ */
+ public int getVSpacing() {
+ return _vspacing;
+ }
+
+ /**
+ * @return
+ */
+ public int getHSpacing() {
+ return _hspacing;
+ }
+
+ /**
+ * @param figure
+ * @return
+ */
+ public TableRowInfo getRowInfo(CSSFigure figure) {
+ return _tableInfo.findRowInfo(figure);
+ }
+
+ public TableCaptionInfo getCaptionInfo() {
+ return _tableInfo._caption;
+ }
+
+ /**
+ * @param figure
+ * @return
+ */
+ public TableRowGroupInfo getGroupInfo(CSSFigure figure) {
+ return _tableInfo.findGroupInfo(figure);
+ }
+
+ /**
+ * @return
+ */
+ public int getRowX() {
+ return _rowx;
+ }
+
+ /**
+ * @return
+ */
+ public int getRowWidth() {
+ return _rowwidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#shouldExpand()
+ */
+ public boolean shouldExpand() {
+ return false;
+ }
+
+ public Dimension getCaptionSize() {
+ return _captionSize;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter#paintFigure(org.eclipse.draw2d.Graphics)
+ */
+ public void paintFigure(Graphics g) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style != null) {
+ ITagEditInfo info = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (info != null && info.needTableDecorator()) {
+ List cells = _tableInfo.getCells();
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellInfo = (TableCellInfo) cells.get(i);
+ IFigure cellfigure = cellInfo.getFigure();
+ Rectangle rect = cellfigure.getBounds().getCopy();
+ rect = rect.expand(1, 1);
+ g.setLineStyle(Graphics.LINE_SOLID);
+ g.setLineWidth(1);
+ g.setForegroundColor(ColorConstants.lightBlue);
+ g.drawRectangle(rect);
+ }
+ }
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CachedTableCellLayout.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CachedTableCellLayout.java
new file mode 100644
index 000000000..40c734e00
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/CachedTableCellLayout.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.layout.BoxUtil;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class CachedTableCellLayout extends CSSBlockFlowLayout {
+ protected Dimension _pageSize = new Dimension();
+
+ protected boolean _calculatingSize = false;
+
+ private int _pageSizeCacheKeys[] = new int[4];
+
+ private Dimension _pageSizeCacheValues[] = new Dimension[4];
+
+ private int _recommendedWidth;
+
+ private Dimension _cacheMaxWidthSize = null;
+
+ private boolean _isTable;
+
+ /**
+ * @param cssfigure
+ */
+ public CachedTableCellLayout(CSSFigure cssfigure) {
+ super(cssfigure);
+ }
+
+ /**
+ * when figure revalidated, means some child or itself get changed somehow,
+ * so clear the cache information here.
+ */
+ public void figureRevalidate() {
+ super.figureRevalidate();
+ _pageSizeCacheKeys = new int[4];
+ _pageSizeCacheValues = new Dimension[4];
+ _pageSize = new Dimension();
+ _recommendedWidth = 0;
+ _cacheMaxWidthSize = null;
+ _isTable = false;
+ }
+
+ /**
+ * TODO: This method is not being called.
+ */
+ public void postValidate() {
+ if (_isTable) {
+ if (_calculatingSize) {
+ _pageSize.width = _blockBox.getWidth();
+ _pageSize.height = _blockBox.getHeight();
+ } else {
+ if (_isTable) {
+ Rectangle rect = getCellRect();
+ _blockBox.setXYWidthHeight(rect);
+ this.getCSSFigure().setBounds(rect);
+ }
+ }
+ List list = getCSSFigure().getChildren();
+ for (int i = 0, n = list.size(); i < n; i++) {
+ ((FlowFigure) list.get(i)).postValidate();
+ }
+ } else {
+ super.postValidate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#preLayout()
+ */
+ protected void preLayout() {
+ _isTable = initializeTableInfo();
+ if (_isTable) {
+ if (!_calculatingSize) {
+ // XXX: I don't know why need to call setValid(false) here, if I
+ // don't call
+ // it, the layout will be wrong.
+ getCSSFigure().setValid(false);
+ }
+ }
+ super.preLayout();
+ }
+
+ public abstract Rectangle getCellRect();
+
+ public abstract boolean initializeTableInfo();
+
+ protected void setupBlock() {
+ if (_isTable) {
+ // Remove all current Fragments
+ _blockBox.clear();
+
+ if (_calculatingSize) {
+ // we are not in the real layout
+ // Setup the one fragment for this Block with the correct X and
+ // available width
+ int recommendedWidth = getRecommendedWidth();
+ _blockBox.setRecommendedWidth(recommendedWidth);
+
+ if (recommendedWidth > 0
+ && recommendedWidth != Integer.MAX_VALUE) {
+ _blockBox.setWidth(recommendedWidth);
+ }
+ } else {
+ Rectangle rect = getCellRect();
+ _blockBox.setWidth(rect.width);
+ _blockBox.setRecommendedWidth(rect.width);
+ _blockBox.setHeight(rect.height);
+ _blockBox.setRecommendedHeight(rect.height);
+ }
+
+ BoxUtil.setupBorderPaddingMargin(_blockBox, getCSSStyle());
+ } else {
+ super.setupBlock();
+ }
+ }
+
+ /**
+ * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
+ */
+ public Dimension getPreferredSize(IFigure container, int width, int h) {
+ if (this.isCalculatingMaxWidth()) {
+ return getMaxContentWidthSize(container, width, h);
+ }
+ try {
+ _calculatingSize = true;
+ // if (width >= 0)
+ // {
+ // width = Math.max(0, width - container.getInsets().getWidth());
+ // }
+
+ for (int i = 0; i < 4; i++) {
+ if (_pageSizeCacheKeys[i] == width
+ && _pageSizeCacheValues[i] != null) {
+ if (h > _pageSizeCacheValues[i].height) {
+ return new Dimension(_pageSizeCacheValues[i].width, h);
+ }
+ return _pageSizeCacheValues[i];
+ }
+ }
+
+ _pageSizeCacheKeys[3] = _pageSizeCacheKeys[2];
+ _pageSizeCacheKeys[2] = _pageSizeCacheKeys[1];
+ _pageSizeCacheKeys[1] = _pageSizeCacheKeys[0];
+ _pageSizeCacheKeys[0] = width;
+
+ _pageSizeCacheValues[3] = _pageSizeCacheValues[2];
+ _pageSizeCacheValues[2] = _pageSizeCacheValues[1];
+ _pageSizeCacheValues[1] = _pageSizeCacheValues[0];
+
+ // Flowpage must temporarily layout to determine its preferred size
+ int oldWidth = getRecommendedWidth();
+ setRecommendedWidth(width);
+ ((CSSFigure) container).setValid(false);
+ container.validate();
+ ((CSSFigure) container).postValidate();
+ _pageSizeCacheValues[0] = new Dimension(_pageSize);
+
+ if (width != oldWidth) {
+ setRecommendedWidth(oldWidth);
+ // container.getUpdateManager().addInvalidFigure(container);
+ }
+ if (h > _pageSizeCacheValues[0].height) {
+ return new Dimension(_pageSizeCacheValues[0].width, h);
+ } else {
+ return _pageSizeCacheValues[0];
+ }
+ } finally {
+ _calculatingSize = false;
+ }
+ }
+
+ public int getRecommendedWidth() {
+ return _recommendedWidth;
+ }
+
+ private void setRecommendedWidth(int width) {
+ if (_recommendedWidth == width) {
+ return;
+ }
+ _recommendedWidth = width;
+ }
+
+ public Dimension getMaxContentWidthSize(IFigure container, int width,
+ int height) {
+ try {
+ _calculatingSize = true;
+
+ if (this._cacheMaxWidthSize == null) {
+ boolean b = getCalcuatingMaxWidth();
+ setCalculatingMaxWidth(true);
+
+ // Flowpage must temporarily layout to determine its preferred
+ // size
+ int oldWidth = getRecommendedWidth();
+ if (width <= 0) {
+ setRecommendedWidth(Integer.MAX_VALUE);
+ } else {
+ setRecommendedWidth(width);
+ }
+ ((CSSFigure) container).setValid(false);
+ container.validate();
+
+ ((CSSFigure) container).postValidate();
+ _cacheMaxWidthSize = new Dimension(_pageSize);
+ if (height > _pageSize.height) {
+ _cacheMaxWidthSize.height = height;
+ }
+
+ if (0 != oldWidth) {
+ setRecommendedWidth(oldWidth);
+ // container.getUpdateManager().addInvalidFigure(container);
+ }
+
+ setCalculatingMaxWidth(b);
+ }
+ return _cacheMaxWidthSize;
+ } finally {
+ _calculatingSize = false;
+ }
+ }
+
+ /**
+ * @return Returns the _isTable.
+ */
+ protected boolean isTable() {
+ return _isTable;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCaptionInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCaptionInfo.java
new file mode 100644
index 000000000..8a8b5c18f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCaptionInfo.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.swt.SWT;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableCaptionInfo extends TableItemInfo {
+ String _align;
+
+ /**
+ * @param figure
+ */
+ public TableCaptionInfo(ICSSFigure figure) {
+ super(figure);
+ ICSSStyle style = figure.getCSSStyle();
+ if (style != null) {
+ _align = style.getStyleProperty(
+ ICSSPropertyID.ATTR_HORIZONTAL_ALIGN).toString();
+ }
+ }
+
+ /**
+ * @return
+ */
+ public Dimension getDimension(int width, int height) {
+ return getFigure().getPreferredSize(width, height);
+ }
+
+ public Dimension getDimension() {
+ return getDimension(SWT.DEFAULT, SWT.DEFAULT);
+ }
+
+ /**
+ * @return Returns the align.
+ */
+ public String getAlign() {
+ // TODO:We do not support left/right align of caption currently. so we
+ // treat them as top.
+ if ("bottom".equalsIgnoreCase(_align)) //$NON-NLS-1$
+ {
+ return _align;
+ } else {
+ return "top"; //$NON-NLS-1$
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCellInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCellInfo.java
new file mode 100644
index 000000000..cc41b1f92
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableCellInfo.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.utils.IntFlexArray;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableCellInfo extends TableItemInfo {
+ int _rowSpan = 1;
+
+ int _colSpan = 1;
+
+ int _colIndex;
+
+ int _rowIndex;
+
+ int _cellWidth = 0;
+
+ int _cellHeight = 0;
+
+ /**
+ * @param childfigure
+ */
+ public TableCellInfo(ICSSFigure childfigure) {
+ super(childfigure);
+ }
+
+ /**
+ * @return
+ */
+ public int getColSpan() {
+ return _colSpan;
+ }
+
+ /**
+ * @return
+ */
+ public int getRowSpan() {
+ return _rowSpan;
+ }
+
+ /**
+ * @return
+ */
+ public int getRowIndex() {
+ return _rowIndex;
+ }
+
+ /**
+ * @return
+ */
+ public int getColumnIndex() {
+ return _colIndex;
+ }
+
+ /**
+ * @return
+ */
+ public Dimension getMinCWDimension() {
+ return getFigure().getPreferredSize(_cellWidth, _cellHeight);
+ }
+
+ /**
+ * @return
+ */
+ public Dimension getMaxCWDimension() {
+ ICSSFigure figure = getFigure();
+ LayoutManager layout = figure.getLayoutManager();
+ if (layout instanceof CSSTableCellLayout) {
+ Dimension d = ((CSSTableCellLayout) layout).getMaxContentWidthSize(
+ figure, _cellWidth, _cellHeight);
+ return d;
+ } else {
+ // should not happen
+ return getMinCWDimension();
+ }
+ }
+
+ /**
+ * @param context
+ */
+ public void calculateCellInfo(TableInfoContext context) {
+ ICSSStyle style = this.getStyle();
+ _rowSpan = style.getRowSpan();
+ _colSpan = style.getColSpan();
+
+ // FIXME: we don't support rowspan and colspan to be 0.
+ // by spec, 0 means span from current col/row to end.
+ if (_rowSpan <= 0) {
+ _rowSpan = 1;
+ }
+ if (_colSpan <= 0) {
+ _colSpan = 1;
+ }
+
+ _rowIndex = context.getCurrentRow();
+
+ IntFlexArray array = context.getIntFlexArray();
+ int currentCol = context.getCurrentCol();
+
+ // find a cell that is not occupied by cells in previous rows.
+ while (array.getAt(currentCol) > 0) {
+ currentCol++;
+ }
+
+ // ok, now array.getAt(currentCol) == 0
+ _colIndex = currentCol;
+
+ for (int i = 0; i < _colSpan; i++, currentCol++) {
+ array.setAt(currentCol, _rowSpan);
+ }
+ context.setCurrentCol(currentCol);
+ }
+
+ /**
+ * @param tablewidth
+ * table width
+ */
+ public void calculateWidth(TableInfo tableInfo, int tablewidth) {
+ ICSSStyle style = this.getFigure().getCSSStyle();
+ if (style == null) {
+ _cellWidth = -1;
+ } else {
+ Object width = style.getStyleProperty(ICSSPropertyID.ATTR_WIDTH);
+ Length recommendedWidth = (width instanceof Length) ? (Length) width
+ : null;
+
+ int rw = 0;
+ if (recommendedWidth == null || recommendedWidth.getValue() <= 0) {
+ rw = 0;
+ } else {
+ if (recommendedWidth.isPercentage()) {
+ // percentage width is used for remaining width
+ // distribution, so not used here.
+ int colspan = this.getColSpan();
+ for (int i = 0; i < colspan; i++) {
+ tableInfo.setWidthPercentage(this.getColumnIndex() + i,
+ recommendedWidth.getValue() / colspan);
+ }
+ } else {
+ rw = recommendedWidth.getValue();
+ if (!style.isSizeIncludeBorderPadding()) {
+ rw += style.getBorderInsets().getWidth()
+ + style.getPaddingInsets().getWidth();
+ }
+ if (this.getColSpan() == 1) {
+ tableInfo._widthSpecified[this.getColumnIndex()] = true;
+ }
+ }
+
+ }
+ _cellWidth = rw;
+ }
+
+ }
+
+ /**
+ * @param height
+ */
+ public void calculateHeight(TableInfo tableInfo, int tableheight) {
+ ICSSStyle style = this.getFigure().getCSSStyle();
+ if (style == null) {
+ _cellHeight = -1;
+ } else {
+ Object height = style.getStyleProperty(ICSSPropertyID.ATTR_HEIGHT);
+ Length recommendedHeight = (height instanceof Length) ? (Length) height
+ : null;
+
+ int rh = 0;
+ if (recommendedHeight == null || recommendedHeight.getValue() <= 0) {
+ rh = 0;
+ } else {
+ if (recommendedHeight.isPercentage()) {
+ int rowspan = this.getRowSpan();
+ for (int i = 0; i < rowspan; i++) {
+ tableInfo.setHeightPercentage(this.getRowIndex() + i,
+ recommendedHeight.getValue() / rowspan);
+ }
+ } else {
+ rh = recommendedHeight.getValue();
+ }
+ if (!style.isSizeIncludeBorderPadding()) {
+ rh += style.getBorderInsets().getHeight()
+ + style.getPaddingInsets().getHeight();
+ }
+ }
+ _cellHeight = rh;
+ }
+
+ }
+
+ /**
+ * @return
+ */
+ public int getHeight() {
+ return _cellHeight;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfo.java
new file mode 100644
index 000000000..a458c0e62
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfo.java
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableInfo extends TableItemInfo {
+ List _tableHeaderGroups = new ArrayList();
+
+ List _tableTRandTRGs = new ArrayList();
+
+ List _tableFooterGroups = new ArrayList();
+
+ TableCaptionInfo _caption;
+
+ int _columnCount;
+
+ int _rowCount;
+
+ List _cells = null;
+
+ private List _rows = null;
+
+ int _tableWidth; // calculated table width, valid after calling to
+
+ // calculateTableWidth
+
+ int _availableWidth;
+
+ int _tableHeight;
+
+ private int[] _widthPercentage;
+
+ private int[] _heightPercentage;
+
+ boolean[] _widthSpecified;
+
+ /**
+ * @param figure
+ */
+ public TableInfo(ICSSFigure figure) {
+ super(figure);
+ }
+
+ public List getTableHeaderGroups() {
+ return _tableHeaderGroups;
+ }
+
+ public List getTRandTRGs() {
+ return _tableTRandTRGs;
+ }
+
+ public List getTableFooterGroups() {
+ return _tableFooterGroups;
+ }
+
+ public int getColumnCount() {
+ return _columnCount;
+ }
+
+ public int getRowCount() {
+ return _rowCount;
+ }
+
+ protected void constructTable() {
+ List child = getFigure().getChildren();
+ for (int i = 0, size = child.size(); i < size; i++) {
+ IFigure childfigure = (IFigure) child.get(i);
+ if (childfigure instanceof ICSSFigure) {
+ ICSSStyle style = ((ICSSFigure) childfigure).getCSSStyle();
+ if (style != null) {
+ String display = style.getDisplay();
+ if ("table-caption".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ _caption = new TableCaptionInfo(
+ (ICSSFigure) childfigure);
+ } else if ("table-row".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ TableRowInfo rowInfo = new TableRowInfo(
+ (ICSSFigure) childfigure);
+ _tableTRandTRGs.add(rowInfo);
+ } else if ("table-row-group".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ TableRowGroupInfo groupInfo = new TableRowGroupInfo(
+ (ICSSFigure) childfigure);
+ _tableTRandTRGs.add(groupInfo);
+ } else if ("table-header-group".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ TableRowGroupInfo groupInfo = new TableRowGroupInfo(
+ (ICSSFigure) childfigure);
+ _tableHeaderGroups.add(groupInfo);
+ } else if ("table-footer-group".equalsIgnoreCase(display)) //$NON-NLS-1$
+ {
+ TableRowGroupInfo groupInfo = new TableRowGroupInfo(
+ (ICSSFigure) childfigure);
+ _tableFooterGroups.add(groupInfo);
+ } else {
+ // something unexpected inside table
+ }
+ } else {
+ // something unexpected inside table
+ }
+ } else {
+ // something unexpected inside table
+ }
+ }
+
+ TableInfoContext context = new TableInfoContext();
+ // now we have the rows ordered, need to calculate row details now.
+ for (int i = 0, size = _tableHeaderGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableHeaderGroups
+ .get(i);
+ groupInfo.calculateRowGroup(context);
+ }
+ for (int i = 0, size = _tableTRandTRGs.size(); i < size; i++) {
+ Object obj = _tableTRandTRGs.get(i);
+ if (obj instanceof TableRowGroupInfo) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) obj;
+ groupInfo.calculateRowGroup(context);
+ } else {
+ TableRowInfo rowInfo = (TableRowInfo) obj;
+ rowInfo.calculateRow(context);
+ }
+ }
+ for (int i = 0, size = _tableFooterGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableFooterGroups
+ .get(i);
+ groupInfo.calculateRowGroup(context);
+ }
+ context.finishTable();
+
+ _columnCount = context.getColumnCount();
+ _rowCount = context.getRowCount();
+
+ this._widthPercentage = new int[_columnCount];
+ this._heightPercentage = new int[_rowCount];
+
+ this._widthSpecified = new boolean[_columnCount];
+ for (int i = 0; i < _columnCount; i++) {
+ this._widthSpecified[i] = false;
+ }
+ }
+
+ public void setWidthPercentage(int columnIndex, int percentageValue) {
+ if (percentageValue > this._widthPercentage[columnIndex]) {
+ this._widthPercentage[columnIndex] = percentageValue;
+ }
+ }
+
+ public void setHeightPercentage(int rowIndex, int percentageValue) {
+ if (percentageValue > this._heightPercentage[rowIndex]) {
+ this._heightPercentage[rowIndex] = percentageValue;
+ }
+ }
+
+ /**
+ * width percentage will be used to calculate remaining width distribution.
+ *
+ * @return
+ */
+ public int[] getWidthPercentages() {
+ return this._widthPercentage;
+ }
+
+ public int[] getHeightPercentages() {
+ return this._heightPercentage;
+ }
+
+ public List getRows() {
+ if (_rows == null) {
+ this._rows = new ArrayList();
+
+ for (int i = 0, size = _tableHeaderGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableHeaderGroups
+ .get(i);
+ _rows.addAll(groupInfo.getRowList());
+ }
+ for (int i = 0, size = _tableTRandTRGs.size(); i < size; i++) {
+ Object obj = _tableTRandTRGs.get(i);
+ if (obj instanceof TableRowGroupInfo) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) obj;
+ _rows.addAll(groupInfo.getRowList());
+ } else {
+ TableRowInfo rowInfo = (TableRowInfo) obj;
+ _rows.add(rowInfo);
+ }
+ }
+ for (int i = 0, size = _tableFooterGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableFooterGroups
+ .get(i);
+ _rows.addAll(groupInfo.getRowList());
+ }
+ }
+ return _rows;
+ }
+
+ public List getCells() {
+ if (_cells == null) {
+ _cells = new ArrayList();
+
+ for (int i = 0, size = _tableHeaderGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableHeaderGroups
+ .get(i);
+ groupInfo.getCells(_cells);
+ }
+ for (int i = 0, size = _tableTRandTRGs.size(); i < size; i++) {
+ Object obj = _tableTRandTRGs.get(i);
+ if (obj instanceof TableRowGroupInfo) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) obj;
+ groupInfo.getCells(_cells);
+ } else {
+ TableRowInfo rowInfo = (TableRowInfo) obj;
+ rowInfo.getCells(_cells);
+ }
+ }
+ for (int i = 0, size = _tableFooterGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableFooterGroups
+ .get(i);
+ groupInfo.getCells(_cells);
+ }
+ }
+ return _cells;
+ }
+
+ /**
+ * @param containerWidth
+ * if the width specification is percentage, then will use
+ * container width.
+ */
+ public void calculateWidth(int contentWidth, int availableWidth) {
+ _tableWidth = contentWidth;
+ _availableWidth = availableWidth;
+
+ // next calculate cell width
+ List cells = getCells();
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
+ cellinfo.calculateWidth(this, _tableWidth);
+ }
+ }
+
+ public void calculateHeight(int contentHeight) {
+ _tableHeight = contentHeight;
+
+ List rows = getRows();
+ for (int i = 0, size = rows.size(); i < size; i++) {
+ TableRowInfo rowinfo = (TableRowInfo) rows.get(i);
+ rowinfo.calculateHeight(this, _tableHeight);
+ }
+
+ // next calculate cell width
+ List cells = getCells();
+ for (int i = 0, size = cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
+ cellinfo.calculateHeight(this, _tableHeight);
+ }
+ }
+
+ /**
+ * @return
+ */
+ public int getTableWidth() {
+ return _tableWidth;
+ }
+
+ /**
+ * @param figure
+ * @return
+ */
+ public TableRowGroupInfo findGroupInfo(CSSFigure figure) {
+ for (int i = 0, size = _tableHeaderGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableHeaderGroups
+ .get(i);
+ if (figure == groupInfo.getFigure()) {
+ return groupInfo;
+ }
+ }
+ for (int i = 0, size = _tableTRandTRGs.size(); i < size; i++) {
+ Object obj = _tableTRandTRGs.get(i);
+ if (obj instanceof TableRowGroupInfo) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) obj;
+ if (figure == groupInfo.getFigure()) {
+ return groupInfo;
+ }
+
+ }
+ }
+ for (int i = 0, size = _tableFooterGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableFooterGroups
+ .get(i);
+ if (figure == groupInfo.getFigure()) {
+ return groupInfo;
+ }
+ }
+ return null; // should not happen.
+ }
+
+ /**
+ * @param figure
+ * @return
+ */
+ public TableRowInfo findRowInfo(CSSFigure figure) {
+ for (int i = 0, size = _tableHeaderGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableHeaderGroups
+ .get(i);
+ TableRowInfo rowinfo = groupInfo.findRowInfo(figure);
+ if (rowinfo != null) {
+ return rowinfo;
+ }
+ }
+ for (int i = 0, size = _tableTRandTRGs.size(); i < size; i++) {
+ Object obj = _tableTRandTRGs.get(i);
+ if (obj instanceof TableRowGroupInfo) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) obj;
+ TableRowInfo rowinfo = groupInfo.findRowInfo(figure);
+ if (rowinfo != null) {
+ return rowinfo;
+ }
+ } else if (obj instanceof TableRowInfo) {
+ TableRowInfo info = (TableRowInfo) obj;
+ if (figure == info.getFigure()) {
+ return info;
+ }
+ }
+ }
+ for (int i = 0, size = _tableFooterGroups.size(); i < size; i++) {
+ TableRowGroupInfo groupInfo = (TableRowGroupInfo) _tableFooterGroups
+ .get(i);
+ TableRowInfo rowinfo = groupInfo.findRowInfo(figure);
+ if (rowinfo != null) {
+ return rowinfo;
+ }
+ }
+ return null; // should not happen.
+ }
+
+ /**
+ *
+ * @return
+ */
+ public boolean hasWidthPercentage() {
+ for (int i = 0; i < this._widthPercentage.length; i++) {
+ if (this._widthPercentage[i] > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfoContext.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfoContext.java
new file mode 100644
index 000000000..4cd3fbdd2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableInfoContext.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.utils.IntFlexArray;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableInfoContext {
+ static Logger _log = PDPlugin.getLogger(TableInfoContext.class);
+
+ int _currentCol = 0;
+
+ int _currentRow = 0;
+
+ IntFlexArray _array = new IntFlexArray();
+
+ int _colCount = 0;
+
+ int _rowCount = 0;
+
+ /**
+ *
+ */
+ public TableInfoContext() {
+ }
+
+ /**
+ * @return
+ */
+ public IntFlexArray getIntFlexArray() {
+ return _array;
+ }
+
+ /**
+ * @return
+ */
+ public int getCurrentCol() {
+ return _currentCol;
+ }
+
+ public void setCurrentCol(int currentcol) {
+ _currentCol = currentcol;
+ }
+
+ public int getCurrentRow() {
+ return _currentRow;
+ }
+
+ /**
+ * @return
+ */
+ public int getColumnCount() {
+ return _colCount;
+ }
+
+ /**
+ *
+ */
+ public void finishRow() {
+ if (_currentCol > _colCount) {
+ _colCount = _currentCol;
+ }
+ _currentCol = 0;
+ _currentRow++;
+ for (int i = 0; i < _colCount; i++) {
+ if (_array.getAt(i) > 0) {
+ _array.setAt(i, _array.getAt(i) - 1);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public void finishTable() {
+ // do some checking here.
+ int additionalRow = 0;
+ for (int i = 0; i < _colCount; i++) {
+ if (_array.getAt(i) > additionalRow) {
+ additionalRow = _array.getAt(i);
+ }
+ }
+ _rowCount = _currentRow + additionalRow;
+ }
+
+ /**
+ *
+ */
+ public void finishRowGroup() {
+ }
+
+ /**
+ * @return
+ */
+ public int getRowCount() {
+ return _rowCount;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableItemInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableItemInfo.java
new file mode 100644
index 000000000..33c6e12e3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableItemInfo.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableItemInfo {
+ public ICSSFigure _figure;
+
+ /**
+ *
+ */
+ public TableItemInfo(ICSSFigure figure) {
+ _figure = figure;
+ }
+
+ public ICSSFigure getFigure() {
+ return _figure;
+ }
+
+ public ICSSStyle getStyle() {
+ return _figure.getCSSStyle();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowGroupInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowGroupInfo.java
new file mode 100644
index 000000000..d9ae2feb3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowGroupInfo.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableRowGroupInfo extends TableItemInfo {
+ List _rowList = new ArrayList();
+
+ private int _rowIndex;
+
+ private int _rowCount;
+
+ /**
+ * @param figure
+ */
+ public TableRowGroupInfo(ICSSFigure figure) {
+ super(figure);
+ }
+
+ public List getRowList() {
+ return _rowList;
+ }
+
+ public int getRowIndex() {
+ return _rowIndex;
+ }
+
+ public int getRowCount() {
+ return this._rowCount;
+ }
+
+ /**
+ * @param context
+ */
+ public void calculateRowGroup(TableInfoContext context) {
+ this._rowIndex = context.getCurrentRow();
+ List children = getFigure().getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ IFigure childfigure = (IFigure) children.get(i);
+ if (childfigure instanceof ICSSFigure) {
+ ICSSStyle childstyle = ((ICSSFigure) childfigure).getCSSStyle();
+ if (childstyle != null
+ && "table-row"
+ .equalsIgnoreCase(childstyle.getDisplay())) {
+ TableRowInfo rowInfo = new TableRowInfo(
+ (ICSSFigure) childfigure);
+ _rowList.add(rowInfo);
+ rowInfo.calculateRow(context);
+ } else {
+ // skip
+ }
+ } else {
+ // skip
+ }
+ }
+ context.finishRowGroup();
+ this._rowCount = context.getCurrentRow() - this._rowIndex;
+ }
+
+ /**
+ * @param _cells
+ */
+ public void getCells(List _cells) {
+ for (int i = 0, size = _rowList.size(); i < size; i++) {
+ TableRowInfo rowInfo = (TableRowInfo) _rowList.get(i);
+ rowInfo.getCells(_cells);
+ }
+ }
+
+ /**
+ * @param figure
+ * @return
+ */
+ public TableRowInfo findRowInfo(CSSFigure figure) {
+ for (int i = 0, size = _rowList.size(); i < size; i++) {
+ TableRowInfo rowInfo = (TableRowInfo) _rowList.get(i);
+ if (figure == rowInfo.getFigure()) {
+ return rowInfo;
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowInfo.java
new file mode 100644
index 000000000..f305d0dfd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/layout/table/TableRowInfo.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.layout.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableRowInfo extends TableItemInfo {
+ List _cells = new ArrayList();
+
+ int _rowIndex;
+
+ private int _rowHeight;
+
+ /**
+ * @param figure
+ */
+ public TableRowInfo(ICSSFigure figure) {
+ super(figure);
+ }
+
+ public List getCells() {
+ return _cells;
+ }
+
+ public int getRowIndex() {
+ return _rowIndex;
+ }
+
+ public int getSpecifiedRowHeight() {
+ return _rowHeight;
+ }
+
+ /**
+ * @param context
+ */
+ public void calculateRow(TableInfoContext context) {
+ this._rowIndex = context.getCurrentRow();
+
+ List children = getFigure().getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ IFigure childfigure = (IFigure) children.get(i);
+ if (childfigure instanceof ICSSFigure) {
+ ICSSStyle childstyle = ((ICSSFigure) childfigure).getCSSStyle();
+ if (childstyle != null) {
+ String display = childstyle.getDisplay();
+ if ("table-cell".equalsIgnoreCase(display)) {
+ TableCellInfo cellInfo = new TableCellInfo(
+ (ICSSFigure) childfigure);
+ cellInfo.calculateCellInfo(context);
+ _cells.add(cellInfo);
+ } else {
+ // skip
+ }
+ }
+ } else {
+ // skip
+ }
+ }
+ // ok, we have finished a row
+ context.finishRow();
+ }
+
+ /**
+ * @param _cells2
+ */
+ public void getCells(List cells) {
+ cells.addAll(this._cells);
+ }
+
+ /**
+ * @param figure
+ * @return
+ */
+ public TableCellInfo getCellInfo(CSSFigure figure) {
+ for (int i = 0, size = _cells.size(); i < size; i++) {
+ TableCellInfo cellinfo = (TableCellInfo) _cells.get(i);
+ if (cellinfo.getFigure() == figure) {
+ return cellinfo;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param info
+ * @param height
+ */
+ public void calculateHeight(TableInfo info, int tableHeight) {
+ ICSSStyle style = this.getFigure().getCSSStyle();
+ if (style == null) {
+ this._rowHeight = -1;
+ } else {
+ Object height = style.getStyleProperty(ICSSPropertyID.ATTR_HEIGHT);
+ Length recommendedHeight = (height instanceof Length) ? (Length) height
+ : null;
+
+ int rh = 0;
+ if (recommendedHeight == null || recommendedHeight.getValue() <= 0) {
+ rh = 0;
+ } else {
+ if (recommendedHeight.isPercentage()) {
+ // not supported.
+ } else {
+ rh = recommendedHeight.getValue();
+ }
+ if (rh > 0 && !style.isSizeIncludeBorderPadding()) {
+ rh += style.getBorderInsets().getHeight()
+ + style.getPaddingInsets().getHeight();
+ }
+ }
+ this._rowHeight = rh;
+ }
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSHtmlListStyleData.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSHtmlListStyleData.java
new file mode 100644
index 000000000..279c092f9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSHtmlListStyleData.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+
+/**
+ * @author mengbo
+ */
+public class CSSHtmlListStyleData {
+ public final static int LIST_T_IMAGE = 0;
+
+ public final static int LIST_T_DISC = 1;
+
+ public final static int LIST_T_CIRCLE = 2;
+
+ public final static int LIST_T_SQUARE = 3;
+
+ public final static int LIST_T_DECIMAL = 0x11;
+
+ public final static int LIST_T_DECIMAL_LEADING_ZERO = 0x12;
+
+ public final static int LIST_T_LOWER_ALPHA = 0x13;
+
+ public final static int LIST_T_LOWER_ROMAN = 0x14;
+
+ public final static int LIST_T_UPPER_ALPHA = 0x15;
+
+ public final static int LIST_T_UPPER_ROMAN = 0x16;
+
+ private CSSMarkerStyleData _markerStyleData;
+
+ private Image _markerImage;
+
+ private int _type;
+
+ public boolean isDefaultPicture() {
+ return (_type & 0xf) != 0;
+ }
+
+ private String getResolvedURL() {
+ String textValue = _markerStyleData.getTextContent();
+ URIResolver resolver = null;// FIXME: this is not implemented yet.
+ // DesignerPropertyTool.getModel().getResolver();
+ if (textValue != null && textValue.length() > 0) {
+ return resolver.getLocationByURI(textValue);
+ }
+ return "";
+ }
+
+ /**
+ * @return Returns the markerImage.
+ */
+ public Image getMarkerImage() {
+ if (!this.isImage()) {
+ return null;
+ }
+ if (_markerImage == null) {
+ String uri = this.getResolvedURL();
+ _markerImage = new Image(null, uri);
+ }
+ return _markerImage;
+ }
+
+ /**
+ * @return Returns the type.
+ */
+ public int getType() {
+ return _type;
+ }
+
+ public void setType(String type) {
+
+ this._type = toTypeInt(type);
+ }
+
+ /**
+ * @return Returns the markerString.
+ */
+ public String getTextValue(int index) {
+ if (!this.isText()) {
+ return null;
+ }
+ // ICounter counter = CounterFactory.getInstance().getCounter(_type);
+ return "";
+
+ }
+
+ public boolean isText() {
+ return (_type & 0xf0) != 0;
+ }
+
+ public boolean isImage() {
+ return (_type == LIST_T_IMAGE);
+ }
+
+ public static int toTypeInt(String type) {
+ if (type.equalsIgnoreCase(ICSSPropertyID.VAL_DECIMAL)) {
+ return LIST_T_DECIMAL;
+ } else if (type
+ .equalsIgnoreCase(ICSSPropertyID.VAL_DECIMAL_LEADING_ZERO)) {
+ return LIST_T_DECIMAL_LEADING_ZERO;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_DISC)) {
+ return LIST_T_DISC;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_CIRCLE)) {
+ return LIST_T_CIRCLE;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_SQUARE)) {
+ return LIST_T_SQUARE;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_IMAGE)) {
+ return LIST_T_IMAGE;
+ }
+ ;
+ return 0;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSMarkerStyleData.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSMarkerStyleData.java
new file mode 100644
index 000000000..0fcbb6e39
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CSSMarkerStyleData.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+import java.util.Vector;
+
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+
+/**
+ * @author mengbo
+ */
+public class CSSMarkerStyleData {
+ private Vector _content;
+
+ private String _textContent;
+
+ private int _Offset;
+
+ private boolean _isOutside;
+
+ /**
+ * @return Returns the isBefore.
+ */
+ public boolean isOutside() {
+ return _isOutside;
+ }
+
+ /**
+ * @param isOutside
+ * The isBefore to set.
+ */
+ public void setPosition(String position) {
+ if (position == ICSSPropertyID.VAL_INSIDE) {
+ _isOutside = false;
+ } else if (position == ICSSPropertyID.VAL_OUTSIDE) {
+ _isOutside = true;
+ }
+ }
+
+ /**
+ * @return Returns the _Offset.
+ */
+ public int getOffset() {
+ return _Offset;
+ }
+
+ /**
+ * @param offset
+ * The _Offset to set.
+ */
+ public void setOffset(int offset) {
+ _Offset = offset;
+ }
+
+ /**
+ * @return Returns the _textValue.
+ */
+ public String getTextContent() {
+ return _textContent;
+ }
+
+ /**
+ * @param value
+ * The _textValue to set.
+ */
+ public void setTextContent(String value) {
+ _textContent = value;
+ }
+
+ public Object getNextElement() {
+ if (_content == null || _content.size() == 0) {
+ return null;
+ }
+ return _content.remove(0);
+ }
+
+ public void setContent(Vector content) {
+ _content = content;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ContentObject.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ContentObject.java
new file mode 100644
index 000000000..5d666f725
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ContentObject.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+/**
+ * A simple template objec, when we resole content in detail, we will create
+ * more complicated object reference structure.
+ *
+ * @author mengbo
+ */
+public class ContentObject {
+ private ICounterValueGenerator _counter;
+
+ /**
+ * @return Returns the _counter.
+ */
+ public ICounterValueGenerator getCounter() {
+ return _counter;
+ }
+
+ /**
+ * @param _counter
+ * The _counter to set.
+ */
+ public void setCounter(ICounterValueGenerator counter) {
+ this._counter = counter;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterHelper.java
new file mode 100644
index 000000000..6519846bf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterHelper.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSPrimitiveValue;
+import org.w3c.dom.css.CSSPrimitiveValue;
+
+/**
+ * @author mengbo
+ */
+public class CounterHelper {
+ public final static int LIST_T_IMAGE = 0;
+
+ public final static int LIST_T_DISC = 1;
+
+ public final static int LIST_T_CIRCLE = 2;
+
+ public final static int LIST_T_SQUARE = 3;
+
+ public final static int LIST_T_DECIMAL = 0x11;
+
+ public final static int LIST_T_DECIMAL_LEADING_ZERO = 0x12;
+
+ public final static int LIST_T_LOWER_ALPHA = 0x13;
+
+ public final static int LIST_T_LOWER_ROMAN = 0x14;
+
+ public final static int LIST_T_UPPER_ALPHA = 0x15;
+
+ public final static int LIST_T_UPPER_ROMAN = 0x16;
+
+ public final static int LIST_T_LOWER_GREEK = 0x21;
+
+ public final static int LIST_T_ARMENIAN = 0x22;
+
+ public final static int LIST_T_GEORGIAN = 0x23;
+
+ public final static int LIST_T_NONE = 0x24;
+
+ // /**
+ // * Collect counters declaration from node and its parents
+ // *
+ // * @param style
+ // * @param counters
+ // * @return
+ // */
+ // public static void getCounters(ICSSStyle style, HashMap counters)
+ // {
+ // processCounterReset(style, counters);
+ // Object content = style.getStyleProperty(ICSSPropertyID.ATTR_CONTENT);
+ // // content counter could be reference or creation of new one.
+ // if (content != null && content != ICSSPropertyMeta.NOT_SPECIFIED)
+ // {
+ // // XXX: what 's the content.
+ // ContentObject contentObject = null;
+ // Object counter = null;
+ // if (content instanceof List)
+ // {
+ // // TODO: we only deal with one currently.
+ // contentObject = (ContentObject) ((List) content).get(0);
+ // }
+ // else if (content instanceof ContentObject)
+ // {
+ // contentObject = (ContentObject) content;
+ // }
+ // if (style.getParentStyle() != null)
+ // {
+ // String identifier = contentObject.getCounter().getIdentifier();
+ // counter = style.getParentStyle().findCounter(identifier, false);
+ // if (counter == null)
+ // {
+ // // no reference, then create it.
+ // counter = contentObject.getCounter();
+ // }
+ // }
+ // Assert.isTrue(counter != null);
+ // ((Counter2) counter).regist(style);
+ // counters.put(((Counter2) counter).getIdentifier(), counter);
+ // }
+ // // counter-increment is reference.
+ // processCounterIncrement(style/* , counters */);
+ // }
+
+ /**
+ * @param style
+ * @param counters
+ */
+ public static void processCounterReset(ICSSStyle style, HashMap counters) {
+ Assert.isTrue(style != null && counters != null);
+ // counter-reset will create new one.
+ Object counterResets = style
+ .getStyleProperty(ICSSPropertyID.ATTR_COUNTER_RESET);
+ if ((counterResets) != null
+ && counterResets != ICSSPropertyMeta.NOT_SPECIFIED) {
+ if (counterResets instanceof List) {
+ List crList = (List) counterResets;
+ for (int i = 0, n = crList.size(); i < n; i++) {
+ ResetObject rObject = (ResetObject) crList.get(i);
+ String name = rObject.getCounterName();
+ Object counter = null;
+ if (counters.size() > 0 && counters.containsKey(name)) {
+ // Already resolved
+ counter = counters.get(name);
+ }
+ if (counter != null) {
+ if (rObject.getInitial() != null) {
+ ((ICounterValueGenerator) counter)
+ .resetCount(rObject.getInitial().intValue());
+ } else {
+ counter = ((ICounterValueGenerator) counter)
+ .resetCount();
+ }
+ counters.put(((ICounterValueGenerator) counter)
+ .getIdentifier(), counter);
+ } else {
+ // create new one
+ Object listStyle = style
+ .getStyleProperty(ICSSPropertyID.ATTR_LIST_STYLE_TYPE);
+ if (listStyle instanceof String) {
+ counter = new CounterValueGenerator(name,
+ (String) listStyle, null, style);
+ if (rObject.getInitial() != null) {
+ ((ICounterValueGenerator) counter)
+ .resetCount(rObject.getInitial()
+ .intValue());
+ } else {
+ counter = ((ICounterValueGenerator) counter)
+ .resetCount();
+ }
+ }
+ counters.put(((ICounterValueGenerator) counter)
+ .getIdentifier(), counter);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param style
+ * @param counters
+ */
+ public static void processCounterIncrement(ICSSStyle style/*
+ * , HashMap
+ * counters
+ */) {
+ Object counterIncrements = style
+ .getStyleProperty(ICSSPropertyID.ATTR_COUNTER_INCREMENT);
+ if (counterIncrements != null
+ && counterIncrements != ICSSPropertyMeta.NOT_SPECIFIED) {
+ if (counterIncrements instanceof List) {
+ List crList = (List) counterIncrements;
+ for (int i = 0, n = crList.size(); i < n; i++) {
+ IncrementObject rObject = (IncrementObject) crList.get(i);
+ String name = rObject.getCounterName();
+ Object counter = null;
+ counter = style.findCounter(name, true);
+ if (counter != null) {
+ if (HTMLListInfoHelper.getValueInt(style) == null) {
+ if (rObject.getIncrement() != null) {
+ ((ICounterValueGenerator) counter)
+ .increase(rObject.getIncrement()
+ .intValue());
+ } else {
+ ((ICounterValueGenerator) counter).increase();
+ }
+ } else {
+ ((ICounterValueGenerator) counter)
+ .setCount(HTMLListInfoHelper
+ .getValueInt(style));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static boolean isImage(ICSSStyle style) {
+ return false;
+ }
+
+ public static boolean isText(ICSSStyle style) {
+ String display = style.getDisplay();
+ Object styleType = style
+ .getStyleProperty(ICSSPropertyID.ATTR_LIST_STYLE_TYPE);
+ return (((String) display)
+ .equalsIgnoreCase(ICSSPropertyID.VAL_LIST_ITEM) //
+ && styleType instanceof String //
+ && !CounterValueGenerator.NON_STRING_TYPES.contains(styleType));
+ }
+
+ public static boolean isNodeImage(ICSSStyle style) {
+ return false;
+ }
+
+ public static int getType(ICSSStyle style) {
+ Object type = style
+ .getStyleProperty(ICSSPropertyID.ATTR_LIST_STYLE_TYPE);
+ if (type instanceof String) {
+ return toTypeInt((String) type);
+ } else {
+ return -1;
+ }
+ }
+
+ public static int toTypeInt(String type) {
+
+ if (type.equalsIgnoreCase(ICSSPropertyID.VAL_DECIMAL)) {
+ return LIST_T_DECIMAL;
+ } else if (type
+ .equalsIgnoreCase(ICSSPropertyID.VAL_DECIMAL_LEADING_ZERO)) {
+ return LIST_T_DECIMAL_LEADING_ZERO;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_DISC)) {
+ return LIST_T_DISC;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_CIRCLE)) {
+ return LIST_T_CIRCLE;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_SQUARE)) {
+ return LIST_T_SQUARE;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_IMAGE)) {
+ return LIST_T_IMAGE;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_UPPER_LATIN)) {
+ return LIST_T_UPPER_ALPHA;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_UPPER_ALPHA)) {
+ return LIST_T_UPPER_ALPHA;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_LOWER_LATIN)) {
+ return LIST_T_LOWER_ALPHA;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_LOWER_ALPHA)) {
+ return LIST_T_LOWER_ALPHA;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_UPPER_ROMAN)) {
+ return LIST_T_UPPER_ROMAN;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_LOWER_ROMAN)) {
+ return LIST_T_LOWER_ROMAN;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_LOWER_GREEK)) {
+ return LIST_T_LOWER_GREEK;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_ARMENIAN)) {
+ return LIST_T_ARMENIAN;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_GEORGIAN)) {
+ return LIST_T_GEORGIAN;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_NONE)) {
+ return LIST_T_NONE;
+ }
+ return 0;
+ }
+
+ // TODO: for future use we need a new ContentObject to hold other objects
+ // declares in css style.
+
+ // public static ContentObject getContentObject(ICSSStyle style)
+ // {
+ // // TODO: currently we only fetch first counter in case there are more
+ // than one counters.
+ // if (style.getStyleProperty(ICSSPropertyID.ATTR_CONTENT) !=
+ // ICSSPropertyMeta.NOT_SPECIFIED)
+ // {
+ // Object content = style.getStyleProperty(ICSSPropertyID.ATTR_CONTENT);
+ // Object object = null;
+ // if (content instanceof List)
+ // {
+ // object = ((List) content).get(0);
+ // }
+ // else if (content instanceof ContentObject)
+ // {
+ // object = content;
+ // }
+ // if (object instanceof ContentObject)
+ // {
+ // return (ContentObject) content;
+ // }
+ // }
+ // return null;
+ // }
+
+ public static boolean isIdentifier(Object cssValue) {
+ return (cssValue instanceof ICSSPrimitiveValue)
+ && ((ICSSPrimitiveValue) cssValue).getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT;
+ }
+
+ public static boolean isNumber(Object cssValue) {
+ return cssValue instanceof ICSSPrimitiveValue
+ && ((ICSSPrimitiveValue) cssValue).getPrimitiveType() == ICSSPrimitiveValue.CSS_INTEGER;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterValueGenerator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterValueGenerator.java
new file mode 100644
index 000000000..8721b4bde
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/CounterValueGenerator.java
@@ -0,0 +1,445 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+
+/**
+ * The counter is used to generate automatic conters and numbering for list
+ * item. XXX: what do we deal with psedo? and we need to refer to web tools
+ * content to consult for style content.
+ *
+ * @author mengbo
+ */
+public class CounterValueGenerator implements ICounterValueGenerator {
+ private final static int DEFAULT_INITIAL_VALUE = 0;
+
+ public static final Set STRING_TYPES = new HashSet();
+
+ public static final Set NON_STRING_TYPES = new HashSet();
+ static {
+ NON_STRING_TYPES.add("disc");
+ NON_STRING_TYPES.add("circle");
+ NON_STRING_TYPES.add("square");
+ STRING_TYPES.add("decimal");
+ STRING_TYPES.add("decimal-leading-zero");
+ STRING_TYPES.add("lower-roman");
+ STRING_TYPES.add("upper-roman");
+ STRING_TYPES.add("lower-greek");
+ STRING_TYPES.add("lower-alpha");
+ STRING_TYPES.add("lower-latin");
+ STRING_TYPES.add("upper-alpha");
+ STRING_TYPES.add("upper-latin");
+ STRING_TYPES.add("hebrew");
+ STRING_TYPES.add("armenian");
+ STRING_TYPES.add("georgian");
+ STRING_TYPES.add("cjk-ideographic");
+ STRING_TYPES.add("hiragana");
+ STRING_TYPES.add("katakana");
+ STRING_TYPES.add("hiragana-iroha");
+ STRING_TYPES.add("katakana-iroha");
+ };
+
+ private final static int DEFAULT_INCREMENT = 1;
+
+ private boolean _first = true;
+
+ private Integer _initial;
+
+ private List _visitors;
+
+ private int _count;
+
+ private String _identifier;
+
+ private String _styleType;
+
+ private String _seperator;
+
+ private ICSSStyle _style;
+
+ public CounterValueGenerator(String identifier, String styleType,
+ String seperator, ICSSStyle style) {
+ _identifier = identifier;
+ _styleType = styleType;
+ _seperator = seperator;
+ _style = style;
+ if (HTMLListInfoHelper.getStartInt(style) != null) {
+ _count = HTMLListInfoHelper.getStartInt(style).intValue();
+ } else {
+ _count = DEFAULT_INITIAL_VALUE;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.w3c.dom.css.Counter#getIdentifier()
+ */
+ public String getIdentifier() {
+ // TODO Auto-generated method stub
+ return _identifier;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.w3c.dom.css.Counter#getListStyle()
+ */
+ public String getListStyle() {
+ // TODO Auto-generated method stub
+ return _styleType;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.w3c.dom.css.Counter#getSeparator()
+ */
+ public String getSeparator() {
+ // TODO Auto-generated method stub
+ return _seperator;
+ }
+
+ // /**
+ // * @return Returns the type.
+ // */
+ // public String getType()
+ // {
+ // return _styleType;
+ // }
+
+ // /**
+ // * @return Returns the markerString.
+ // */
+ // public String getTextValue()
+ // {
+ // Assert.isTrue(this.isText());
+ // _index = getDeclaredIndex();
+ // Node container = findParentComtainer();
+ // if (container == null)
+ // {
+ // // what condition?
+ // return "";
+ // }
+ // String exp = "";
+ // int startIndex = getStartIndex(container);
+ // int maxLength = calculateMaxlength(container, 0) + startIndex - 1;
+ // Assert.isTrue(maxLength > 0);
+ // if (_index == -1)
+ // {
+ // // no declared value
+ // calculateIndex(container);
+ // Assert.isTrue(_index > -1);
+ // exp = Integer.toString(_index + startIndex);
+ // }
+ // else
+ // {
+ // exp = Integer.toString(_index);
+ // }
+ // if (getType() == CounterHelper.LIST_T_DECIMAL)
+ // {
+ // exp = appendSuffix(exp, Integer.toString(maxLength).length() -
+ // exp.length());
+ // }
+ // else if (getType() == CounterHelper.LIST_T_DECIMAL_LEADING_ZERO)
+ // {
+ // exp = addPrefix(exp, maxLength - exp.length());
+ // }
+ // return exp + ".";
+ //
+ // }
+
+ // private String addPrefix(String exp, int length)
+ // {
+ // while (length > 0)
+ // {
+ // exp = "0" + exp;
+ // length--;
+ // }
+ // return exp;
+ // }
+ //
+ // private String appendSuffix(String exp, int length)
+ // {
+ // while (length > 0)
+ // {
+ // exp = exp + " ";
+ // length--;
+ // }
+ // return exp;
+ // }
+
+ // private boolean calculateIndex(Node node)
+ // {
+ // if (node == _node)
+ // {
+ // _index++;
+ // return true;
+ // }
+ // String name = node.getNodeName();
+ // if (name != null && name.equalsIgnoreCase("li"))
+ // {
+ // _index++;
+ // }
+ // if (!node.hasChildNodes())
+ // {
+ // return false;
+ // }
+ // node = node.getFirstChild();
+ // while (node != null)
+ // {
+ // name = node.getNodeName();
+ // if (name != null && !(name.equalsIgnoreCase("ul") ||
+ // name.equalsIgnoreCase("ol")))
+ // {
+ // if (calculateIndex(node))
+ // {
+ // return true;
+ // }
+ // }
+ // node = node.getNextSibling();
+ // }
+ // return false;
+ // }
+
+ // This method may be refered for the zero-leading calculation.
+ // private int calculateMaxlength(Node node, int index)
+ // {
+ // String name = node.getNodeName();
+ // if (name != null && name.equalsIgnoreCase("li"))
+ // {
+ // index++;
+ // }
+ // if (!node.hasChildNodes())
+ // {
+ // return index;
+ // }
+ // node = node.getFirstChild();
+ // while (node != null)
+ // {
+ // name = node.getNodeName();
+ // if (name != null && !(name.equalsIgnoreCase("ul") ||
+ // name.equalsIgnoreCase("ol")))
+ // {
+ // index = calculateMaxlength(node, index);
+ // }
+ // node = node.getNextSibling();
+ // }
+ // return index;
+ // }
+ //
+
+ // private int getStartIndex(Node container)
+ // {
+ // String value = ((Element) container).getAttribute("start");
+ // try
+ // {
+ // int index = Integer.parseInt(value);
+ // if (index < 0)
+ // {
+ // return 1;
+ // }
+ // return index;
+ // }
+ // catch (Exception e)
+ // {
+ // return 1;
+ // }
+ // }
+
+ // private boolean isStringTyped(ICSSStyle style)
+ // {
+ // style.getStyleProperty("list-style-type");
+ // return true;
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#clone()
+ */
+ protected Object clone() throws CloneNotSupportedException {
+ CounterValueGenerator newInstance = new CounterValueGenerator(
+ _identifier, _styleType, _seperator, _style);
+ return newInstance;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.Counter2#increase()
+ */
+ public void increase(int increment) {
+ if (!_first || HTMLListInfoHelper.getStartInt(_style) == null) {
+ _count += increment;
+ }
+ _first = false;
+ }
+
+ public void increase() {
+ increase(DEFAULT_INCREMENT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.Counter2#setCount()
+ */
+ public ICounterValueGenerator resetCount() {
+ try {
+ ICounterValueGenerator counter = (ICounterValueGenerator) this
+ .clone();
+ _initial = null;
+ _count = HTMLListInfoHelper.getStartInt(_style) != null ? HTMLListInfoHelper
+ .getStartInt(_style).intValue()
+ : DEFAULT_INITIAL_VALUE;
+ return counter;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ /**
+ * @return Returns the _initial.
+ */
+ public int getInitial() {
+ if (HTMLListInfoHelper.getStartInt(_style) != null) {
+ return HTMLListInfoHelper.getStartInt(_style).intValue();
+ } else {
+ return _initial != null ? _initial.intValue()
+ : DEFAULT_INITIAL_VALUE;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.Counter2#setCount()
+ */
+ public ICounterValueGenerator resetCount(int initial) {
+ try {
+ CounterValueGenerator counter = (CounterValueGenerator) this
+ .clone();
+ _initial = new Integer(initial);
+ _count = initial;
+ return counter;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator#setCount(org.eclipse.jst.pagedesigner.css2.list.HTMLListInfo)
+ */
+ public void setCount(Integer value) {
+ if (value != null) {
+ _count = value.intValue();
+ _first = false;
+ }
+ }
+
+ // /**
+ // * The clients of this counter need to regist them.
+ // *
+ // * @see
+ // org.eclipse.jst.pagedesigner.css2.list.Counter2#regist(java.lang.Object)
+ // */
+ // public void regist(Object caller)
+ // {
+ // Assert.isTrue(caller instanceof ICSSStyle);
+ // if (_visitors == null)
+ // {
+ // _visitors = new LinkedList();
+ // }
+ // if (!_visitors.contains(caller))
+ // {
+ // _visitors.add(caller);
+ // }
+ // }
+ //
+ // /**
+ // * (non-Javadoc)
+ // *
+ // * @see
+ // org.eclipse.jst.pagedesigner.css2.list.Counter2#unregist(java.lang.Object)
+ // */
+ // public void unregist(Object caller)
+ // {
+ // if (_visitors.contains(caller))
+ // {
+ // _visitors.remove(caller);
+ // }
+ // }
+
+ /**
+ * Return the int value.
+ *
+ * @author mengbo
+ */
+ public int getCurrentCount() {
+ return _count;
+ }
+
+ /**
+ * Currently we recalculate the count, to enhance the performance, we may
+ * use _count, but this requires delicate synchronization when the
+ * calculation is looped.
+ */
+ public Integer getCount(Object oCaller) {
+ Assert.isTrue(oCaller instanceof ICSSStyle && _visitors != null
+ && _visitors.size() > 0);
+ ICSSStyle caller = (ICSSStyle) oCaller;
+ if (!_visitors.contains(caller)) {
+ return null;
+ }
+ int result = getInitial();
+
+ for (int i = 0, n = _visitors.size(); i < n; i++) {
+ ICSSStyle style = (ICSSStyle) _visitors.get(i);
+ // get the count;
+ Object counterIncrements = style
+ .getStyleProperty(ICSSPropertyID.ATTR_COUNTER_INCREMENT);
+ if (counterIncrements != null
+ && counterIncrements != ICSSPropertyMeta.NOT_SPECIFIED) {
+ if (counterIncrements instanceof List) {
+ List crList = (List) counterIncrements;
+ for (int j = 0, nn = crList.size(); j < nn; j++) {
+ IncrementObject rObject = (IncrementObject) crList
+ .get(j);
+ String name = rObject.getCounterName();
+ if (getIdentifier().equalsIgnoreCase(name)) {
+ if (rObject.getIncrement() != null) {
+ result += rObject.getIncrement().intValue();
+ } else {
+ result += DEFAULT_INCREMENT;
+ }
+ }
+ }
+ }
+ }
+ if (style == caller) {
+ return new Integer(result);
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/HTMLListInfoHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/HTMLListInfoHelper.java
new file mode 100644
index 000000000..01b660fdf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/HTMLListInfoHelper.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.style.AbstractStyle;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Resolve the attrbites 'start' on 'ol' and 'value' on 'li'.
+ *
+ * @author mengbo
+ */
+public class HTMLListInfoHelper {
+ /**
+ * @return Returns the start.
+ */
+ private static String getStart(ICSSStyle _style) {
+ if (_style instanceof AbstractStyle) {
+ Element element = ((AbstractStyle) _style).getElement();
+ Node parent = null;
+ if ((parent = EditModelQuery.getParent(IHTMLConstants.TAG_OL,
+ element, true)) != null) {
+ return ((Element) parent)
+ .getAttribute(IHTMLConstants.ATTR_START);
+ }
+ }
+ return null;
+ }
+
+ public static Integer getStartInt(ICSSStyle style) {
+ try {
+ return new Integer(getStart(style));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * @return Returns the value.
+ */
+ private static String getValue(ICSSStyle _style) {
+ if (_style instanceof AbstractStyle) {
+ Element element = ((AbstractStyle) _style).getElement();
+ if (element != null) {
+ return element.getAttribute(IHTMLConstants.ATTR_VALUE);
+ }
+ }
+ return null;
+ }
+
+ public static Integer getValueInt(ICSSStyle style) {
+ try {
+ return Integer.valueOf(getValue(style));
+ } catch (NumberFormatException ex) {
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ICounterValueGenerator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ICounterValueGenerator.java
new file mode 100644
index 000000000..86c979302
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ICounterValueGenerator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+/**
+ * @author mengbo
+ */
+public interface ICounterValueGenerator {
+ public String getIdentifier();
+
+ public ICounterValueGenerator resetCount(int initial);
+
+ public ICounterValueGenerator resetCount();
+
+ /*
+ * Set the counter based on value.
+ */
+ public void setCount(Integer value);
+
+ // public void regist(Object caller);
+ // public void unregist(Object caller);
+
+ /*
+ * Increase counter based on declared increment number
+ */
+ public void increase(int increment);
+
+ /*
+ * Increase counter with default increment number(1)
+ */
+ public void increase();
+
+ public Integer getCount(Object caller);
+
+ public int getCurrentCount();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IIndexConverter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IIndexConverter.java
new file mode 100644
index 000000000..152d1dd8f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IIndexConverter.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+/**
+ * @author mengbo
+ */
+public interface IIndexConverter {
+ String getString(int index);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IncrementObject.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IncrementObject.java
new file mode 100644
index 000000000..4b2ac8ac3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/IncrementObject.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+/**
+ * @author mengbo
+ */
+public class IncrementObject {
+ private String _counterName;
+
+ private Integer _increment;
+
+ public IncrementObject(String name, Integer increment) {
+ _counterName = name;
+ _increment = increment;
+ }
+
+ /**
+ * @return Returns the _counterName.
+ */
+ public String getCounterName() {
+ return _counterName;
+ }
+
+ /**
+ * @param name
+ * The _counterName to set.
+ */
+ public void setCounterName(String name) {
+ _counterName = name;
+ }
+
+ /**
+ * @return Returns the _increment.
+ */
+ public Integer getIncrement() {
+ return _increment;
+ }
+
+ /**
+ * @param _increment
+ * The _increment to set.
+ */
+ public void setIncrement(Integer _increment) {
+ this._increment = _increment;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ListStyleUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ListStyleUtil.java
new file mode 100644
index 000000000..5412580b3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ListStyleUtil.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+/**
+ * @author mengbo
+ */
+public class ListStyleUtil {
+ public static String convertTypeToString(int type, int index) {
+ if (type == CSSHtmlListStyleData.LIST_T_LOWER_ROMAN
+ || type == CSSHtmlListStyleData.LIST_T_UPPER_ROMAN) {
+ // TODO: to implement roman.
+ // return decimalToRoman(index);
+ } else if (type == CSSHtmlListStyleData.LIST_T_DECIMAL
+ || type == CSSHtmlListStyleData.LIST_T_DECIMAL_LEADING_ZERO) {
+ return Integer.toString(index);
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ResetObject.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ResetObject.java
new file mode 100644
index 000000000..bfaabf55a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/list/ResetObject.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.list;
+
+/**
+ * @author mengbo
+ */
+public class ResetObject {
+ private String _counterName;
+
+ private Integer _initial;
+
+ public ResetObject(String name, Integer initial) {
+ _counterName = name;
+ _initial = initial;
+ }
+
+ /**
+ * @return Returns the _counterName.
+ */
+ public String getCounterName() {
+ return _counterName;
+ }
+
+ /**
+ * @param name
+ * The _counterName to set.
+ */
+ public void setCounterName(String name) {
+ _counterName = name;
+ }
+
+ /**
+ * @return Returns the _increment.
+ */
+ public Integer getInitial() {
+ return _initial;
+ }
+
+ /**
+ * @param _initial
+ * The _increment to set.
+ */
+ public void setInitial(Integer _initial) {
+ this._initial = _initial;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterFactory.java
new file mode 100644
index 000000000..9a08dd3b4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterFactory.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.marker;
+
+import org.eclipse.jst.pagedesigner.css2.list.CSSHtmlListStyleData;
+
+/**
+ * @author mengbo
+ */
+public class CounterFactory {
+ private static DecimalCounter _decimalCounterInstance;
+
+ private static RomanCounter _romanCounterInstance;
+
+ private static CounterFactory _instance;
+
+ public static CounterFactory getInstance() {
+ if (_instance == null) {
+ _instance = new CounterFactory();
+ }
+ return _instance;
+ }
+
+ public ICounter getCounter(int type) {
+ switch (type) {
+ case CSSHtmlListStyleData.LIST_T_DECIMAL:
+ case CSSHtmlListStyleData.LIST_T_DECIMAL_LEADING_ZERO:
+ if (_decimalCounterInstance == null) {
+ _decimalCounterInstance = new DecimalCounter();
+ }
+ return _decimalCounterInstance;
+ case CSSHtmlListStyleData.LIST_T_LOWER_ROMAN:
+ case CSSHtmlListStyleData.LIST_T_UPPER_ROMAN:
+ if (_romanCounterInstance == null) {
+ _romanCounterInstance = new RomanCounter();
+ }
+ return _romanCounterInstance;
+ default:
+ return null;
+
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterUtil.java
new file mode 100644
index 000000000..d1627c7e5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/CounterUtil.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.marker;
+
+import org.eclipse.jst.pagedesigner.css2.list.CounterHelper;
+
+/**
+ * @author mengbo
+ */
+public class CounterUtil {
+ public static String convertCount(int count, int type) {
+ // XXX: currently we only support style that IE supported.for type that
+ // does not
+ // support we return an empty String.
+ StringBuffer buffer = new StringBuffer();
+ switch (type) {
+ case CounterHelper.LIST_T_DECIMAL:
+ buffer.append(count);
+ buffer.append('.');
+ break;
+ case CounterHelper.LIST_T_UPPER_ALPHA:
+ case CounterHelper.LIST_T_LOWER_ALPHA:
+ char charA = 'a';
+ if (type == CounterHelper.LIST_T_UPPER_ALPHA) {
+ charA = 'A';
+ }
+ int index = count;
+ while (index > 0 && index > 26) {
+ buffer.append((char) (charA + (index / 26) - 1));
+ index = index % 26;
+ }
+ buffer.append((char) (charA + (index - 1)));
+ buffer.append(".");
+ break;
+ case CounterHelper.LIST_T_UPPER_ROMAN:
+ case CounterHelper.LIST_T_LOWER_ROMAN:
+ String string = new RomanCounter().getString(count);
+ if (type == CounterHelper.LIST_T_LOWER_ROMAN) {
+ buffer.append(string.toLowerCase());
+ } else {
+ buffer.append(string);
+ }
+ buffer.append(".");
+ break;
+ case CounterHelper.LIST_T_ARMENIAN:
+ break;
+ case CounterHelper.LIST_T_DECIMAL_LEADING_ZERO:
+ break;
+ case CounterHelper.LIST_T_LOWER_GREEK:
+ break;
+ case CounterHelper.LIST_T_GEORGIAN:
+ break;
+ default:
+ break;
+ }
+ return buffer.toString();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/DecimalCounter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/DecimalCounter.java
new file mode 100644
index 000000000..d74adbda4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/DecimalCounter.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.marker;
+
+import org.eclipse.jst.pagedesigner.css2.list.CSSHtmlListStyleData;
+
+/**
+ * @author mengbo
+ */
+public class DecimalCounter extends EnumerableCounter {
+ protected DecimalCounter() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.EnumerableCounter#getString(int)
+ */
+ public String getNextString(int index, int type) {
+ String result;
+ switch (type) {
+ case CSSHtmlListStyleData.LIST_T_DECIMAL:
+ return Integer.toString(index);
+
+ case CSSHtmlListStyleData.LIST_T_DECIMAL_LEADING_ZERO:
+ StringBuffer sb = new StringBuffer();
+ int count = getChildrenCount();
+ for (int i = sb.length(); i < count; i++) {
+ sb.append('0');
+ }
+ sb.append(Integer.toString(index));
+ return sb.toString();
+ default:
+ return null;
+ }
+ }
+
+ public int getChildrenCount() {
+ return 1;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/EnumerableCounter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/EnumerableCounter.java
new file mode 100644
index 000000000..190d9a31b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/EnumerableCounter.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.marker;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ */
+public abstract class EnumerableCounter implements ICounter {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.ICounter#getNextObject(org.w3c.dom.Element,
+ * java.lang.String)
+ */
+ public Object getNextObject(Element element, int type) {
+ int index = calculateIndex(element);
+ return getNextString(index, type);
+ }
+
+ public int calculateIndex(Element element) {
+ String tag = element.getLocalName();
+ Node parent = element.getParentNode();
+ NodeList children = parent.getChildNodes();
+ int index = 1;
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child == element) {
+ break;
+ }
+ if (child.getLocalName().equalsIgnoreCase(tag)) {
+ index++;
+ }
+ }
+ return index;
+ }
+
+ public abstract String getNextString(int index, int type);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/ICounter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/ICounter.java
new file mode 100644
index 000000000..93d06bbdf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/ICounter.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.marker;
+
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public interface ICounter {
+ public Object getNextObject(Element element, int type);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/RomanCounter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/RomanCounter.java
new file mode 100644
index 000000000..a017abab3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/marker/RomanCounter.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.marker;
+
+import org.eclipse.jst.pagedesigner.css2.list.CSSHtmlListStyleData;
+
+/**
+ * @author mengbo
+ */
+public class RomanCounter extends EnumerableCounter {
+ protected RomanCounter() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.EnumerableCounter#getString(int,
+ * boolean)
+ */
+ public String getNextString(int index, int type) {
+ switch (type) {
+ case CSSHtmlListStyleData.LIST_T_LOWER_ROMAN:
+ return getString(index).toLowerCase();
+ case CSSHtmlListStyleData.LIST_T_UPPER_ROMAN:
+ return getString(index);
+ default:
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.list.NumberCounter#getString(int)
+ */
+ public String getString(int index) {
+ // FIXME: Need to enhance more.
+ StringBuffer roman = new StringBuffer();
+ int a, b, c, d, e;
+ a = (index / 1000) * 1000;
+ b = ((index / 100) % 10) * 100;
+ c = ((index / 10) % 10) * 10;
+ d = ((index / 1) % 10) * 1;
+
+ if (a == 1000)
+ roman.append("M");
+ else if (a == 2000)
+ roman.append("MM");
+ else if (a == 3000)
+ roman.append("MMM");
+
+ if (b == 100)
+ roman.append("C");
+ else if (b == 200)
+ roman.append("CC");
+ else if (b == 300)
+ roman.append("CCC");
+ else if (b == 400)
+ roman.append("CD");
+ else if (b == 500)
+ roman.append("D");
+ else if (b == 600)
+ roman.append("DC");
+ else if (b == 700)
+ roman.append("DCC");
+ else if (b == 800)
+ roman.append("DCCC");
+ else if (b == 900)
+ roman.append("CM");
+
+ if (c == 10)
+ roman.append("X");
+ else if (c == 20)
+ roman.append("XX");
+ else if (c == 30)
+ roman.append("XXX");
+ else if (c == 40)
+ roman.append("XL");
+ else if (c == 50)
+ roman.append("L");
+ else if (c == 60)
+ roman.append("LX");
+ else if (c == 70)
+ roman.append("LXX");
+ else if (c == 80)
+ roman.append("LXXX");
+ else if (c == 90)
+ roman.append("XC");
+
+ if (d == 1)
+ roman.append("I");
+ else if (d == 2)
+ roman.append("II");
+ else if (d == 3)
+ roman.append("III");
+ else if (d == 4)
+ roman.append("IV");
+ else if (d == 5)
+ roman.append("V");
+ else if (d == 6)
+ roman.append("VI");
+ else if (d == 7)
+ roman.append("VII");
+ else if (d == 8)
+ roman.append("VIII");
+ else if (d == 9)
+ roman.append("IX");
+
+ return roman.toString();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BackgroundColorMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BackgroundColorMeta.java
new file mode 100644
index 000000000..9b304d70a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BackgroundColorMeta.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.color.CSSColorManager;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class BackgroundColorMeta extends CSSPropertyMeta {
+ private static final String[] _keywords = new String[] { ICSSPropertyID.VAL_TRANSPARENT };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public BackgroundColorMeta() {
+ super(false, ICSSPropertyID.VAL_TRANSPARENT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String text = value.getCssText();
+ Object result = CSSColorManager.getInstance().getColor(text);
+ if (result != null) {
+ return result;
+ } else {
+ return getInitialValue(propertyName, style);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return _keywords;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ Object result;
+ String colorAttr = null;
+ if (ICSSPropertyID.ATTR_BACKGROUND_COLOR.equalsIgnoreCase(propertyName)) {
+ colorAttr = DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_BGCOLOR);
+ }
+ if (colorAttr != null && colorAttr.trim().length() != 0) {
+ colorAttr = colorAttr.trim();
+ result = CSSColorManager.getInstance().getColor(colorAttr);
+ return result;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderCollapseMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderCollapseMeta.java
new file mode 100644
index 000000000..874a137ef
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderCollapseMeta.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ */
+public class BorderCollapseMeta extends CSSPropertyMeta {
+ static String[] keywords = new String[] { ICSSPropertyID.VAL_COLLAPSE,
+ ICSSPropertyID.VAL_SEPARATE };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public BorderCollapseMeta() {
+ // XXX: the spec says COLLAPSE is initial value, but seemed that IE
+ // is using separate as default
+ super(true, ICSSPropertyID.VAL_SEPARATE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return keywords;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderColorMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderColorMeta.java
new file mode 100644
index 000000000..16aeccb98
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderColorMeta.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.color.CSSColorManager;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class BorderColorMeta extends CSSPropertyMeta {
+
+ private static final String[] _keywords = new String[] { ICSSPropertyID.VAL_TRANSPARENT };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public BorderColorMeta() {
+ super(false, ICSSPropertyID.VAL_TRANSPARENT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String text = value.getCssText();
+ Object result = CSSColorManager.getInstance().getColor(text);
+ if (result != null) {
+ return result;
+ } else {
+ return getInitialValue(propertyName, style);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return _keywords;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ Object result;
+ String colorAttr = null;
+ if (IHTMLConstants.TAG_HR.equalsIgnoreCase(htmltag)) {
+ colorAttr = DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_COLOR);
+ } else if (ICSSPropertyID.ATTR_BACKGROUND_COLOR
+ .equalsIgnoreCase(propertyName)) {
+ colorAttr = DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_BGCOLOR);
+ }
+ if (colorAttr != null && colorAttr.trim().length() != 0) {
+ colorAttr = colorAttr.trim();
+ result = CSSColorManager.getInstance().getColor(colorAttr);
+ return result;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderSpacingMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderSpacingMeta.java
new file mode 100644
index 000000000..f5bf6735d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderSpacingMeta.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.CSSValueList;
+
+/**
+ * The value will always be of type int[2]
+ *
+ * @author mengbo
+ */
+public class BorderSpacingMeta extends CSSPropertyMeta {
+ public static final int[] INITIAL_SPACING = new int[] { 3, 3 };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public BorderSpacingMeta() {
+ // the specification says "border-spacing" is inherited. But seemed
+ // browse is not treating it as inherited. So we treat is as not
+ // inherited.
+ super(false, INITIAL_SPACING);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return EMPTY_KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ if (value == null || value.getCssValueType() == CSSValue.CSS_CUSTOM) {
+ return INITIAL_SPACING;
+ }
+ if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ int intvalue = toIntValue(value.getCssText(), style);
+ if (intvalue >= 0) {
+ return new int[] { intvalue, intvalue };
+ } else {
+ return INITIAL_SPACING;
+ }
+ } else if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
+ CSSValueList list = (CSSValueList) value;
+ if (list.getLength() >= 2) {
+ int i1 = toIntValue(list.item(0).getCssText(), style);
+ int i2 = toIntValue(list.item(1).getCssText(), style);
+ if (i1 < 0) {
+ i1 = 0;
+ }
+ if (i2 < 0) {
+ i2 = 0;
+ }
+ return new int[] { i1, i2 };
+ } else {
+ return INITIAL_SPACING;
+ }
+ } else {
+ return INITIAL_SPACING;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (IHTMLConstants.TAG_TABLE.equalsIgnoreCase(htmltag)) {
+ String spacing = DOMUtil.getAttributeIgnoreCase(element,
+ IHTMLConstants.ATTR_CELLSPACING);
+ if (spacing != null) {
+ int intvalue = toIntValue(spacing, style);
+ if (intvalue >= 0) {
+ return new int[] { intvalue, intvalue };
+ }
+ }
+ }
+
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+
+ protected int toIntValue(String valuetext, ICSSStyle style) {
+ Object length = LengthMeta.toLength(valuetext, style, PERCENTAGE_NONE,
+ style.getCSSFont());
+ if (length instanceof Length && !((Length) length).isPercentage()) {
+ return ((Length) length).getValue();
+ } else {
+ return Integer.MIN_VALUE;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderStyleMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderStyleMeta.java
new file mode 100644
index 000000000..7dcf7ff53
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderStyleMeta.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class BorderStyleMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_NONE,
+ ICSSPropertyID.VAL_HIDDEN, ICSSPropertyID.VAL_DOTTED,
+ ICSSPropertyID.VAL_DASHED, ICSSPropertyID.VAL_SOLID,
+ ICSSPropertyID.VAL_DOUBLE, ICSSPropertyID.VAL_GROOVE,
+ ICSSPropertyID.VAL_RIDGE, ICSSPropertyID.VAL_INSET,
+ ICSSPropertyID.VAL_OUTSET };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public BorderStyleMeta() {
+ super(false, ICSSPropertyID.VAL_NONE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (IHTMLConstants.TAG_TABLE.equalsIgnoreCase(htmltag)) {
+ return calculateTableOverride(element, propertyName);
+ } else if (IHTMLConstants.TAG_TD.equalsIgnoreCase(htmltag)
+ || IHTMLConstants.TAG_TH.equalsIgnoreCase(htmltag)) {
+ return calculateTDOverride(element, propertyName, style);
+ } else if (IHTMLConstants.TAG_IMG.equalsIgnoreCase(htmltag)) {
+ String border = DOMUtil.getAttributeIgnoreCase(element,
+ IHTMLConstants.ATTR_BORDER);
+ if (border != null) {
+ return ICSSPropertyID.VAL_SOLID;
+ }
+ }
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+
+ /**
+ * @param element
+ * @param propertyName
+ * @return
+ */
+ private Object calculateTDOverride(Element element, String propertyName,
+ ICSSStyle style) {
+ // if element is empty, and "empty-cells" property is hide, then we
+ // don't display border.
+ Object obj = style.getStyleProperty(ICSSPropertyID.ATTR_EMPTY_CELLS);
+ if (EmptyCellsMeta.HIDE.equals(obj) && TableUtil.isEmptyCell(element)) {
+ return ICSSPropertyID.VAL_NONE;
+ }
+
+ // find containing table first
+ Node parent = element;
+ Element tableEle = null;
+ while ((parent = parent.getParentNode()) != null
+ && parent instanceof Element) {
+ if (((Element) parent).getTagName().equalsIgnoreCase(
+ IHTMLConstants.TAG_TABLE)) {
+ tableEle = (Element) parent;
+ break;
+ }
+
+ }
+ if (tableEle != null) {
+ String rules = DOMUtil.getAttributeIgnoreCase(tableEle,
+ IHTMLConstants.ATTR_RULES);
+ String borderstr = DOMUtil.getAttributeIgnoreCase(tableEle,
+ IHTMLConstants.ATTR_BORDER);
+ if (rules == null || rules.length() == 0) {
+ if (borderstr == null || "0".equals(borderstr.trim())) {
+ return ICSSPropertyID.VAL_NONE;
+ } else {
+ return ICSSPropertyID.VAL_TDBORDERSTYLE;
+ }
+ } else {
+ // ok, we got a value for rules
+ if (TableUtil.matchRules(extractEdge(propertyName), rules)) {
+ return ICSSPropertyID.VAL_TDBORDERSTYLE;
+ } else {
+ return ICSSPropertyID.VAL_NONE;
+ }
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param element
+ * @param propertyName
+ * @return
+ */
+ private Object calculateTableOverride(Element element, String propertyName) {
+ String frame = DOMUtil.getAttributeIgnoreCase(element,
+ IHTMLConstants.ATTR_FRAME);
+ String borderstr = DOMUtil.getAttributeIgnoreCase(element,
+ IHTMLConstants.ATTR_BORDER);
+ // border="0" implies frame="void"
+ if ("0".equals(borderstr)) {
+ return ICSSPropertyID.VAL_NONE;
+ }
+ if (frame == null || frame.length() == 0) {
+ if (borderstr == null) {
+ return ICSSPropertyID.VAL_NONE;
+ } else if (borderstr.trim().length() == 0) {
+ frame = IHTMLConstants.ATTR_BORDER;
+ } else {
+ try {
+ Integer.parseInt(borderstr);
+ frame = IHTMLConstants.ATTR_BORDER;
+ } catch (Exception ex) {
+ frame = borderstr;
+ }
+ }
+ }
+ // ok, we got a value for frame.
+ if (TableUtil.matchFrame(extractEdge(propertyName), frame)) {
+ return ICSSPropertyID.VAL_OUTSET;
+ } else {
+ return ICSSPropertyID.VAL_NONE;
+ }
+ }
+
+ static String extractEdge(String propertyName) {
+ if (ICSSPropertyID.ATTR_BORDER_BOTTOM_STYLE
+ .equalsIgnoreCase(propertyName)) {
+ return "bottom";
+ } else if (ICSSPropertyID.ATTR_BORDER_LEFT_STYLE
+ .equalsIgnoreCase(propertyName)) {
+ return "left";
+ } else if (ICSSPropertyID.ATTR_BORDER_RIGHT_STYLE
+ .equalsIgnoreCase(propertyName)) {
+ return "right";
+ } else {
+ return "top";
+ }
+ }
+
+ /**
+ * @param propertyName
+ * @return
+ */
+ public static boolean isBorderStyle(String propertyName) {
+ return ICSSPropertyID.ATTR_BORDER_BOTTOM_STYLE
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_BORDER_LEFT_STYLE
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_BORDER_RIGHT_STYLE
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_BORDER_TOP_STYLE
+ .equalsIgnoreCase(propertyName);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderWidthMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderWidthMeta.java
new file mode 100644
index 000000000..d60ca7291
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/BorderWidthMeta.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ *
+ * @author mengbo
+ */
+// FIXME: when the border-style is none, how should we treat border-width?
+public class BorderWidthMeta extends LengthMeta {
+
+ private static final Length LENGTH_4 = new Length(4, false);
+
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_AUTO,
+ ICSSPropertyID.VAL_THIN, ICSSPropertyID.VAL_MEDIUM,
+ ICSSPropertyID.VAL_THICK };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public BorderWidthMeta() {
+ super(false, LENGTH_4); // medium length.
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.LengthMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getPercentageType()
+ */
+ public int getPercentageType() {
+ return PERCENTAGE_NONE;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.LengthMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ // Computed value: absolute length; '0' if the border style is 'none' or
+ // 'hidden'
+ Object stylevalue = style.getStyleProperty("border-"
+ + extractEdge(propertyName) + "-style");
+ if (ICSSPropertyID.VAL_NONE.equals(stylevalue)
+ || ICSSPropertyID.VAL_HIDDEN.equals(stylevalue)) {
+ return Length.LENGTH_0;
+ }
+
+ Object obj = super.calculateCSSValueResult(value, propertyName, style);
+ if (ICSSPropertyID.VAL_THIN.equals(obj)) {
+ return Length.LENGTH_1;
+ } else if (ICSSPropertyID.VAL_MEDIUM.equals(obj)) {
+ return Length.LENGTH_3;
+ } else if (ICSSPropertyID.VAL_THICK.equals(obj)) {
+ return Length.LENGTH_8;
+ }
+ return obj;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if ("table".equalsIgnoreCase(htmltag)) {
+ return calculateTableOverride(element, propertyName);
+ } else if ("td".equalsIgnoreCase(htmltag)
+ || "th".equalsIgnoreCase(htmltag)) {
+ return calculateTDOverride(element, propertyName);
+ } else if ("img".equalsIgnoreCase(htmltag)) {
+ String border = DOMUtil.getAttributeIgnoreCase(element, "border");// ICSSPropertyID.ATTR_BORDERSIZE);
+ if (border != null) {
+ try {
+ return new Length(Integer.parseInt(border), false);
+ } catch (Exception ex) {
+ // Integer processing, no need to report.
+ }
+ }
+ }
+
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+
+ /**
+ * @param element
+ * @param propertyName
+ * @return
+ */
+ private Object calculateTDOverride(Element element, String propertyName) {
+ // find containing table first
+ Node parent = element;
+ Element tableEle = null;
+ while ((parent = parent.getParentNode()) != null
+ && parent instanceof Element) {
+ if (((Element) parent).getTagName().equalsIgnoreCase("table")) {
+ tableEle = (Element) parent;
+ break;
+ }
+
+ }
+ if (tableEle != null) {
+ String rules = DOMUtil.getAttributeIgnoreCase(tableEle, "rules");
+ String borderstr = DOMUtil.getAttributeIgnoreCase(tableEle,
+ "border");
+ if (rules == null || rules.length() == 0) {
+ if (borderstr == null || "0".equals(borderstr.trim())) {
+ return null;
+ } else {
+ return Length.LENGTH_1;
+ }
+ } else {
+ // ok, we got a value for rules
+ if (TableUtil.matchRules(extractEdge(propertyName), rules)) {
+ return Length.LENGTH_1;
+ } else {
+ return Length.LENGTH_0;
+ }
+ }
+ } else {
+ return Length.LENGTH_0;
+ }
+ }
+
+ /**
+ * @param element
+ * @param propertyName
+ * @return
+ */
+ private Object calculateTableOverride(Element element, String propertyName) {
+ String frame = DOMUtil.getAttributeIgnoreCase(element, "frame");
+ String borderstr = DOMUtil.getAttributeIgnoreCase(element, "border");
+ // border="0" implies frame="void"
+ if ("0".equals(borderstr)) {
+ return Length.LENGTH_0;
+ }
+ if (frame == null || frame.length() == 0) {
+ if (borderstr == null) {
+ return null;
+ } else if (borderstr.trim().length() == 0) {
+ return Length.LENGTH_1;
+ } else {
+ try {
+ return new Length(Integer.parseInt(borderstr), false);
+ } catch (Exception ex) {
+ frame = borderstr;
+ }
+ }
+ }
+ // ok, we got a value for frame.
+ if (TableUtil.matchFrame(extractEdge(propertyName), frame)) {
+ if (borderstr != null) {
+ try {
+ return new Length(Integer.parseInt(borderstr), false);
+ } catch (Exception ex) {
+ // ignore. pass through to return length_1
+ }
+ }
+ return Length.LENGTH_1;
+ } else {
+ return Length.LENGTH_0;
+ }
+ }
+
+ static String extractEdge(String propertyName) {
+ if (ICSSPropertyID.ATTR_BORDER_BOTTOM_WIDTH
+ .equalsIgnoreCase(propertyName)) {
+ return "bottom";
+ } else if (ICSSPropertyID.ATTR_BORDER_LEFT_WIDTH
+ .equalsIgnoreCase(propertyName)) {
+ return "left";
+ } else if (ICSSPropertyID.ATTR_BORDER_RIGHT_WIDTH
+ .equalsIgnoreCase(propertyName)) {
+ return "right";
+ } else {
+ return "top";
+ }
+ }
+
+ /**
+ * @param propertyName
+ * @return
+ */
+ public static boolean isBorderWidth(String propertyName) {
+ return ICSSPropertyID.ATTR_BORDER_BOTTOM_WIDTH
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_BORDER_LEFT_WIDTH
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_BORDER_RIGHT_WIDTH
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_BORDER_TOP_WIDTH
+ .equalsIgnoreCase(propertyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getInitialValue(java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object getInitialValue(String propertyName, ICSSStyle style) {
+ // Computed value: absolute length; '0' if the border style is 'none' or
+ // 'hidden'
+ Object stylevalue = style.getStyleProperty("border-"
+ + extractEdge(propertyName) + "-style");
+ if (ICSSPropertyID.VAL_NONE.equals(stylevalue)
+ || ICSSPropertyID.VAL_HIDDEN.equals(stylevalue)) {
+ return Length.LENGTH_0;
+ }
+ return super.getInitialValue(propertyName, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSMetaRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSMetaRegistry.java
new file mode 100644
index 000000000..be3e05bda
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSMetaRegistry.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author mengbo
+ */
+public class CSSMetaRegistry {
+ Map _map = new HashMap();
+
+ private static CSSMetaRegistry _instance;
+
+ private CSSMetaRegistry() {
+ initialize();
+ }
+
+ public void initialize() {
+ _map.put(ICSSPropertyID.ATTR_DISPLAY, new DisplayMeta());
+ _map.put(ICSSPropertyID.ATTR_TEXTALIGN, new TextAlignMeta());
+ _map.put(ICSSPropertyID.ATTR_HORIZONTAL_ALIGN,
+ new HorizontalAlignMeta());
+ _map.put(ICSSPropertyID.ATTR_TEXTDECORATION, new TextDecorationMeta());
+ _map.put(ICSSPropertyID.ATTR_WHITESPACE, new WhiteSpaceMeta());
+ _map.put(ICSSPropertyID.ATTR_WIDTH, new WidthMeta());
+ _map.put(ICSSPropertyID.ATTR_MIN_WIDTH, new WidthMeta());
+ _map.put(ICSSPropertyID.ATTR_HEIGHT, new HeightMeta());
+ _map.put(ICSSPropertyID.ATTR_MIN_HEIGHT, new HeightMeta());
+
+ _map.put(ICSSPropertyID.ATTR_BORDER_LEFT_WIDTH, new BorderWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_RIGHT_WIDTH, new BorderWidthMeta());
+ _map
+ .put(ICSSPropertyID.ATTR_BORDER_BOTTOM_WIDTH,
+ new BorderWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_TOP_WIDTH, new BorderWidthMeta());
+
+ _map.put(ICSSPropertyID.ATTR_BORDER_LEFT_STYLE, new BorderStyleMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_RIGHT_STYLE, new BorderStyleMeta());
+ _map
+ .put(ICSSPropertyID.ATTR_BORDER_BOTTOM_STYLE,
+ new BorderStyleMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_TOP_STYLE, new BorderStyleMeta());
+
+ _map.put(ICSSPropertyID.ATTR_BORDER_LEFT_COLOR, new BorderColorMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_RIGHT_COLOR, new BorderColorMeta());
+ _map
+ .put(ICSSPropertyID.ATTR_BORDER_BOTTOM_COLOR,
+ new BorderColorMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_TOP_COLOR, new BorderColorMeta());
+
+ _map.put(ICSSPropertyID.ATTR_PADDING_LEFT, new PaddingWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_PADDING_RIGHT, new PaddingWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_PADDING_BOTTOM, new PaddingWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_PADDING_TOP, new PaddingWidthMeta());
+
+ _map.put(ICSSPropertyID.ATTR_MARGIN_LEFT, new MarginWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_MARGIN_RIGHT, new MarginWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_MARGIN_BOTTOM, new MarginWidthMeta());
+ _map.put(ICSSPropertyID.ATTR_MARGIN_TOP, new MarginWidthMeta());
+
+ _map.put(ICSSPropertyID.ATTR_FONT_FAMILY, new FontFamilyMeta());
+ _map.put(ICSSPropertyID.ATTR_FONT_SIZE, new FontSizeMeta());
+ _map.put(ICSSPropertyID.ATTR_FONT_STYLE, new FontStyleMeta());
+ _map.put(ICSSPropertyID.ATTR_FONT_WEIGHT, new FontWeightMeta());
+
+ _map.put(ICSSPropertyID.ATTR_BACKGROUND_COLOR,
+ new BackgroundColorMeta());
+ _map.put(ICSSPropertyID.ATTR_COLOR, new ColorPropertyMeta());
+ _map.put(ICSSPropertyID.ATTR_TEXTCOLOR, new ColorPropertyMeta());
+
+ _map.put(ICSSPropertyID.ATTR_BORDER_COLLAPSE, new BorderCollapseMeta());
+ _map.put(ICSSPropertyID.ATTR_BORDER_SPACING, new BorderSpacingMeta());
+
+ _map.put(ICSSPropertyID.ATTR_LIST_STYLE_TYPE, new ListStyleTypeMeta());
+ _map
+ .put(ICSSPropertyID.ATTR_LIST_STYLE_IMAGE,
+ new ListStyleImageMeta());
+ _map.put(ICSSPropertyID.ATTR_LIST_STYLE_POSITION,
+ new ListStylePositionMeta());
+ _map.put(ICSSPropertyID.ATTR_COUNTER_RESET, new CounterResetMeta());
+ _map.put(ICSSPropertyID.ATTR_COUNTER_INCREMENT,
+ new CounterIncrementMeta());
+
+ _map.put(ICSSPropertyID.ATTR_TOP, new PositionOffsetMeta());
+ _map.put(ICSSPropertyID.ATTR_RIGHT, new PositionOffsetMeta());
+ _map.put(ICSSPropertyID.ATTR_BOTTOM, new PositionOffsetMeta());
+ _map.put(ICSSPropertyID.ATTR_LEFT, new PositionOffsetMeta());
+ _map.put(ICSSPropertyID.ATTR_POSITION, new PositionMeta());
+
+ _map.put(ICSSPropertyID.ATTR_EMPTY_CELLS, new EmptyCellsMeta());
+ _map.put(ICSSPropertyID.ATTR_VISIBILITY, new VisibilityMeta());
+ _map.put(ICSSPropertyID.ATTR_VERTICAL_ALIGN, new VerticalAlignMeta());
+
+ _map.put(ICSSPropertyID.ATTR_OVERFLOW, new OverflowMeta());
+ }
+
+ public ICSSPropertyMeta getMeta(String property) {
+ return (ICSSPropertyMeta) _map.get(property);
+ }
+
+ public static final CSSMetaRegistry getInstance() {
+ if (_instance == null) {
+ _instance = new CSSMetaRegistry();
+ }
+ return _instance;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSPropertyMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSPropertyMeta.java
new file mode 100644
index 000000000..c19b44178
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CSSPropertyMeta.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public abstract class CSSPropertyMeta implements ICSSPropertyMeta {
+ public static final String[] EMPTY_KEYWORDS = new String[0];
+
+ boolean _inherited;
+
+ Object _initialValue;
+
+ public CSSPropertyMeta(boolean inherit, Object initvalue) {
+ this._inherited = inherit;
+ this._initialValue = initvalue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#isInherited()
+ */
+ public boolean isInherited() {
+ return _inherited;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#getHTMLElementInitialValue(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String)
+ */
+ public Object getHTMLElementInitialValue(Element element, String htmltag,
+ String propertyName) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#getInitialValue()
+ */
+ public Object getInitialValue(String propertyName, ICSSStyle style) {
+ return _initialValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#getPercentageType()
+ */
+ public int getPercentageType() {
+ return PERCENTAGE_NONE;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ // child class should override this method!!!
+ return null;
+ }
+
+ /**
+ * for many properties, they have a set of keyword property values.
+ *
+ * @return
+ */
+ protected abstract String[] getKeywordValues();
+
+ /**
+ * @param value
+ * @return null if is not a keyword.
+ */
+ protected String checkKeywordValues(String value) {
+ if (value == null)
+ return null;
+ String[] keywords = getKeywordValues();
+ if (keywords != null) {
+ for (int i = 0; i < keywords.length; i++) {
+ if (keywords[i].equalsIgnoreCase(value)) {
+ return keywords[i];
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String s = checkKeywordValues(value.getCssText());
+ if (s != null) {
+ return s;
+ } else {
+ return this.getInitialValue(propertyName, style);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ColorPropertyMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ColorPropertyMeta.java
new file mode 100644
index 000000000..098555a43
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ColorPropertyMeta.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.Arrays;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.color.CSSColorManager;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.swt.graphics.Color;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * "color" will be in this type
+ *
+ * @author mengbo
+ */
+public class ColorPropertyMeta extends CSSPropertyMeta {
+ private static final Object DEFAULT_COLOR = ColorConstants.black;
+
+ private static final String[] KEYWORDS = new String[] {};
+
+ private final static String[] NOTSUPPORT_TAG = { IHTMLConstants.TAG_H1,
+ IHTMLConstants.TAG_H2, IHTMLConstants.TAG_H3,
+ IHTMLConstants.TAG_H4, IHTMLConstants.TAG_H5, IHTMLConstants.TAG_H6 };
+
+ public Color getDefaultColor() {
+ return null;
+ }
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public ColorPropertyMeta() {
+ super(true, DEFAULT_COLOR);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+
+ String text = value.getCssText();
+ Object result = CSSColorManager.getInstance().getColor(text);
+ if (result != null) {
+ return result;
+ } else {
+ return this.getInitialValue(propertyName, style);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (Arrays.asList(NOTSUPPORT_TAG).contains(htmltag.toLowerCase())) {
+ return null;
+ }
+ Object result;
+ String colorAttr = null;
+ // There are some conditions need to be dealt with hyperlink and text
+ // properties.
+ if (ICSSPropertyID.ATTR_COLOR.equalsIgnoreCase(propertyName)) {
+ colorAttr = DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_COLOR);
+ if (colorAttr == null
+ && element.getLocalName().equalsIgnoreCase(
+ IHTMLConstants.TAG_BODY)) {
+ colorAttr = DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_TEXT);
+ }
+ }
+ if (colorAttr != null) {
+ colorAttr = colorAttr.trim();
+ result = CSSColorManager.getInstance().getColor(colorAttr);
+ return result;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ContentMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ContentMeta.java
new file mode 100644
index 000000000..01e9652a9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ContentMeta.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ */
+public class ContentMeta extends CSSPropertyMeta {
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public ContentMeta() {
+ // why inherit this??
+ super(false, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ /*
+ * public Object calculateCSSValueResult(CSSValue value, String
+ * propertyName, AbstractStyle style) { if (value instanceof Counter) {
+ * Counter c = (Counter)value; ContentObject object = new ContentObject();
+ *
+ * MyCounter counter = new MyCounter(c.getIdentifier(), c.getListStyle(),
+ * c.getSeparator()); object.setCounter(counter); return object; } return
+ * value; }
+ */
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterIncrementMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterIncrementMeta.java
new file mode 100644
index 000000000..0f9b525ec
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterIncrementMeta.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.list.CounterHelper;
+import org.eclipse.jst.pagedesigner.css2.list.IncrementObject;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * For CounterIncrementMeta, the valid value could be the following: 1. NULL 2.
+ * NOT_SPECIFIED 3. a List of IncrementObject.
+ *
+ * @author mengbo
+ */
+public class CounterIncrementMeta extends CSSPropertyMeta {
+ public CounterIncrementMeta() {
+ super(false, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ return getCounter(value);
+ }
+
+ public List getCounter(CSSValue value) {
+ if (value == null) {
+ return null;
+ }
+ List result = new ArrayList();
+ IncrementObject incrementObject = null;
+ String identifier = null;
+ Integer increment = null;
+ ICSSNode cssValue = (ICSSNode) value;
+ while (cssValue != null) {
+ // find next idetifier.
+ while (cssValue != null && !CounterHelper.isIdentifier(cssValue)) {
+ cssValue = cssValue.getNextSibling();
+ }
+ if (cssValue == null) {
+ return null;
+ } else {
+ // identifier:
+ identifier = ((ICSSPrimitiveValue) value).getStringValue();
+ cssValue = cssValue.getNextSibling();
+ // value:
+ if (CounterHelper.isNumber(cssValue)) {
+ increment = new Integer((int) ((ICSSPrimitiveValue) value)
+ .getFloatValue(ICSSPrimitiveValue.CSS_INTEGER));
+ }
+ }
+
+ if (identifier != null) {
+ incrementObject = new IncrementObject(identifier, increment);
+ result.add(incrementObject);
+ }
+ }
+ return result;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterResetMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterResetMeta.java
new file mode 100644
index 000000000..251442f13
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/CounterResetMeta.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.list.CounterHelper;
+import org.eclipse.jst.pagedesigner.css2.list.ResetObject;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class CounterResetMeta extends CSSPropertyMeta {
+ public CounterResetMeta() {
+ super(false, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ return getCounter(value);
+ }
+
+ public List getCounter(CSSValue value) {
+ if (value == null) {
+ return null;
+ }
+ List result = new ArrayList();
+ ResetObject resetObject = null;
+ String identifier = null;
+ Integer initial = null;
+ ICSSNode cssValue = (ICSSNode) value;
+ while (cssValue != null) {
+ // find next idetifier.
+ while (cssValue != null && !CounterHelper.isIdentifier(cssValue)) {
+ cssValue = cssValue.getNextSibling();
+ }
+ if (cssValue == null) {
+ return null;
+ } else {
+ // identifier:
+ identifier = ((ICSSPrimitiveValue) value).getStringValue();
+ cssValue = cssValue.getNextSibling();
+ // value:
+ if (CounterHelper.isNumber(cssValue)) {
+ initial = new Integer((int) ((ICSSPrimitiveValue) value)
+ .getFloatValue(ICSSPrimitiveValue.CSS_INTEGER));
+ }
+ }
+
+ if (identifier != null) {
+ resetObject = new ResetObject(identifier, initial);
+ result.add(resetObject);
+ }
+ }
+ return result;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/DisplayMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/DisplayMeta.java
new file mode 100644
index 000000000..553a257fa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/DisplayMeta.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class DisplayMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_INLINE,
+ ICSSPropertyID.VAL_BLOCK, ICSSPropertyID.VAL_INLINE_BLOCK,
+ ICSSPropertyID.VAL_LIST_ITEM, ICSSPropertyID.VAL_RUN_IN,
+ ICSSPropertyID.VAL_COMPACT, ICSSPropertyID.VAL_MARKER,
+ ICSSPropertyID.VAL_TABLE, ICSSPropertyID.VAL_INLINE_TABLE,
+ ICSSPropertyID.VAL_TABLE_ROW_GROUP,
+ ICSSPropertyID.VAL_TABLE_HEADER_GROUP,
+ ICSSPropertyID.VAL_TABLE_FOOTER_GROUP,
+ ICSSPropertyID.VAL_TABLE_ROW,
+ ICSSPropertyID.VAL_TABLE_COLUMN_GROUP,
+ ICSSPropertyID.VAL_TABLE_COLUMN, ICSSPropertyID.VAL_TABLE_CELL,
+ ICSSPropertyID.VAL_TABLE_CAPTION, ICSSPropertyID.VAL_NONE };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public DisplayMeta() {
+ super(false, ICSSPropertyID.VAL_INLINE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String text = value.getCssText();
+ if (text == null)
+ return ICSSPropertyID.VAL_INLINE;
+ String key = this.checkKeywordValues(text);
+ if (key != null)
+ return key;
+ else
+ return ICSSPropertyID.VAL_INLINE;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/EmptyCellsMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/EmptyCellsMeta.java
new file mode 100644
index 000000000..50785b3d4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/EmptyCellsMeta.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class EmptyCellsMeta extends CSSPropertyMeta {
+ public static final String SHOW = "show";
+
+ public static final String HIDE = "hide";
+
+ public static final String[] _keywords = new String[] { SHOW, HIDE };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public EmptyCellsMeta() {
+ // FIXME: on CSS spec, initial value should be "show".
+ // but seemed IE's default is hide.
+ super(true, HIDE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return _keywords;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FloatInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FloatInfo.java
new file mode 100644
index 000000000..12ad19f23
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FloatInfo.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSPrimitiveValue;
+import org.w3c.dom.css.CSSPrimitiveValue;
+
+/**
+ * copied from wtp's internal code.
+ *
+ * @author mengbo
+ */
+public final class FloatInfo {
+ /**
+ *
+ */
+ public FloatInfo(String text) {
+ parse(text);
+ }
+
+ /**
+ *
+ */
+ void parse(String text) {
+ StringBuffer bufValue = new StringBuffer();
+ StringBuffer bufIdent = new StringBuffer();
+ boolean bNum = true;
+ int len = text.length();
+ for (int i = 0; i < len; i++) {
+ char c = text.charAt(i);
+ if (bNum) {
+ if ('0' <= c && c <= '9' || c == '.' || c == '+' || c == '-') {
+ bufValue.append(c);
+ } else {
+ bufIdent.append(c);
+ bNum = false;
+ }
+ } else {
+ bufIdent.append(c);
+ }
+ }
+ String valueStr = bufValue.toString();
+ _value = Float.valueOf(valueStr).floatValue();
+ _identifier = bufIdent.toString();
+ _type = getFloatValueType(valueStr, _identifier);
+ }
+
+ /**
+ *
+ */
+ public float getValue() {
+ return _value;
+ }
+
+ /**
+ *
+ */
+ String getIdentifier() {
+ return _identifier;
+ }
+
+ /**
+ *
+ */
+ public short getValueType() {
+ return _type;
+ }
+
+ /**
+ *
+ */
+ static short getFloatValueType(String value, String ident) {
+ ident = ident.toLowerCase();
+ short valueType;
+ if (ident.length() == 0) {
+ if (0 <= value.indexOf('.')) {
+ valueType = CSSPrimitiveValue.CSS_NUMBER;
+ } else {
+ valueType = ICSSPrimitiveValue.CSS_INTEGER;
+ }
+ } else if (ident.equals("%")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_PERCENTAGE;
+ } else if (ident.equalsIgnoreCase("em")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_EMS;
+ } else if (ident.equalsIgnoreCase("ex")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_EXS;
+ } else if (ident.equalsIgnoreCase("px")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_PX;
+ } else if (ident.equalsIgnoreCase("cm")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_CM;
+ } else if (ident.equalsIgnoreCase("mm")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_MM;
+ } else if (ident.equalsIgnoreCase("in")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_IN;
+ } else if (ident.equalsIgnoreCase("pt")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_PT;
+ } else if (ident.equalsIgnoreCase("pc")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_PC;
+ } else if (ident.equalsIgnoreCase("deg")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_DEG;
+ } else if (ident.equalsIgnoreCase("rad")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_RAD;
+ } else if (ident.equalsIgnoreCase("grad")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_GRAD;
+ } else if (ident.equalsIgnoreCase("ms")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_MS;
+ } else if (ident.equalsIgnoreCase("s")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_S;
+ } else if (ident.equalsIgnoreCase("hz")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_HZ;
+ } else if (ident.equalsIgnoreCase("khz")) {
+ //$NON-NLS-1$
+ valueType = CSSPrimitiveValue.CSS_KHZ;
+ } else {
+ valueType = CSSPrimitiveValue.CSS_DIMENSION;
+ }
+ return valueType;
+ }
+
+ private float _value = 0.0f;
+
+ private String _identifier = null;
+
+ private short _type = CSSPrimitiveValue.CSS_UNKNOWN;
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontFamilyMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontFamilyMeta.java
new file mode 100644
index 000000000..c8e4fb3f2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontFamilyMeta.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Display;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.CSSValueList;
+
+/**
+ * @author mengbo
+ */
+public class FontFamilyMeta extends CSSPropertyMeta {
+ public static final String DEFAULT_FONT = "Times New Roman";
+
+ private static FontData[] _FontData;
+
+ private static FontData[] getFontData() {
+ if (_FontData == null) {
+ ArrayList list = new ArrayList();
+ list.addAll(Arrays.asList(Display.getCurrent().getFontList(null,
+ false)));
+ list.addAll(Arrays.asList(Display.getCurrent().getFontList(null,
+ true)));
+ _FontData = (FontData[]) list.toArray(new FontData[list.size()]);
+ }
+ return _FontData;
+ }
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public FontFamilyMeta() {
+ super(true, DEFAULT_FONT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
+ CSSValueList valueList = (CSSValueList) value;
+ for (int i = 0, count = valueList.getLength(); i < count; i++) {
+ String name = ((CSSValue) valueList.item(i)).getCssText();
+ name = trimPadding(name);
+ if (isSupportedFont(name)) {
+ return name;
+ }
+ }
+ }
+ return trimPadding(value.getCssText());
+ }
+
+ private String trimPadding(String name) {
+ String value = name;
+ if (value != null) {
+ value = value.replaceAll("\"", "");
+ value = value.replaceAll("'", "");
+ }
+ return value;
+ }
+
+ private boolean isSupportedFont(String name) {
+ FontData[] fontData = getFontData();
+ for (int i = 0; i < fontData.length; i++) {
+ if (fontData[i].getName().equalsIgnoreCase(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if ("FONT".equalsIgnoreCase(htmltag)
+ || "BASEFONT".equalsIgnoreCase(htmltag)) {
+ String face = DOMUtil.getAttributeIgnoreCase(element, "face");
+ if (face != null) {
+ String[] names = getFontNameList(face);
+ for (int i = 0; i < names.length; i++) {
+ if (isSupportedFont(names[i])) {
+ return names[i];
+ }
+ }
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ private String[] getFontNameList(String face) {
+ StringTokenizer tokenizer = new StringTokenizer(face, ",");
+ String[] names = new String[tokenizer.countTokens()];
+ for (int i = 0; i < names.length; i++) {
+ names[i] = trimPadding(tokenizer.nextToken());
+ }
+ return names;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontSizeMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontSizeMeta.java
new file mode 100644
index 000000000..2b98b0485
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontSizeMeta.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * The result value should be Length object only.
+ *
+ * @author mengbo
+ */
+// XXX: in the future, we may add "unit" into Length, the one unit will be
+// "MEDIUM"
+// and specific for font. Means the relative size to MEDIUM. Then it is possible
+// for
+// the caller to decide the actual font size based on the style specific MEDIUM
+// size.
+public class FontSizeMeta extends LengthMeta {
+ private static final String[] KEYWORDS = { ICSSPropertyID.VAL_XX_SMALL,
+ ICSSPropertyID.VAL_X_SMALL, ICSSPropertyID.VAL_SMALL,
+ ICSSPropertyID.VAL_MEDIUM, ICSSPropertyID.VAL_LARGE,
+ ICSSPropertyID.VAL_X_LARGE, ICSSPropertyID.VAL_XX_LARGE,
+ ICSSPropertyID.VAL_LARGER, ICSSPropertyID.VAL_SMALLER };
+
+ public static final double MEDIUM_VAL_INT = 16;
+
+ public static final double SCALING_FACTOR = 1.2;
+
+ public static final double FACTORS[] = { 0.6, 0.89, 1, 1.2, 1.5, 2.0, 3.0 };
+
+ // The scaling factors in IE is different from CSS definition. Here we
+ // follow IE.
+ public static final double CSS_ABSOLUTE_FACTORS[] = { 0.63, 0.82, 1, 1.12,
+ 1.5, 2.0, 3.0 };
+
+ public static final int MIN_SIZE_FOR_SMALLER = 1;
+
+ public static final int MIN_SIZE_FOR_LARGER = 9;
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public FontSizeMeta() {
+ super(true, new Length((int) MEDIUM_VAL_INT, false));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.LengthMeta#getBaseFont(org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ protected ICSSFont getBaseFont(ICSSStyle style) {
+ return style.getParentStyle().getCSSFont();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getPercentageType()
+ */
+ public int getPercentageType() {
+ return PERCENTAGE_FONT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.LengthMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ Object obj = super.calculateCSSValueResult(value, propertyName, style);
+ if (obj instanceof Length) {
+ return obj;
+ }
+ // otherwise, it is keyword.
+ return convertKeyword(obj, style);
+ }
+
+ protected Length convertKeyword(Object fontsizeobj, ICSSStyle style) {
+ int fontsize;
+ int parentfontsize = style.getParentStyle().getCSSFont().getFontSize();
+ if (fontsizeobj instanceof Length) {
+ fontsize = ((Length) fontsizeobj).getValue();
+ } else if (ICSSPropertyID.VAL_XX_SMALL.equals(fontsizeobj)) {
+ fontsize = (int) (MEDIUM_VAL_INT * CSS_ABSOLUTE_FACTORS[0]);
+ } else if (ICSSPropertyID.VAL_X_SMALL.equals(fontsizeobj)) {
+ fontsize = (int) (MEDIUM_VAL_INT * CSS_ABSOLUTE_FACTORS[1]);
+ } else if (ICSSPropertyID.VAL_SMALL.equals(fontsizeobj)) {
+ fontsize = (int) (MEDIUM_VAL_INT * CSS_ABSOLUTE_FACTORS[2]);
+ } else if (ICSSPropertyID.VAL_MEDIUM.equals(fontsizeobj)) {
+ fontsize = (int) Math.round(MEDIUM_VAL_INT
+ * CSS_ABSOLUTE_FACTORS[3]);
+ } else if (ICSSPropertyID.VAL_LARGE.equals(fontsizeobj)) {
+ fontsize = (int) (MEDIUM_VAL_INT * CSS_ABSOLUTE_FACTORS[4]);
+ } else if (ICSSPropertyID.VAL_X_LARGE.equals(fontsizeobj)) {
+ fontsize = (int) (MEDIUM_VAL_INT * CSS_ABSOLUTE_FACTORS[5]);
+ } else if (ICSSPropertyID.VAL_XX_LARGE.equals(fontsizeobj)) {
+ fontsize = (int) (MEDIUM_VAL_INT * CSS_ABSOLUTE_FACTORS[6]);
+ } else if (ICSSPropertyID.VAL_SMALLER.equals(fontsizeobj)) {
+ fontsize = (int) (parentfontsize / SCALING_FACTOR);
+ if (fontsize < MIN_SIZE_FOR_SMALLER) {
+ fontsize = MIN_SIZE_FOR_SMALLER;
+ }
+ } else if (ICSSPropertyID.VAL_LARGER.equals(fontsizeobj)) {
+ fontsize = (int) (parentfontsize * SCALING_FACTOR);
+ if (fontsize < MIN_SIZE_FOR_LARGER) {
+ fontsize = MIN_SIZE_FOR_LARGER;
+ }
+ } else {
+ fontsize = parentfontsize;
+ }
+
+ return new Length(fontsize, false);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (IHTMLConstants.TAG_FONT.equalsIgnoreCase(htmltag)
+ || ICSSPropertyID.ATTR_BASEFONT.equalsIgnoreCase(htmltag)) {
+ String size = DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_SIZE);
+ if (size != null) {
+ size = size.trim();
+ try {
+ int fontSize = 0;
+ if (size.startsWith("+")) //$NON-NLS-1$
+ {
+ fontSize = Integer.parseInt(size.substring(1)) + 3;
+ } else if (size.startsWith("-")) //$NON-NLS-1$
+ {
+ fontSize = 3 - Integer.parseInt(size.substring(1));
+ } else {
+ fontSize = Integer.parseInt(size);
+ }
+ if (fontSize < 1) {
+ fontSize = 1;
+ }
+ if (fontSize > 7) {
+ fontSize = 7;
+ }
+ return new Length((int) (Math.round(FACTORS[fontSize - 1]
+ * MEDIUM_VAL_INT)), false);
+ } catch (Exception ex) {
+ // Error in tag font attr calculating.
+ // _log.error("Error.FontSizeMeta.0", ex); //$NON-NLS-1$
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontStyleMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontStyleMeta.java
new file mode 100644
index 000000000..8464868b0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontStyleMeta.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ */
+public class FontStyleMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_NORMAL,
+ ICSSPropertyID.VAL_ITALIC, ICSSPropertyID.VAL_OBLIQUE };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public FontStyleMeta() {
+ super(true, ICSSPropertyID.VAL_NORMAL);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontWeightMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontWeightMeta.java
new file mode 100644
index 000000000..fe7aed723
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/FontWeightMeta.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * The result value will always be integer, range 100-900 This class has already
+ * translate things like "normal", "bold", "bolder", "lighter" into integer
+ * value.
+ *
+ * @author mengbo
+ */
+public class FontWeightMeta extends CSSPropertyMeta {
+
+ public static final Integer NORMAL_WEIGHT = new Integer(400);
+
+ public static final Integer BOLD_WEIGHT = new Integer(700);
+
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_NORMAL,
+ ICSSPropertyID.VAL_BOLD, ICSSPropertyID.VAL_BOLDER,
+ ICSSPropertyID.VAL_LIGHTER };
+
+ private Logger _log = PDPlugin.getLogger(FontWeightMeta.class);
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public FontWeightMeta() {
+ super(true, NORMAL_WEIGHT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String text = value.getCssText();
+ String result = checkKeywordValues(text);
+ if (result == null) {
+ try {
+ int i = Integer.parseInt(text);
+ if (i < 100) {
+ i = 100;
+ }
+ if (i > 900) {
+ i = 900;
+ }
+ return new Integer(i);
+ } catch (Exception ex) {
+ // Error in integer processing.
+ _log.error("Info.FontWeightMeta.0", ex); //$NON-NLS-1$
+ return NORMAL_WEIGHT;
+ }
+ } else if (ICSSPropertyID.VAL_NORMAL.equals(result)) {
+ return NORMAL_WEIGHT;
+ } else if (ICSSPropertyID.VAL_BOLD.equals(result)) {
+ return BOLD_WEIGHT;
+ } else if (ICSSPropertyID.VAL_BOLDER.equals(result)) {
+ // int i = style.getParentStyle().getCSSFont().getWeight() + 100;
+ // if (i < 100)
+ // i = 100;
+ // if (i > 900)
+ // i = 900;
+ // return new Integer(i);
+ return BOLD_WEIGHT;
+ } else if (ICSSPropertyID.VAL_LIGHTER.equals(result)) {
+ int i = style.getParentStyle().getCSSFont().getWeight() - 100;
+ if (i < 100) {
+ i = 100;
+ }
+ if (i > 900) {
+ i = 900;
+ }
+ return new Integer(i);
+ }
+ return NORMAL_WEIGHT;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HeightMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HeightMeta.java
new file mode 100644
index 000000000..2c635ff2b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HeightMeta.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class HeightMeta extends LengthMeta {
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public HeightMeta() {
+ super(false, ICSSPropertyID.VAL_AUTO);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (!"input".equalsIgnoreCase(htmltag)) //$NON-NLS-1$
+ {
+ String attributeName = ICSSPropertyID.ATTR_HEIGHT;
+ if ("hr".equalsIgnoreCase(htmltag)) {
+ attributeName = ICSSPropertyID.ATTR_SIZE;
+ }
+
+ String height = DOMUtil.getAttributeIgnoreCase(element,
+ attributeName);
+ if (height != null) {
+ return LengthMeta.toLength(height, style, this
+ .getPercentageType(), getBaseFont(style));
+ }
+ }
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HorizontalAlignMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HorizontalAlignMeta.java
new file mode 100644
index 000000000..c54952868
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/HorizontalAlignMeta.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.Arrays;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class HorizontalAlignMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_LEFT,
+ "bottom", "top", //$NON-NLS-1$ //$NON-NLS-2$
+ ICSSPropertyID.VAL_RIGHT, ICSSPropertyID.VAL_CENTER,
+ ICSSPropertyID.VAL_JUSTIFY };
+
+ private static final String[] HOR_SLIGN_HTMLTAGS = new String[] {
+ "TABLE", "HR", "LEGEND", "APPLET", "IFRAME", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ "IMG", "INPUT", "OBJECT", "CAPTION" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public HorizontalAlignMeta() {
+ super(true, NOT_SPECIFIED);
+ }
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public HorizontalAlignMeta(boolean inherit, Object initvalue) {
+ super(inherit, initvalue);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+
+ if (Arrays.asList(HOR_SLIGN_HTMLTAGS).contains(htmltag.toUpperCase())) {
+ String align = DOMUtil.getAttributeIgnoreCase(element, "align"); //$NON-NLS-1$
+ return checkKeywordValues(align);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#getHTMLElementInitialValue(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String)
+ */
+ public Object getHTMLElementInitialValue(Element element, String htmltag,
+ String propertyName) {
+ if ("HR".equalsIgnoreCase(htmltag.toUpperCase())) //$NON-NLS-1$
+ {
+ return ICSSPropertyID.VAL_CENTER;
+ } else if (Arrays.asList(HOR_SLIGN_HTMLTAGS).contains(
+ htmltag.toUpperCase())) {
+ return ICSSPropertyID.VAL_LEFT;
+ }
+
+ return super.getHTMLElementInitialValue(element, htmltag, propertyName);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyID.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyID.java
new file mode 100644
index 000000000..2939923b9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyID.java
@@ -0,0 +1,382 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ */
+public interface ICSSPropertyID {
+ public static final String ATTR_DISPLAY = "display";
+
+ public static final String ATTR_WHITESPACE = "white-space";
+
+ public static final String ATTR_TEXTDECORATION = "text-decoration";
+
+ public static final String ATTR_TEXTALIGN = "text-align";
+
+ public static final String ATTR_WIDTH = "width";
+
+ public static final String ATTR_MIN_WIDTH = "min-width";
+
+ public static final String ATTR_HEIGHT = "height";
+
+ public static final String ATTR_MIN_HEIGHT = "min-height";
+
+ public static final String ATTR_BORDER_LEFT_WIDTH = "border-left-width";
+
+ public static final String ATTR_BORDER_RIGHT_WIDTH = "border-right-width";
+
+ public static final String ATTR_BORDER_BOTTOM_WIDTH = "border-bottom-width";
+
+ public static final String ATTR_BORDER_TOP_WIDTH = "border-top-width";
+
+ public static final String ATTR_FONT_FAMILY = "font-family";
+
+ public static final String ATTR_FONT_SIZE = "font-size";
+
+ public static final String ATTR_FONT_STYLE = "font-style";
+
+ public static final String ATTR_FONT_WEIGHT = "font-weight";
+
+ public static final String ATTR_BORDER_LEFT_STYLE = "border-left-style";
+
+ public static final String ATTR_BORDER_RIGHT_STYLE = "border-right-style";
+
+ public static final String ATTR_BORDER_BOTTOM_STYLE = "border-bottom-style";
+
+ public static final String ATTR_BORDER_TOP_STYLE = "border-top-style";
+
+ public static final String ATTR_BORDER_LEFT_COLOR = "border-left-color";
+
+ public static final String ATTR_BORDER_RIGHT_COLOR = "border-right-color";
+
+ public static final String ATTR_BORDER_BOTTOM_COLOR = "border-bottom-color";
+
+ public static final String ATTR_BORDER_TOP_COLOR = "border-top-color";
+
+ public static final String ATTR_PADDING_RIGHT = "padding-right";
+
+ public static final String ATTR_PADDING_BOTTOM = "padding-bottom";
+
+ public static final String ATTR_PADDING_LEFT = "padding-left";
+
+ public static final String ATTR_PADDING_TOP = "padding-top";
+
+ public static final String ATTR_MARGIN_RIGHT = "margin-right";
+
+ public static final String ATTR_MARGIN_BOTTOM = "margin-bottom";
+
+ public static final String ATTR_MARGIN_LEFT = "margin-left";
+
+ public static final String ATTR_MARGIN_TOP = "margin-top";
+
+ public static final String ATTR_BACKGROUND_COLOR = "background-color";
+
+ public static final String ATTR_COLOR = "color";
+
+ public static final String ATTR_TEXTCOLOR = "text";
+
+ public static final String ATTR_BORDER_COLLAPSE = "border-collapse";
+
+ public static final String ATTR_BORDER_SPACING = "border-spacing";
+
+ public static final String ATTR_LIST_STYLE_TYPE = "list-style-type";
+
+ public static final String ATTR_LIST_STYLE_POSITION = "list-style-position";
+
+ public static final String ATTR_LIST_STYLE_IMAGE = "list-style-image";
+
+ public static final String ATTR_COUNTER_RESET = "counter-reset";
+
+ public static final String ATTR_COUNTER_INCREMENT = "counter-increment";
+
+ public static final String ATTR_EMPTY_CELLS = "empty-cells";
+
+ public static final String ATTR_VISIBILITY = "visibility";
+
+ public static final String ATTR_VERTICAL_ALIGN = "vertical-align";
+
+ public static final String ATTR_HORIZONTAL_ALIGN = "horizontal-align";
+
+ public static final String ATTR_CONTENT = "content";
+
+ public static final String ATTR_BGCOLOR = "bgcolor";
+
+ public static final String ATTR_TEXT = "text";
+
+ public final static String ATTR_MULTIPLE = "multiple";
+
+ public final static String ATTR_ITEMLABEL = "itemLabel";
+
+ public final static String ATTR_BINDING = "binding";
+
+ public final static String ATTR_ITEMVALUE = "itemValue";
+
+ public final static String ATTR_VALUE = "value";
+
+ public static final String ATTR_URI = "uri";
+
+ public static final String ATTR_PREFIX = "prefix";
+
+ public static final String ATTR_STYLECLASS = "styleClass";
+
+ public static final String ATTR_SIZE = "size";
+
+ public static final String ATTR_BASEFONT = "basefont";
+
+ public static final String ATTR_ROWSPAN = "rowSpan";
+
+ public static final String ATTR_COLSPAN = "colSpan";
+
+ public static final String ATTR_TYPE = "type";
+
+ public static final String ATTR_URL = "url";
+
+ public static final String ATTR_SRC = "src";
+
+ public static final String ATTR_TAGLIB_LOCATION = "taglib-location";
+
+ public static final String ATTR_TAGLIB_URI = "taglib-uri";
+
+ public static final String ATTR_IMAGE = "image";
+
+ public static final String ATTR_RESET = "reset";
+
+ public static final String ATTR_FOOTER = "footer";
+
+ public static final String ATTR_HEADER = "header";
+
+ public static final String ATTR_COLUMNS = "columns";
+
+ public static final String ATTR_COLUMNCLASSES = "columnClasses";
+
+ public static final String ATTR_CLASS = "class";
+
+ public static final String ATTR_STYLE = "style";
+
+ public static final String ATTR_PAGE = "page";
+
+ public static final String ATTR_HREF = "href";
+
+ public static final String ATTR_NAME = "name";
+
+ public static final String ATTR_BASENAME = "basename";
+
+ public static final String ATTR_ACTION = "action";
+
+ public static final String ATTR_TARGET = "target";
+
+ public static final String ATTR_TOP = "top";
+
+ public static final String ATTR_BOTTOM = "bottom";
+
+ public static final String ATTR_LEFT = "left";
+
+ public static final String ATTR_RIGHT = "right";
+
+ public static final String ATTR_POSITION = "position";
+
+ public static final String VAL_TRANSPARENT = "transparent";
+
+ public static final String VAL_COLLAPSE = "collapse";
+
+ public static final String VAL_SEPARATE = "separate";
+
+ public static final String ATTR_OVERFLOW = "overflow";
+
+ // border style values
+ public static final String VAL_HIDDEN = "hidden";
+
+ public static final String VAL_DOTTED = "dotted";
+
+ public static final String VAL_DASHED = "dashed";
+
+ public static final String VAL_SOLID = "solid";
+
+ public static final String VAL_DOUBLE = "double";
+
+ public static final String VAL_GROOVE = "groove";
+
+ public static final String VAL_RIDGE = "ridge";
+
+ public static final String VAL_INSET = "inset";
+
+ public static final String VAL_OUTSET = "outset";
+
+ // XXX: we introduce a new style for TD default border style, since it
+ // seemed IE
+ // is using none of the above style for td.
+ public static final String VAL_TDBORDERSTYLE = "__td_border_style__";
+
+ public static final String VAL_THIN = "thin";
+
+ public static final String VAL_THICK = "thick";
+
+ public static final String VAL_INLINE = "inline";
+
+ public static final String VAL_BLOCK = "block";
+
+ public static final String VAL_INLINE_BLOCK = "inline-block";
+
+ public static final String VAL_LIST_ITEM = "list-item";
+
+ public static final String VAL_RUN_IN = "run-in";
+
+ public static final String VAL_COMPACT = "compact";
+
+ public static final String VAL_MARKER = "marker";
+
+ public static final String VAL_TABLE = "table";
+
+ public static final String VAL_INLINE_TABLE = "inline-table";
+
+ public static final String VAL_TABLE_ROW_GROUP = "table-row-group";
+
+ public static final String VAL_TABLE_HEADER_GROUP = "table-header-group";
+
+ public static final String VAL_TABLE_FOOTER_GROUP = "table-footer-group";
+
+ public static final String VAL_TABLE_ROW = "table-row";
+
+ public static final String VAL_TABLE_COLUMN_GROUP = "table-column-group";
+
+ public static final String VAL_TABLE_COLUMN = "table-column";
+
+ public static final String VAL_TABLE_CELL = "table-cell";
+
+ public static final String VAL_TABLE_CAPTION = "table-caption";
+
+ public static final String VAL_NONE = "none";
+
+ public static final String VAL_XX_SMALL = "xx-small";
+
+ public static final String VAL_X_SMALL = "x-small";
+
+ public static final String VAL_SMALL = "small";
+
+ public static final String VAL_MEDIUM = "medium";
+
+ public static final String VAL_LARGE = "large";
+
+ public static final String VAL_X_LARGE = "x-large";
+
+ public static final String VAL_XX_LARGE = "xx-large";
+
+ public static final String VAL_LARGER = "larger";
+
+ public static final String VAL_SMALLER = "smaller";
+
+ public static final String VAL_ITALIC = "italic";
+
+ public static final String VAL_OBLIQUE = "oblique";
+
+ public static final String VAL_NORMAL = "normal";
+
+ public static final String VAL_BOLD = "bold";
+
+ public static final String VAL_BOLDER = "bolder";
+
+ public static final String VAL_LIGHTER = "lighter";
+
+ public static final String VAL_AUTO = "auto";
+
+ public static final String VAL_OUTSIDE = "outside";
+
+ public static final String VAL_INSIDE = "inside";
+
+ public static final String VAL_LEFT = "left";
+
+ public static final String VAL_RIGHT = "right";
+
+ public static final String VAL_CENTER = "center";
+
+ public static final String VAL_JUSTIFY = "justify";
+
+ public static final String VAL_UNDERLINE = "underline";
+
+ public static final String VAL_OVERLINE = "overline";
+
+ public static final String VAL_LINETHROUGH = "line-through";
+
+ public static final String VAL_BLINK = "blink";
+
+ public static final String VAL_PRE = "pre";
+
+ public static final String VAL_NOWRAP = "nowrap";
+
+ public final static String VAL_DISC = "disc"; //$NON-NLS-1$
+
+ public final static String VAL_CIRCLE = "circle"; //$NON-NLS-1$
+
+ public final static String VAL_DECIMAL = "decimal"; //$NON-NLS-1$
+
+ public final static String VAL_CJK_IDEOGRAPHIC = "cjk-ideographic"; //$NON-NLS-1$
+
+ public final static String VAL_DECIMAL_LEADING_ZERO = "decimal-leading-zero"; //$NON-NLS-1$
+
+ public final static String VAL_ARMENIAN = "armenian"; //$NON-NLS-1$
+
+ public final static String VAL_LOWER_ALPHA = "lower-alpha"; //$NON-NLS-1$
+
+ public final static String VAL_LOWER_GREEK = "lower-greek"; //$NON-NLS-1$
+
+ public final static String VAL_LOWER_LATIN = "lower-latin"; //$NON-NLS-1$
+
+ public final static String VAL_LOWER_ROMAN = "lower-roman"; //$NON-NLS-1$
+
+ public final static String VAL_UPPER_ALPHA = "upper-alpha"; //$NON-NLS-1$
+
+ public final static String VAL_UPPER_LATIN = "upper-latin"; //$NON-NLS-1$
+
+ public final static String VAL_UPPER_ROMAN = "upper-roman"; //$NON-NLS-1$
+
+ public final static String VAL_HIRAGANA = "hiragana"; //$NON-NLS-1$
+
+ public final static String VAL_HIRAGANA_IROHA = "hiragana-iroha"; //$NON-NLS-1$
+
+ public final static String VAL_HEBREW = "hebrew"; //$NON-NLS-1$
+
+ public final static String VAL_GEORGIAN = "georgian"; //$NON-NLS-1$
+
+ public final static String VAL_KATAKANA = "katakana"; //$NON-NLS-1$
+
+ public final static String VAL_KATAKANA_IROHA = "katakana-iroha"; //$NON-NLS-1$
+
+ public final static String VAL_SQUARE = "square"; //$NON-NLS-1$
+
+ public final static String VAL_IMAGE = "image"; //$NON-NLS-1$
+
+ public static final String VAL_MULTIPLE = "multiple";
+
+ public static final String VAL_BUTTON = "button";
+
+ public static final String VAL_CHECKBOX = "checkbox";
+
+ public static final String VAL_RADIO = "radio";
+
+ public static final String VAL_FILE = "file";
+
+ public static final String VAL_RESET = "reset";
+
+ public static final String VAL_SUBMIT = "submit";
+
+ public static final String VAL_PASSWORD = "password";
+
+ public static final String VAL_TEXT = "text";
+
+ public static final String VAL_VISIBLE = "visible";
+
+ public static final String VAL_SCROLL = "scroll";
+
+ public static final String TAG_TAGLIB = "taglib";
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyMeta.java
new file mode 100644
index 000000000..6f93c9ac3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ICSSPropertyMeta.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public interface ICSSPropertyMeta {
+ public static final int PERCENTAGE_NONE = 0;
+
+ public static final int PERCENTAGE_BOXSIZE = 1;
+
+ public static final int PERCENTAGE_HEIGHT_CONTAININGBLOCK = 2;
+
+ public static final int PERCENTAGE_FONT = 3;
+
+ public static final int PERCENTAGE_WIDTH_CONTAININGBLOCK = 4;
+
+ public static final Object NOT_SPECIFIED = "NOT_SPECIFIED";
+
+ /**
+ * whether default inherit.
+ *
+ * @return
+ */
+ public boolean isInherited();
+
+ /**
+ * initial value
+ *
+ * @return
+ */
+ public Object getInitialValue(String propertyName, ICSSStyle style);
+
+ public Object getHTMLElementInitialValue(Element element, String htmltag,
+ String propertyName);
+
+ /**
+ * what's percentage value based on.
+ *
+ * @return
+ */
+ public int getPercentageType();
+
+ /**
+ * for many CSS property, there is corresponding HTML attribute can also
+ * specify value for them. This method should check whether the element has
+ * corresponding HTML attribute provide value.
+ *
+ * @param element
+ * the element
+ * @param htmltag
+ * the html tag name. This is for in case element is jsp/jsf
+ * element, and have non html tag name.
+ * @param propertyName
+ * the property name.
+ * @param style
+ * the style
+ * @return null if no attribute override.
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style);
+
+ /**
+ * @param value
+ * @param propertyName
+ * @param style
+ * @return
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style);
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/LengthMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/LengthMeta.java
new file mode 100644
index 000000000..5da2c6c51
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/LengthMeta.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.swt.widgets.Display;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class LengthMeta extends CSSPropertyMeta {
+ private static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_AUTO };
+
+ private static Logger _log = PDPlugin.getLogger(LengthMeta.class);
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public LengthMeta(boolean inherit, Object initvalue) {
+ super(inherit, initvalue);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ if (value == null || value.getCssValueType() == CSSValue.CSS_VALUE_LIST
+ || value.getCssValueType() == CSSValue.CSS_CUSTOM) {
+ return ICSSPropertyID.VAL_AUTO;
+ }
+ if (value.getCssValueType() == CSSValue.CSS_INHERIT) {
+ return ICSSPropertyID.VAL_AUTO;
+ }
+ CSSPrimitiveValue primitive = (CSSPrimitiveValue) value;
+ String key = checkKeywordValues(primitive.getCssText());
+ if (key != null) {
+ return key;
+ }
+ short unitType = primitive.getPrimitiveType();
+ float fvalue;
+ try {
+ fvalue = primitive.getFloatValue(unitType);
+ } catch (DOMException ex) {
+ _log.info("Get length failed, use auto value instead ("
+ + value.getCssText() + ")");
+ return ICSSPropertyID.VAL_AUTO;
+ }
+ return toLength(fvalue, unitType, style, this.getPercentageType(),
+ getBaseFont(style));
+ }
+
+ public static Object toLength(String lengthStr, ICSSStyle style,
+ int percenttype, ICSSFont font) {
+ try {
+ FloatInfo floatinfo = new FloatInfo(lengthStr);
+ return toLength(floatinfo.getValue(), floatinfo.getValueType(),
+ style, percenttype, font);
+ } catch (Exception e) {
+ return ICSSPropertyID.VAL_AUTO;
+ }
+ }
+
+ /**
+ * Will not calculate percentage value. Used for calculate the "width" and
+ * "height" css property
+ *
+ * @param value
+ * @param parentValue
+ * @param font
+ * @return
+ */
+ public static Object toLength(float result, short unitType,
+ ICSSStyle style, int percenttype, ICSSFont font) {
+ switch (unitType) {
+ case CSSPrimitiveValue.CSS_PERCENTAGE:
+ if (percenttype == PERCENTAGE_FONT) {
+ result = (int) ((result * font.getFontSize()) / 100.0);
+ break;
+ }
+ return new Length((int) result, true);
+ case CSSPrimitiveValue.CSS_PX: // no more calculation needed
+ case CSSPrimitiveValue.CSS_NUMBER:
+ break;
+ case CSSPrimitiveValue.CSS_EMS:
+ result *= font.getFontSize();
+ break;
+ case CSSPrimitiveValue.CSS_EXS:
+ result *= font.getXHeight();
+ break;
+ case CSSPrimitiveValue.CSS_CM:
+ result = cmToPixel(result);
+ break;
+ case CSSPrimitiveValue.CSS_IN:
+ result = inToPixel(result);
+ break;
+ case CSSPrimitiveValue.CSS_MM:
+ result = mmToPixel(result);
+ break;
+ case CSSPrimitiveValue.CSS_PT:
+ result = ptToPixel(result);
+ break;
+ case CSSPrimitiveValue.CSS_PC:
+ result = pcToPixel(result);
+ break;
+ case CSSPrimitiveValue.CSS_STRING:
+ return ICSSPropertyID.VAL_AUTO;
+ // FIXME:every thing is delt with?
+ }
+ // ok, when reach here, means we get the float value "result"
+ return new Length((int) result, false);
+ }
+
+ /**
+ * child class can override this method. e.g: font-size style's base font is
+ * parent style's font.
+ *
+ * @param style
+ * @return
+ */
+ protected ICSSFont getBaseFont(ICSSStyle style) {
+ return style.getCSSFont();
+ }
+
+ private static float pcToPixel(float value) {
+ return ptToPixel(12 * value);
+ }
+
+ /**
+ * @param floatValue
+ * @return
+ */
+ private static float ptToPixel(float floatValue) {
+ // the points used by CSS 2.1 are equal to 1/72th of an inch.
+ return inToPixel(floatValue / 72);
+ }
+
+ /**
+ * @param floatValue
+ * @return
+ */
+ private static float mmToPixel(float floatValue) {
+ return cmToPixel(floatValue / 10);
+ }
+
+ /**
+ * @param floatValue
+ * @return
+ */
+ private static float inToPixel(float floatValue) {
+ return getDPI() * floatValue;
+ }
+
+ /**
+ * @param floatValue
+ * @return
+ */
+ private static float cmToPixel(float floatValue) {
+ // 1 inch is equal to 2.54 centimeters
+ return inToPixel((float) (floatValue / 2.54));
+ }
+
+ /**
+ * @return
+ */
+ private static float getDPI() {
+ // XXX: cache the value?
+ return Display.getCurrent().getDPI().x;
+ }
+
+ public static boolean isAuto(Object result) {
+ if (result == ICSSPropertyID.VAL_AUTO) {
+ return true;
+ }
+ if (result instanceof Length && ((Length) result).getValue() <= 0) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleImageMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleImageMeta.java
new file mode 100644
index 000000000..e87208009
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleImageMeta.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class ListStyleImageMeta extends CSSPropertyMeta {
+ private static final String INITIAL_VALUE = ICSSPropertyID.VAL_NONE;
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public ListStyleImageMeta() {
+ super(true, INITIAL_VALUE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ return DOMUtil.getAttributeIgnoreCase(element,
+ ICSSPropertyID.ATTR_LIST_STYLE_IMAGE);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStylePositionMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStylePositionMeta.java
new file mode 100644
index 000000000..c6c8cef40
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStylePositionMeta.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ */
+public class ListStylePositionMeta extends CSSPropertyMeta {
+ private static final String INITIAL_VALUE = ICSSPropertyID.VAL_OUTSIDE;
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public ListStylePositionMeta() {
+ super(true, INITIAL_VALUE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleTypeMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleTypeMeta.java
new file mode 100644
index 000000000..bf6d4641a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/ListStyleTypeMeta.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class ListStyleTypeMeta extends CSSPropertyMeta {
+ private static final String INITIAL_VALUE = ICSSPropertyID.VAL_DISC;
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public ListStyleTypeMeta() {
+ super(true, INITIAL_VALUE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.style.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ return value.getCssText();
+ }
+
+ // /*
+ // * (non-Javadoc)
+ // *
+ // * @see
+ // org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ // java.lang.String, java.lang.String,
+ // org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ // */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ String listStyle = DOMUtil.getAttributeIgnoreCase(element, "type");
+ if (listStyle == null && element != null
+ && element.getParentNode() != null) {
+ listStyle = DOMUtil.getAttributeIgnoreCase((Element) element
+ .getParentNode(), "type");
+ }
+ if (listStyle != null) {
+ listStyle = listStyle.trim();
+ if (listStyle.equals("1")) {
+ return ICSSPropertyID.VAL_DECIMAL;
+ } else if (listStyle.equals("a")) {
+ return ICSSPropertyID.VAL_LOWER_ALPHA;
+ } else if (listStyle.equals("A")) {
+ return ICSSPropertyID.VAL_UPPER_ALPHA;
+ } else if (listStyle.equals("i")) {
+ return ICSSPropertyID.VAL_LOWER_ROMAN;
+ } else if (listStyle.equals("I")) {
+ return ICSSPropertyID.VAL_UPPER_ROMAN;
+ }
+ return listStyle;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/MarginWidthMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/MarginWidthMeta.java
new file mode 100644
index 000000000..f5d23c470
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/MarginWidthMeta.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ */
+public class MarginWidthMeta extends LengthMeta {
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public MarginWidthMeta() {
+ super(false, ICSSPropertyID.VAL_AUTO);
+ }
+
+ /**
+ * @param propertyName
+ * @return
+ */
+ public static boolean isMarginWidth(String propertyName) {
+ return ICSSPropertyID.ATTR_MARGIN_BOTTOM.equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_MARGIN_TOP
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_MARGIN_LEFT
+ .equalsIgnoreCase(propertyName)
+ || ICSSPropertyID.ATTR_MARGIN_RIGHT
+ .equalsIgnoreCase(propertyName);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/OverflowMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/OverflowMeta.java
new file mode 100644
index 000000000..6014eb610
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/OverflowMeta.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class OverflowMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_VISIBLE,
+ ICSSPropertyID.VAL_HIDDEN, ICSSPropertyID.VAL_SCROLL,
+ ICSSPropertyID.VAL_AUTO };
+
+ public OverflowMeta() {
+ super(false, ICSSPropertyID.VAL_VISIBLE);
+ }
+
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String display = style.getDisplay();
+ // we only support overflow for "block". Which means we don't support it
+ // for table/inline-block, etc.
+ if (!"block".equalsIgnoreCase(display)) {
+ return ICSSPropertyID.VAL_VISIBLE;
+ }
+ return super.calculateCSSValueResult(value, propertyName, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PaddingWidthMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PaddingWidthMeta.java
new file mode 100644
index 000000000..a91a89260
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PaddingWidthMeta.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class PaddingWidthMeta extends LengthMeta {
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public PaddingWidthMeta() {
+ super(false, ICSSPropertyID.VAL_AUTO);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (IHTMLConstants.TAG_TD.equalsIgnoreCase(htmltag)
+ || IHTMLConstants.TAG_TH.equalsIgnoreCase(htmltag)) {
+ Node parent = element;
+ Element tableEle = null;
+ while ((parent = parent.getParentNode()) != null
+ && parent instanceof Element) {
+ if (((Element) parent).getTagName().equalsIgnoreCase(
+ IHTMLConstants.TAG_TABLE)) {
+ tableEle = (Element) parent;
+ break;
+ }
+ }
+ if (tableEle != null) {
+ String padding = DOMUtil.getAttributeIgnoreCase(tableEle,
+ "cellpadding");//$NON-NLS-1$
+ if (padding != null) {
+ return LengthMeta.toLength(padding, style, this
+ .getPercentageType(), getBaseFont(style));
+ }
+ }
+ }
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionMeta.java
new file mode 100644
index 000000000..28cafbaf2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionMeta.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PositionMeta extends CSSPropertyMeta {
+ public static final String STATIC = "static";
+
+ public static final String ABSOLUTE = "absolute";
+
+ public static final String RELATIVE = "relative";
+
+ public static final String FIXED = "fixed";
+
+ public static final String[] _keywords = new String[] { STATIC, ABSOLUTE,
+ RELATIVE, FIXED };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public PositionMeta() {
+ super(false, STATIC);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return _keywords;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionOffsetMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionOffsetMeta.java
new file mode 100644
index 000000000..f96864d5a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/PositionOffsetMeta.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PositionOffsetMeta extends LengthMeta {
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public PositionOffsetMeta() {
+ super(false, ICSSPropertyID.VAL_AUTO);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TableUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TableUtil.java
new file mode 100644
index 000000000..1415cef67
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TableUtil.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableUtil {
+ static final String TOP = "top";
+
+ static final String BOTTOM = "bottom";
+
+ static final String LEFT = "left";
+
+ static final String RIGHT = "right";
+
+ public static boolean matchFrame(String edge, String frame) {
+ if ("above".equalsIgnoreCase(frame)) {
+ return TOP.equalsIgnoreCase(edge);
+ } else if ("below".equalsIgnoreCase(frame)) {
+ return BOTTOM.equalsIgnoreCase(edge);
+ } else if ("hsides".equalsIgnoreCase(frame)) {
+ return TOP.equalsIgnoreCase(edge) || BOTTOM.equalsIgnoreCase(edge);
+ } else if ("vsides".equalsIgnoreCase(frame)) {
+ return LEFT.equalsIgnoreCase(edge) || RIGHT.equalsIgnoreCase(edge);
+ } else if ("lhs".equalsIgnoreCase(frame)) {
+ return LEFT.equalsIgnoreCase(edge);
+ } else if ("rhs".equalsIgnoreCase(frame)) {
+ return RIGHT.equalsIgnoreCase(edge);
+ } else if ("box".equalsIgnoreCase(frame)
+ || "border".equalsIgnoreCase(frame)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param string
+ * @param rules
+ * @return
+ */
+ public static boolean matchRules(String edge, String rules) {
+ // TODO: "groups" not supported.
+
+ if ("rows".equalsIgnoreCase(rules)) {
+ return TOP.equalsIgnoreCase(edge) || BOTTOM.equalsIgnoreCase(edge);
+ } else if ("cols".equalsIgnoreCase(rules)) {
+ return LEFT.equalsIgnoreCase(edge) || RIGHT.equalsIgnoreCase(edge);
+ } else if ("all".equalsIgnoreCase(rules)) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * @param element
+ * @return
+ * @see http://www.w3.org/TR/CSS21/tables.html#empty-cells
+ */
+ public static boolean isEmptyCell(Element element) {
+ NodeList children = element.getChildNodes();
+ if (children.getLength() == 0) {
+ return true;
+ }
+ // we only do simple checking here. When the element has one child
+ // and is text and is whitespace only, then we also treat as empty cell
+ if (children.getLength() == 1) {
+ Node child = children.item(0);
+ if (child instanceof Text) {
+ String text = child.getNodeValue();
+ if (HTMLUtil.isHTMLWhitespaceString(text)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextAlignMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextAlignMeta.java
new file mode 100644
index 000000000..2e07141dc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextAlignMeta.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import java.util.Arrays;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class TextAlignMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_LEFT,
+ ICSSPropertyID.VAL_RIGHT, ICSSPropertyID.VAL_CENTER,
+ ICSSPropertyID.VAL_JUSTIFY };
+
+ private static final String[] HOR_SLIGN_HTMLTAGS = new String[] {
+ IHTMLConstants.TAG_TABLE, IHTMLConstants.TAG_HR,
+ IHTMLConstants.TAG_LEGEND, IHTMLConstants.TAG_APPLET,
+ IHTMLConstants.TAG_IFRAME, IHTMLConstants.TAG_IMG,
+ IHTMLConstants.TAG_INPUT, IHTMLConstants.TAG_OBJECT,
+ IHTMLConstants.TAG_CAPTION };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public TextAlignMeta() {
+ super(true, NOT_SPECIFIED);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ // /for td, it may look for the attribute value up to tr, but must stop
+ // at table.
+ // so for table,set _inherited=false to stop it.
+ if (IHTMLConstants.TAG_TABLE.equalsIgnoreCase(htmltag)) {
+ this._inherited = false;
+ } else {
+ this._inherited = true;
+ }
+ if (Arrays.asList(HOR_SLIGN_HTMLTAGS).contains(htmltag.toLowerCase())) {
+ return null;
+ }
+
+ String align = DOMUtil.getAttributeIgnoreCase(element,
+ IHTMLConstants.ATTR_ALIGN);
+ String value = checkKeywordValues(align);
+ if (value != null) {
+ return value;
+ }
+ if ("middle".equalsIgnoreCase(align)) {
+ return ICSSPropertyID.VAL_CENTER;
+ }
+
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextDecorationMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextDecorationMeta.java
new file mode 100644
index 000000000..19833a15d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/TextDecorationMeta.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.CSSValueList;
+
+/**
+ * @author mengbo
+ */
+public class TextDecorationMeta extends CSSPropertyMeta {
+ public static final int NONE = 0;
+
+ public static final int UNDERLINE = 1;
+
+ public static final int OVERLINE = 1 << 1;
+
+ public static final int LINETHROUGH = 1 << 2;
+
+ public static final int BLINK = 1 << 3;
+
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_NONE,
+ ICSSPropertyID.VAL_UNDERLINE, ICSSPropertyID.VAL_OVERLINE,
+ ICSSPropertyID.VAL_LINETHROUGH, ICSSPropertyID.VAL_BLINK };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public TextDecorationMeta() {
+ // the spec say text-decoration is not inherited. but the description
+ // seemed to make use inherit easier.
+ // It seems that the property is inherited in IE and Mozilla.
+ super(true, new Integer(NONE));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateCSSValueResult(org.w3c.dom.css.CSSValue,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.property.AbstractStyle)
+ */
+ public Object calculateCSSValueResult(CSSValue value, String propertyName,
+ ICSSStyle style) {
+ String[] decorations = null;
+ if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
+ CSSValueList valueList = (CSSValueList) value;
+ decorations = new String[valueList.getLength()];
+ for (int i = 0; i < decorations.length; i++) {
+ decorations[i] = ((CSSValue) valueList.item(i)).getCssText();
+ }
+ } else {
+ decorations = new String[1];
+ decorations[0] = value.getCssText();
+ }
+
+ int intvalue = 0;
+ for (int i = 0; i < decorations.length; i++) {
+ String key = super.checkKeywordValues(decorations[i]);
+ if (key == ICSSPropertyID.VAL_NONE) {
+ intvalue = NONE;
+ } else if (key == ICSSPropertyID.VAL_UNDERLINE) {
+ intvalue |= UNDERLINE;
+ } else if (key == ICSSPropertyID.VAL_OVERLINE) {
+ intvalue |= OVERLINE;
+ } else if (key == ICSSPropertyID.VAL_LINETHROUGH) {
+ intvalue |= LINETHROUGH;
+ } else if (key == ICSSPropertyID.VAL_BLINK) {
+ intvalue |= BLINK;
+ }
+ }
+
+ return new Integer(intvalue);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VerticalAlignMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VerticalAlignMeta.java
new file mode 100644
index 000000000..5720b8476
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VerticalAlignMeta.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class VerticalAlignMeta extends LengthMeta {
+ public static final String BASELINE = "baseline"; //$NON-NLS-1$
+
+ public static final String MIDDLE = "middle"; //$NON-NLS-1$
+
+ public static final String SUB = "sub"; //$NON-NLS-1$
+
+ public static final String SUPER = "super"; //$NON-NLS-1$
+
+ public static final String TEXT_TOP = "text-top"; //$NON-NLS-1$
+
+ public static final String TEXT_BOTTOM = "text-bottom"; //$NON-NLS-1$
+
+ public static final String TOP = "top"; //$NON-NLS-1$
+
+ public static final String BOTTOM = "bottom"; //$NON-NLS-1$
+
+ public static final String CENTER = "center"; //$NON-NLS-1$
+
+ public static final String DEFAULT_VERTICAL_ALIGN = BASELINE;
+
+ private static final String[] KEYWORDS = new String[] { BASELINE, MIDDLE,
+ SUB, SUPER, TEXT_TOP, TEXT_BOTTOM, TOP, BOTTOM };
+
+ private static final String[] htmlAttributes = new String[] { IHTMLConstants.ATTR_VALIGN };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public VerticalAlignMeta() {
+ super(true, DEFAULT_VERTICAL_ALIGN);
+ }
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public VerticalAlignMeta(boolean inherit, Object initvalue) {
+ super(inherit, initvalue);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ for (int i = 0; i < htmlAttributes.length; i++) {
+ String align = DOMUtil.getAttributeIgnoreCase(element,
+ htmlAttributes[i]);
+ if (TOP.equalsIgnoreCase(align)) {
+ return TOP;
+ }
+ if (MIDDLE.equalsIgnoreCase(align)) {
+ return MIDDLE;
+ }
+ if (BOTTOM.equalsIgnoreCase(align)) {
+ return BOTTOM;
+ }
+ if (BASELINE.equalsIgnoreCase(align)) {
+ return BASELINE;
+ }
+ if (CENTER.equalsIgnoreCase(align)) {
+ return MIDDLE;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VisibilityMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VisibilityMeta.java
new file mode 100644
index 000000000..668bbd3ff
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/VisibilityMeta.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class VisibilityMeta extends CSSPropertyMeta {
+ public static final String VISIBLE = "visible";
+
+ public static final String HIDDEN = "hidden";
+
+ public static final String COLLAPSE = "collapse";
+
+ public static final String[] KEYWORDS = new String[] { VISIBLE, HIDDEN,
+ COLLAPSE };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public VisibilityMeta() {
+ super(true, VISIBLE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WhiteSpaceMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WhiteSpaceMeta.java
new file mode 100644
index 000000000..afcb81ef6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WhiteSpaceMeta.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class WhiteSpaceMeta extends CSSPropertyMeta {
+ static final String[] KEYWORDS = new String[] { ICSSPropertyID.VAL_NORMAL,
+ ICSSPropertyID.VAL_PRE, ICSSPropertyID.VAL_NOWRAP };
+
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public WhiteSpaceMeta() {
+ super(true, ICSSPropertyID.VAL_NORMAL);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#getKeywordValues()
+ */
+ protected String[] getKeywordValues() {
+ return KEYWORDS;
+ }
+
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (IHTMLConstants.TAG_TD.equalsIgnoreCase(htmltag)
+ || IHTMLConstants.TAG_TH.equalsIgnoreCase(htmltag)) {
+ String noWrap = DOMUtil.getAttributeIgnoreCase(element,
+ IHTMLConstants.ATTR_NOWRAP);
+ if (Boolean.TRUE.toString().equalsIgnoreCase(noWrap)) {
+ return ICSSPropertyID.VAL_NOWRAP;
+ }
+ }
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WidthMeta.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WidthMeta.java
new file mode 100644
index 000000000..1f5851e13
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/property/WidthMeta.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.property;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class WidthMeta extends LengthMeta {
+ /**
+ * @param inherit
+ * @param initvalue
+ */
+ public WidthMeta() {
+ super(false, ICSSPropertyID.VAL_AUTO);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.property.CSSPropertyMeta#calculateHTMLAttributeOverride(org.w3c.dom.Element,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.css2.ICSSStyle)
+ */
+ public Object calculateHTMLAttributeOverride(Element element,
+ String htmltag, String propertyName, ICSSStyle style) {
+ if (!IHTMLConstants.TAG_INPUT.equalsIgnoreCase(htmltag)
+ && !IHTMLConstants.TAG_BUTTON.equalsIgnoreCase(htmltag)) {
+ String width = DOMUtil
+ .getAttributeIgnoreCase(element, propertyName);
+ if (width != null) {
+ return LengthMeta.toLength(width, style, this
+ .getPercentageType(), getBaseFont(style));
+ }
+ }
+ return super.calculateHTMLAttributeOverride(element, htmltag,
+ propertyName, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/DimensionInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/DimensionInfo.java
new file mode 100644
index 000000000..74454aa65
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/DimensionInfo.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.provider;
+
+import org.eclipse.draw2d.geometry.Dimension;
+
+/**
+ * This is a struct, include a dimension and a ascent info.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class DimensionInfo {
+ Dimension _dimension;
+
+ int _ascent;
+
+ /**
+ *
+ * @param d
+ * @param ascent
+ * -1 means ascent is same as dimension height
+ */
+ public DimensionInfo(Dimension d, int ascent) {
+ this._dimension = d;
+ this._ascent = ascent;
+ }
+
+ /**
+ * @param width
+ * @param height
+ * @param i
+ */
+ public DimensionInfo(int width, int height, int i) {
+ this(new Dimension(width, height), i);
+ }
+
+ public Dimension getDimension() {
+ return _dimension;
+ }
+
+ public int getAscent() {
+ return _ascent;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSTextProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSTextProvider.java
new file mode 100644
index 000000000..f5446aead
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSTextProvider.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.provider;
+
+/**
+ * This class behave as the information provider of CSSTextFigure.
+ *
+ * @author mengbo
+ */
+public interface ICSSTextProvider {
+ /**
+ * get the style.
+ *
+ * @return can't be null
+ */
+ // public ICSSStyle getCSSStyle();
+ /**
+ * this is the final data to be displayed. There is no need for the
+ * CSSTextFigure to normalize it.
+ *
+ * @return
+ */
+ public String getTextData();
+
+ /**
+ * get the selected information.
+ *
+ * @return
+ */
+ public int[] getSelectedRange();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSWidgetProvider.java
new file mode 100644
index 000000000..b1b8a12c6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/provider/ICSSWidgetProvider.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.provider;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+
+/**
+ * @author mengbo
+ */
+public interface ICSSWidgetProvider {
+ /**
+ * can be null
+ *
+ * @return
+ */
+ public ICSSStyle getCSSStyle();
+
+ public boolean isHandlingBorder();
+
+ /**
+ * whether the parameter and return value includes border depends on the
+ * isHandlingBorder
+ *
+ * @param width
+ * -1 means no suggested value
+ * @param height
+ * -1 means no suggested value
+ * @return
+ */
+ public DimensionInfo getPreferredDimension(int width, int height);
+
+ /**
+ * if isHandlingBorder return false, then "rect" will be the rect without
+ * border, and this method should not paint border.
+ *
+ * If isHandlingBorder returns true, then "rect" include border, and this
+ * method should also paint its own border.
+ *
+ * @param rect
+ */
+ public void paintFigure(Graphics g, Rectangle rect);
+
+ /**
+ * @return
+ */
+ public boolean isInline();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/AbstractStyle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/AbstractStyle.java
new file mode 100644
index 000000000..706cb118a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/AbstractStyle.java
@@ -0,0 +1,662 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.CSSUtil;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.CSSFontManager;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFontManager;
+import org.eclipse.jst.pagedesigner.css2.list.CounterHelper;
+import org.eclipse.jst.pagedesigner.css2.list.CounterValueGenerator;
+import org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator;
+import org.eclipse.jst.pagedesigner.css2.property.CSSMetaRegistry;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * @author mengbo
+ */
+public class AbstractStyle implements ICSSStyle {
+ public static final String ATTR_NAME = "name";
+
+ public static final String ATTR_ID = "id";
+
+ protected Element _element;
+
+ private Map _cachedValues = new HashMap();
+
+ private ICSSFont _font = null;
+
+ private CSSStyleDeclaration _cache;
+
+ private CSSStyleDeclaration _defaultCache;
+
+ private boolean _cssDeclareWasSearched = false;
+
+ private boolean _cssDefaultDeclareWasSearched = false;
+
+ private Insets _borderInsets, _marginInsets, _paddingInsets;
+
+ private ICSSStyle _parentStyle;
+
+ private HashMap _counters = null;
+
+ public Element getElement() {
+ return _element;
+ }
+
+ public AbstractStyle(Element element) {
+ _element = element;
+ }
+
+ /**
+ * reset all the cache.
+ */
+ public void reset() {
+ _cachedValues.clear();
+ _font = null;
+ _cache = null;
+ _defaultCache = null;
+ _cssDeclareWasSearched = false;
+ _cssDefaultDeclareWasSearched = false;
+ // if (_counters != null)
+ // {
+ // unregistCounter();
+ // _counters.clear();
+ // _counters = null;
+ // }
+ _borderInsets = _marginInsets = _paddingInsets = null;
+ }
+
+ /**
+ * this is a hook method so caller can use it to override default
+ * calculation. Note, after the call to <code>reset</code>, it will be
+ * lost.
+ *
+ * @param property
+ * @param value
+ */
+ public void setStyleProperty(String property, Object value) {
+ _cachedValues.put(property, value);
+ }
+
+ /**
+ * get a style property value.
+ *
+ * @param property
+ * @return
+ */
+ public Object getStyleProperty(String property) {
+ Object value = _cachedValues.get(property);
+ if (value == null) {
+ value = calculateProperty(property);
+ if (value != null) {
+ _cachedValues.put(property, value);
+ }
+ }
+ return value;
+ }
+
+ /**
+ * in this method, should first check the "style" attribute, then combine
+ * that with document style.
+ *
+ * @return
+ */
+ protected CSSStyleDeclaration calculateDeclaration() {
+ String name = getHtmlElement().getAttribute("id");
+ if (name == null || name.length() == 0) {
+ name = getHtmlElement().getAttribute("name");
+ }
+ return CSSUtil.getCSSDeclaration(this.getHtmlElement(), name);
+ }
+
+ protected CSSStyleDeclaration calculateDefaultDeclaration() {
+ return CSSUtil.getDefaultCSSDeclaration(this.getHtmlElement(), null);
+ }
+
+ public CSSStyleDeclaration getDeclaration() {
+ // FIXME:may need to be change, boolean variable is not a best way.
+ if (!_cssDeclareWasSearched) {
+ _cache = calculateDeclaration();
+ _cssDeclareWasSearched = true;
+ }
+ return _cache;
+ }
+
+ public CSSStyleDeclaration getDefaultDeclaration() {
+ // FIXME:may need to be change, boolean variable is not a best way.
+ if (!_cssDefaultDeclareWasSearched) {
+ _defaultCache = calculateDefaultDeclaration();
+ _cssDefaultDeclareWasSearched = true;
+ }
+ return _defaultCache;
+ }
+
+ public Object getHTMLelementInitValue(String propertyName) {
+ ICSSPropertyMeta meta = getPropertyMeta(propertyName);
+ if (meta != null) {
+ Object obj = meta.getHTMLElementInitialValue(_element,
+ getHTMLTag(), propertyName);
+ if (obj == null) {
+ obj = meta.getInitialValue(propertyName, this);
+ }
+ return obj;
+ }
+ return ICSSPropertyMeta.NOT_SPECIFIED;
+ }
+
+ protected Object calculateProperty(String propertyName) {
+ ICSSPropertyMeta meta = getPropertyMeta(propertyName);
+ Object result = null;
+ // get declaration
+ CSSStyleDeclaration decl = getDeclaration();
+ CSSValue value = decl == null ? null : decl
+ .getPropertyCSSValue(propertyName);
+ if (value == null) {
+ if (meta != null) {
+ result = meta.calculateHTMLAttributeOverride(_element,
+ getHTMLTag(), propertyName, this);
+ if (result != null) {
+ return result;
+ }
+ }
+ decl = getDefaultDeclaration();
+ }
+ value = decl == null ? null : decl.getPropertyCSSValue(propertyName);
+
+ if (value != null && value.getCssValueType() == CSSValue.CSS_INHERIT) {
+ result = getParentResultValue(meta, propertyName);
+ } else if (value == null) {
+ if (meta != null) {
+ result = meta.calculateHTMLAttributeOverride(_element,
+ getHTMLTag(), propertyName, this);
+ }
+ if (result == null) {
+ result = calculateLocalOverride(meta, propertyName);
+ }
+ if (result == null) {
+ if (meta == null) {
+ result = ICSSPropertyMeta.NOT_SPECIFIED;
+ } else {
+ if (meta.isInherited()) {
+ result = getParentResultValue(meta, propertyName);
+ } else {
+ result = meta.getInitialValue(propertyName, this);
+ }
+ }
+ }
+ } else {
+ result = calculateCSSValueResult(meta, value, propertyName);
+ }
+ return result;
+ }
+
+ /**
+ * get the corresponding HTML tag for this style. This is for certain HTML
+ * tag can also provide style information.
+ *
+ * @return
+ */
+ protected String getHTMLTag() {
+ return _element.getTagName();
+ }
+
+ /**
+ * @param propertyName
+ * @return
+ */
+ protected ICSSPropertyMeta getPropertyMeta(String propertyName) {
+ return CSSMetaRegistry.getInstance().getMeta(propertyName);
+ }
+
+ /**
+ * convert the CSSValue to the property type specified data result.
+ *
+ * @param value
+ * @param propertyName
+ * @return should not return null.
+ */
+ protected Object calculateCSSValueResult(ICSSPropertyMeta meta,
+ CSSValue value, String propertyName) {
+ if (meta == null) {
+ return ICSSPropertyMeta.NOT_SPECIFIED;
+ } else {
+ return meta.calculateCSSValueResult(value, propertyName, this);
+ }
+ }
+
+ /**
+ * it is possible that some attribute of the element may provide style
+ * information. child class should override this method. Also, some element
+ * type may have internally build style, such as input-submit may use
+ * special border. NOTE: it is very important that in calculateLocalOverride
+ * you don't directly or indirectly call getStyleProperty() to avoid
+ * deadloop.
+ *
+ * @param propertyName
+ * @return null means no style information in other attributes. Otherwise
+ * return property specific data result -- normally will use meta to
+ * convert the attribute.
+ */
+ protected Object calculateLocalOverride(ICSSPropertyMeta meta,
+ String propertyName) {
+ // // do some default margin thing.
+ // if (ICSSPropertyID.ATTR_MARGIN_RIGHT.equalsIgnoreCase(propertyName)
+ // || ICSSPropertyID.ATTR_MARGIN_BOTTOM.equalsIgnoreCase(propertyName))
+ // {
+ // return MARGIN_LENGTH;
+ // }
+ // else if
+ // (ICSSPropertyID.ATTR_MARGIN_LEFT.equalsIgnoreCase(propertyName))
+ // {
+ // // to make a little room, so it is possible for user to position the
+ // // mouse before the first element in a block.
+ // return MARGIN_LEFT;
+ // }
+ return null;
+ }
+
+ /**
+ * This is only called when inherit value from parent.
+ *
+ * @param propertyName
+ * @return
+ */
+ protected Object getParentResultValue(ICSSPropertyMeta meta,
+ String propertyName) {
+ ICSSStyle style = getParentStyle();
+ return style.getStyleProperty(propertyName);
+ }
+
+ public void setParentStyle(ICSSStyle parentStyle) {
+ this._parentStyle = parentStyle;
+ reset();
+ }
+
+ public ICSSStyle getParentStyle() {
+ if (_parentStyle != null) {
+ return _parentStyle;
+ }
+ Node node = _element.getParentNode();
+ while (node instanceof Element && node instanceof INodeNotifier) {
+ ICSSStyle parentStyle = (ICSSStyle) ((INodeNotifier) node)
+ .getAdapterFor(ICSSStyle.class);
+ if (parentStyle != null) {
+ return parentStyle;
+ } else {
+ node = node.getParentNode();
+ }
+ }
+ return DefaultStyle.getInstance();
+ }
+
+ /**
+ * Will not return null
+ *
+ * @return
+ */
+ public ICSSFont getCSSFont() {
+ if (_font == null) {
+ _font = getFontManager().createFont(this);
+ }
+ return _font;
+ }
+
+ /**
+ * @return
+ */
+ private ICSSFontManager getFontManager() {
+ return CSSFontManager.getInstance();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#dispose()
+ */
+ public void dispose() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getMarginInsets()
+ */
+ public Insets getMarginInsets() {
+ if (_marginInsets == null) {
+ int top = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_TOP);
+ int left = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_LEFT);
+ int bottom = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_BOTTOM);
+ int right = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_RIGHT);
+ _marginInsets = new Insets(top, left, bottom, right);
+ }
+ return _marginInsets;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getPaddingInsets()
+ */
+ public Insets getPaddingInsets() {
+ if (_paddingInsets == null) {
+ int top = getInsetProperty(ICSSPropertyID.ATTR_PADDING_TOP);
+ int left = getInsetProperty(ICSSPropertyID.ATTR_PADDING_LEFT);
+ int bottom = getInsetProperty(ICSSPropertyID.ATTR_PADDING_BOTTOM);
+ int right = getInsetProperty(ICSSPropertyID.ATTR_PADDING_RIGHT);
+ _paddingInsets = new Insets(top, left, bottom, right);
+ }
+ return _paddingInsets;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getBorderInsets()
+ */
+ public Insets getBorderInsets() {
+ if (_borderInsets == null) {
+ int top = getInsetProperty(ICSSPropertyID.ATTR_BORDER_TOP_WIDTH);
+ int left = getInsetProperty(ICSSPropertyID.ATTR_BORDER_LEFT_WIDTH);
+ int bottom = getInsetProperty(ICSSPropertyID.ATTR_BORDER_BOTTOM_WIDTH);
+ int right = getInsetProperty(ICSSPropertyID.ATTR_BORDER_RIGHT_WIDTH);
+ _borderInsets = new Insets(top, left, bottom, right);
+ }
+ return _borderInsets;
+ }
+
+ /**
+ * @param border_top_width
+ * @return
+ */
+ private int getInsetProperty(String propertyName) {
+ Object obj = this.getStyleProperty(propertyName);
+ if (obj instanceof Length) {
+ Length l = (Length) obj;
+ if (l.isPercentage()) {
+ return 0; // FIXME:
+ } else {
+ return l.getValue();
+ }
+ }
+
+ return 0;
+ }
+
+ public boolean isAdapterForType(Object type) {
+ return (type == ICSSStyle.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#isSizeIncludeBorderPadding()
+ */
+ public boolean isSizeIncludeBorderPadding() {
+ String display = this.getDisplay();
+ if ("table-cell".equalsIgnoreCase(display)) {
+ return false;
+ }
+ String tag = this.getHTMLTag();
+ if ("img".equalsIgnoreCase(tag)) {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.sse.model.INodeAdapter#notifyChanged(com.ibm.sse.model.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getBackgroundColor()
+ */
+ public Object getColor() {
+ Object _color = null;
+ if (_color == null) {
+ _color = getStyleProperty(ICSSPropertyID.ATTR_COLOR);
+ if (_color == null) {
+ _color = getStyleProperty(ICSSPropertyID.ATTR_TEXTCOLOR);
+ }
+ }
+ return _color;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getColor()
+ */
+ public Object getBackgroundColor() {
+ Object _backgroundColor = null;
+ if (_backgroundColor == null) {
+ _backgroundColor = getStyleProperty(ICSSPropertyID.ATTR_BACKGROUND_COLOR);
+ }
+ return _backgroundColor;
+ }
+
+ public Element getHtmlElement() {
+ // if (_element instanceof IDOMElement)
+ // {
+ // EditPart part = (EditPart) ((IDOMElement)
+ // _element).getAdapterFor(EditPart.class);
+ // if (part instanceof ElementEditPart)
+ // {
+ // ElementEditPart elementPart = (ElementEditPart) part;
+ // ITagHandler h = elementPart.getTagHandler();
+ // if (h != null)
+ // {
+ // return h.mapCustomElement(_element);
+ // }
+ // }
+ //
+ // }
+ return _element;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getDisplay()
+ */
+ public String getDisplay() {
+ Object display = this.getStyleProperty(ICSSPropertyID.ATTR_DISPLAY);
+ String displayStr;
+ if (display == null) {
+ displayStr = ICSSPropertyID.VAL_INLINE;
+ } else if (display instanceof String) {
+ displayStr = (String) display;
+ } else {
+ displayStr = display.toString();
+ }
+ if (ICSSPropertyID.VAL_INLINE.equalsIgnoreCase(displayStr)
+ && IHTMLConstants.TAG_TABLE.equalsIgnoreCase(getHTMLTag())) {
+ return ICSSPropertyID.VAL_INLINE_TABLE;
+ }
+ if (ICSSPropertyID.VAL_INLINE.equalsIgnoreCase(displayStr)) {
+ Object width = this.getStyleProperty(ICSSPropertyID.ATTR_WIDTH);
+ if (width instanceof Length) {
+ return ICSSPropertyID.VAL_INLINE_BLOCK;
+ }
+ Object height = this.getStyleProperty(ICSSPropertyID.ATTR_HEIGHT);
+ if (height instanceof Length) {
+ return ICSSPropertyID.VAL_INLINE_BLOCK;
+ }
+ return displayStr;
+ } else {
+ return displayStr;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getListStyle()
+ */
+ public Map getCounters() {
+ if (_counters == null) {
+ _counters = new HashMap();
+ CounterHelper.processCounterReset(this, _counters);
+ }
+ return _counters;
+ }
+
+ /**
+ * Get named counter from counters.
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getCounter(java.lang.String)
+ */
+ public ICounterValueGenerator findCounter(String name, boolean must) {
+ Map counters = getCounters();
+ if (counters == null || !counters.containsKey(name)) {
+ if (getParentStyle() != null
+ && !(getParentStyle() instanceof DefaultStyle)) {
+ // ensure it is registered somewhere.
+ return getParentStyle().findCounter(name, must);
+ }
+ // must is called by counter-increment
+ else if (must) {
+ // the caller should do the other setting.
+ ICounterValueGenerator counter = new CounterValueGenerator(
+ name, null, null, this);
+ counter.resetCount();
+ counters.put(name, counter);
+ }
+ }
+ return (ICounterValueGenerator) counters.get(name);
+ }
+
+ /**
+ * @param buffer
+ */
+ public void dumpDebugInfo(StringBuffer buffer) {
+ if (_cache != null) {
+ buffer.append("cache:\n");
+ buffer.append(_cache.getCssText()).append("\n");
+ }
+ if (_defaultCache != null) {
+ buffer.append("default cache:\n");
+ buffer.append(_defaultCache.getCssText()).append("\n");
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getColSpan()
+ */
+ public int getColSpan() {
+ int colspan = DOMUtil.getIntAttributeIgnoreCase(getHtmlElement(),
+ "colspan", 1);
+ // if span == 0, means span all col from the current column to end
+ // colume
+ if (colspan < 0) {
+ return 1;
+ } else {
+ return colspan;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getRowSpan()
+ */
+ public int getRowSpan() {
+ int rowspan = DOMUtil.getIntAttributeIgnoreCase(getHtmlElement(),
+ "rowspan", 1);
+ if (rowspan < 0) {
+ return 1;
+ } else {
+ return rowspan;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#isInSelection()
+ */
+ public boolean isInSelection() {
+ IRangeSelectionProxy proxy = (IRangeSelectionProxy) getAdapter(IRangeSelectionProxy.class);
+ if (proxy != null) {
+ return proxy.isRangeSelected();
+ }
+ ICSSStyle parentStyle = getParentStyle();
+ if (parentStyle != null) {
+ return parentStyle.isInSelection();
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ if (this._element instanceof INodeNotifier) {
+ Object ret = ((INodeNotifier) _element).getAdapterFor(adapter);
+ if (ret != null && adapter.isInstance(ret)) {
+ return ret;
+ }
+ }
+ return null;
+ }
+
+ // private void unregistCounter()
+ // {
+ // if (_counters != null)
+ // {
+ // Collection c = _counters.values();
+ // Iterator iter = c.iterator();
+ // while (iter.hasNext())
+ // {
+ // Counter2 counter = (Counter2) iter.next();
+ // counter.unregist(this);
+ // }
+ // }
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#resetCounters()
+ */
+ public void processCounters() {
+ this._counters = null;
+ CounterHelper.processCounterIncrement(this);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ControlOverrideSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ControlOverrideSupport.java
new file mode 100644
index 000000000..d8d67df55
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ControlOverrideSupport.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.jst.pagedesigner.css2.property.BorderStyleMeta;
+import org.eclipse.jst.pagedesigner.css2.property.BorderWidthMeta;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+import org.eclipse.jst.pagedesigner.css2.property.TextDecorationMeta;
+import org.eclipse.jst.pagedesigner.css2.value.Length;
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * This class provides support for setting default styles of certain UI
+ * controls.
+ *
+ * @author mengbo
+ */
+public class ControlOverrideSupport {
+ static Color _buttonBackground = ColorConstants.button;
+
+ public static Object handleButtonOverride(ICSSPropertyMeta meta,
+ String propertyName) {
+ // if (BorderStyleMeta.isBorderStyle(propertyName))
+ // {
+ // return ICSSPropertyID.VAL_RIDGE;
+ // }
+ // else if (BorderWidthMeta.isBorderWidth(propertyName))
+ // {
+ // return Length.LENGTH_3;
+ // }
+ // else if
+ // (ICSSPropertyID.ATTR_TEXTDECORATION.equalsIgnoreCase(propertyName))
+ // {
+ // return new Integer(TextDecorationMeta.NONE);
+ // }
+ // else if
+ // (ICSSPropertyID.ATTR_BACKGROUND_COLOR.equalsIgnoreCase(propertyName))
+ // {
+ // return _buttonBackground;
+ // }
+ // else if
+ // (ICSSPropertyID.ATTR_PADDING_LEFT.equalsIgnoreCase(propertyName) ||
+ // ICSSPropertyID.ATTR_PADDING_RIGHT.equalsIgnoreCase(propertyName))
+ // {
+ // return Length.LENGTH_8;
+ // }
+
+ return null;
+ }
+
+ public static Object handleInputTextOverride(ICSSPropertyMeta meta,
+ String propertyName) {
+ if (BorderStyleMeta.isBorderStyle(propertyName)) {
+ return ICSSPropertyID.VAL_GROOVE;
+ } else if (BorderWidthMeta.isBorderWidth(propertyName)) {
+ return Length.LENGTH_3;
+ } else if (ICSSPropertyID.ATTR_TEXTDECORATION
+ .equalsIgnoreCase(propertyName)) {
+ return new Integer(TextDecorationMeta.NONE);
+ }
+
+ return null;
+ }
+
+ public static Object handleHighlightBorderOverride(ICSSPropertyMeta meta,
+ String propertyName) {
+ if (BorderStyleMeta.isBorderStyle(propertyName)) {
+ return ICSSPropertyID.VAL_DOTTED;
+ } else if (BorderWidthMeta.isBorderWidth(propertyName)) {
+ return Length.LENGTH_1;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/DefaultStyle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/DefaultStyle.java
new file mode 100644
index 000000000..70e066065
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/DefaultStyle.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+import java.util.Map;
+
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.CSSFontManager;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator;
+import org.eclipse.jst.pagedesigner.css2.property.CSSMetaRegistry;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+
+/**
+ * @author mengbo
+ */
+public class DefaultStyle implements ICSSStyle {
+
+ private static final Insets EMPTY_INSETS = new Insets();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#reset()
+ */
+ public void reset() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getStyleProperty(java.lang.String)
+ */
+ public Object getStyleProperty(String property) {
+ ICSSPropertyMeta meta = CSSMetaRegistry.getInstance().getMeta(property);
+ if (meta == null) {
+ return ICSSPropertyMeta.NOT_SPECIFIED;
+ } else {
+ return meta.getInitialValue(property, this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getMarginInsets()
+ */
+ public Insets getMarginInsets() {
+ return EMPTY_INSETS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getBorderInsets()
+ */
+ public Insets getBorderInsets() {
+ return EMPTY_INSETS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getPaddingInsets()
+ */
+ public Insets getPaddingInsets() {
+ return EMPTY_INSETS;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#isSizeIncludeBorderPadding()
+ */
+ public boolean isSizeIncludeBorderPadding() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#dispose()
+ */
+ public void dispose() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.sse.model.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ return type == ICSSStyle.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.sse.model.INodeAdapter#notifyChanged(com.ibm.sse.model.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ }
+
+ ICSSFont defaultFont = CSSFontManager.getInstance().createDefaultFont();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getCSSFont()
+ */
+ public ICSSFont getCSSFont() {
+ return defaultFont;
+ }
+
+ /**
+ * @return
+ */
+ public static ICSSStyle getInstance() {
+ if (_instance == null) {
+ _instance = new DefaultStyle();
+ }
+ return _instance;
+ }
+
+ static DefaultStyle _instance;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getParentStyle()
+ */
+ public ICSSStyle getParentStyle() {
+ // return this;
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getBackgroundColor()
+ */
+ public Object getBackgroundColor() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getColor()
+ */
+ public Object getColor() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getDisplay()
+ */
+ public String getDisplay() {
+ return "inline";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getListStyle()
+ */
+ public Map getCounters() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getCounter(java.lang.String)
+ */
+ public ICounterValueGenerator findCounter(String name, boolean must) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getColSpan()
+ */
+ public int getColSpan() {
+ return 1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getRowSpan()
+ */
+ public int getRowSpan() {
+ return 1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#isInSelection()
+ */
+ public boolean isInSelection() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#resetCounters()
+ */
+ public void processCounters() {
+ // do nothing.
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getHTMLelementValue(java.lang.String)
+ */
+ public Object getHTMLelementInitValue(String propertyName) {
+ ICSSPropertyMeta meta = CSSMetaRegistry.getInstance().getMeta(
+ propertyName);
+ if (meta == null) {
+ return ICSSPropertyMeta.NOT_SPECIFIED;
+ } else {
+ return meta.getInitialValue(propertyName, this);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/HiddenElementStyle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/HiddenElementStyle.java
new file mode 100644
index 000000000..46c190754
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/HiddenElementStyle.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+import org.eclipse.jst.pagedesigner.parts.EditProxyAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Element;
+
+public class HiddenElementStyle extends DefaultStyle {
+ private EditProxyAdapter _editProxyAdapter;
+
+ private Element _convertedElement;
+
+ private static ITagEditInfo _tagEditInfo = new ITagEditInfo() {
+
+ public boolean isWidget() {
+ return true;
+ }
+
+ public boolean needBorderDecorator() {
+ return false;
+ }
+
+ public boolean needTableDecorator() {
+ return false;
+ }
+
+ public int getMinWidth() {
+ return 0;
+ }
+
+ public int getMinHeight() {
+ return 0;
+ }
+ };
+
+ public HiddenElementStyle(EditProxyAdapter adapter) {
+ this._editProxyAdapter = adapter;
+ }
+
+ public HiddenElementStyle(Element convertedElement) {
+ this._convertedElement = convertedElement;
+ }
+
+ public boolean isInSelection() {
+ if (_convertedElement instanceof INodeNotifier) {
+ Object ret = ((INodeNotifier) _convertedElement)
+ .getAdapterFor(AbstractStyle.class);
+ if (ret instanceof AbstractStyle) {
+ return ((AbstractStyle) ret).isInSelection();
+ }
+ }
+
+ if (_editProxyAdapter != null) {
+ return _editProxyAdapter.isRangeSelected();
+ }
+
+ return false;
+ }
+
+ public Object getAdapter(Class adapter) {
+ if (_convertedElement instanceof INodeNotifier) {
+ Object ret = ((INodeNotifier) _convertedElement)
+ .getAdapterFor(AbstractStyle.class);
+ if (ret instanceof AbstractStyle) {
+ return ((AbstractStyle) ret).getAdapter(adapter);
+ }
+ }
+ if (_editProxyAdapter != null && adapter == ITagEditInfo.class) {
+ return _tagEditInfo;
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/IRangeSelectionProxy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/IRangeSelectionProxy.java
new file mode 100644
index 000000000..499193e1f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/IRangeSelectionProxy.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IRangeSelectionProxy {
+
+ /**
+ * @return
+ */
+ boolean isRangeSelected();
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ITagEditInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ITagEditInfo.java
new file mode 100644
index 000000000..d19b98249
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ITagEditInfo.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ITagEditInfo {
+ public boolean isWidget();
+
+ public boolean needBorderDecorator();
+
+ public boolean needTableDecorator();
+
+ /**
+ * for some element in design mode we want to them to have a default min
+ * size.
+ *
+ * @return positive value means an expected min size.
+ */
+ public int getMinWidth();
+
+ public int getMinHeight();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ImageStyleHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ImageStyleHelper.java
new file mode 100644
index 000000000..9e5240046
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/ImageStyleHelper.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class ImageStyleHelper {
+ public static Image loadImage(String url, Element source) {
+ if (source instanceof IDOMElement) {
+ IDOMModel model = ((IDOMElement) source).getModel();
+ URIResolver resolver = model.getResolver();
+ if (resolver != null)
+ url = resolver.getLocationByURI(url);
+ }
+ if (url != null) {
+ return new Image(null, url);
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/StyleUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/StyleUtil.java
new file mode 100644
index 000000000..9f1e0c5c0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/style/StyleUtil.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.style;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class StyleUtil {
+ public static boolean isInWidget(ICSSStyle style) {
+ while (style != null && style != DefaultStyle.getInstance()) {
+ ITagEditInfo info = (ITagEditInfo) style
+ .getAdapter(ITagEditInfo.class);
+ if (info != null && info.isWidget()) {
+ return true;
+ }
+
+ style = style.getParentStyle();
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/value/Length.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/value/Length.java
new file mode 100644
index 000000000..47afe93dc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/value/Length.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.value;
+
+/**
+ * @author mengbo
+ */
+public class Length {
+ public static final Length LENGTH_0 = new Length(0, false);
+
+ public static final Length LENGTH_1 = new Length(1, false);
+
+ public static final Length LENGTH_2 = new Length(2, false);
+
+ public static final Length LENGTH_3 = new Length(3, false);
+
+ public static final Length LENGTH_8 = new Length(8, false);
+
+ boolean _percentage;
+
+ int _value;
+
+ public Length(int value, boolean percentage) {
+ _value = value;
+ _percentage = percentage;
+ }
+
+ public boolean isPercentage() {
+ return _percentage;
+ }
+
+ public int getValue() {
+ return _value;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/AbstractWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/AbstractWidgetProvider.java
new file mode 100644
index 000000000..f380d712d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/AbstractWidgetProvider.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class AbstractWidgetProvider implements ICSSWidgetProvider {
+ public static int BORDERTHICK = 2;
+
+ ICSSStyle _style;
+
+ public AbstractWidgetProvider(ICSSStyle style) {
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getCSSStyle()
+ */
+ public ICSSStyle getCSSStyle() {
+ return _style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#isHandlingBorder()
+ */
+ public boolean isHandlingBorder() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#isInline()
+ */
+ public boolean isInline() {
+ return true;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/BorderUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/BorderUtil.java
new file mode 100644
index 000000000..4a3b06b75
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/BorderUtil.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import java.util.List;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowBox;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BorderUtil {
+ public final static int VERTICAL_BAR = 0;
+
+ public final static int HORIZONTAL_BAR = 1;
+
+ public final static int BOTH = 2;
+
+ public final static int SCROLL_WIDTH = 16;
+
+ public final static int BORDER_THICK = 2;
+
+ /**
+ * draw a mask to a rectangle
+ *
+ * @param Graphics
+ * @param Rectangle
+ * @param Color
+ */
+ public static void maskRectangle(Graphics g, Rectangle rect, Color color) {
+ // default color is blue
+ if (color == null) {
+ color = ColorConstants.blue;
+ }
+
+ // get old information and keep them
+ int lineStyle = g.getLineStyle();
+ Color foregroundColor = g.getForegroundColor();
+
+ g.setLineStyle(SWT.LINE_SOLID);
+ g.setForegroundColor(color);
+ for (int i = 0, n = rect.height; i < n; i++, i++) {
+ for (int j = 0, m = rect.width; j < m; j++, j++) {
+ g.drawLine(rect.x + j, rect.y + i, rect.x + j, rect.y + i);
+ }
+ }
+
+ // restore to the old state
+ g.setLineStyle(lineStyle);
+ g.setForegroundColor(foregroundColor);
+ }
+
+ public static void drawBorder(Graphics g, Rectangle rect, int thick,
+ boolean inset) {
+ drawBorder(g, rect.x, rect.y, rect.width, rect.height, thick, inset);
+ }
+
+ /**
+ * draw a standard border.
+ *
+ * @param g
+ * @param left
+ * @param top
+ * @param width
+ * @param height
+ * @param thick
+ * @param inset
+ */
+ public static void drawBorder(Graphics g, int left, int top, int width,
+ int height, int thick, boolean inset) {
+ Color[] ltColors = new Color[] {
+ Display.getCurrent().getSystemColor(
+ SWT.COLOR_WIDGET_LIGHT_SHADOW),
+ Display.getCurrent().getSystemColor(
+ SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW) };
+ if (inset) {
+ ltColors = new Color[] { ColorConstants.buttonDarker,
+ ColorConstants.buttonDarkest };
+ }
+ for (int i = 0; i < thick; i++) {
+ g.setForegroundColor(ltColors[ltColors.length * i / thick]);
+ g.drawLine(left + i, top + i, left + width - 1 - i, top + i);
+ g.drawLine(left + i, top + i, left + i, top + height - i - i);
+ }
+
+ Color[] rbColors = new Color[] {
+ Display.getCurrent().getSystemColor(
+ SWT.COLOR_WIDGET_DARK_SHADOW),
+ Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY) };
+ if (inset) {
+ rbColors = new Color[] { ColorConstants.buttonLightest,
+ ColorConstants.button };
+ }
+ for (int i = 0; i < thick; i++) {
+ g.setForegroundColor(rbColors[ltColors.length * i / thick]);
+ g.drawLine(left + i, top - i + height - 1, left + width - 1 - i,
+ top - i + height - 1);
+ g.drawLine(left + width - 1 - i, top + i, left + width - 1 - i, top
+ + height - 1 - i);
+ }
+ }
+
+ public static void drawScrollBar(Graphics g, int scrollWidth,
+ Rectangle rect, int style) {
+ drawScrollBar(g, scrollWidth, BORDER_THICK, rect, style);
+ }
+
+ public static void drawScrollBar(Graphics g, int scrollWidth,
+ int borderThick, Rectangle rect, int style) {
+ if (style == BOTH) {
+ int width = scrollWidth;
+ int left = rect.x + rect.width - width;
+ int top = rect.y;
+ int height = rect.height;
+ Rectangle barRect = new Rectangle(left, top, width, height);
+ fillBar(g, barRect);
+ barRect = new Rectangle(left, top, width, height - scrollWidth);
+ drawVerticalPart(g, scrollWidth, borderThick, barRect);
+
+ left = rect.x + borderThick;
+ top = top + height - scrollWidth;
+ width = rect.width;
+ height = scrollWidth;
+ barRect = new Rectangle(left, top, width, height);
+ fillBar(g, barRect);
+ barRect = new Rectangle(left, top, width - scrollWidth - 2, height);
+ drawHorizontalPart(g, scrollWidth, borderThick, barRect);
+ } else if (style == VERTICAL_BAR) {
+ int width = scrollWidth;
+ int left = rect.x + rect.width - width;
+ int top = rect.y;
+ int height = rect.height;
+ Rectangle barRect = new Rectangle(left, top, width, height);
+ fillBar(g, barRect);
+ drawVerticalPart(g, scrollWidth, borderThick, barRect);
+ } else if (style == HORIZONTAL_BAR) {
+ int left = rect.x + borderThick;
+ int top = rect.y + rect.height - scrollWidth;
+ int width = rect.width;
+ int height = scrollWidth;
+ Rectangle barRect = new Rectangle(left, top, width, height);
+ fillBar(g, barRect);
+ drawHorizontalPart(g, scrollWidth, borderThick, barRect);
+ }
+ }
+
+ private static void fillBar(Graphics g, Rectangle rect) {
+ g.setBackgroundColor(ColorConstants.button);
+ g.fillRectangle(rect);
+ }
+
+ private static void drawVerticalPart(Graphics g, int arrawLength,
+ int borderThick, Rectangle rect) {
+ int left = rect.x;
+ int top = rect.y;
+ int width = Math.min(arrawLength, rect.width);
+ int height = Math.min(arrawLength, rect.height / 2);
+
+ Rectangle borderRect = new Rectangle(left, top, width, height);
+ BorderUtil.drawBorder(g, borderRect, borderThick, false);
+
+ g.setForegroundColor(ColorConstants.black);
+ int decoratorWidth = (width - borderThick * 2) / 2;
+ int length = decoratorWidth / 2 + 1;
+ int leftX = rect.x + (width - decoratorWidth) / 2 - 1;
+ int bottomY = rect.y + (height + length) / 2 - 1;
+ for (int i = 0; i < length; i++) {
+ g.drawLine(leftX + i, bottomY - i, leftX - i + decoratorWidth,
+ bottomY - i);
+ }
+
+ top = rect.y + rect.height - height;
+ borderRect = new Rectangle(left, top, width, height);
+ BorderUtil.drawBorder(g, borderRect, borderThick, false);
+
+ int topY = top + (height - length) / 2;
+ g.setForegroundColor(ColorConstants.black);
+ for (int i = 0; i < length; i++) {
+ g.drawLine(leftX + i, topY + i, leftX - i + decoratorWidth, topY
+ + i);
+ }
+ }
+
+ private static void drawHorizontalPart(Graphics g, int arrawLength,
+ int borderThick, Rectangle rect) {
+ int left = rect.x;
+ int top = rect.y;
+ int width = Math.min(arrawLength, rect.width / 2);
+ int height = Math.min(arrawLength, rect.height);
+
+ Rectangle borderRect = new Rectangle(left, top, width, height);
+ BorderUtil.drawBorder(g, borderRect, borderThick, false);
+
+ g.setForegroundColor(ColorConstants.black);
+ int decoratorHeight = (height - borderThick * 2) / 2;
+ int length = decoratorHeight / 2 + 1;
+ int leftX = rect.x + (width + length) / 2 - 1;
+ int bottomY = rect.y + (height - length) / 2 - 1;
+ for (int i = 0; i < length; i++) {
+ g.drawLine(leftX - i, bottomY + i, leftX - i, bottomY - i
+ + decoratorHeight);
+ }
+
+ left = rect.x + rect.width - width;
+ borderRect = new Rectangle(left, top, width, height);
+ BorderUtil.drawBorder(g, borderRect, borderThick, false);
+
+ leftX = left + (width - length) / 2;
+ g.setForegroundColor(ColorConstants.black);
+ for (int i = 0; i < length; i++) {
+ g.drawLine(leftX + i, bottomY + i, leftX + i, bottomY - i
+ + decoratorHeight);
+ }
+ }
+
+ public static void drawVertialBar(Graphics g, int arrawWidth,
+ int arrawHeight, int borderThick, Rectangle rect) {
+ drawScrollBar(g, arrawWidth, borderThick, rect, VERTICAL_BAR);
+ }
+
+ /**
+ * @param figure
+ * @param graphics
+ */
+ public static void drawBorderDecorator(CSSFigure figure, Graphics graphics) {
+ graphics.setLineWidth(1);
+ graphics.setLineStyle(Graphics.LINE_DOT);
+ graphics.setForegroundColor(ColorConstants.lightBlue);
+ List fragments = figure.getFragmentsForRead();
+ for (int i = 0, size = fragments.size(); i < size; i++) {
+ FlowBox box = (FlowBox) fragments.get(i);
+ // XXX: why -1?
+ graphics.drawRectangle(box._x, box._y, box.getWidth() - 1, box
+ .getHeight() - 1);
+ }
+ graphics.restoreState();
+ }
+
+ /**
+ * @param figure
+ * @param g
+ */
+ public static void maskFigure(CSSFigure figure, Graphics g) {
+ List fragments = figure.getFragmentsForRead();
+ for (int i = 0, size = fragments.size(); i < size; i++) {
+ FlowBox box = (FlowBox) fragments.get(i);
+ maskRectangle(g, new Rectangle(box._x, box._y, box.getWidth(), box
+ .getHeight()), null);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ButtonWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ButtonWidgetProvider.java
new file mode 100644
index 000000000..3627f72f7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ButtonWidgetProvider.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.layout.TextLayoutSupport;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * For ButtonWidget, it displays some text value in it. And lays the text with
+ * nowrap.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class ButtonWidgetProvider extends AbstractWidgetProvider {
+ // The button width should include the label length and padding,
+ // to let the button looks fine, we set the padding 0.46 width as the label
+ // length.
+ private final static double HORIZONTAL_RATE = 1.46;
+
+ // The button height should include the label height and padding,
+ // to let the button looks fine, we set the padding 0.36 height as the
+ // character height.
+ private final static double VERTICAL_PADDING_RATE = 0.36;
+
+ static final String[] DEFAULTLINES = new String[] { " " };
+
+ private String _value = "";
+
+ private String[] _lines = DEFAULTLINES;
+
+ private List _fragments = new ArrayList();
+
+ /**
+ * @param style
+ */
+ public ButtonWidgetProvider(ICSSStyle style) {
+ super(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+ }
+ if (height <= 0) {
+ height = getDefaultHeight();
+ }
+ return new DimensionInfo(new Dimension(width, height), -1);
+ }
+
+ /**
+ * by default, the combo's width will be calculated from the longest option
+ * value.
+ *
+ * @return
+ */
+ public int getDefaultWidth() {
+ int longestStringWidth = 0;
+ if (_lines != null) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtFont = font.getSwtFont();
+ for (int i = 0; i < _lines.length; i++) {
+ int width = FigureUtilities.getTextWidth(_lines[i], swtFont);
+ if (width > longestStringWidth) {
+ longestStringWidth = width;
+ }
+ }
+ }
+ // text area width + padding
+ return (int) ((longestStringWidth) * HORIZONTAL_RATE);
+ }
+
+ /**
+ *
+ * @return
+ * @see TextInputWidgetProvider#getDefaultHeight()
+ */
+ public int getDefaultHeight() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtfont = font.getSwtFont();
+ int fontHeight = FigureUtilities.getFontMetrics(swtfont).getHeight();
+ return (int) ((fontHeight) * (_lines.length + VERTICAL_PADDING_RATE));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ Object textAlign = style
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN);
+ if (ICSSPropertyMeta.NOT_SPECIFIED == textAlign) {
+ textAlign = "center";
+ }
+ Font font = style.getCSSFont().getSwtFont();
+ g.setFont(font);
+ int fontHeight = FigureUtilities.getFontMetrics(font).getHeight();
+
+ Color newColor = null;
+ Object color = style.getColor();
+ if (color instanceof Color) {
+ g.setForegroundColor((Color) color);
+ } else if (color instanceof RGB) {
+ newColor = new Color(Display.getCurrent(), (RGB) color);
+ g.setForegroundColor(newColor);
+ } else {
+ g.setForegroundColor(ColorConstants.black);
+ }
+
+ g.clipRect(rect);
+
+ int y = rect.y + (int) (fontHeight * VERTICAL_PADDING_RATE / 2);
+ if (rect.height > fontHeight * _lines.length) {
+ y = rect.y + (rect.height - fontHeight * _lines.length) / 2;
+ }
+
+ for (int i = 0; i < _lines.length && y < rect.y + rect.height; i++) {
+ int width = FigureUtilities.getTextWidth(_lines[i], font);
+ int x = TextLayoutSupport.getBeginX(textAlign, rect, width);
+ g.drawString(_lines[i], x, y);
+ TextLayoutSupport.paintTextDecoration(g, new Rectangle(x, y, width,
+ fontHeight), ((Integer) getCSSStyle().getStyleProperty(
+ ICSSPropertyID.ATTR_TEXTDECORATION)).intValue());
+ y += fontHeight;
+ }
+
+ if (newColor != null) {
+ newColor.dispose();
+ }
+ }
+
+ public void setValue(String value) {
+ if (value == null) {
+ value = "";
+ }
+ _value = value;
+ _lines = splitValue(_value);
+ }
+
+ /**
+ * Split the value to multiple lines.
+ *
+ * @param _value2
+ * @return
+ */
+ private String[] splitValue(String _value2) {
+ if (_value2 == null || "".equals(_value2)) {
+ return DEFAULTLINES;
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(_value2, "\r\n");
+ String[] result = new String[tokenizer.countTokens()];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = tokenizer.nextToken().replaceAll("\t", " ");
+ }
+ return result;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/CheckboxWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/CheckboxWidgetProvider.java
new file mode 100644
index 000000000..2bbd8f6b4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/CheckboxWidgetProvider.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CheckboxWidgetProvider extends AbstractWidgetProvider {
+ private boolean isChecked;
+
+ public CheckboxWidgetProvider(ICSSStyle style) {
+ super(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+ }
+ if (height <= 0) {
+ height = getDefaultWidth();
+ }
+ return new DimensionInfo(new Dimension(width, height), height * 4 / 5);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ int centerX = rect.x + rect.width / 2;
+ int centerY = rect.y + rect.height / 2;
+
+ // we always draw it as a square.
+ int width = Math.min(rect.width, rect.height);
+ int innerWidth = width * 4 / 5;
+
+ int left = centerX - innerWidth / 2;
+ int top = centerY - innerWidth / 2;
+ BorderUtil.drawBorder(g, left, top, innerWidth, innerWidth, 2, true);
+ if (isChecked()) {
+ g.pushState();
+ Display display = Display.getCurrent();
+ g.setForegroundColor(display.getSystemColor(SWT.COLOR_BLACK));
+ g.drawLine(left + 3, top + 2, left + innerWidth - 3, top
+ + innerWidth - 4);
+ g.drawLine(left + 2, top + 2, left + innerWidth - 3, top
+ + innerWidth - 3);
+
+ g.drawLine(left + innerWidth - 4, top + 2, left + 2, top
+ + innerWidth - 4);
+ g.drawLine(left + innerWidth - 3, top + 2, left + 2, top
+ + innerWidth - 3);
+ g.popState();
+ }
+ }
+
+ public int getDefaultWidth() {
+ // FIXME: don't know the how to define the default width yet.
+ return 15;
+ }
+
+ /**
+ * @return Returns the checked.
+ */
+ public boolean isChecked() {
+ return isChecked;
+ }
+
+ public void setChecked(boolean checked) {
+ this.isChecked = checked;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ComboWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ComboWidgetProvider.java
new file mode 100644
index 000000000..5a4926668
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ComboWidgetProvider.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ * @author mengbo
+ * @version 1.5
+ */
+public class ComboWidgetProvider extends AbstractWidgetProvider {
+ private static final int VERTICAL_PADDING = 6;
+
+ private static final int HORIZONTAL_PADDING = 12;
+
+ private static int ARRAWWIDTH = 16;
+
+ private static int ARROWHEIGHT = 16;
+
+ private String _firstString;
+
+ private String _longestString;
+
+ private String _label;
+
+ public ComboWidgetProvider(ICSSStyle style) {
+ super(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+
+ }
+ if (height <= 0) {
+ height = getDefaultHeight();
+ }
+ return new DimensionInfo(new Dimension(width, height), -1);
+ }
+
+ /**
+ * by default, the combo's width will be calculated from the longest option
+ * value.
+ *
+ * @return
+ */
+ public int getDefaultWidth() {
+ int textareaWidth;
+ if (this._longestString == null || this._longestString.length() == 0) {
+ textareaWidth = 20;
+ } else {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+
+ textareaWidth = FigureUtilities.getTextWidth(_longestString, font
+ .getSwtFont());
+ }
+ return textareaWidth + ARRAWWIDTH + HORIZONTAL_PADDING;
+ }
+
+ /**
+ *
+ * @return
+ * @see TextInputWidgetProvider#getDefaultHeight()
+ */
+ public int getDefaultHeight() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtfont = font.getSwtFont();
+ int fontSize = FigureUtilities.getFontMetrics(swtfont).getHeight();
+ return fontSize + VERTICAL_PADDING;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ if (this._firstString != null) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ g.setFont(font.getSwtFont());
+
+ Color newColor = null;
+ Object color = style.getColor();
+ if (color instanceof Color) {
+ g.setForegroundColor((Color) color);
+ } else if (color instanceof RGB) {
+ newColor = new Color(Display.getCurrent(), (RGB) color);
+ g.setForegroundColor(newColor);
+ } else {
+ g.setForegroundColor(ColorConstants.black);
+ }
+ g.clipRect(rect);
+ String label = _label != null ? _label : _firstString;
+ label = label.replaceAll("[ \r\n]+", " ");
+ if (label.endsWith(" ")) {
+ label = label.substring(0, label.length() - 1);
+ }
+ g.drawString(label, rect.x + HORIZONTAL_PADDING / 2, rect.y
+ + VERTICAL_PADDING / 2);
+ if (newColor != null) {
+ newColor.dispose();
+ }
+
+ }
+
+ BorderUtil.drawBorder(g, rect.x, rect.y, rect.width, rect.height,
+ BORDERTHICK, true);
+ // next the drop down button
+ int width = ARRAWWIDTH;
+ int left = rect.x + rect.width - width - BORDERTHICK;
+ int top = rect.y + BORDERTHICK;
+ int height = rect.height - BORDERTHICK * 2;
+ g.setBackgroundColor(ColorConstants.button);
+ g.fillRectangle(left, top, width, height);
+
+ Rectangle borderRect = new Rectangle(left, top, width, height);
+ BorderUtil.drawBorder(g, borderRect.x, borderRect.y, borderRect.width,
+ borderRect.height, BORDERTHICK, false);
+
+ g.setForegroundColor(ColorConstants.black);
+
+ int decoratorWidth = (width - BORDERTHICK * 2) / 2;
+ int length = decoratorWidth / 2 + 1;
+ int leftX = left + (width - decoratorWidth) / 2 - 1;
+ int topY = top + (height - length) / 2 + 1;
+ for (int i = 0; i < length; i++) {
+ g.drawLine(leftX + i, topY + i, leftX - i + decoratorWidth, topY
+ + i);
+ }
+ }
+
+ /**
+ * set the options to be displayed in this combo box. Will calculate out the
+ * first string and the longest string.
+ *
+ * @param options
+ */
+ public void setOptions(String[] options) {
+ if (options == null || options.length == 0) {
+ this._firstString = null;
+ this._longestString = null;
+ } else {
+ this._firstString = options[0];
+ this._longestString = (options[0] == null ? "" : options[0]);
+ for (int i = 1; i < options.length; i++) {
+ if (options[i] == null) {
+ continue;
+ }
+ if (options[i].length() > this._longestString.length()) {
+ this._longestString = options[i];
+ }
+ }
+ }
+ }
+
+ public void setSelectedLabel(String label) {
+ this._label = label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#isHandlingBorder()
+ */
+ public boolean isHandlingBorder() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/HiddenProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/HiddenProvider.java
new file mode 100644
index 000000000..8ca921b16
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/HiddenProvider.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.style.HiddenElementStyle;
+import org.eclipse.jst.pagedesigner.parts.EditProxyAdapter;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class HiddenProvider extends ImageWidgetProvider {
+ private final static int GAP = 3;
+
+ private String _label = null;
+
+ private boolean _labelVisible = true;
+
+ private FontMetrics _fontMetrics;
+
+ /**
+ * @param image
+ * @param style
+ */
+ public HiddenProvider(Image image, Element convertedElement) {
+ super(image, new HiddenElementStyle(convertedElement));
+ }
+
+ public HiddenProvider(Image image, ElementEditPart editPart) {
+ super(image, new HiddenElementStyle(new EditProxyAdapter(editPart)));
+ }
+
+ // public HiddenProvider(Image image, String label)
+ // {
+ // this(image);
+ // this._label = label;
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ int preWidth = width;
+ int preHeight = height;
+ _fontMetrics = getFontMetrics();
+ if (width <= 0) {
+ preWidth = getLabelWidth() + _imageWidth;
+ }
+ if (height <= 0) {
+ preHeight = Math.max(getLabelHeight(), _imageHeight);
+ }
+ return new DimensionInfo(preWidth, preHeight, -1);
+ }
+
+ private FontMetrics getFontMetrics() {
+ Font swtfont = Display.getCurrent().getSystemFont();
+ return FigureUtilities.getFontMetrics(swtfont);
+ }
+
+ private int getLabelHeight() {
+ if (_labelVisible && (_label != null) && (!_label.equals(""))
+ && (_fontMetrics != null)) {
+ return _fontMetrics.getHeight();
+ }
+ return 0;
+ }
+
+ public int getLabelWidth() {
+ if (_labelVisible && _label != null && !_label.equals("")
+ && _fontMetrics != null) {
+ Font swtfont = Display.getCurrent().getSystemFont();
+ return FigureUtilities.getTextWidth(_label, swtfont) + GAP;
+ }
+ return 0;
+ }
+
+ public void paintFigure(Graphics g,
+ org.eclipse.draw2d.geometry.Rectangle rect) {
+ g.setBackgroundColor(ColorConstants.cyan);
+ g.fillRectangle(rect);
+ g.setClip(rect);
+ int imageAreaWidth = Math.min(rect.width, _imageWidth);
+ int imageAreaHeight = Math.min(rect.height, _imageHeight);
+ if (_image != null) {
+ g.drawImage(_image, 0, 0, _imageWidth, _imageHeight, rect.x, rect.y
+ + (rect.height - imageAreaHeight) / 2, imageAreaWidth,
+ imageAreaHeight);
+ }
+ if (_label != null && _labelVisible) {
+ int leading = 0;
+ if (_fontMetrics != null) {
+ leading = _fontMetrics.getLeading();
+ }
+ g.drawString(_label, imageAreaWidth + GAP, rect.y
+ + (rect.height - getLabelHeight()) / 2 + leading);
+ }
+ }
+
+ public String getLabel() {
+ return _label;
+ }
+
+ public void setLabel(String label) {
+ this._label = label;
+ }
+
+ public boolean isLabelVisible() {
+ return _labelVisible;
+ }
+
+ public void setLabelVisible(boolean labelVisible) {
+ this._labelVisible = labelVisible;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ImageWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ImageWidgetProvider.java
new file mode 100644
index 000000000..510cf42b3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ImageWidgetProvider.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author mengbo
+ */
+public class ImageWidgetProvider extends AbstractWidgetProvider {
+ private static final String NOPIC_IMAGE_NAME = "PD_nopic.jpg";
+
+ private static Image _noPicImage;
+
+ private static int _noPicWidth;
+
+ private static int _noPicHeight;
+
+ protected Image _image;
+
+ protected int _imageWidth;
+
+ protected int _imageHeight;
+
+ public ImageWidgetProvider(Image image, ICSSStyle style) {
+ super(style);
+
+ // set up image and image width/height
+ org.eclipse.swt.graphics.Rectangle rect = null;
+ if (image != null) {
+ rect = image.getBounds();
+ if (rect.width <= 0 || rect.height <= 0) {
+ useNoPicImage();
+ } else {
+ _image = image;
+ _imageWidth = rect.width;
+ _imageHeight = rect.height;
+ }
+ } else {
+ useNoPicImage();
+ }
+ }
+
+ /**
+ *
+ */
+ private void useNoPicImage() {
+ if (_noPicImage == null || _noPicImage.isDisposed()) {
+ ImageDescriptor noPicImageDesc = PDPlugin.getDefault()
+ .getImageDescriptor(NOPIC_IMAGE_NAME);
+ _noPicImage = noPicImageDesc.createImage();
+ org.eclipse.swt.graphics.Rectangle rect = _noPicImage.getBounds();
+ _noPicWidth = rect.width;
+ _noPicHeight = rect.height;
+ }
+ _image = _noPicImage;
+ _imageWidth = _noPicWidth;
+ _imageHeight = _noPicHeight;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0 && height <= 0) {
+ // we are free, so use image size
+ org.eclipse.swt.graphics.Rectangle a = _image.getBounds();
+ return new DimensionInfo(a.width, a.height, -1);
+ } else if (width > 0 && height > 0) {
+ return new DimensionInfo(width, height, -1);
+ } else if (height > 0) {
+ width = (int) ((double) _imageWidth * height / _imageHeight);
+ return new DimensionInfo(width, height, -1);
+ } else {
+ height = (int) ((double) _imageHeight * width / _imageWidth);
+ return new DimensionInfo(width, height, -1);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ if (_image != null) {
+ g.drawImage(_image, 0, 0, _imageWidth, _imageHeight, rect.x,
+ rect.y, rect.width, rect.height);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/InputFileWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/InputFileWidgetProvider.java
new file mode 100644
index 000000000..c21eb5c00
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/InputFileWidgetProvider.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.border.CSSBorder;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.MessageFormater;
+
+/**
+ * @author mengbo
+ */
+public class InputFileWidgetProvider extends AbstractWidgetProvider {
+ private static final String BODER_QUERY_TEMPLETE = "border-{0}-style";
+
+ private static final int GAP = 2;
+
+ private ICSSWidgetProvider _sub1;
+
+ private ICSSWidgetProvider _sub2;
+
+ /**
+ * @param style
+ */
+ public InputFileWidgetProvider(ICSSStyle style, ICSSWidgetProvider sub1,
+ ICSSWidgetProvider sub2) {
+ super(style);
+ _sub1 = sub1;
+ _sub2 = sub2;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ Insets borderInset = new Insets();
+ Insets borderPaddingInset = new Insets();
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ borderInset = style.getBorderInsets();
+ borderPaddingInset = borderInset.getAdded(style.getPaddingInsets());
+ }
+
+ Dimension d1 = _sub1.getPreferredDimension(-1, -1).getDimension();
+ Dimension d2 = _sub2.getPreferredDimension(-1, -1).getDimension();
+
+ int minWidth = d2.width + 2 * (borderInset.left + borderInset.right)
+ + GAP;
+ int prefWidth = d1.width + d2.width + 2
+ * (borderPaddingInset.left + borderPaddingInset.right) + GAP;
+ int minHeight = borderInset.top + borderInset.bottom;
+ int prefHeight = Math.max(d1.height, d2.height)
+ + borderPaddingInset.top + borderPaddingInset.bottom;
+
+ if (width > 0 && minWidth > width) {
+ prefWidth = minWidth;
+ } else if (width != 0) {
+ prefWidth = width;
+ }
+
+ if (height > 0 && minHeight > height) {
+ prefHeight = minHeight;
+ } else if (height != 0) {
+ prefHeight = height;
+ }
+ return new DimensionInfo(prefWidth, prefHeight, -1);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ Rectangle rect1, rect2;
+
+ Insets borderInset = new Insets();
+ Insets paddingInset = new Insets();
+ Insets borderPaddingInset = new Insets();
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ borderInset = style.getBorderInsets();
+ paddingInset = style.getPaddingInsets();
+ borderPaddingInset.add(borderInset).add(paddingInset);
+ }
+
+ Dimension d1 = _sub1.getPreferredDimension(-1, -1).getDimension();
+ Dimension d2 = _sub2.getPreferredDimension(-1, -1).getDimension();
+ int prefWidth = d1.width + d2.width + 2 * borderPaddingInset.left + 2
+ * borderPaddingInset.right + GAP;
+ if (rect.width < prefWidth) {
+ paddingInset.left = 0;
+ paddingInset.right = 0;
+ }
+ int prefHeight = Math.max(d1.height, d2.height)
+ + borderPaddingInset.top + borderPaddingInset.bottom;
+ if (rect.height < prefHeight) {
+ paddingInset.top = 0;
+ paddingInset.bottom = 0;
+ }
+
+ int width = rect.width
+ - d2.width
+ - (borderInset.left + borderInset.right + paddingInset.left + paddingInset.right)
+ - GAP;
+ rect1 = new Rectangle(rect.x - 1, rect.y, width, rect.height);
+ rect2 = new Rectangle(rect.x + rect1.width + 2, rect.y, rect.width
+ - rect1.width - 3, rect.height);
+ Rectangle innerRect1 = rect1.getCopy().crop(borderInset);
+ Rectangle innerRect2 = rect2.getCopy().crop(borderInset);
+
+ g.pushState();
+ g.setBackgroundColor(ColorConstants.button);
+ g.fillRectangle(innerRect2);
+ g.popState();
+
+ CSSBorder cssBorder = new CSSBorder(style);
+ String[] edges = new String[] { ICSSStyle.LEFT, ICSSStyle.RIGHT,
+ ICSSStyle.TOP, ICSSStyle.BOTTOM };
+ for (int i = 0; i < edges.length; i++) {
+ cssBorder.paintEdge(g, rect1, innerRect1, edges[i],
+ getBorderStyle(edges[i]));
+ }
+ for (int i = 0; i < edges.length; i++) {
+ String borderStyle = getBorderStyle(edges[i]);
+ if (ICSSPropertyID.VAL_INSET.equals(borderStyle)) {
+ borderStyle = ICSSPropertyID.VAL_OUTSET;
+ }
+ cssBorder.paintEdge(g, rect2, innerRect2, edges[i], borderStyle);
+ }
+
+ _sub2.paintFigure(g, innerRect2.getCopy().crop(paddingInset));
+ // _sub1.paintFigure(g, innerRect1.crop(paddingInset));
+ }
+
+ private String getBorderStyle(String edge) {
+ ICSSStyle style = getCSSStyle();
+ if (style != null) {
+ String property = MessageFormater
+ .format(BODER_QUERY_TEMPLETE, edge);
+ String borderStyle = style.getStyleProperty(property).toString();
+ return borderStyle;
+ }
+ return ICSSPropertyID.VAL_HIDDEN;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#isHandlingBorder()
+ */
+ public boolean isHandlingBorder() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ListWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ListWidgetProvider.java
new file mode 100644
index 000000000..3906425b2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/ListWidgetProvider.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ListWidgetProvider extends AbstractWidgetProvider {
+ private static int DEFAULTSIZE = 4;
+
+ private static final int VERTICAL_PADDING = 6;
+
+ private static final int HORIZONTAL_PADDING = 12;
+
+ private static int ARRAWWIDTH = 16;
+
+ private static int ARROWHEIGHT = 16;
+
+ private String[] _options;
+
+ private int _rows = DEFAULTSIZE;
+
+ public ListWidgetProvider(ICSSStyle style) {
+ super(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+ }
+ if (height <= 0) {
+ height = getDefaultHeight();
+ }
+ return new DimensionInfo(width, height, -1);
+ }
+
+ /**
+ * by default, the combo's width will be calculated from the longest option
+ * value.
+ *
+ * @return
+ */
+ public int getDefaultWidth() {
+ int longestStringWidth = 0;
+ if (_options != null) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtFont = font.getSwtFont();
+ for (int i = 0; i < _options.length; i++) {
+ int width = FigureUtilities.getTextWidth(_options[i], swtFont);
+ if (width > longestStringWidth) {
+ longestStringWidth = width;
+ }
+ }
+ }
+ // text area width + borderWidth + vertical scroll width
+ return (longestStringWidth) + HORIZONTAL_PADDING + ARRAWWIDTH;
+ }
+
+ /**
+ *
+ * @return
+ * @see TextInputWidgetProvider#getDefaultHeight()
+ */
+ public int getDefaultHeight() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtfont = font.getSwtFont();
+ int fontHeight = FigureUtilities.getFontMetrics(swtfont).getHeight();
+ return (fontHeight) * _rows + VERTICAL_PADDING;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ BorderUtil.drawBorder(g, rect.x, rect.y, rect.width, rect.height,
+ BORDERTHICK, true);
+ if (_options != null) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtfont = font.getSwtFont();
+ g.setFont(swtfont);
+
+ Color newColor = null;
+ Object color = style.getColor();
+ if (color instanceof Color) {
+ g.setForegroundColor((Color) color);
+ } else if (color instanceof RGB) {
+ newColor = new Color(Display.getCurrent(), (RGB) color);
+ g.setForegroundColor(newColor);
+ } else {
+ g.setForegroundColor(ColorConstants.black);
+ }
+ int fontHeight = FigureUtilities.getFontMetrics(swtfont)
+ .getHeight();
+ int x = rect.x + HORIZONTAL_PADDING / 2;
+ int y = rect.y + VERTICAL_PADDING / 2;
+
+ g.clipRect(rect);
+ for (int i = 0; i < _options.length
+ && (i * fontHeight < rect.height - VERTICAL_PADDING); i++) {
+ g.drawString(_options[i], x, y);
+ y += fontHeight;
+ }
+ if (newColor != null) {
+ newColor.dispose();
+ }
+
+ int borderThick = 2;
+ Rectangle barRect = new Rectangle(rect.x, rect.y + borderThick,
+ rect.width - borderThick, rect.height - 2 * borderThick);
+ BorderUtil.drawVertialBar(g, ARRAWWIDTH, ARROWHEIGHT, borderThick,
+ barRect);
+ }
+ }
+
+ /**
+ * @param string
+ * @param x
+ * @param y
+ * @return
+ */
+ private String normalize(String string) {
+ if (string == null) {
+ return "";
+ }
+ int index = string.indexOf('\r');
+ if (index >= 0) {
+ string = string.substring(0, index);
+ }
+ index = string.indexOf('\n');
+ if (index >= 0) {
+ string = string.substring(0, index);
+ }
+ return string;
+ }
+
+ /**
+ * set the options to be displayed in this combo box.
+ *
+ * @param options
+ */
+ public void setOptions(String[] options) {
+ this._options = options;
+ if (_options != null) {
+ for (int i = 0; i < _options.length; i++) {
+ _options[i] = normalize(_options[i]);
+ }
+ }
+ }
+
+ /**
+ * set the default number of rows to be displayed.
+ *
+ * @param rows
+ */
+ public void setRows(int rows) {
+ _rows = (rows > 0 ? rows : DEFAULTSIZE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#isHandlingBorder()
+ */
+ public boolean isHandlingBorder() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/RadioWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/RadioWidgetProvider.java
new file mode 100644
index 000000000..195c8605e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/RadioWidgetProvider.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RadioWidgetProvider extends AbstractWidgetProvider {
+ private boolean isChecked;
+
+ public RadioWidgetProvider(ICSSStyle style) {
+ super(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+ }
+ if (height <= 0) {
+ height = getDefaultWidth();
+ }
+ return new DimensionInfo(width, height, height * 4 / 5);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ int centerX = rect.x + rect.width / 2;
+ int centerY = rect.y + rect.height / 2;
+
+ // we always draw it as a circle.
+ int width = Math.min(rect.width, rect.height);
+ int cycleWidth = width * 3 / 5;
+
+ // FIXME: when the size of the radio is big, the line width may need
+ // calculate to be bigger.
+ int lineWidth = 2;
+ g.setLineWidth(lineWidth);
+
+ g.setForegroundColor(ColorConstants.buttonDarker);
+ g.drawArc(centerX - cycleWidth / 2, centerY - cycleWidth + 1,
+ cycleWidth, cycleWidth, 45, 180);
+
+ g.setForegroundColor(ColorConstants.button);
+ g.drawArc(centerX - cycleWidth / 2, centerY - cycleWidth + 1,
+ cycleWidth, cycleWidth, 225, 180);
+
+ // since the two cycle may not overlap very well, some space between
+ // them will be displayed.
+ // so we make the bigger cycle to be a little thicker.
+ cycleWidth += (2 * lineWidth - 2);
+ lineWidth += 1;
+
+ if (cycleWidth < width) {
+ g.setForegroundColor(ColorConstants.buttonDarkest);
+ g.drawArc(centerX - cycleWidth / 2, centerY - cycleWidth + 1,
+ cycleWidth, cycleWidth, 45, 180);
+ }
+
+ if (isChecked()) {
+ g.setBackgroundColor(ColorConstants.black);
+ g.fillArc(centerX - 1, centerY - cycleWidth / 2 - 1, 4, 4, 0, 360);
+ }
+ }
+
+ public int getDefaultWidth() {
+ // FIXME: don't know the how to define the default width yet.
+ return 15;
+ }
+
+ /**
+ * @return Returns the checked.
+ */
+ public boolean isChecked() {
+ return isChecked;
+ }
+
+ public void setChecked(boolean checked) {
+ this.isChecked = checked;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextAreaWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextAreaWidgetProvider.java
new file mode 100644
index 000000000..e1b16167e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextAreaWidgetProvider.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.layout.TextLayoutSupport;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TextAreaWidgetProvider extends AbstractWidgetProvider {
+ private static final int DEFAULTCOLUMN = 20;
+
+ private static final int DEFAULTROWS = 2;
+
+ private static final int VERTICAL_PADDING = 2;
+
+ private static final int HORIZONTAL_PADDING = 2;
+
+ private static int ARRAWWIDTH = 16;
+
+ private static int ARROWHEIGHT = 16;
+
+ private int _columns = DEFAULTCOLUMN;
+
+ private int _rows = DEFAULTROWS;
+
+ private String _value;
+
+ /**
+ * @param style
+ */
+ public TextAreaWidgetProvider(ICSSStyle style) {
+ super(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+ }
+ if (height <= 0) {
+ height = getDefaultHeight();
+ }
+ return new DimensionInfo(width, height, -1);
+ }
+
+ /**
+ * @return
+ */
+ private int getDefaultHeight() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtfont = font.getSwtFont();
+ int fontHeight = FigureUtilities.getFontMetrics(swtfont).getHeight();
+
+ return (fontHeight) * _rows + VERTICAL_PADDING;
+ }
+
+ /**
+ * @return
+ */
+ private int getDefaultWidth() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+
+ int fontWidth = FigureUtilities.getFontMetrics(font.getSwtFont())
+ .getAverageCharWidth();
+ return _columns * fontWidth + ARRAWWIDTH + HORIZONTAL_PADDING;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ if (_value != null) {
+ g.clipRect(rect);
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ int decoration = ((Integer) style
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTDECORATION))
+ .intValue();
+ ICSSFont font = style.getCSSFont();
+ g.setFont(font.getSwtFont());
+
+ Color newColor = null;
+ Object color = style.getColor();
+ if (color instanceof Color) {
+ g.setForegroundColor((Color) color);
+ } else if (color instanceof RGB) {
+ newColor = new Color(Display.getCurrent(), (RGB) color);
+ g.setForegroundColor(newColor);
+ } else {
+ g.setForegroundColor(ColorConstants.black);
+ }
+
+ Object textAlign = style
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN);
+ int begin = 0;
+ int end = 0;
+ int fontHeight = FigureUtilities.getFontMetrics(font.getSwtFont())
+ .getHeight();
+
+ int fontWidth = FigureUtilities.getFontMetrics(font.getSwtFont())
+ .getAverageCharWidth();
+ int columns = (rect.width - HORIZONTAL_PADDING) / fontWidth;
+
+ int i = 0;
+ while (true) {
+ int y = rect.y + VERTICAL_PADDING / 2 + fontHeight * i;
+ if (y >= rect.bottom()) {
+ break;
+ }
+ end += columns;
+ if (end > _value.length()) {
+ end = _value.length();
+ }
+ end = getTextCount(begin, end, g.getFont(), rect.width
+ - ARRAWWIDTH);
+
+ String text = _value.substring(begin, end);
+
+ int width = FigureUtilities.getTextWidth(text, g.getFont());
+ int x = TextLayoutSupport.getBeginX(textAlign, rect, width);
+ g.drawString(text, x, y);
+
+ TextLayoutSupport.paintTextDecoration(g, new Rectangle(x, y,
+ width, fontHeight), decoration);
+ begin = end;
+
+ if (end == _value.length()) {
+ break;
+ }
+ i++;
+ }
+ if (newColor != null) {
+ newColor.dispose();
+ }
+ }
+ int borderThick = 2;
+ BorderUtil
+ .drawVertialBar(g, ARRAWWIDTH, ARROWHEIGHT, borderThick, rect);
+ }
+
+ private int getTextCount(int begin, int end, Font swtFont, int textWidth) {
+ while (FigureUtilities.getTextWidth(_value.substring(begin, end),
+ swtFont) > textWidth) {
+ end--;
+ }
+ return end;
+ }
+
+ public void setColumns(int columns) {
+ this._columns = (columns > 0 ? columns : DEFAULTCOLUMN);
+ }
+
+ public void setRows(int rows) {
+ this._rows = (rows > 0 ? rows : DEFAULTROWS);
+ }
+
+ public void setValue(String value) {
+ this._value = value;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextInputWidgetProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextInputWidgetProvider.java
new file mode 100644
index 000000000..d4f9508a5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/css2/widget/TextInputWidgetProvider.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.css2.widget;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureUtilities;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
+import org.eclipse.jst.pagedesigner.css2.layout.TextLayoutSupport;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.DimensionInfo;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TextInputWidgetProvider extends AbstractWidgetProvider {
+ private static final int VERTICAL_INCREMENT = 2;
+
+ public static final int PWD_SIZE = 18;
+
+ private int DEFAULTSIZE = 20;
+
+ private int _size = DEFAULTSIZE;
+
+ private String _value;
+
+ public TextInputWidgetProvider(ICSSStyle style) {
+ this(style, 20);
+ }
+
+ public TextInputWidgetProvider(ICSSStyle style, int size) {
+ super(style);
+ DEFAULTSIZE = size;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#getPreferredDimension(int,
+ * int)
+ */
+ public DimensionInfo getPreferredDimension(int width, int height) {
+ if (width <= 0) {
+ width = getDefaultWidth();
+
+ }
+ if (height <= 0) {
+ height = getDefaultHeight();
+ }
+ return new DimensionInfo(width, height, -1);
+ }
+
+ /**
+ * @return
+ */
+ private int getDefaultHeight() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ ICSSFont font = style.getCSSFont();
+ Font swtfont = font.getSwtFont();
+ int fontSize = FigureUtilities.getFontMetrics(swtfont).getHeight();
+ return fontSize + VERTICAL_INCREMENT;
+ }
+
+ public int getDefaultWidth() {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ return computeWidth(style.getCSSFont());
+ }
+
+ private int computeWidth(ICSSFont font) {
+ int fontWidth = FigureUtilities
+ .getTextWidth("abcde", font.getSwtFont());//$NON-NLS-1$
+ return (fontWidth + 1) * _size / 5;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider#paintFigure(org.eclipse.draw2d.Graphics,
+ * org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void paintFigure(Graphics g, Rectangle rect) {
+ String value = getValue();
+ if (value != null) {
+ ICSSStyle style = this.getCSSStyle();
+ if (style == null) {
+ style = DefaultStyle.getInstance();
+ }
+ Object textAlign = style
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTALIGN);
+
+ Font font = style.getCSSFont().getSwtFont();
+ g.setFont(font);
+
+ Color newColor = null;
+ Object color = style.getColor();
+ if (color instanceof Color) {
+ g.setForegroundColor((Color) color);
+ } else if (color instanceof RGB) {
+ newColor = new Color(Display.getCurrent(), (RGB) color);
+ g.setForegroundColor(newColor);
+ } else {
+ g.setForegroundColor(ColorConstants.black);
+ }
+ g.clipRect(rect);
+ int width = FigureUtilities.getTextWidth(value, g.getFont());
+ int x = TextLayoutSupport.getBeginX(textAlign, rect, width);
+ int y = rect.y + VERTICAL_INCREMENT / 2;
+
+ g.drawString(value, x, y);
+ TextLayoutSupport.paintTextDecoration(g, new Rectangle(x, y, width,
+ g.getFontMetrics().getHeight()), ((Integer) getCSSStyle()
+ .getStyleProperty(ICSSPropertyID.ATTR_TEXTDECORATION))
+ .intValue());
+ if (newColor != null) {
+ newColor.dispose();
+ }
+ }
+ }
+
+ /**
+ * set the value in this text input control
+ *
+ * @param value
+ */
+ public void setValue(String value) {
+ this._value = value;
+ }
+
+ public void setSize(int size) {
+ this._size = (size <= 0 ? DEFAULTSIZE : size);
+ }
+
+ /**
+ * get current value in this text input control
+ *
+ * @return
+ */
+ public String getValue() {
+ return _value;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/FeedBackInfo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/FeedBackInfo.java
new file mode 100644
index 000000000..dcd8b8094
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/FeedBackInfo.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd;
+
+/**
+ * @author mengbo
+ */
+public class FeedBackInfo {
+ private String _description;
+
+ private int _order;
+
+ /**
+ *
+ */
+ public FeedBackInfo(String desc, int order) {
+ this._description = desc;
+ }
+
+ /**
+ * the description may be used in tooltip or wizard dialog selection to tell
+ * user the effect of the drop.
+ *
+ * @return
+ */
+ public String getDescription() {
+ return _description;
+ }
+
+ /**
+ * how important this feedback is. This information may be used when we
+ * ordering the choices in the wizard.
+ *
+ * range from 0-10, the bigger, the more important.
+ *
+ * @return
+ */
+ public int getOrder() {
+ return _order;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/ILocalDropHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/ILocalDropHandler.java
new file mode 100644
index 000000000..54cd48ba3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/ILocalDropHandler.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd;
+
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public interface ILocalDropHandler {
+ /**
+ * whether this handler will use wizard for user to config detail
+ *
+ * @return
+ */
+ public boolean useWizard();
+
+ public boolean useWizard(Object localData, IHTMLGraphicalViewer viewer);
+
+ /**
+ *
+ * @param localData
+ * @param widget
+ * @return
+ */
+ public FeedBackInfo supportUpdateWidget(Object localData, Node widget);
+
+ /**
+ * This method will only be called when <code>supportUpdateWidget</code>
+ * return true and <code>useWizard</code> return true.
+ *
+ * @param localData
+ * @param widget
+ * @param viewer
+ * @return
+ */
+ public IWizard getWizard(Object localData, Node widget,
+ IHTMLGraphicalViewer viewer);
+
+ /**
+ * this method is called when the handler don't support wizard.
+ *
+ * @param localData
+ * @param widget
+ * @param viewer
+ */
+ public void doUpdateWidget(Object localData, Node widget,
+ IHTMLGraphicalViewer viewer);
+
+ /**
+ *
+ * @param localData
+ * @param position
+ * @return
+ */
+ public FeedBackInfo supportInsertElements(Object localData,
+ IDOMPosition position);
+
+ /**
+ *
+ * @param localData
+ * @param position
+ * @param viewer
+ * @return
+ */
+ public IWizard getWizard(Object localData, IDOMPosition position,
+ IHTMLGraphicalViewer viewer);
+
+ public void doInsertElements(Object localData, IDOMPosition position,
+ IHTMLGraphicalViewer viewer);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/LocalDropRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/LocalDropRequest.java
new file mode 100644
index 000000000..5bf936138
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/LocalDropRequest.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.requests.DropRequest;
+
+/**
+ * @author mengbo
+ */
+public class LocalDropRequest extends Request implements DropRequest {
+ // XXX: need move this constant to somewhere else.
+ public static final String REQ_LOCAL_DROP = "Local Drop";
+
+ private Point _location;
+
+ private Object _localObject;
+
+ /**
+ *
+ */
+ public LocalDropRequest() {
+ super(REQ_LOCAL_DROP);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Returns the location of the object to be created.
+ *
+ * @return the location
+ */
+ public Point getLocation() {
+ return _location;
+ }
+
+ /**
+ * Sets the location where the new object will be placed.
+ *
+ * @param location
+ * the location
+ */
+ public void setLocation(Point location) {
+ this._location = location;
+ }
+
+ public Object getLocalObject() {
+ return _localObject;
+ }
+
+ public void setLocalObject(Object local) {
+ this._localObject = local;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceDropTargetListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceDropTargetListener.java
new file mode 100644
index 000000000..153791fec
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceDropTargetListener.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.jst.pagedesigner.commands.PaletteDropInsertCommand;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemDescriptor;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.texteditor.ITextEditorDropTargetListener;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.sse.ui.internal.ExtendedEditorDropTargetAdapter;
+
+/**
+ * @author mengbo
+ */
+public class DesignerSourceDropTargetListener extends
+ ExtendedEditorDropTargetAdapter implements
+ ITextEditorDropTargetListener {
+ private int _location;
+
+ private StructuredTextEditor _textEditor;
+
+ public DesignerSourceDropTargetListener(StructuredTextEditor textEditor) {
+ super(false);
+ _textEditor = textEditor;
+ setTextViewer(_textEditor.getTextViewer());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.ITextEditorDropTargetListener#getTransfers()
+ */
+ public Transfer[] getTransfers() {
+ return new Transfer[] { TemplateTransfer.getInstance(),
+ TextTransfer.getInstance() };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void dragOperationChanged(DropTargetEvent event) {
+ super.dragOperationChanged(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void dragOver(DropTargetEvent event) {
+ StyledText text = null;
+ if (_textEditor.getTextViewer() != null) {
+ text = _textEditor.getTextViewer().getTextWidget();
+ if (TemplateTransfer.getInstance().isSupportedType(
+ event.currentDataType)) {
+ if (_textEditor.getTextViewer() != null) {
+ Point p = new Point(event.x, event.y);
+ SourceViewerDragDropHelper.getInstance().updateCaret(
+ _textEditor, p);
+ _location = text.getCaretOffset();
+ if (TemplateTransfer.getInstance().isSupportedType(
+ event.currentDataType)) {
+ _location = SourceViewerDragDropHelper.getInstance()
+ .getValidLocation(_textEditor, _location);
+ }
+ SourceViewerDragDropHelper.getInstance().showCaret(
+ _textEditor, _location);
+ }
+ } else if (TextTransfer.getInstance().isSupportedType(
+ event.currentDataType)) {
+ super.dragOver(event);
+ _location = text.getCaretOffset();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void drop(DropTargetEvent event) {
+ StyledText text = null;
+ if (_textEditor.getTextViewer() != null) {
+ text = _textEditor.getTextViewer().getTextWidget();
+ }
+ text.setCaretOffset(_location);
+ Command command = getCommand(event);
+ if (command == null) {
+ return;
+ }
+ command.execute();
+ }
+
+ private Command getCommand(DropTargetEvent event) {
+ if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
+ Object data = event.data;
+ if (data instanceof String) {
+ SourceViewLocalDropCommand command = new SourceViewLocalDropCommand(
+ _textEditor, data, _location);
+ return command;
+ }
+ } else if (TemplateTransfer.getInstance().isSupportedType(
+ event.currentDataType)) {
+ Object data = event.data;
+ PaletteDropInsertCommand command = null;
+ if (data instanceof PaletteItemDescriptor) {
+ PaletteItemDescriptor descriptor = (PaletteItemDescriptor) data;
+ // "Create new item"
+ command = new PaletteDropInsertCommand(
+ PageDesignerResources
+ .getInstance()
+ .getString(
+ "DesignerSourceDropTargetListener.InserCommandLabel"), _textEditor, descriptor, _location); //$NON-NLS-1$
+ }
+ return command;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceMouseTrackAdapter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceMouseTrackAdapter.java
new file mode 100644
index 000000000..cf5e7bd36
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerSourceMouseTrackAdapter.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.gef.EditDomain;
+import org.eclipse.gef.palette.ToolEntry;
+import org.eclipse.jst.pagedesigner.commands.PaletteDropInsertCommand;
+import org.eclipse.jst.pagedesigner.commands.SourceViewerCommand;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemToolEntry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.sse.ui.internal.ExtendedEditorDropTargetAdapter;
+
+/**
+ * @author mengbo
+ */
+public class DesignerSourceMouseTrackAdapter extends
+ ExtendedEditorDropTargetAdapter implements MouseListener,
+ MouseMoveListener {
+ private int _location;
+
+ private StructuredTextEditor _textEditor;
+
+ private EditDomain _domain;
+
+ public DesignerSourceMouseTrackAdapter(StructuredTextEditor textEditor,
+ EditDomain domain) {
+ super(false);
+ _textEditor = textEditor;
+ _domain = domain;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent event) {
+ Object object = getPaletteObject();
+ StyledText text = null;
+ if (_textEditor.getTextViewer() != null) {
+ text = _textEditor.getTextViewer().getTextWidget();
+ } else {
+ return;
+ }
+ if (object == null) {
+ text.setCursor(new Cursor(null, SWT.CURSOR_IBEAM));
+ return;
+ }
+ Point p = new Point(event.x, event.y);
+ p = _textEditor.getTextViewer().getTextWidget().toDisplay(p);
+ SourceViewerDragDropHelper.getInstance().updateCaret(_textEditor, p);
+ _location = text.getCaretOffset();
+ _location = SourceViewerDragDropHelper.getInstance().getValidLocation(
+ _textEditor, _location);
+ _location = SourceViewerDragDropHelper.getInstance().showCaret(
+ _textEditor, _location);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseUp(MouseEvent event) {
+ if (event.button != 1) {
+ if (_domain.getPaletteViewer() != null) {
+ _domain.getPaletteViewer().setActiveTool(null);
+ }
+ return;
+ } else {
+ SourceViewerCommand command = getCommand(event);
+ if (command != null) {
+ command.execute();
+ resetPalette();
+ }
+ _location = 0;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.palette.PaletteListener#activeToolChanged(org.eclipse.gef.ui.palette.PaletteViewer,
+ * org.eclipse.gef.palette.ToolEntry)
+ */
+ public Object getPaletteObject() {
+ if (_domain.getPaletteViewer() != null) {
+ Object tool = _domain.getPaletteViewer().getActiveTool();
+ if (tool instanceof ItemToolEntry) {
+ Object object = ((ItemToolEntry) tool).getItemDesc();
+ return object;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDown(MouseEvent e) {
+ }
+
+ private PaletteDropInsertCommand getCommand(MouseEvent event) {
+ Object data = getPaletteObject();
+ PaletteDropInsertCommand command = null;
+ if (data instanceof PaletteItemDescriptor) {
+ PaletteItemDescriptor descriptor = (PaletteItemDescriptor) data;
+ // "Create new item"
+ command = new PaletteDropInsertCommand(
+ PageDesignerResources
+ .getInstance()
+ .getString(
+ "DesignerSourceDropTargetListener.InserCommandLabel"),
+ _textEditor, descriptor, _location);
+ }
+ return command;
+ }
+
+ private void resetPalette() {
+ if (_domain.getPaletteViewer() != null) {
+ ToolEntry tool = _domain.getPaletteViewer().getPaletteRoot()
+ .getDefaultEntry();
+ if (tool != null) {
+ _domain.getPaletteViewer().setActiveTool((ToolEntry) tool);
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerTemplateTransferDragSourceListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerTemplateTransferDragSourceListener.java
new file mode 100644
index 000000000..91d0409e9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DesignerTemplateTransferDragSourceListener.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemToolEntry;
+
+/**
+ * @author mengbo
+ */
+public class DesignerTemplateTransferDragSourceListener extends
+ TemplateTransferDragSourceListener {
+
+ /**
+ * @param viewer
+ */
+ public DesignerTemplateTransferDragSourceListener(EditPartViewer viewer) {
+ super(viewer);
+ }
+
+ protected Object getTemplate() {
+ Object object = super.getTemplate();
+ if (object == null) {
+ List selection = getViewer().getSelectedEditParts();
+ if (selection.size() == 1) {
+ EditPart editpart = (EditPart) getViewer()
+ .getSelectedEditParts().get(0);
+ Object model = editpart.getModel();
+ if (model instanceof ItemToolEntry) {
+ return ((ItemToolEntry) model).getItemDesc();
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DropSelectionWizard.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DropSelectionWizard.java
new file mode 100644
index 000000000..76c026a93
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/DropSelectionWizard.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.dnd.ILocalDropHandler;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class DropSelectionWizard extends Wizard {
+ private final String INTIAL_DEFAULT_PAGE_IMAGE = "newsuade_wiz.gif";
+
+ private Object _localData;
+
+ private IHTMLGraphicalViewer _viewer;
+
+ private Map _feedbackToHandlers;
+
+ private boolean _updateWidget;
+
+ private Node _widget;
+
+ private IDOMPosition _position;
+
+ private SimpleWizardSelectionPage _firstPage;
+
+ private DropSelectionWizard(IHTMLGraphicalViewer viewer, Object localData,
+ Map handlers) {
+ this.setWindowTitle(Messages.getString("DropSelectionWizard.Title")); //$NON-NLS-1$
+ ImageDescriptor desc = PDPlugin.getDefault().getImageDescriptor(
+ INTIAL_DEFAULT_PAGE_IMAGE);
+ setDefaultPageImageDescriptor(desc);
+ this._viewer = viewer;
+ this._localData = localData;
+ this._feedbackToHandlers = handlers;
+
+ _firstPage = new SimpleWizardSelectionPage(_viewer, _localData,
+ _feedbackToHandlers);
+ }
+
+ /**
+ *
+ */
+ public DropSelectionWizard(IHTMLGraphicalViewer viewer, Object localData,
+ Map handlers, Node widget) {
+ this(viewer, localData, handlers);
+ _updateWidget = true;
+ _widget = widget;
+
+ _firstPage.setWidget(widget);
+ }
+
+ public DropSelectionWizard(IHTMLGraphicalViewer viewer, Object localData,
+ Map handlers, IDOMPosition position) {
+ this(viewer, localData, handlers);
+ _updateWidget = false;
+ _position = position;
+
+ _firstPage.setPosition(position);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.Wizard#addPages()
+ */
+ public void addPages() {
+ addPage(_firstPage);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.Wizard#needsPreviousAndNextButtons()
+ */
+ public boolean needsPreviousAndNextButtons() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.Wizard#canFinish()
+ */
+ public boolean canFinish() {
+ if (getContainer().getCurrentPage() == _firstPage) {
+ Object obj = _firstPage.getCurrentHandler();
+ if (obj instanceof ILocalDropHandler)
+ return true;
+ else
+ return false;
+ } else {
+ return super.canFinish();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.IWizard#performFinish()
+ */
+ public boolean performFinish() {
+ if (getContainer().getCurrentPage() == _firstPage) {
+ Object obj = _firstPage.getCurrentHandler();
+ if (obj instanceof ILocalDropHandler) {
+ ILocalDropHandler handler = (ILocalDropHandler) obj;
+ if (_updateWidget) {
+ handler.doUpdateWidget(_localData, _widget, _viewer);
+ } else {
+ handler.doInsertElements(_localData, _position, _viewer);
+ }
+ return true;
+ }
+ }
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropCommand.java
new file mode 100644
index 000000000..ce6f6db1a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropCommand.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.Map;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jst.pagedesigner.common.dialogs.CommonWizardDialog;
+import org.eclipse.jst.pagedesigner.dnd.ILocalDropHandler;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.widgets.Shell;
+import org.w3c.dom.Node;
+
+/**
+ * This is the command that performs the drop operation. There is no need for
+ * this command to go into command stack, it simply open wizards, and let
+ * wizards to handle the remaining things.
+ *
+ * @author mengbo
+ */
+public class LocalDropCommand extends Command {
+ /**
+ * the map from feedback to ILocalDropHandler
+ */
+ private Map _feedbackToHandlers;
+
+ private IHTMLGraphicalViewer _viewer;
+
+ private Object _localObject;
+
+ private Node _widget;
+
+ private IDOMPosition _position;
+
+ /**
+ * constructor
+ */
+ public LocalDropCommand(IHTMLGraphicalViewer viewer, Object localObject,
+ Map feedbackHandlers) {
+ _viewer = viewer;
+ _localObject = localObject;
+ _feedbackToHandlers = feedbackHandlers;
+ }
+
+ public void setWidget(Node widget) {
+ _widget = widget;
+ }
+
+ public void setDOMPosition(IDOMPosition position) {
+ _position = position;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void execute() {
+ if (_feedbackToHandlers.size() == 1) {
+ // only have one choice.
+ ILocalDropHandler handler = (ILocalDropHandler) _feedbackToHandlers
+ .values().toArray()[0];
+ if (handler.useWizard(_localObject, _viewer)) {
+ IWizard wizard;
+ if (_widget != null) {
+ wizard = handler.getWizard(_localObject, _widget, _viewer);
+ } else {
+ wizard = handler
+ .getWizard(_localObject, _position, _viewer);
+ }
+ CommonWizardDialog wizardDialog = new CommonWizardDialog(
+ getShell(), wizard);
+ wizardDialog.setTitle(Messages
+ .getString("LocalDropCommand.DropHandler"));
+ wizardDialog.create();
+ wizardDialog.open();
+ } else {
+ if (_widget != null) {
+ handler.doUpdateWidget(_localObject, _widget, _viewer);
+ } else {
+ handler.doInsertElements(_localObject, _position, _viewer);
+ }
+ }
+ } else {
+ CommonWizardDialog wizardDialog = new CommonWizardDialog(
+ getShell(), getWizard());
+ wizardDialog.setTitle(Messages
+ .getString("LocalDropCommand.DropHandler"));
+ wizardDialog.setBlockOnOpen(false);
+ wizardDialog.create();
+ wizardDialog.open();
+ }
+ }
+
+ /**
+ * @return
+ */
+ private IWizard getWizard() {
+ if (_widget != null) {
+ return new DropSelectionWizard(_viewer, _localObject,
+ _feedbackToHandlers, _widget);
+ } else {
+ return new DropSelectionWizard(_viewer, _localObject,
+ _feedbackToHandlers, _position);
+ }
+ }
+
+ /**
+ * @return
+ */
+ private Shell getShell() {
+ return _viewer.getControl().getShell();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropEditPolicy.java
new file mode 100644
index 000000000..f78f8f4e1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalDropEditPolicy.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.RectangleFigure;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editpolicies.GraphicalEditPolicy;
+import org.eclipse.jst.pagedesigner.dnd.FeedBackInfo;
+import org.eclipse.jst.pagedesigner.dnd.ILocalDropHandler;
+import org.eclipse.jst.pagedesigner.dnd.LocalDropRequest;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.editpolicies.LocationHelper;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.tools.ExposeHelper;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.DnDPositionValidator;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * This is the editpolicy to handle LocalSelectionDrop
+ *
+ * @author mengbo
+ */
+public class LocalDropEditPolicy extends GraphicalEditPolicy {
+ private RectangleFigure _feedbackFigure;
+
+ // indicate whether update is checked
+ private static boolean _checkUpdate = true;
+
+ public boolean checkUpdateWidget(EditPart widgetEditPart,
+ LocalDropRequest request, Map results) {
+ if (!(widgetEditPart instanceof ElementEditPart)) {
+ return false;
+ }
+ Node widget = ((ElementEditPart) widgetEditPart).getIDOMNode();
+ ILocalDropHandler[] handlers = RegistryReader.getAllHandlers();
+ Object localData = request.getLocalObject();
+ for (int i = 0; i < handlers.length; i++) {
+ FeedBackInfo feedback = handlers[i].supportUpdateWidget(localData,
+ widget);
+ if (feedback != null) {
+ results.put(feedback, handlers[i]);
+ }
+ }
+ return !results.isEmpty();
+ }
+
+ public boolean checkInsertElement(LocalDropRequest request,
+ EditPart[] host, Map results, DesignPosition[] dpHolder,
+ IDOMPosition[] position) {
+ DesignPosition designPosition = EditPartPositionHelper
+ .findEditPartPosition(host[0], request.getLocation(),
+ new DnDPositionValidator(new ActionData(
+ ActionData.DATABINDING_DND, request)));
+ dpHolder[0] = designPosition;
+ if (designPosition == null) {
+ return false;
+ }
+
+ host[0] = designPosition.getContainerPart();
+ position[0] = DOMPositionHelper.toDOMPosition(designPosition);
+ ILocalDropHandler[] handlers = RegistryReader.getAllHandlers();
+ Object localData = request.getLocalObject();
+ for (int i = 0; i < handlers.length; i++) {
+ FeedBackInfo feedback = handlers[i].supportInsertElements(
+ localData, position[0]);
+ if (feedback != null) {
+ results.put(feedback, handlers[i]);
+ }
+ }
+ return !results.isEmpty();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getTargetEditPart(org.eclipse.gef.Request)
+ */
+ public EditPart getTargetEditPart(Request request) {
+ if (request instanceof LocalDropRequest) {
+ LocalDropRequest r = (LocalDropRequest) request;
+ EditPart host = getHost();
+ if (_checkUpdate && checkUpdateWidget(host, r, new HashMap())) {
+ return host;
+ }
+ EditPart[] hostHolder = new EditPart[] { host };
+ if (checkInsertElement(r, hostHolder, new HashMap(),
+ new DesignPosition[1], new IDOMPosition[1])) {
+ return hostHolder[0];
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ public Command getCommand(Request request) {
+ if (request instanceof LocalDropRequest) {
+ LocalDropRequest r = (LocalDropRequest) request;
+ EditPart host = getHost();
+
+ Map result = new HashMap();
+ if (_checkUpdate && checkUpdateWidget(host, r, result)) {
+ LocalDropCommand command = new LocalDropCommand(
+ getViewer(host), r.getLocalObject(), result);
+ command.setWidget(((NodeEditPart) host).getIDOMNode());
+ return command;
+ }
+ result.clear();
+
+ EditPart[] hostHolder = new EditPart[] { host };
+ IDOMPosition[] positionHolder = new IDOMPosition[1];
+ if (checkInsertElement(r, hostHolder, result,
+ new DesignPosition[1], positionHolder)) {
+ LocalDropCommand command = new LocalDropCommand(
+ getViewer(host), r.getLocalObject(), result);
+ command.setDOMPosition(positionHolder[0]);
+ return command;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param host
+ * @return
+ */
+ private IHTMLGraphicalViewer getViewer(EditPart host) {
+ return (IHTMLGraphicalViewer) ((GraphicalEditPart) host).getViewer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void eraseTargetFeedback(Request request) {
+ if (_feedbackFigure != null) {
+ removeFeedback(_feedbackFigure);
+ _feedbackFigure = null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#showTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void showTargetFeedback(Request request) {
+ if (request instanceof LocalDropRequest) {
+ LocalDropRequest r = (LocalDropRequest) request;
+ EditPart host = getHost();
+ if (_checkUpdate && checkUpdateWidget(host, r, new HashMap())) {
+ Rectangle rect = LocationHelper
+ .getAbsoluteBounds((GraphicalEditPart) host);
+ showFeedbackRect(rect);
+ return;
+ }
+ EditPart[] hostHolder = new EditPart[] { host };
+ DesignPosition[] holder = new DesignPosition[1];
+ if (checkInsertElement(r, hostHolder, new HashMap(), holder,
+ new IDOMPosition[1])) {
+ Rectangle rect = EditPartPositionHelper
+ .convertToAbsoluteCaretRect(holder[0]);
+ showFeedbackRect(rect);
+ if (getHost() instanceof GraphicalEditPart) {
+ ExposeHelper exposeHelper = new ExposeHelper(
+ getViewer(getHost()));
+ exposeHelper.adjustVertical(r.getLocation());
+ }
+ return;
+ }
+ }
+ }
+
+ protected RectangleFigure getFeedbackFigure() {
+ if (_feedbackFigure == null) {
+ _feedbackFigure = new RectangleFigure();
+ _feedbackFigure.setFill(true);
+ _feedbackFigure.setOutline(true);
+ _feedbackFigure.setLineWidth(1);
+ _feedbackFigure.setForegroundColor(ColorConstants.red);
+ _feedbackFigure.setBounds(new Rectangle(0, 0, 0, 0));
+ _feedbackFigure.setXOR(true);
+ addFeedback(_feedbackFigure);
+ }
+ return _feedbackFigure;
+ }
+
+ protected void showFeedbackRect(Rectangle rect) {
+ RectangleFigure pf = getFeedbackFigure();
+ pf.translateToRelative(rect);
+ pf.setBounds(rect);
+ }
+
+ /**
+ * @return Returns the _forUpdate.
+ */
+ public static boolean isCheckUpdate() {
+ return _checkUpdate;
+ }
+
+ /**
+ * @param update
+ * The _forUpdate to set.
+ */
+ public static void setCheckUpdate(boolean update) {
+ _checkUpdate = update;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalSelectionDropTargetListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalSelectionDropTargetListener.java
new file mode 100644
index 000000000..ebb000bd7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/LocalSelectionDropTargetListener.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.dnd.AbstractTransferDropTargetListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.guiutils.Alerts;
+import org.eclipse.jst.pagedesigner.dnd.LocalDropRequest;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
+
+/**
+ * @author mengbo
+ */
+public class LocalSelectionDropTargetListener extends
+ AbstractTransferDropTargetListener {
+ /**
+ * @param viewer
+ */
+ public LocalSelectionDropTargetListener(EditPartViewer viewer) {
+ super(viewer, LocalSelectionTransfer.getInstance());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ LocalDropRequest request = new LocalDropRequest();
+ request.setLocation(getDropLocation());
+ request.setLocalObject(getCurrentLocalObject());
+ return request;
+ }
+
+ public Object getCurrentLocalObject() {
+ ISelection sel = LocalSelectionTransfer.getInstance().getSelection();
+ if (sel instanceof IStructuredSelection) {
+ return ((IStructuredSelection) sel).getFirstElement();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#updateTargetRequest()
+ */
+ protected void updateTargetRequest() {
+ LocalDropRequest dropRequest = (LocalDropRequest) getTargetRequest();
+ dropRequest.setLocation(getDropLocation());
+ dropRequest.setLocalObject(getCurrentLocalObject());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#setCurrentEvent(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void setCurrentEvent(DropTargetEvent currentEvent) {
+ super.setCurrentEvent(currentEvent);
+ if (currentEvent != null) {
+ if (currentEvent.detail != DND.DROP_NONE) {
+ currentEvent.detail = DND.DROP_COPY;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void dragOperationChanged(DropTargetEvent event) {
+ // switch the insert or update
+ if ((event.detail & (DND.DROP_COPY)) != 0) {
+ LocalDropEditPolicy.setCheckUpdate(false);
+ } else {
+ LocalDropEditPolicy.setCheckUpdate(true);
+ }
+ super.dragOperationChanged(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void drop(DropTargetEvent event) {
+ String path = ((HTMLGraphicalViewer) getViewer()).getModel()
+ .getBaseLocation();
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceRoot root = workspace.getRoot();
+ IPath filePath = new Path(path);
+ if (root.getFile(filePath).exists()) {
+ getViewer().getControl().setFocus();
+ super.drop(event);
+ LocalDropEditPolicy.setCheckUpdate(true);
+ } else {
+ Alerts alert = PDPlugin.getAlerts();
+ alert.info("LocalSelectionDropTargetListener.MessageDialog.Title",
+ "LocalSelectionDropTargetListener.MessageDialog.Message");
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/Messages.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/Messages.java
new file mode 100644
index 000000000..0e6af8a08
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/Messages.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "org.eclipse.jst.pagedesigner.dnd.internal.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ // TODO Auto-generated method stub
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/PDTemplateTransferDropTargetListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/PDTemplateTransferDropTargetListener.java
new file mode 100644
index 000000000..a0f91f25d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/PDTemplateTransferDropTargetListener.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.dnd.AbstractTransferDropTargetListener;
+import org.eclipse.gef.dnd.TemplateTransfer;
+import org.eclipse.gef.requests.CreateRequest;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemCreationRequest;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PDTemplateTransferDropTargetListener extends
+ AbstractTransferDropTargetListener {
+
+ /**
+ * @param viewer
+ */
+ public PDTemplateTransferDropTargetListener(EditPartViewer viewer) {
+ super(viewer, TemplateTransfer.getInstance());
+ }
+
+ /**
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ Request request = new ItemCreationRequest();
+ return request;
+ }
+
+ /**
+ * A helper method that casts the target Request to a CreateRequest.
+ *
+ * @return CreateRequest
+ */
+ protected final Request getCreateRequest() {
+ return getTargetRequest();
+ }
+
+ /**
+ * The purpose of a template is to be copied. Therefore, the drop operation
+ * can't be anything but <code>DND.DROP_COPY</code>.
+ *
+ * @see AbstractTransferDropTargetListener#handleDragOperationChanged()
+ */
+ protected void handleDragOperationChanged() {
+ getCurrentEvent().detail = DND.DROP_COPY;
+ super.handleDragOperationChanged();
+ }
+
+ /**
+ * The purpose of a template is to be copied. Therefore, the Drop operation
+ * is set to <code>DND.DROP_COPY</code> by default.
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#handleDragOver()
+ */
+ protected void handleDragOver() {
+ getCurrentEvent().detail = DND.DROP_COPY;
+ getCurrentEvent().feedback = DND.FEEDBACK_SCROLL | DND.FEEDBACK_EXPAND;
+ super.handleDragOver();
+ }
+
+ /**
+ * Assumes that the target request is a {@link CreateRequest}.
+ */
+ protected void updateTargetRequest() {
+ // We should never see request that is not of ItemCreationRequest type,
+ // but there is an error case that Eclipse send out other types
+ // requests.
+ // Add this test to avoid potential error.
+ if (getCreateRequest() instanceof ItemCreationRequest) {
+ ItemCreationRequest request = (ItemCreationRequest) getCreateRequest();
+ PaletteItemDescriptor itemDescriptor = (PaletteItemDescriptor) TemplateTransfer
+ .getInstance().getObject();
+ request.setItemDescriptor(itemDescriptor);
+ request.setLocation(getDropLocation());
+ }
+ }
+
+ public void drop(DropTargetEvent event) {
+ if (getCreateRequest() instanceof ItemCreationRequest) {
+ getViewer().getControl().setFocus();
+ super.drop(event);
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/RegistryReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/RegistryReader.java
new file mode 100644
index 000000000..eed779aef
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/RegistryReader.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dnd.ILocalDropHandler;
+
+/**
+ * Read the registry to find out all the LocalDropHandlers.
+ *
+ * @author mengbo
+ */
+public class RegistryReader {
+ final private static Logger _log = PDPlugin.getLogger(RegistryReader.class);
+
+ private static ILocalDropHandler[] _handlers = null;
+
+ public static synchronized ILocalDropHandler[] getAllHandlers() {
+ if (_handlers == null) {
+ _handlers = readAllHandlers();
+ }
+ return _handlers;
+
+ }
+
+ private static ILocalDropHandler[] readAllHandlers() {
+ List result = new ArrayList();
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+ IExtension[] extensions = extensionPoint.getExtensions();
+
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension ext = extensions[i];
+ IConfigurationElement[] dropHandlers = ext
+ .getConfigurationElements();
+
+ for (int j = 0; j < dropHandlers.length; j++) {
+ if (dropHandlers[j].getName().equals(
+ IJMTConstants.LOCAL_DROP_HANDLER)) {
+ dropHandlers[j].getAttribute("class");
+ Object obj;
+ try {
+ obj = dropHandlers[j]
+ .createExecutableExtension("class");
+
+ if (obj instanceof ILocalDropHandler) {
+ result.add(obj);
+ }
+ } catch (CoreException e) {
+ _log.info("CoreException", e);
+ }
+ }
+ }
+ }
+ ILocalDropHandler[] ret = new ILocalDropHandler[result.size()];
+ result.toArray(ret);
+ return ret;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/ResouceDropTargetListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/ResouceDropTargetListener.java
new file mode 100644
index 000000000..2fc618355
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/ResouceDropTargetListener.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.dnd.AbstractTransferDropTargetListener;
+import org.eclipse.jst.pagedesigner.dnd.LocalDropRequest;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+
+/**
+ * The drop target listener for DnD from Windows explorer.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class ResouceDropTargetListener extends
+ AbstractTransferDropTargetListener {
+
+ public ResouceDropTargetListener(EditPartViewer viewer) {
+ super(viewer, FileTransfer.getInstance());
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ LocalDropRequest request = new LocalDropRequest();
+ request.setLocation(getDropLocation());
+ request.setLocalObject(getCurrentLocalObject());
+ return request;
+ }
+
+ public Object getCurrentLocalObject() {
+ Object result = null;
+ try {
+ Object data = ((FileTransfer) getTransfer())
+ .nativeToJava(getCurrentEvent().currentDataType);
+ if (data instanceof String[]) {
+ result = ((String[]) data)[0];
+ }
+ } catch (Exception e) {
+ // Don't know the tag type.
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#updateTargetRequest()
+ */
+ protected void updateTargetRequest() {
+ LocalDropRequest dropRequest = (LocalDropRequest) getTargetRequest();
+ dropRequest.setLocation(getDropLocation());
+ dropRequest.setLocalObject(getCurrentLocalObject());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.dnd.AbstractTransferDropTargetListener#setCurrentEvent(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void setCurrentEvent(DropTargetEvent currentEvent) {
+ super.setCurrentEvent(currentEvent);
+ if (currentEvent != null) {
+ if (currentEvent.detail != DND.DROP_NONE) {
+ currentEvent.detail = DND.DROP_COPY;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void dragOperationChanged(DropTargetEvent event) {
+ // switch the insert or update
+ if ((event.detail & (DND.DROP_COPY)) != 0) {
+ LocalDropEditPolicy.setCheckUpdate(false);
+ } else {
+ LocalDropEditPolicy.setCheckUpdate(true);
+ }
+ super.dragOperationChanged(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void drop(DropTargetEvent event) {
+ getViewer().getControl().setFocus();
+ super.drop(event);
+ LocalDropEditPolicy.setCheckUpdate(true);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SimpleWizardSelectionPage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SimpleWizardSelectionPage.java
new file mode 100644
index 000000000..a608b59ec
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SimpleWizardSelectionPage.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.IWizardNode;
+import org.eclipse.jface.wizard.WizardSelectionPage;
+import org.eclipse.jst.pagedesigner.dnd.FeedBackInfo;
+import org.eclipse.jst.pagedesigner.dnd.ILocalDropHandler;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.w3c.dom.Node;
+
+/**
+ * UI wizard selection page. To let user select which ILocalDropHandler to use
+ * to handle the drop.
+ *
+ * @author mengbo
+ */
+public class SimpleWizardSelectionPage extends WizardSelectionPage implements
+ ISelectionChangedListener {
+ private Object _localData;
+
+ private IHTMLGraphicalViewer _viewer;
+
+ private boolean _updateWidget;
+
+ private Node _widget;
+
+ private IDOMPosition _position;
+
+ /**
+ * for those handler that support wizard, then map to WizardNode, otherwise
+ * still map to the handler
+ */
+ private Map _objToWizardNodeOrHandler = new HashMap();
+
+ private Map _feedbackToHandlers;
+
+ private Object _currentHandler = null; // IWizardNode or a
+
+ // ILocalDropHandler that don't
+ // useWizard.
+
+ /**
+ * @param pageName
+ */
+ public SimpleWizardSelectionPage(IHTMLGraphicalViewer viewer,
+ Object localData, Map handlers) {
+ super(Messages.getString("SimpleWizardSelectionPage.PageName")); //$NON-NLS-1$
+ this.setTitle(Messages.getString("SimpleWizardSelectionPage.Title")); //$NON-NLS-1$
+ this.setDescription(Messages
+ .getString("SimpleWizardSelectionPage.Description")); //$NON-NLS-1$
+ this
+ .setMessage(Messages
+ .getString("SimpleWizardSelectionPage.Message")); //$NON-NLS-1$
+
+ this._viewer = viewer;
+ this._localData = localData;
+ this._feedbackToHandlers = handlers;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.verticalSpacing = 10;
+ container.setLayout(layout);
+ container.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label label = new Label(container, SWT.NONE);
+ label
+ .setText(Messages
+ .getString("SimpleWizardSelectionPage.Operation")); //$NON-NLS-1$
+ GridData gd = new GridData();
+ label.setLayoutData(gd);
+
+ final ListViewer listViewer = new ListViewer(container);
+ listViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ listViewer.setContentProvider(new IStructuredContentProvider() {
+ public Object[] getElements(Object inputElement) {
+ return ((List) inputElement).toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ }
+ });
+ listViewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ return SimpleWizardSelectionPage.this.getText(element);
+ }
+ });
+ listViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ selectionChanged(new SelectionChangedEvent(listViewer,
+ listViewer.getSelection()));
+ advanceToNextPage();
+ }
+ });
+ listViewer.setSorter(new ViewerSorter());
+ listViewer.setInput(getElements());
+ listViewer.addSelectionChangedListener(this);
+ Dialog.applyDialogFont(container);
+ setControl(container);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection sel = event.getSelection();
+ if (sel instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) sel).getFirstElement();
+ if (obj != null) {
+ _currentHandler = this._objToWizardNodeOrHandler.get(obj);
+ if (_currentHandler == null) {
+ _currentHandler = getWizardNodeOrHandler(obj);
+ this._objToWizardNodeOrHandler.put(obj, _currentHandler);
+ }
+
+ if (_currentHandler instanceof IWizardNode) {
+ this.setSelectedNode((IWizardNode) _currentHandler);
+ } else {
+ this.getWizard().getContainer().updateButtons();
+ }
+ }
+ }
+ }
+
+ /**
+ * @param obj
+ * @return
+ */
+ private Object getWizardNodeOrHandler(Object obj) {
+ final ILocalDropHandler dropHandler = (ILocalDropHandler) _feedbackToHandlers
+ .get(obj);
+ if (dropHandler.useWizard(_localData, _viewer)) {
+ return new IWizardNode() {
+ IWizard _wizard = null;
+
+ public void dispose() {
+ }
+
+ public Point getExtent() {
+ return null;
+ }
+
+ public IWizard getWizard() {
+ if (_wizard == null) {
+ if (_updateWidget) {
+ _wizard = dropHandler.getWizard(_localData,
+ _widget, _viewer);
+ } else {
+ _wizard = dropHandler.getWizard(_localData,
+ _position, _viewer);
+ }
+ }
+ return _wizard;
+ }
+
+ public boolean isContentCreated() {
+ return _wizard != null;
+ }
+ };
+ } else {
+ return dropHandler;
+ }
+ }
+
+ /**
+ * could be have next page or just directly perform the action.
+ *
+ */
+ public void advanceToNextPage() {
+
+ getContainer().showPage(getNextPage());
+ }
+
+ /**
+ * @param element
+ * @return
+ */
+ protected String getText(Object element) {
+ return ((FeedBackInfo) element).getDescription();
+ }
+
+ /**
+ * @return
+ */
+ protected List getElements() {
+ return new ArrayList(this._feedbackToHandlers.keySet());
+ }
+
+ /**
+ * @param widget
+ */
+ public void setWidget(Node widget) {
+ _updateWidget = true;
+ _widget = widget;
+ }
+
+ /**
+ * @param position
+ */
+ public void setPosition(IDOMPosition position) {
+ _updateWidget = false;
+ _position = position;
+ }
+
+ /**
+ * @return
+ */
+ public Object getCurrentHandler() {
+ return _currentHandler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.WizardSelectionPage#canFlipToNextPage()
+ */
+ public boolean canFlipToNextPage() {
+ return getCurrentHandler() instanceof IWizardNode
+ && super.canFlipToNextPage();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewLocalDropCommand.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewLocalDropCommand.java
new file mode 100644
index 000000000..4363916ba
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewLocalDropCommand.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.jst.pagedesigner.commands.SourceViewerCommand;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+
+/**
+ * @author mengbo
+ */
+public class SourceViewLocalDropCommand extends SourceViewerCommand {
+ /**
+ * the map from feedback to ILocalDropHandler
+ */
+ private int _location;
+
+ private StructuredTextEditor _textEditor;
+
+ private Object _data;
+
+ /**
+ *
+ */
+ public SourceViewLocalDropCommand(StructuredTextEditor textEditor,
+ Object data, int location) {
+ super(PageDesignerResources.getInstance().getString(
+ "SourceViewLocalDropCommand.Label.InsertSyntax"), textEditor); //$NON-NLS-1$
+ _textEditor = textEditor;
+ _data = data;
+ _location = location;
+ }
+
+ public void doExecute() {
+ _textEditor.getTextViewer().getTextWidget().insert((String) _data);
+ }
+
+ public void setSelection() {
+ _textEditor.getTextViewer().setSelectedRange(_location,
+ ((String) _data).length());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewerDragDropHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewerDragDropHelper.java
new file mode 100644
index 000000000..70d673c3c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/SourceViewerDragDropHelper.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.gef.SharedCursors;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
+import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * This class will 1. determine it's insertion or update 2. call validator
+ * corresponding helper to resolve it.
+ *
+ * @author mengbo
+ */
+public class SourceViewerDragDropHelper {
+ private static SourceViewerDragDropHelper _instance;
+
+ public static SourceViewerDragDropHelper getInstance() {
+ if (_instance == null) {
+ _instance = new SourceViewerDragDropHelper();
+ }
+ return _instance;
+ }
+
+ private Point toControl(TextViewer textViewer, Point point) {
+ return (textViewer != null ? textViewer.getTextWidget()
+ .toControl(point) : point);
+ }
+
+ private int getDropOffset(StructuredTextEditor ste, Point pt) {
+ StyledText st = ste.getTextViewer().getTextWidget();
+ int offset = st.getCaretOffset();
+ try {
+ offset = st.getOffsetAtLocation(pt);
+ } catch (IllegalArgumentException e) {
+ boolean found = false;
+ Point p = new Point((pt.x > 0 ? pt.x : 0), pt.y);
+ // search nearest character
+ for (; p.x > -1; p.x--) {
+ try {
+ offset = st.getOffsetAtLocation(p);
+
+ /*
+ * Now that a valid offset has been found, try to place at
+ * the end of the line
+ */
+ if (ste.getTextViewer() != null
+ && ste.getTextViewer().getDocument() != null) {
+ IRegion lineInfo = null;
+ try {
+ lineInfo = ste.getTextViewer().getDocument()
+ .getLineInformationOfOffset(offset);
+ } catch (BadLocationException e1) {
+ }
+ if (lineInfo != null)
+ offset = lineInfo.getOffset()
+ + lineInfo.getLength();
+ }
+
+ found = true;
+ break;
+ } catch (IllegalArgumentException ex) {
+ // for trying location, no need to catch.
+ }
+ }
+ if (!found) {
+ offset = st.getCharCount();
+ }
+ }
+ return offset;
+ }
+
+ public void updateCaret(StructuredTextEditor textEditor, Point location,
+ Point caret) {
+ TextViewer textViewer = textEditor.getTextViewer();
+ if (textViewer != null) {
+ Point pt = toControl(textViewer, location);
+ StyledText st = textViewer.getTextWidget();
+
+ // auto scroll
+ Rectangle ca = st.getClientArea();
+ int margin = st.getLineHeight();
+
+ if (pt.y < margin) { // up
+ st.invokeAction(ST.LINE_UP);
+ } else if (pt.y > ca.height - margin) { // down
+ st.invokeAction(ST.LINE_DOWN);
+ }
+
+ // draw insertion point
+ int offset = getDropOffset(textEditor, pt);
+ if (offset != st.getCaretOffset()) {
+ st.setCaretOffset(offset);
+ st.setSelection(offset);
+ }
+
+ Point newCaret = st.getLocationAtOffset(offset);
+ if (newCaret.equals(caret)) {
+ return;
+ }
+
+ Caret ct = st.getCaret();
+ Point size = ct.getSize();
+
+ GC gc = new GC(st);
+ gc.setXORMode(true);
+ gc.setLineWidth(size.x);
+
+ // erase old caret
+ if (caret != null) {
+ Color originalForeground = gc.getForeground();
+ gc.setForeground(st.getBackground());
+ gc.drawLine(caret.x, caret.y, caret.x, caret.y + size.y);
+ gc.setForeground(originalForeground);
+ }
+
+ st.redraw();
+ st.update();
+
+ // draw new caret
+ if (caret == null) {
+ caret = newCaret;
+ } else {
+ caret.x = newCaret.x;
+ caret.y = newCaret.y;
+ }
+ if (ct.getImage() != null) {
+ gc.drawImage(ct.getImage(), caret.x, caret.y);
+ } else {
+ gc.drawLine(caret.x, caret.y, caret.x, caret.y + size.y);
+ }
+
+ gc.dispose();
+ }
+ }
+
+ public void updateCaret(StructuredTextEditor textEditor, Point location) {
+ TextViewer textViewer = textEditor.getTextViewer();
+ if (textViewer != null) {
+ Point pt = toControl(textViewer, location);
+ StyledText st = textViewer.getTextWidget();
+
+ // auto scroll
+ Rectangle ca = st.getClientArea();
+ int margin = st.getLineHeight();
+
+ if (pt.y < margin) { // up
+ st.invokeAction(ST.LINE_UP);
+ } else if (pt.y > ca.height - margin) { // down
+ st.invokeAction(ST.LINE_DOWN);
+ }
+
+ // draw insertion point
+ int offset = getDropOffset(textEditor, pt);
+ if (offset != st.getCaretOffset()) {
+ st.setCaretOffset(offset);
+ st.setSelection(offset);
+ }
+ }
+ }
+
+ public int showCaret(StructuredTextEditor textEditor, int location) {
+ StyledText text = textEditor.getTextViewer().getTextWidget();
+ text.setCursor(SharedCursors.CURSOR_TREE_ADD);
+ text.setCaretOffset(location);
+ if (!text.isFocusControl()) {
+ text.setFocus();
+ }
+ return text.getCaretOffset();
+ }
+
+ protected ModelQuery getModelQuery(Node node) {
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ return ModelQueryUtil.getModelQuery((Document) node);
+ } else {
+ return ModelQueryUtil.getModelQuery(node.getOwnerDocument());
+ }
+ }
+
+ public IDOMPosition findPosition(int caretPos, Node element) {
+ EditValidateUtil.validNode(element);
+ IDOMPosition position = EditModelQuery.getInstance().createDomposition(
+ ((IDOMNode) element).getModel(), caretPos, false);
+ return position;
+ }
+
+ public void format(TextViewer viewer, Node node) {
+ if (node == null) {
+ return;
+ }
+ Node tmp;
+ int start, offset;
+ if (node.getPreviousSibling() != null) {
+ tmp = node.getPreviousSibling();
+ start = ((IndexedRegion) tmp).getEndOffset();
+ } else {
+ tmp = node;
+ start = ((IndexedRegion) tmp).getStartOffset();
+ }
+ if (node.getNextSibling() != null) {
+ tmp = node.getNextSibling();
+ offset = ((IndexedRegion) tmp).getStartOffset() - start;
+ } else {
+ tmp = node;
+ offset = ((IndexedRegion) tmp).getEndOffset() - start;
+ }
+ viewer.setSelectedRange(start, offset);
+ viewer.doOperation(ISourceViewer.FORMAT);
+ }
+
+ public void changeCaret(StructuredTextEditor textEditor, boolean reset) {
+ if (reset) {
+ StyledText text = textEditor.getTextViewer().getTextWidget();
+ text.setCursor(new Cursor(null, SWT.CURSOR_IBEAM));
+ }
+ }
+
+ public int getValidLocation(StructuredTextEditor textEditor,
+ int locationOffset) {
+ Node node = getCaretNode(textEditor, locationOffset);
+ if (node == null) {
+ // empty page?
+ return 0;
+ }
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ return locationOffset;
+ }
+ return calculateCaretLocation(node, locationOffset);
+ }
+
+ public int getOffset(StructuredTextEditor textEditor, Point location) {
+ StyledText text = textEditor.getTextViewer().getTextWidget();
+ return text.getOffsetAtLocation(location);
+ }
+
+ // private IStructuredModel getModel(StructuredTextEditor textEditor)
+ // {
+ // IStructuredModel model = null;
+ // if (textEditor.getDocumentProvider() != null)
+ // {
+ // if (textEditor.getDocumentProvider() instanceof IModelProvider)
+ // {
+ // model = ((IModelProvider)
+ // textEditor.getDocumentProvider()).getModel(textEditor.getEditorInput());
+ // }
+ // else
+ // {
+ // IDocument doc =
+ // textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
+ // if (doc instanceof IDocument)
+ // {
+ // model =
+ // StructuredModelManager.getModelManager().getExistingModelForEdit(doc);
+ // if (model == null)
+ // {
+ // model =
+ // StructuredModelManager.getModelManager().getExistingModelForEdit((IDocument)
+ // doc);
+ // }
+ // }
+ // }
+ // }
+ // return model;
+ // }
+
+ /**
+ * IExtendedMarkupEditor method
+ */
+ public Node getCaretNode(StructuredTextEditor textEditor, int pos) {
+ IStructuredModel model = textEditor.getModel();
+ // getModel(textEditor);
+ if (model == null) {
+ return null;
+ }
+ IndexedRegion inode = model.getIndexedRegion(pos);
+ if (inode == null) {
+ inode = model.getIndexedRegion(pos - 1);
+ }
+ return (inode instanceof Node) ? (Node) inode : null;
+ }
+
+ /**
+ * Calculate and adjust the location in compare with Node.
+ *
+ * @param node
+ * @param location
+ * @return
+ */
+ public int calculateCaretLocation(Node node, int location) {
+ int pos[][] = new int[2][2];
+ pos[0][0] = EditModelQuery.getNodeStartIndex(node);
+ pos[0][1] = EditModelQuery.getNodeStartNameEndIndex(node);
+ pos[1][0] = EditModelQuery.getNodeEndNameStartIndex(node);
+ pos[1][1] = EditModelQuery.getNodeEndIndex(node);
+ if (pos[0][0] >= location || pos[1][0] == location
+ || pos[1][1] <= location) {
+ return location;
+ } else if (pos[0][0] <= location && pos[0][1] >= location) {
+ if (((pos[0][1] + pos[0][0]) / 2) >= location) {
+ return pos[0][0];
+ } else {
+ return pos[0][1];
+ }
+ } else if (pos[1][0] <= location && pos[1][1] >= location) {
+ if (((pos[1][1] + pos[1][0]) / 2) >= location) {
+ return pos[1][0];
+ } else {
+ return pos[1][1];
+ }
+ }
+ return location;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/TextEditorDropTargetListenerFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/TextEditorDropTargetListenerFactory.java
new file mode 100644
index 000000000..538bb9730
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/TextEditorDropTargetListenerFactory.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dnd.internal;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.jst.pagedesigner.editors.DesignerStructuredTextEditorJSP;
+import org.eclipse.ui.texteditor.ITextEditorDropTargetListener;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+
+/**
+ * @author mengbo
+ */
+public class TextEditorDropTargetListenerFactory implements IAdapterFactory {
+
+ /**
+ *
+ */
+ public TextEditorDropTargetListenerFactory() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (ITextEditorDropTargetListener.class.equals(adapterType)) {
+ if (adaptableObject instanceof DesignerStructuredTextEditorJSP) {
+ DesignerSourceDropTargetListener listener = new DesignerSourceDropTargetListener(
+ (StructuredTextEditor) adaptableObject);
+ return listener;
+ }
+
+ }
+ return null;
+
+ }
+
+ public Class[] getAdapterList() {
+ Class[] classes = new Class[1];
+ classes[0] = ITextEditorDropTargetListener.class;
+ return classes;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/messages.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/messages.properties
new file mode 100644
index 000000000..9f415f6d5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dnd/internal/messages.properties
@@ -0,0 +1,7 @@
+DropSelectionWizard.Title=Drop Operation Handling
+SimpleWizardSelectionPage.PageName=Select Operation
+SimpleWizardSelectionPage.Title=Select Operation
+SimpleWizardSelectionPage.Description=Select Action
+SimpleWizardSelectionPage.Message=Select the operation you want to perform from the following list
+SimpleWizardSelectionPage.Operation=Operations:
+LocalDropCommand.DropHandler=Drop Handler
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/CaretMoveIterator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/CaretMoveIterator.java
new file mode 100644
index 000000000..188e85918
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/CaretMoveIterator.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+import org.w3c.dom.traversal.NodeIterator;
+
+/**
+ * @author mengbo
+ */
+public class CaretMoveIterator {
+ private final static Logger _log = PDPlugin
+ .getLogger(CaretMoveIterator.class);
+
+ private final boolean INNER_DEBUG = false;
+
+ private NodeIterator _nodeIterator;
+
+ private IMovementMediator _validator;
+
+ private IDOMPosition _currentPosition;
+
+ private boolean _forward;
+
+ /**
+ * constructor
+ */
+ public CaretMoveIterator(NodeIterator nodeIterator,
+ IMovementMediator validator, IDOMPosition position, boolean forward) {
+ super();
+ _nodeIterator = nodeIterator;
+ _validator = validator;
+ _currentPosition = position;
+ _forward = forward;
+ }
+
+ public NodeIterator getNodeIterator() {
+ return _nodeIterator;
+ }
+
+ /**
+ * @return Returns the _currentPosition.
+ */
+ public IDOMPosition getCurrentPosition() {
+ return _currentPosition;
+ }
+
+ /**
+ * @param position
+ * The _currentPosition to set.
+ */
+ public void setCurrentPosition(IDOMPosition position) {
+ _currentPosition = position;
+ }
+
+ // assume the currentPosition is invalid
+ private IDOMPosition moveOut(Node container) {
+ IDOMPosition result = new DOMRefPosition(container, _forward);
+ String name = container.getNodeName();
+ if (name != null
+ && EditModelQuery.HTML_STYLE_NODES.contains(name.toLowerCase())) {
+ result = moveToNextPosition(result, _validator);
+ }
+ return result;
+ }
+
+ public IDOMPosition moveIn(Node node) {
+ IDOMPosition result = null;
+ if (INNER_DEBUG) {
+ _log.info("- Move into: " + node.getLocalName());
+ }
+ if (_validator.isEditable(new Target(node))) {
+ int index;
+ // Transparent text is not editable, so this is not transparent.
+ if (EditModelQuery.isText(node)) {
+ index = (_forward) ? 0 : ((Text) node).getData().length();
+ result = new DOMPosition(node, index);
+ // move ahead one pos.
+ IDOMPosition pos = getNextTextPosition(result);
+ if (pos != null) {
+ result = pos;
+ }
+ } else {
+ if (node.hasChildNodes()) {
+ index = _forward ? 0 : node.getChildNodes().getLength();
+ result = new DOMPosition(node, index); // DOMRefPosition(next,
+ // !_forward);
+ } else {
+ result = new DOMPosition(node, 0);
+ }
+ }
+ } else {
+ if (node.hasChildNodes()) {
+ Node child = _forward ? node.getFirstChild() : node
+ .getLastChild();
+ result = new DOMRefPosition(child, _forward);
+ while (child != null) {
+ if (_validator.allowsMoveIn(new Target(child))) {
+ result = moveIn(child);
+ break;
+ }
+ child = _forward ? child.getNextSibling() : child
+ .getPreviousSibling();
+ }
+ } else {
+ // Should be impposible to reach here.
+ result = new DOMPosition(node, 0);
+ }
+ }
+ return result;
+ }
+
+ private IDOMPosition getNextTextPosition(IDOMPosition position) {
+ IDOMPosition result = null;
+ String value = position.getContainerNode().getNodeValue();
+ int i = position.getOffset();
+ if (_forward) {
+ if (i < value.length()) {
+ if (HTMLUtil.isHTMLWhitespace(value.charAt(i))) {
+ while (i < value.length()
+ && HTMLUtil.isHTMLWhitespace(value.charAt(i))) {
+ i++;
+ }
+ result = new DOMPosition(position.getContainerNode(), i);
+ } else if (i < value.length()) {
+ result = new DOMPosition(position.getContainerNode(), i + 1);
+ }
+ }
+ } else {
+ if (i > 0) {
+ if (HTMLUtil.isHTMLWhitespace(value.charAt(i - 1))) {
+ while (i > 0
+ && HTMLUtil.isHTMLWhitespace(value.charAt(i - 1))) {
+ i--;
+ }
+ result = new DOMPosition(position.getContainerNode(), i);
+ } else if (i > 0) {
+ result = new DOMPosition(position.getContainerNode(), i - 1);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Assume the original position are valid.
+ *
+ * @param position
+ * @param validator
+ * @param _forward
+ * @param referenceImediatly
+ * @return
+ */
+ private IDOMPosition moveToNextPosition(IDOMPosition position,
+ IMovementMediator validator) {
+ IDOMPosition currentPosition = null;
+ if (validator.isValidPosition(position) && position.isText()) {
+ currentPosition = getNextTextPosition(position);
+ }
+ if (currentPosition == null) {
+ Node nextNode = EditModelQuery.getInstance().getSibling(position,
+ _forward);
+ while (EditModelQuery.isText(nextNode)
+ && ((Text) nextNode).getData().length() == 0) {
+ nextNode = EditModelQuery.getInstance().getSibling(nextNode,
+ _forward);
+ }
+ if (nextNode != null) {
+ // move in?
+ if (validator.allowsMoveIn(new Target(nextNode))) {
+ currentPosition = moveIn(nextNode);
+ // Stop when it is in table. For others we continue search
+ // for text.
+ if (!canStopHere(nextNode) && //
+ EditModelQuery.getInstance().getSibling(
+ currentPosition, _forward) != null) {
+ currentPosition = moveToNextPosition(currentPosition,
+ validator);
+ }
+ }
+ // not allowed to move in. e.g. it's empty string.
+ else {
+ currentPosition = new DOMRefPosition(nextNode, _forward);// skip(position);
+ }
+ } else {
+ if (validator.allowsMoveOut(new Target(
+ getNaviContainer(position)))) {
+ currentPosition = moveOut(getNaviContainer(position));
+ }
+ }
+ }
+ currentPosition = EditHelper.ensureDOMPosition(currentPosition);
+ if (currentPosition != null
+ && !validator.isValidPosition(currentPosition)) {
+ currentPosition = moveToNextPosition(currentPosition, validator);
+ }
+ return currentPosition;
+ }
+
+ /**
+ * When the tag starts from new line, or in table, then caret can be put at
+ * 0 offset.
+ *
+ * @param node
+ * @return
+ */
+ private boolean canStopHere(Node node) {
+ boolean result = false;
+ if (EditModelQuery.isText(node)) {
+ result = true;
+ } else if (node != null && node.getNodeName() != null) {
+ result |= node.getNodeName().equals(IHTMLConstants.TAG_TD);
+ result |= EditModelQuery.isBlockNode(node);
+ }
+ return result;
+ }
+
+ /**
+ * Move operation position to next edit position. We may need rule to valid
+ * it based on operation ID and direction. We need to pack transparent
+ * string.
+ *
+ * @param operation
+ * @param currentPosition
+ * @param forward
+ * @param validator
+ * @return
+ */
+ public IDOMPosition moveToNextEditPosition(IDOMPosition currentPosition,
+ boolean forward, IMovementMediator validator) {
+ IDOMPosition result = null;
+ if ((currentPosition = moveToNextPosition(currentPosition, validator)) != null) {
+ result = currentPosition;
+ } else {
+ result = _currentPosition;
+ }
+ return result;
+ }
+
+ private Node getNaviContainer(IDOMPosition position) {
+ if (position.isText()) {
+ return position.getContainerNode().getParentNode();
+ } else {
+ return position.getContainerNode();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPosition.java
new file mode 100644
index 000000000..1c340bd2a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPosition.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class DOMPosition implements IDOMPosition {
+ Node _containerNode;
+
+ int _offset;
+
+ public DOMPosition(Node containerNode, int offset) {
+ _containerNode = containerNode;
+ _offset = offset;
+ }
+
+ /**
+ * this is the offset in the DOM tree. When parent node is text node, the
+ * offset if the offset into the actual displayed data of the text node.
+ *
+ * when parent is not text node, then the offset is the index in
+ * getIDOMNode().getChildNodes()
+ *
+ * @return
+ */
+ public int getOffset() {
+ return _offset;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getNextSiblingNode()
+ */
+ public Node getNextSiblingNode() {
+ if (isText())
+ return null;
+ NodeList children = _containerNode.getChildNodes();
+ int length = children.getLength();
+ if (_offset >= length || _offset < 0)
+ return null;
+ else
+ return (IDOMNode) children.item(_offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getPreviousSiblingNode()
+ */
+ public Node getPreviousSiblingNode() {
+ if (isText())
+ return null;
+ NodeList children = _containerNode.getChildNodes();
+ int length = children.getLength();
+ if (_offset > length || _offset <= 0)
+ return null;
+ else
+ return (IDOMNode) children.item(_offset - 1);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getContainerNode()
+ */
+ public Node getContainerNode() {
+ return _containerNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#isText()
+ */
+ public boolean isText() {
+ return _containerNode instanceof Text;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getSibling(boolean)
+ */
+ public Node getSibling(boolean forward) {
+ if (forward)
+ return getNextSiblingNode();
+ else
+ return getPreviousSiblingNode();
+ }
+
+ public IDOMPosition handleReplacement(Node original, Node replacement) {
+ if (original == this._containerNode) {
+ return new DOMPosition(replacement, this._offset);
+ } else {
+ return this;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "DOMPosition: (" + _containerNode + " : " + _offset + ")";
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPositionHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPositionHelper.java
new file mode 100644
index 000000000..e1f116dac
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMPositionHelper.java
@@ -0,0 +1,402 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class DOMPositionHelper {
+ public static DesignPosition toDesignRefPosition(DOMRefPosition position) {
+ Node node = position.getReferenceNode();
+ do {
+ IDOMNode container = (IDOMNode) node.getParentNode();
+ EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
+ if (part != null) {
+ // XXX: what if the node has not corresponding part?
+ EditPart child = DOMPositionHelper.findEditPart(part, node);
+ if (child != null) {
+ return new DesignRefPosition(child, position.isForward());
+ } else {
+ return DesignPosition.INVALID;
+ }
+ } else {
+ node = node.getParentNode();
+ }
+ } while (true);
+ }
+
+ /**
+ *
+ * @param position
+ * if it is null, then will return null
+ * @return null if position is null or invalid.
+ */
+ public static DesignPosition toDesignPosition(IDOMPosition position) {
+ if (position == null) {
+ return null;
+ }
+ if (position instanceof DOMRefPosition) {
+ return toDesignRefPosition((DOMRefPosition) position);
+ }
+ do {
+ IDOMNode container = (IDOMNode) position.getContainerNode();
+ EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
+ if (part != null) {
+ if (container instanceof Text) {
+ String textData = ((Text) container).getData();
+ String displayData = ((TextEditPart) part).getTextData();
+ return new DesignPosition(part,
+ textDataOffsetToDisplayOffset(textData,
+ displayData, position.getOffset()));
+ } else {
+ Node pre = position.getPreviousSiblingNode();
+ while (pre != null) {
+ int index = findChildEditPartIndex(part, pre);
+ if (index != -1) {
+ return new DesignPosition(part, index + 1);
+ }
+ pre = pre.getPreviousSibling();
+ }
+ return new DesignPosition(part, 0);
+ }
+ } else {
+ position = new DOMRefPosition(position.getContainerNode(),
+ false);
+ }
+ } while (true);
+ }
+
+ /**
+ * Here is the position is not currect, currently it will returns invalid
+ * pos.
+ *
+ * @param position
+ * @return
+ */
+ public static DesignPosition toDesignPosition1(IDOMPosition position) {
+ if (position instanceof DOMRefPosition) {
+ return toDesignRefPosition((DOMRefPosition) position);
+ }
+ do {
+ IDOMNode container = (IDOMNode) position.getContainerNode();
+ EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
+ if (part != null) {
+ if (container instanceof Text) {
+ String textData = ((Text) container).getData();
+ String displayData = ((TextEditPart) part).getTextData();
+ return new DesignPosition(part,
+ textDataOffsetToDisplayOffset(textData,
+ displayData, position.getOffset()));
+ } else {
+ Node pre = position.getPreviousSiblingNode();
+ while (pre != null) {
+ int index = findChildEditPartIndex(part, pre);
+ if (index != -1) {
+ return new DesignPosition(part, index + 1);
+ }
+ pre = pre.getPreviousSibling();
+ }
+ return new DesignPosition(part, 0);
+ }
+ } else {
+ return DesignPosition.INVALID;
+ }
+ } while (true);
+ }
+
+ static int findChildEditPartIndex(EditPart parent, Node node) {
+ List children = parent.getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ if (((EditPart) children.get(i)).getModel() == node) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ static EditPart findEditPart(EditPart parent, Node node) {
+ List children = parent.getChildren();
+ EditPart part;
+ for (int i = 0; i < children.size(); i++) {
+ if ((part = (EditPart) children.get(i)).getModel() == node) {
+ return part;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * convert a DesignPosition into DOMPosition.
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition toDOMRefPosition(DesignRefPosition position) {
+ // ok, it is not text.
+ EditPart sibling = position.getRefPart();
+ if (sibling != null) {
+ return new DOMRefPosition((Node) sibling.getModel(), position
+ .caretIsAtRight());
+ }
+ // should never happens
+ Assert.isTrue(false);
+ return null;
+ }
+
+ /**
+ * convert a DesignPosition into DOMPosition.
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition toDOMPosition(DesignPosition position) {
+ if (!EditValidateUtil.validPosition(position)) {
+ return null;
+ } else if (position instanceof DesignRefPosition) {
+ return toDOMRefPosition((DesignRefPosition) position);
+ }
+ EditPart part = position.getContainerPart();
+ if (part instanceof TextEditPart) {
+ Text text = (Text) ((TextEditPart) part).getIDOMNode();
+ int offset = position.getOffset();
+ if (offset == 0) {
+ return new DOMPosition(text, 0);
+ } else {
+ String displayData = ((TextEditPart) part).getTextData();
+ String nodeData = text.getData();
+ if (offset >= displayData.length()) {
+ // point to end of the text node.
+ return new DOMPosition(text, nodeData.length());
+ } else {
+ // we need to calculate it out.
+ int index = displayOffsetToTextDataOffset(displayData,
+ nodeData, offset);
+ return new DOMPosition(text, index);
+ }
+ }
+ } else {
+ // ok, it is not text.
+ EditPart sibling = position.getSiblingEditPart(true);
+ if (sibling != null) {
+ return new DOMRefPosition((Node) sibling.getModel(), false);
+ }
+
+ sibling = position.getSiblingEditPart(false);
+ if (sibling != null) {
+ return new DOMRefPosition((Node) sibling.getModel(), true);
+ }
+
+ // no previous sibling, no next sibling, the parent node must be
+ // empty
+ return new DOMPosition((Node) part.getModel(), 0);
+ }
+ }
+
+ /**
+ * if "position" is inside a text node, then split the text node and return
+ * a new IDOMPosition semantically equals to the position in the two
+ * splitted text. If the "position" is not a text position, then no action
+ * will be done.
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition splitText(IDOMPosition position) {
+ Node container = position.getContainerNode();
+ if (container instanceof Text) {
+ int offset = position.getOffset();
+ if (offset <= 0) {
+ // at beginning of text node. no need to split
+ return new DOMRefPosition(container, false);
+ }
+ String textData = ((Text) container).getData();
+ if (offset >= textData.length()) {
+ // at end of text node. no need to split
+ return new DOMRefPosition(container, true);
+ }
+ // ok, we need split
+ ((Text) container).splitText(offset);
+ return new DOMRefPosition(container, true);
+ } else
+ return position;
+ }
+
+ /**
+ * Remove all the content in the range. And return the new position.
+ *
+ * @param range
+ * @return
+ */
+ public static IDOMPosition removeRange(DOMRange range) {
+ boolean ordered = range.isOrdered();
+ IDOMPosition start = ordered ? range.getStartPosition() : range
+ .getEndPosition();
+ IDOMPosition end = ordered ? range.getEndPosition() : range
+ .getStartPosition();
+
+ // FIXME: Not DONE:
+ return end;
+ }
+
+ /**
+ * try to merge the position in adjacent text node (if it is not already in)
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition mergeIntoText(IDOMPosition position) {
+ if (position.getContainerNode() instanceof Text)
+ return position;
+ Node pre = position.getPreviousSiblingNode();
+ if (pre instanceof Text) {
+ return new DOMPosition(pre, ((Text) pre).getData().length());
+ }
+ Node after = position.getNextSiblingNode();
+ if (after instanceof Text) {
+ return new DOMPosition(after, 0);
+ }
+ return position;
+ }
+
+ /**
+ * @param displayData
+ * @param nodeData
+ * @param offset
+ * @return
+ */
+ // FIXME: this method is still buggy
+ public static int displayOffsetToTextDataOffset(String displayData,
+ String nodeData, int offset) {
+ char[] display = displayData.toCharArray();
+ if (offset >= display.length) {
+ // offset is already at end
+ return nodeData.length();
+ }
+ char[] node = nodeData.toCharArray();
+ int nodeDataLength = node.length;
+ int displayIndex = 0;
+ int nodeIndex = 0;
+
+ while (displayIndex < offset && nodeIndex < nodeDataLength) {
+ if (display[displayIndex] == node[nodeIndex]) {
+ displayIndex++;
+ nodeIndex++;
+ continue;
+ }
+ if (HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
+ if (HTMLUtil.isHTMLWhitespace(display[displayIndex])) {
+ displayIndex++;
+ nodeIndex++;
+ } else {
+ nodeIndex++;
+ }
+ continue;
+ } else {
+ // should not happen!
+ displayIndex++;
+ nodeIndex++;
+ }
+ }
+
+ if (nodeIndex >= nodeDataLength)
+ return nodeDataLength;
+ // else means displayIndex == offset
+ // since we already checked that offset < displayLength, so we can get
+ // the next char
+ if (display[offset] != ' ') {
+ // we may need to skip whitespaces after nodeIndex
+ while (nodeIndex < nodeDataLength
+ && HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
+ nodeIndex++;
+ }
+ }
+ return nodeIndex;
+ }
+
+ /**
+ * @param textData
+ * @param displayData
+ * @param offset
+ * @return
+ */
+ // FIXME: this method is still buggy
+ public static int textDataOffsetToDisplayOffset(String nodeData,
+ String displayData, int offset) {
+ if (offset >= nodeData.length()) {
+ return displayData.length();
+ }
+ char[] node = nodeData.toCharArray();
+ char[] display = displayData.toCharArray();
+
+ int displayIndex = 0;
+ int nodeIndex = 0;
+ int displayDataLength = display.length;
+
+ while (nodeIndex < offset && displayIndex < displayDataLength) {
+ if (display[displayIndex] == node[nodeIndex]) {
+ displayIndex++;
+ nodeIndex++;
+ continue;
+ }
+ if (HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
+ if (HTMLUtil.isHTMLWhitespace(display[displayIndex])) {
+ displayIndex++;
+ nodeIndex++;
+ } else {
+ nodeIndex++;
+ }
+ continue;
+ } else {
+ // should not happen!
+ displayIndex++;
+ nodeIndex++;
+ }
+ }
+ return displayIndex;
+ }
+
+ /**
+ * Convert a IDOMPosition to IDOMRefPosition. If can't convert to
+ * IDOMRefPosition, will return the original one.
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition toDOMRefPosition(IDOMPosition position) {
+ if (position.isText()) {
+ return position; // can't convert Text node.
+ }
+ if (position instanceof IDOMRefPosition) {
+ return position;
+ }
+ if (position.getNextSiblingNode() != null) {
+ return new DOMRefPosition(position.getNextSiblingNode(), false);
+ }
+ if (position.getPreviousSiblingNode() != null) {
+ return new DOMRefPosition(position.getPreviousSiblingNode(), true);
+ } else {
+ return new DOMRefPosition2(position.getContainerNode(), true);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRange.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRange.java
new file mode 100644
index 000000000..bd8053928
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRange.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class DOMRange {
+ IDOMPosition _start;
+
+ IDOMPosition _end;
+
+ /**
+ *
+ */
+ public DOMRange(IDOMPosition p1, IDOMPosition p2) {
+ _start = p1;
+ _end = p2;
+ }
+
+ public IDOMPosition getStartPosition() {
+ return _start;
+ }
+
+ public IDOMPosition getEndPosition() {
+ return _end;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isEmpty() {
+ return _start.getContainerNode() == _end.getContainerNode()
+ && _start.getOffset() == _end.getOffset();
+ }
+
+ public boolean isOrdered() {
+ Node common = DOMUtil.findCommonAncester(_start.getContainerNode(),
+ _end.getContainerNode());
+ if (common == null) {
+ return true;
+ }
+ IDOMPosition s = moveUp(_start, common);
+ IDOMPosition e = moveUp(_end, common);
+ return e.getOffset() >= s.getOffset();
+ }
+
+ private IDOMPosition moveUp(IDOMPosition p, Node ancester) {
+ while (p.getContainerNode() != ancester) {
+ p = new DOMRefPosition(p.getContainerNode(), false);
+ }
+ return p;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRangeHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRangeHelper.java
new file mode 100644
index 000000000..238c5bb90
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRangeHelper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class DOMRangeHelper {
+ public static DOMRange toDOMRange(DesignRange range) {
+ if (range.getStartPosition() == range.getEndPosition()) {
+ IDOMPosition dp = DOMPositionHelper.toDOMPosition(range
+ .getStartPosition());
+ return new DOMRange(dp, dp);
+ } else
+ return new DOMRange(DOMPositionHelper.toDOMPosition(range
+ .getStartPosition()), DOMPositionHelper.toDOMPosition(range
+ .getEndPosition()));
+ }
+
+ public static DesignRange toDesignRange(DOMRange range) {
+ if (range.getStartPosition() == range.getEndPosition()) {
+ DesignPosition dp = DOMPositionHelper.toDesignPosition(range
+ .getStartPosition());
+ return new DesignRange(dp, dp);
+ }
+ return new DesignRange(DOMPositionHelper.toDesignPosition(range
+ .getStartPosition()), DOMPositionHelper.toDesignPosition(range
+ .getEndPosition()));
+ }
+
+ public static DOMRange handleReplacement(DOMRange range, Node original,
+ Node replacement) {
+ if (range.getStartPosition() == range.getEndPosition()) {
+ IDOMPosition pos = range.getStartPosition().handleReplacement(
+ original, replacement);
+ return new DOMRange(pos, pos);
+ } else {
+ return new DOMRange(range.getStartPosition().handleReplacement(
+ original, replacement), range.getEndPosition()
+ .handleReplacement(original, replacement));
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition.java
new file mode 100644
index 000000000..480a4d969
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * DOMRefPosition is another way to identify a position in the document tree. It
+ * has the advantage against the DOMPosition, that even something change in the
+ * document, DOMRefPosition may still reference the correct position.
+ *
+ * @author mengbo
+ */
+public class DOMRefPosition implements IDOMRefPosition {
+ Node _refNode;
+
+ boolean _forward;
+
+ /**
+ * @param refNode
+ * @param forward
+ * true means the position after refNode. false means the
+ * position before refNode
+ */
+ public DOMRefPosition(Node refNode, boolean forward) {
+ _refNode = refNode;
+ _forward = forward;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getSibling(boolean)
+ */
+ public Node getSibling(boolean forward) {
+ if (forward != _forward)
+ return _refNode;
+ if (forward)
+ return _refNode.getNextSibling();
+ else
+ return _refNode.getPreviousSibling();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getNextSiblingNode()
+ */
+ public Node getNextSiblingNode() {
+ return getSibling(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getPreviousSiblingNode()
+ */
+ public Node getPreviousSiblingNode() {
+ return getSibling(false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getContainerNode()
+ */
+ public Node getContainerNode() {
+ return _refNode.getParentNode();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#getOffset()
+ */
+ public int getOffset() {
+ Node parent = _refNode.getParentNode();
+ if (parent == null) {
+ return _forward ? 1 : 0;
+ } else {
+ NodeList list = parent.getChildNodes();
+ for (int i = 0, n = list.getLength(); i < n; i++) {
+ if (list.item(i) == _refNode) {
+ return _forward ? (i + 1) : i;
+ }
+ }
+ // should not happen.
+ return -1;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.range.IDOMPosition#isText()
+ */
+ public boolean isText() {
+ return false;
+ }
+
+ public IDOMPosition handleReplacement(Node original, Node replacement) {
+ if (this._refNode == original) {
+ return new DOMRefPosition(replacement, this._forward);
+ } else {
+ return this;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "DOMRefPosition: (" + (_forward ? "after " : "before ")
+ + _refNode + ")";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMRefPosition#getReferenceNode()
+ */
+ public Node getReferenceNode() {
+ return _refNode;
+ }
+
+ public boolean isForward() {
+ return _forward;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition2.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition2.java
new file mode 100644
index 000000000..100428cd3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMRefPosition2.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.w3c.dom.Node;
+
+/**
+ * This ref position use a parent node as reference. And provide whether this
+ * location is at the beginning of its parent or last of its parent.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class DOMRefPosition2 implements IDOMRefPosition {
+ Node _parentNode;
+
+ boolean _last;
+
+ /**
+ * @param replacement
+ * @param _last2
+ */
+ public DOMRefPosition2(Node parent, boolean last) {
+ _parentNode = parent;
+ _last = last;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMRefPosition#getReferenceNode()
+ */
+ public Node getReferenceNode() {
+ return _parentNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#getSibling(boolean)
+ */
+ public Node getSibling(boolean forward) {
+ if (forward) {
+ if (_last) {
+ return null;
+ } else {
+ return _parentNode.getFirstChild();
+ }
+ } else {
+ if (_last) {
+ return _parentNode.getLastChild();
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#getNextSiblingNode()
+ */
+ public Node getNextSiblingNode() {
+ return getSibling(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#getPreviousSiblingNode()
+ */
+ public Node getPreviousSiblingNode() {
+ return getSibling(false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#getContainerNode()
+ */
+ public Node getContainerNode() {
+ return _parentNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#getOffset()
+ */
+ public int getOffset() {
+ if (!_last) {
+ return 0;
+ } else {
+ return _parentNode.getChildNodes().getLength();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#isText()
+ */
+ public boolean isText() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.dom.IDOMPosition#handleReplacement(org.w3c.dom.Node,
+ * org.w3c.dom.Node)
+ */
+ public IDOMPosition handleReplacement(Node original, Node replacement) {
+ if (original == _parentNode) {
+ return new DOMRefPosition2(replacement, _last);
+ } else
+ return this;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMStyleUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMStyleUtil.java
new file mode 100644
index 000000000..66a0c2d17
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMStyleUtil.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.ElementCSSInlineStyle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DOMStyleUtil {
+ public static String getInlineStyleProperty(Element original,
+ String cssProperty) {
+ if (original instanceof ElementCSSInlineStyle) {
+ CSSStyleDeclaration styledecl = ((ElementCSSInlineStyle) original)
+ .getStyle();
+ if (styledecl == null) {
+ if (original.getAttribute("style") == null) {
+ return null;
+ }
+ // else mean it has style attribute.
+ }
+
+ if (styledecl != null) {
+ return styledecl.getPropertyValue(cssProperty);
+ }
+ }
+
+ // when we reach here, means we can't use the CSSStyleDeclaration API to
+ // get style, we'll take the
+ // pain to do the parsing and replacing.
+ // normally should not happen. But anyway, we need to have a fail safe
+ // path.
+
+ String oldstyle = original.getAttribute("style");
+ if (oldstyle == null || oldstyle.length() == 0) {
+ return null;
+ }
+ StringTokenizer tokenizer = new StringTokenizer(oldstyle, ";");
+
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken().trim();
+ if (token.length() == 0) {
+ continue;
+ }
+ int index = token.indexOf(':');
+ if (index == -1) {
+ continue;
+ }
+ String propertyName = token.substring(0, index).trim();
+ if (cssProperty.equals(propertyName)) {
+ // ok, we found the property
+ return token.substring(index + 1).trim();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * insert style into element
+ *
+ * @param original
+ * @param map
+ */
+ public static void insertStyle(Element original, Map map) {
+ if (original instanceof ElementCSSInlineStyle) {
+ CSSStyleDeclaration styledecl = ((ElementCSSInlineStyle) original)
+ .getStyle();
+ if (styledecl == null) {
+ if (original.getAttribute("style") == null) {
+ original.setAttribute("style", "");
+ styledecl = ((ElementCSSInlineStyle) original).getStyle();
+ }
+ }
+
+ if (styledecl != null) {
+ for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
+ String key = (String) iter.next();
+ String value = (String) map.get(key);
+ if (value == null) {
+ styledecl.removeProperty(key);
+ } else {
+ styledecl.setProperty(key, value, null);
+ }
+ }
+
+ return;
+ }
+ }
+
+ // when we reach here, means we can't use the CSSStyleDeclaration API to
+ // change style, we'll take the
+ // pain to do the parsing and replacing.
+ // normally should not happen. But anyway, we need to have a fail safe
+ // path.
+
+ String oldstyle = original.getAttribute("style");
+ if (oldstyle == null) {
+ oldstyle = "";
+ }
+ StringTokenizer tokenizer = new StringTokenizer(oldstyle, ";");
+
+ StringBuffer buffer = new StringBuffer();
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken().trim();
+ if (token.length() == 0) {
+ continue;
+ }
+ int index = token.indexOf(':');
+ if (index == -1) {
+ // wrong property? ignore.
+ buffer.append(token).append("; ");
+ continue;
+ }
+ String propertyName = token.substring(0, index).trim();
+
+ if (map.containsKey(propertyName)) {
+ String propertyValue = (String) map.remove(propertyName);
+ if (propertyValue == null) {
+ // we want to remove this css property. so don't append
+ // anything here
+ } else {
+ buffer.append(propertyName).append(": ").append(
+ propertyValue).append("; ");
+ }
+ } else {
+ buffer.append(token).append("; ");
+ }
+ }
+ // ok, we have loop through existing properties and did replacement.
+ // now _styleProperties only contain those new CSS properties we need to
+ for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
+ String key = (String) iter.next();
+ String value = (String) map.get(key);
+ if (value != null) {
+ buffer.append(key).append(": ").append(value).append("; ");
+ }
+ }
+ original.setAttribute("style", buffer.toString());
+ }
+
+ /**
+ * @param ele
+ * @return
+ */
+ public static boolean supportStyleAttribute(IDOMElement ele) {
+ CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
+ if (decl != null && decl.getAttributes().getNamedItem("style") != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMUtil.java
new file mode 100644
index 000000000..205f2575a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/DOMUtil.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class DOMUtil {
+ private static Logger _logger = PDPlugin.getLogger(DOMUtil.class);
+
+ /**
+ * Get a list of ancester nodes starting from the Document till the node.
+ *
+ * @param node
+ * @return
+ */
+ private static List getAncesters(Node node) {
+ List list = new ArrayList();
+ while (node != null) {
+ list.add(node);
+ if (node instanceof Document) {
+ break;
+ } else {
+ node = node.getParentNode();
+ }
+ }
+ if (node == null) {
+ // if part ==null, means we didn't find a DocumentEditPart,
+ // something must be wrong.
+ return null;
+ }
+ // reverse to make it starting from the docuemnteditpart node.
+ Collections.reverse(list);
+ list.add(null); // add an null terminator.
+ return list;
+ }
+
+ /**
+ * find the smallest common ancester of two edit part.
+ *
+ * @param node1
+ * @param node2
+ * @return
+ */
+ public static Node findCommonAncester(Node node1, Node node2) {
+ List list1 = getAncesters(node1);
+ if (list1 == null) {
+ return null;
+ }
+ List list2 = getAncesters(node2);
+ if (list2 == null) {
+ return null;
+ }
+ if (list1.get(0) != list2.get(0)) {
+ return null;
+ }
+ Node common = (Node) list1.get(0);
+ for (int i = 1;; i++) {
+ Node p1 = (Node) list1.get(i);
+ Node p2 = (Node) list2.get(i);
+ if (p1 == null || p2 == null) {
+ return common;
+ }
+ if (p1 != p2) {
+ return common;
+ }
+ common = p1;
+ }
+
+ }
+
+ /**
+ * this method is almost same as <code>cloneNodeDeep()</code>. The
+ * difference is that this method will try to ignore all kinds of error.
+ *
+ * In SSE, if the document model enforce some kinds of validation, then the
+ * clone may fail. During some cases, we want to ignore the validation
+ * errors.
+ *
+ * @param destDoc
+ * @param sourceNode
+ * @return
+ */
+ public static Node cloneNodeDeepIgnoreError(Document destDoc,
+ Node sourceNode) {
+ switch (sourceNode.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ Element sourceEle = (Element) sourceNode;
+ Element resultEle = destDoc.createElement(sourceEle.getTagName());
+ NamedNodeMap attrs = sourceEle.getAttributes();
+ for (int i = 0, size = attrs.getLength(); i < size; i++) {
+ Attr a = (Attr) attrs.item(i);
+ try {
+ resultEle.setAttribute(a.getName(), a.getValue());
+ } catch (Exception ex) {
+ // ignore
+ _logger.info("Exception", ex);
+ }
+ }
+ NodeList children = sourceEle.getChildNodes();
+ for (int i = 0, size = children.getLength(); i < size; i++) {
+ Node n = children.item(i);
+ Node d = cloneNodeDeepIgnoreError(destDoc, n);
+ if (d != null) {
+ try {
+ resultEle.appendChild(d);
+ } catch (Exception ex) {
+ // ignore
+ _logger.info("Exception", ex);
+ }
+ }
+ }
+ return resultEle;
+ case Node.TEXT_NODE:
+ Text txt = destDoc.createTextNode(sourceNode.getNodeValue());
+ if (txt instanceof IDOMText && sourceNode instanceof IDOMText) {
+ try {
+ ((IDOMText) txt).setSource(((IDOMText) sourceNode)
+ .getSource());
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ return txt;
+ case Node.CDATA_SECTION_NODE:
+ return destDoc.createCDATASection(sourceNode.getNodeValue());
+ default:
+ return null; // not support.
+ }
+ }
+
+ public static Node cloneNodeDeep(Document destDoc, Node sourceNode) {
+ switch (sourceNode.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ Element sourceEle = (Element) sourceNode;
+ Element resultEle = destDoc.createElement(sourceEle.getTagName());
+ NamedNodeMap attrs = sourceEle.getAttributes();
+ for (int i = 0, size = attrs.getLength(); i < size; i++) {
+ Attr a = (Attr) attrs.item(i);
+ resultEle.setAttribute(a.getName(), a.getValue());
+ }
+ NodeList children = sourceEle.getChildNodes();
+ for (int i = 0, size = children.getLength(); i < size; i++) {
+ Node n = children.item(i);
+ Node d = cloneNodeDeep(destDoc, n);
+ if (d != null) {
+ resultEle.appendChild(d);
+ }
+ }
+ return resultEle;
+ case Node.TEXT_NODE:
+ Text txt = destDoc.createTextNode(sourceNode.getNodeValue());
+ if (txt instanceof IDOMText && sourceNode instanceof IDOMText) {
+ try {
+ ((IDOMText) txt).setSource(((IDOMText) sourceNode)
+ .getSource());
+ } catch (Exception ex) {
+ // ignore
+ _logger.info("Exception", ex);
+ }
+ }
+ return txt;
+ case Node.CDATA_SECTION_NODE:
+ return destDoc.createCDATASection(sourceNode.getNodeValue());
+ default:
+ return null; // not support.
+ }
+ }
+
+ /**
+ * check whether the ancester relationship exist for the two nodes.
+ *
+ * @param ancester
+ * @param child
+ * @return
+ */
+ public static boolean isAncester(Node ancester, Node child) {
+ while (child != null) {
+ if (child == ancester) {
+ return true;
+ }
+ child = child.getParentNode();
+ }
+ return false;
+ }
+
+ /**
+ * insert the node at specified position.
+ *
+ * @param insertPosition
+ * @param insert
+ * @return null if fail, otherwise return the inserted node.
+ */
+ public static Node insertNode(IDOMPosition domPosition, Node node) {
+ IDOMPosition position = DOMPositionHelper.splitText(domPosition);
+ if (position == null || position.getContainerNode() == null) {
+ return null;
+ }
+ if (position.getNextSiblingNode() == null) {
+ position.getContainerNode().appendChild(node);
+ } else {
+ position.getContainerNode().insertBefore(node,
+ position.getNextSiblingNode());
+ }
+
+ return node;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditHelper.java
new file mode 100644
index 000000000..2c91d3eab
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditHelper.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.range.WorkNode;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class EditHelper {
+ public final static boolean INNER_DEBUG = false;
+
+ public final static int OUT_OF_LEFT = 1;
+
+ public final static int LEFT_NAME = 2;
+
+ public final static int IN_MIDDLE = 3;
+
+ public final static int RIGHT_NAME = 4;
+
+ public final static int OUT_OF_RIGHT = 5;
+
+ public static final EditHelper _instance = new EditHelper();
+
+ private static Logger _log = PDPlugin.getLogger(EditHelper.class);
+
+ private EditHelper() {
+ }
+
+ /**
+ * Move operation position infront of next non-blank and non-transparent
+ * char. The caller should ensure position's container node is not
+ * tranparent text node.
+ *
+ * @param position
+ * @param forward
+ * @param forEmpty
+ * @return
+ */
+ public int getTextNextOffset(IDOMPosition position, boolean forward,
+ boolean forEmpty) {
+ EditValidateUtil.validPosition(position);
+ Assert.isTrue(!EditModelQuery.isTransparentText(position
+ .getContainerNode()));
+ Text text = (Text) position.getContainerNode();
+ int offset = position.getOffset();
+ String data = text.getNodeValue();
+ if (forward) {
+ while (offset < data.length()
+ && HTMLUtil.isHTMLWhitespace(data.charAt(offset))) {
+ offset++;
+ }
+ } else {
+ while (offset > 0
+ && HTMLUtil.isHTMLWhitespace(data.charAt(offset - 1))) {
+ offset--;
+ }
+ }
+ return offset;
+
+ }
+
+ public static EditHelper getInstance() {
+ return _instance;
+ }
+
+ /**
+ * This caret from current operation postion to next position, this method
+ * will convert DesignPosition in to DOMPosition, then call dom function to
+ * move dom position. Here we might insert some complex rules to see whether
+ * move is valid.
+ *
+ * @param action
+ * @param currentPosition
+ * @param forward
+ * @return
+ */
+ public static DesignPosition moveToNextEditPosition(int action,
+ DesignPosition currentPosition, boolean forward) {
+ IDOMPosition position;
+ position = DOMPositionHelper.toDOMPosition(currentPosition);
+ position = moveToNextEditPosition(position, forward,
+ new InlineEditingNavigationMediator(
+ new ActionData(action, null)));
+ if (position == null) {
+ return currentPosition;
+ }
+
+ EditValidateUtil.validPosition(position);
+ return DOMPositionHelper.toDesignPosition(position);
+ }
+
+ /**
+ * Move operation position to next edit position. We may need rule to valid
+ * it based on operation ID and direction. We need to pack transparent
+ * string.
+ *
+ * @param operation
+ * @param currentPosition
+ * @param forward
+ * @param validator
+ * @return
+ */
+ public static IDOMPosition moveToNextEditPosition(
+ IDOMPosition currentPosition, boolean forward,
+ IMovementMediator validator) {
+ IDOMPosition result = null;
+ CaretMoveIterator moveIterator = new CaretMoveIterator(null, validator,
+ currentPosition, forward);
+ if ((result = moveIterator.moveToNextEditPosition(currentPosition,
+ forward, validator)) == null) {
+ result = currentPosition;
+ }
+ return result;
+ }
+
+ /**
+ * Delete a node, in case it is 'body' or 'html', it won't perform delete.
+ *
+ * @param node
+ * @return
+ */
+ public static Node deleteNode(Node node) {
+ if (node == null || node.getNodeName() == null) {
+ return null;
+ }
+ String name = node.getLocalName();
+
+ if (name != null
+ && (name.equalsIgnoreCase(IHTMLConstants.TAG_BODY)
+ || name.equalsIgnoreCase(IHTMLConstants.TAG_HEAD) || name
+ .equalsIgnoreCase(IHTMLConstants.TAG_HTML))) {
+ return null;
+ }
+ Node parent = node.getParentNode();
+ name = parent.getNodeName();
+ if (parent != null
+ && name != null
+ && parent.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_HEAD)) {
+ return null;
+ }
+ return parent.removeChild(node);
+ }
+
+ /**
+ * Order the IDOMPositions in a range in ascending order.
+ *
+ * @param range
+ * @return
+ */
+ public static DOMRange normal(DOMRange range) {
+ EditValidateUtil.validRange(range);
+ IDOMPosition p1 = range.getStartPosition();
+ IDOMPosition p2 = range.getEndPosition();
+ if (EditModelQuery.getIndexedRegionLocation(p1) > EditModelQuery
+ .getIndexedRegionLocation(p2)) {
+ return new DOMRange(p2, p1);
+ } else {
+ return range;
+ }
+ }
+
+ /**
+ * Move position in to node from its outside, the node should be breakble.
+ *
+ * @param node
+ * @param forward
+ * @return
+ */
+ public static IDOMPosition moveInto(Node node, IMovementMediator validator,
+ boolean forward) {
+ CaretMoveIterator moveIterator = new CaretMoveIterator(null, validator,
+ new DOMRefPosition(node, !forward), forward);
+ return moveIterator.moveIn(node);
+ }
+
+ /**
+ * Convert a DomRefPosition into DOMPosition.
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition ensureDOMPosition(IDOMPosition position) {
+ if (position instanceof DOMRefPosition) {
+ return new DOMPosition(position.getContainerNode(), position
+ .getOffset());
+ }
+ return position;
+ }
+
+ public void processText(Text currentNode, final int pos1, final int pos2,
+ Node top, Stack workNode) {
+ // the text could be tranparent, or 0 length.
+ Assert.isTrue(pos1 <= pos2);
+ if (pos1 == pos2) {
+ return;
+ }
+ // int left = EditModelQuery.getNodeStartIndex(currentNode);
+ // int right = EditModelQuery.getNodeEndIndex(currentNode);
+ int location1 = getLocation(currentNode, pos1, false);
+ int location2 = getLocation(currentNode, pos2, false);
+ if (location1 <= IN_MIDDLE && location2 >= IN_MIDDLE) {
+ workNode.push(new WorkNode(currentNode, pos1, pos2));
+ }
+ }
+
+ public void collectNodes(Node currentNode, final int pos1, final int pos2,
+ Node top, Stack result) {
+ Assert.isTrue(pos1 <= pos2);
+ if (pos1 == pos2) {
+ return;
+ }
+ if (EditModelQuery.isText(currentNode)) {
+ processText((Text) currentNode, pos1, pos2, top, result);
+ } else {
+ int location1 = getLocation(currentNode, pos1, false);
+ int location2 = getLocation(currentNode, pos2, false);
+ if (location1 < IN_MIDDLE && location2 > IN_MIDDLE) {
+ // TODO: push the node into result.--
+ result.push(new WorkNode(currentNode, pos1, pos2));
+ } else if (location1 <= IN_MIDDLE && location2 >= IN_MIDDLE) {
+ if (currentNode.hasChildNodes()) {
+ Node child = currentNode.getFirstChild();
+ Stack myResult = new Stack();
+ while (child != null) {
+ collectNodes(child, pos1, pos2, top, myResult);
+ child = child.getNextSibling();
+ }
+ if (location1 < IN_MIDDLE && location2 >= IN_MIDDLE
+ || location1 <= IN_MIDDLE && location2 > IN_MIDDLE) {
+ WorkNode workNode = new WorkNode(currentNode, pos1,
+ pos2);
+ while (myResult.size() > 0) {
+ WorkNode w = (WorkNode) myResult.remove(0);
+ if (w.getNode().getParentNode() == workNode
+ .getNode()) {
+ w.setParent(workNode);
+ }
+ result.push(w);
+ }
+ // TODO: push parent into result.--
+ result.push(workNode);
+ }
+ } else {
+ if (!(location1 == IN_MIDDLE && location2 == IN_MIDDLE)) {
+ // TODO: push this node into result.
+ result.push(new WorkNode(currentNode, pos1, pos2));
+ }
+ }
+ }
+ }
+ }
+
+ public int getLocation(Node currentNode, int pos, boolean isOffset) {
+ if (EditModelQuery.getInstance().isSingleRegionNode(currentNode)) {
+ // if (EditModelQuery.isText(currentNode))
+ {
+
+ int left = EditModelQuery.getNodeStartIndex(currentNode);
+ int right = EditModelQuery.getNodeEndIndex(currentNode);
+ if (isOffset) {
+ pos += left;
+ }
+ if (pos <= left) {
+ return OUT_OF_LEFT;
+ } else if (left < pos && pos < right) {
+ return IN_MIDDLE;
+ } else {
+ return OUT_OF_RIGHT;
+ }
+ }
+ } else {
+ int left = EditModelQuery.getNodeStartIndex(currentNode);
+ int left1 = EditModelQuery.getNodeStartNameEndIndex(currentNode);
+ int right = EditModelQuery.getNodeEndNameStartIndex(currentNode);
+ int right1 = EditModelQuery.getNodeEndIndex(currentNode);
+ if (isOffset) {
+ pos += left;
+ }
+ if (pos <= left) {
+ return OUT_OF_LEFT;
+ } else if (left < pos && pos < left1) {
+ return LEFT_NAME;
+ } else if (left1 <= pos && pos <= right) {
+ return IN_MIDDLE;
+ } else if (right < pos && pos < right1) {
+ return RIGHT_NAME;
+ } else {
+ return OUT_OF_RIGHT;
+ }
+ }
+
+ }
+
+ private Node cutCurrentNode(int pos[], Node currentNode,
+ IDOMPosition position) {
+ // at right edge
+ int curpos = EditModelQuery.getIndexedRegionLocation(position);
+ if (pos[0] <= curpos) {
+ pos[1] = EditModelQuery.getNodeStartIndex(currentNode);
+ currentNode = deleteNode(currentNode);
+ if (INNER_DEBUG) {
+ _log.info("cut:" + currentNode);
+ }
+ return currentNode;
+ } else if (pos[1] >= curpos) {
+ pos[0] = EditModelQuery.getNodeEndIndex(currentNode);
+ currentNode = deleteNode(currentNode);
+ if (INNER_DEBUG) {
+ _log.info("cut:" + currentNode);
+ }
+ return currentNode;
+ }
+ return null;
+ }
+
+ private int getPos(DOMRange range, boolean forStart) {
+ if (forStart) {
+ return EditModelQuery.getIndexedRegionLocation(range
+ .getStartPosition());
+ } else {
+ return EditModelQuery.getIndexedRegionLocation(range
+ .getEndPosition());
+ }
+ }
+
+ public EditPart getEditPart(DesignPosition position, boolean forward) {
+ if (position instanceof DesignRefPosition) {
+ return ((DesignRefPosition) position).getRefPart();
+ }
+ EditPart container = position.getContainerPart();
+ if (container instanceof TextEditPart) {
+ return container;
+ }
+ if (container != null) {
+ List children = container.getChildren();
+ for (int i = 0, n = children.size(); i < n; i++) {
+ if (i == position.getOffset()) {
+ int index = (forward) ? i - 1 : i + 1;
+ if (index < 0) {
+ index = 0;
+ }
+ if (index >= children.size()) {
+ index = children.size() - 1;
+ }
+
+ return (EditPart) children.get(index);
+ }
+ }
+ }
+ return null;
+ }
+
+ public static IDOMPosition splitNode(IDOMPosition position) {
+ if (EditValidateUtil.validPosition(position)) {
+ Node container = null;
+ // Avoid to split tag at its edge
+ if (position.getOffset() > 0) {
+ if (position.isText()) {
+ container = position.getContainerNode();
+ if (position.getOffset() < ((Text) container).getLength()) {
+ position = DOMPositionHelper.splitText(position);
+ } else {
+ // position = new
+ // DOMRefPosition(position.getContainerNode(), true);
+ }
+ } else {
+ if (position.getNextSiblingNode() != null) {
+ container = position.getContainerNode();
+ Node parent = container.getParentNode();
+
+ Document document = EditModelQuery
+ .getDocumentNode(container);
+ Node newContainer = document.createElement(container
+ .getNodeName());
+ Node node = position.getPreviousSiblingNode();
+ Node refNode = null;
+ while (node != null) {
+ Node prev = node.getPreviousSibling();
+ node = node.getParentNode().removeChild(node);
+
+ newContainer.insertBefore(node, refNode);
+ refNode = node;
+ node = prev;
+ }
+ parent.insertBefore(newContainer, container);
+ // set the newContainer node align attribute to the
+ // original align attribue
+ // copy nodes under container node to container node's
+ // parent node
+ if (container.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_P)) {
+ Element pNode = (Element) container;
+ String align = pNode
+ .getAttribute(IHTMLConstants.ATTR_ALIGN);
+ if (align != null && !"".equalsIgnoreCase(align)) {
+ ((Element) newContainer).setAttribute(
+ IHTMLConstants.ATTR_ALIGN, align);
+ }
+ NodeList nodeList = pNode.getChildNodes();
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node tempNode = nodeList.item(i);
+ parent.insertBefore(tempNode, container);
+ }
+ }
+ return new DOMRefPosition(newContainer, true);
+ } else {
+ // position = new
+ // DOMRefPosition(position.getContainerNode(), true);
+ }
+ }
+ } else {
+ // container = position.getContainerNode();
+ // position = new DOMRefPosition(container, false);
+ }
+ }
+ return position;
+ }
+
+ /*
+ * Return the position of this 'position' in relative to it's container.
+ */
+ public static int getLocation(IDOMPosition position) {
+ if (position.getOffset() == 0) {
+ return -1;
+ } else {
+ if (position.isText()) {
+ if (position.getOffset() == ((Text) position.getContainerNode())
+ .getLength()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ if (position.getOffset() == position.getContainerNode()
+ .getChildNodes().getLength()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+ }
+
+ public static EditPart getPart(Node node) {
+ if (node instanceof INodeNotifier) {
+ ((INodeNotifier) node).getAdapterFor(EditPart.class);
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java
new file mode 100644
index 000000000..9097433b3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditModelQuery.java
@@ -0,0 +1,1795 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.parts.HTMLEditPartsFactory;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.swt.SWT;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class EditModelQuery {
+ private static Logger _log = PDPlugin.getLogger(EditModelQuery.class);
+
+ private static EditModelQuery _instance;
+
+ public static final int START_INDEX_BEFORE_TAG = 1;
+
+ public static final int END_INDEX_WITHIN_TAG = 2;
+
+ public static final HashSet SPECIAL_EMPTY_CHARS = new HashSet();
+
+ public static final HashMap CHAR_NODE_MAP = new HashMap();
+
+ // Cursor can't go outside of these container.
+ public static final HashSet HTML_CONSTRAINED_CONTAINERS = new HashSet();
+
+ public static final HashSet HTML_STYLE_NODES = new HashSet();
+
+ public static final HashSet UNREMOVEBLE_TAGS = new HashSet();
+
+ // Nodes that can hold other nodes.
+ public static final String[] HTML_CONTAINER_NODES = {
+ //
+ IHTMLConstants.TAG_BODY, //
+ IHTMLConstants.TAG_HTML, //
+ IHTMLConstants.TAG_SPAN, //
+ IHTMLConstants.TAG_FORM, //
+ IHTMLConstants.TAG_P,//
+ IHTMLConstants.TAG_SPAN,//
+ IHTMLConstants.TAG_DIV,//
+ IHTMLConstants.TAG_LI,//
+ IHTMLConstants.TAG_OL,//
+ IHTMLConstants.TAG_UL //
+ };
+
+ public static final String[] NON_HTML_CONTAINER_NODES = {
+ IJSFConstants.TAG_VIEW, //
+ IJSFConstants.TAG_PANELGRID, //
+ IJSFConstants.TAG_PANELGROUP, //
+ IJSFConstants.TAG_SUBVIEW };
+ static {
+ UNREMOVEBLE_TAGS.add(IHTMLConstants.TAG_HTML);
+ UNREMOVEBLE_TAGS.add(IHTMLConstants.TAG_HEAD);
+ UNREMOVEBLE_TAGS.add(IHTMLConstants.TAG_BODY);
+ EditModelQuery.CHAR_NODE_MAP.put(new Character(SWT.CR),
+ IHTMLConstants.TAG_BR);
+ EditModelQuery.CHAR_NODE_MAP.put(new Character(SWT.LF),
+ IHTMLConstants.TAG_BR);
+ EditModelQuery.SPECIAL_EMPTY_CHARS.add(" ");
+ EditModelQuery.SPECIAL_EMPTY_CHARS.add("\t");
+ EditModelQuery.SPECIAL_EMPTY_CHARS.add("\r");
+ EditModelQuery.SPECIAL_EMPTY_CHARS.add("\n");
+ EditModelQuery.HTML_CONSTRAINED_CONTAINERS.add(IHTMLConstants.TAG_TD);
+ EditModelQuery.HTML_CONSTRAINED_CONTAINERS.add(IHTMLConstants.TAG_TR);
+ EditModelQuery.HTML_CONSTRAINED_CONTAINERS
+ .add(IHTMLConstants.TAG_TABLE);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_B);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_EM);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H1);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H2);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H3);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H4);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H5);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_H6);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_A);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_U);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_I);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_S);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_STRONG);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_TT);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_BIG);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_SMALL);
+ EditModelQuery.HTML_STYLE_NODES.add(IHTMLConstants.TAG_FONT);
+ }
+
+ private EditModelQuery() {
+ }
+
+ public static EditModelQuery getInstance() {
+ if (_instance == null) {
+ _instance = new EditModelQuery();
+ }
+ return _instance;
+ }
+
+ /**
+ * Get previous sibling, or if sibling is null then get previous neighbor.
+ *
+ * @param node
+ * @return
+ */
+ public Node getPreviousNeighbor(Node node) {
+ if (!EditValidateUtil.validNode(node)) {
+ return null;
+ }
+ while (node != null && node.getNodeType() != Node.DOCUMENT_NODE
+ && node.getPreviousSibling() == null) {
+ node = node.getParentNode();
+ }
+ return (node != null && node.getNodeType() != Node.DOCUMENT_NODE) ? node
+ .getPreviousSibling()
+ : null;
+ }
+
+ /**
+ * Get privous sibling, or if sibling is null then get previous neighor's
+ * rightmost child, which is adjacent to 'node'.
+ *
+ * @param node
+ * @return
+ */
+ public Node getPreviousLeafNeighbor(Node node) {
+ return getLastLeafChild(getPreviousNeighbor(node));
+ }
+
+ /**
+ * Get next sibling, or if sibling is null get next neighbor.
+ *
+ * @param node
+ * @return
+ */
+ public Node getNextNeighbor(Node node) {
+ if (!EditValidateUtil.validNode(node)) {
+ return null;
+ }
+
+ while (node != null && node.getNodeType() != Node.DOCUMENT_NODE
+ && node.getNextSibling() == null) {
+ node = node.getParentNode();
+ }
+ return (node != null && node.getNodeType() != Node.DOCUMENT_NODE) ? node
+ .getNextSibling()
+ : null;
+ }
+
+ /**
+ * Get next sibling, or if sibling is null get next neighbor's leftmost leaf
+ * child which will be adjacent to 'node'.
+ *
+ * @param node
+ * @return
+ */
+ public Node getNextLeafNeighbor(Node node) {
+ return getFirstLeafChild(getNextNeighbor(node));
+ }
+
+ /**
+ * Get node's rightmost leaf child.
+ *
+ * @param node
+ * @return
+ */
+ private Node getLastLeafChild(Node node) {
+ if (node == null) {
+ return null;
+ }
+ if (node.getLastChild() != null) {
+ return getLastLeafChild(node.getLastChild());
+ } else {
+ return node;
+ }
+ }
+
+ /**
+ * Get node's leftmost leaf child.
+ *
+ * @param node
+ * @return
+ */
+ protected Node getFirstLeafChild(Node node) {
+ if (node == null) {
+ return null;
+ }
+
+ if (node.getFirstChild() != null) {
+ return getFirstLeafChild(node.getFirstChild());
+ } else {
+ return node;
+ }
+ }
+
+ /**
+ * To see if node is within a indexed region that is started from 'start',
+ * ended at 'end'
+ */
+ public static boolean within(int start, int end, Node theNode) {
+ return getNodeStartIndex(theNode) >= start
+ && getNodeEndIndex(theNode) <= end;
+ }
+
+ /**
+ * To see whether the 'position' is within indexed location (start, end)
+ *
+ * @param start
+ * @param end
+ * @param position
+ * @return
+ */
+ public boolean within(int start, int end, IDOMPosition position) {
+ int pos = getIndexedRegionLocation(position);
+ return start <= pos && pos <= end;
+ }
+
+ /**
+ * To see whether the 'theNode' is not within indexed region (start, end)
+ *
+ * @param start
+ * @param end
+ * @param theNode
+ * @return
+ */
+ public static boolean outOf(int start, int end, Node theNode) {
+ if (getNodeLenth(theNode) > 0) {
+ return getNodeStartIndex(theNode) >= end
+ || getNodeEndIndex(theNode) <= start;
+ } else {
+ return !((getNodeStartIndex(theNode) >= start && getNodeEndIndex(theNode) <= end));
+ }
+ }
+
+ /**
+ * Determine whether the position is at node's edge. When the offset is at
+ * edge, it is in the leftmost or rightmost offset of node's region.
+ *
+ * @param node
+ * @param offset
+ * @param direction
+ * @return
+ */
+ public boolean atEdge(IDOMPosition position, boolean forward) {
+ Node node = position.getContainerNode();
+ int offset = position.getOffset();
+ if (forward) {
+ if (EditModelQuery.isText(node)) {
+ return offset == node.getNodeValue().length();
+ } else {
+ return offset == node.getChildNodes().getLength();
+ }
+ } else {
+ return offset == 0;
+ }
+ }
+
+ /**
+ * Get node's neighbor on the node tree, if forward, then get next,
+ * otherwise go backward.
+ *
+ * @param node
+ * @param forward
+ * @return
+ */
+ public Node getNeighbor(Node node, boolean forward) {
+ if (forward) {
+ return getNextNeighbor(node);
+ } else {
+ return getPreviousNeighbor(node);
+ }
+ }
+
+ /**
+ * Get neighbor which is descendent of root.
+ *
+ * @param node
+ * @param root
+ * @return
+ */
+ public Node getPreviousNeighbor(Node node, Node root) {
+ if (!EditValidateUtil.validNode(node)) {
+ return null;
+ }
+ while (node != null && node != root
+ && node.getNodeType() != Node.DOCUMENT_NODE
+ && node.getPreviousSibling() == null) {
+ node = node.getParentNode();
+ }
+ return (node != null && node != root && node.getNodeType() != Node.DOCUMENT_NODE) ? node
+ .getPreviousSibling()
+ : null;
+ }
+
+ /**
+ * Get neighbor which is descendent of root.
+ *
+ * @param node
+ * @param root
+ * @return
+ */
+ public Node getNextNeighbor(Node node, Node root) {
+ if (!EditValidateUtil.validNode(node)) {
+ return null;
+ }
+
+ while (node != null && node != root
+ && node.getNodeType() != Node.DOCUMENT_NODE
+ && node.getNextSibling() == null) {
+ node = node.getParentNode();
+ }
+ return (node != null && node != root && node.getNodeType() != Node.DOCUMENT_NODE) ? node
+ .getNextSibling()
+ : null;
+ }
+
+ /**
+ * Get neighbor which is descendent of root.
+ *
+ * @param node
+ * @param forward
+ * @param root
+ * @return
+ */
+ public Node getNeighbor(Node node, boolean forward, Node root) {
+ Assert.isTrue(root != null);
+ if (forward) {
+ return getNextNeighbor(node, root);
+ } else {
+ return getPreviousNeighbor(node, root);
+ }
+ }
+
+ /**
+ * Get node's leaf child which is adjacent to 'node', according to
+ * 'forward', it will search backward or forward.
+ *
+ * @param node
+ * @param forward
+ * @return
+ */
+ public Node getLeafNeighbor(Node node, boolean forward) {
+ if (node == null) {
+ return null;
+ }
+ if (forward) {
+ return getNextLeafNeighbor(node);
+ } else {
+ return getPreviousLeafNeighbor(node);
+ }
+ }
+
+ /**
+ * Get neighbor's leaf child, which is adjacent to 'node'
+ *
+ * @param node
+ * @param childIndex
+ * @param forward
+ * @return
+ */
+ public Node getLeafNeighbor(Node node, int childIndex, boolean forward) {
+ if (node == null) {
+ return null;
+ }
+ Node neighbor = getNeighbor(node, childIndex, forward);
+ if (neighbor != null) {
+ if (forward) {
+ return getFirstLeafChild(neighbor);
+ } else {
+ return getLastLeafChild(neighbor);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * First try sibling, if it retruns null, try search neighbor.
+ *
+ * @param parent
+ * @param childIndex
+ * @param forward
+ * @return
+ */
+ public Node getNeighbor(Node parent, int childIndex, boolean forward) {
+ if (!EditValidateUtil.validNode(parent)) {
+ return null;
+ }
+
+ NodeList nodeList = parent.getChildNodes();
+ if (nodeList != null && nodeList.getLength() > 0) {
+ if (nodeList.getLength() < childIndex) {
+ return null;
+ }
+ Node childNode = null;
+ if (!forward) {
+ --childIndex;
+ }
+ childNode = nodeList.item(childIndex);
+ if (childNode != null) {
+ return childNode;
+ } else {
+ return getNeighbor(parent, forward);
+ }
+ } else {
+ if (parent.getNodeType() == Node.TEXT_NODE) {
+ return getNeighbor(parent, forward);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * To see whether the textSelection start and end are on the same.
+ *
+ * @param model
+ * @param textSelection
+ * @param lookForChildren
+ * @return
+ */
+ public static boolean isSame(IStructuredModel model,
+ TextSelection textSelection) {
+ if (model != null && textSelection != null) {
+ int t1 = textSelection.getOffset();
+ int t2 = textSelection.getLength() + t1;
+ return model.getIndexedRegion(t1) == model.getIndexedRegion(t2);
+ }
+ return false;
+ }
+
+ /**
+ * To see if the range and text selection covered the same range.
+ *
+ * @param model
+ * @param range
+ * @param textSelection
+ * @return
+ */
+ public static boolean isSame(IStructuredModel model, DesignRange range,
+ TextSelection textSelection) {
+ if (model != null && range != null && textSelection != null) {
+ int t1 = textSelection.getOffset();
+ int t2 = textSelection.getLength() + t1;
+ int r1 = getIndexedRegionLocation(DOMRangeHelper.toDOMRange(range)
+ .getStartPosition());
+ int r2 = getIndexedRegionLocation(DOMRangeHelper.toDOMRange(range)
+ .getEndPosition());
+ return (model.getIndexedRegion(t1) == model.getIndexedRegion(r1) && //
+ model.getIndexedRegion(t2) == model.getIndexedRegion(r2))
+ || (model.getIndexedRegion(t2) == model
+ .getIndexedRegion(r1) && //
+ model.getIndexedRegion(t1) == model.getIndexedRegion(r2));
+ }
+ return false;
+ }
+
+ /**
+ * To see whether the selection is single point.
+ *
+ * @param model
+ * @param textSelection
+ * @return
+ */
+ public static boolean isSamePoint(TextSelection textSelection) {
+ return textSelection.getLength() == 0;
+ }
+
+ /**
+ * To see whether two IDOMPosition are pointed to a same location.
+ *
+ * @param p1
+ * @param p2
+ * @return
+ */
+ public static boolean isSame(IDOMPosition p1, IDOMPosition p2) {
+ if (p1 == p2
+ || (p1.getContainerNode() == p2.getContainerNode() && p1
+ .getOffset() == p2.getOffset())) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * To see whether the range's start and end position are pointed to a same
+ * location.
+ *
+ * @param range
+ * @return
+ */
+ public static boolean isSame(DOMRange range) {
+ EditValidateUtil.validRange(range);
+ return isSame(range.getStartPosition(), range.getEndPosition());
+ }
+
+ public static boolean isSame(DesignRange range) {
+ return isSame(range.getStartPosition(), range.getEndPosition());
+ }
+
+ public static boolean isSame(DesignPosition p1, DesignPosition p2) {
+ if (p1 == p2) {
+ return true;
+ }
+ if (p1.getContainerNode() == p2.getContainerNode()
+ && p1.getOffset() == p2.getOffset()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isWithinSameText(IDOMPosition p1, IDOMPosition p2) {
+ if (p1 == null || p2 == null) {
+ return false;
+ }
+ return p1.isText() && p2.isText()
+ && p1.getContainerNode() == p2.getContainerNode();
+ }
+
+ /**
+ * Get the node absolute start location in its residing IStructuredModel.
+ *
+ * @param p
+ * @return
+ */
+ public static int getIndexedRegionLocation(IDOMPosition p) {
+ if (!EditValidateUtil.validPosition(p)) {
+ return -1;
+ }
+ Node parent = p.getContainerNode();
+ if (p.isText()) {
+ return ((IndexedRegion) parent).getStartOffset() + p.getOffset();
+ } else {
+ int index = p.getOffset();
+ if (!parent.hasChildNodes()) {
+ // Element:
+ if (!isDocument(parent)) {
+ IStructuredDocumentRegion region = ((IDOMNode) parent)
+ .getStartStructuredDocumentRegion();
+ return region.getEnd();
+ }
+ // Document node:
+ else {
+ int offset = ((IndexedRegion) parent).getStartOffset();
+ return offset;
+ }
+ } else {
+ NodeList children = parent.getChildNodes();
+ // After rightmost child
+ if (children.getLength() == index) {
+ if (!isDocument(parent)) {
+ int pos = getNodeEndNameStartIndex(parent);
+ return pos;
+ } else {
+ int offset = ((IndexedRegion) parent).getEndOffset();
+ return offset;
+ }
+ }
+ // Before a child
+ else {
+ Node node = children.item(index);
+ return ((IndexedRegion) node).getStartOffset();
+ }
+ }
+ }
+ }
+
+ /**
+ * To determine whether the position is at the edge of a node. TODO: temp
+ * func for later combination
+ *
+ * @param node
+ * @param position
+ * @return
+ */
+ public boolean isLinked(IDOMPosition nodePos, IDOMPosition position,
+ boolean left) {
+ int index = getIndexedRegionLocation(position);
+ if (left) {
+ int pos = getIndexedRegionLocation(nodePos);
+ return pos == index;
+ } else {
+ Node node = null;
+ int end;
+ if (nodePos.isText()) {
+ node = nodePos.getContainerNode();
+ end = ((IndexedRegion) node).getEndOffset();
+ } else {
+ node = nodePos.getNextSiblingNode();
+ Assert.isTrue(node != null);
+ end = ((IndexedRegion) node).getEndOffset();
+ }
+ return end == index;
+ }
+ }
+
+ /**
+ * To see if the location is at the node's indexed pos, posType can be
+ * START_INDEX_BEFORE_TAG, END_INDEX_WITHIN_TAG When location is at these
+ * two position, webtools returns the container tag name, so we need to know
+ * these.
+ *
+ * @param location
+ * @param node
+ * @return
+ */
+ public boolean isAtNodeNameEdge(int location, Node node, int posType) {
+ int start = getNodeEndNameStartIndex(node);
+ return location == start;
+ }
+
+ public boolean isAtNodeNameEdge(int location, Node node) {
+ return isAtNodeNameEdge(location, node, START_INDEX_BEFORE_TAG)
+ || isAtNodeNameEdge(location, node, END_INDEX_WITHIN_TAG);
+ }
+
+ /**
+ * If text only contains chars '\r' or '\n', it is considered to be
+ * transparent.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean isTransparentText(Node node) {
+ // should valid non null?
+ Assert.isTrue(node != null);
+ if (node == null || !isText(node)) {
+ return false;
+ }
+ if (!EditValidateUtil.validText(node)) {
+ return false;
+ }
+
+ Text text = (Text) node;
+ if (text.getLength() == 0) {
+ return true;
+ }
+ String value = text.getNodeValue();
+ int i = 0;
+ while (i < value.length() && HTMLUtil.isHTMLWhitespace(value.charAt(i))) {
+ i++;
+ }
+ return i == value.length();
+ }
+
+ /**
+ * Get node index in its parent's children.
+ *
+ * @param node
+ * @return
+ */
+ public static int getNodeIndex(Node node) {
+ EditValidateUtil.validNode(node);
+ Node parent = node.getParentNode();
+ int index = 0;
+ for (Node child = parent.getFirstChild(); child != null; child = child
+ .getNextSibling()) {
+ if (child == node) {
+ return index;
+ }
+ index++;
+ }
+ return -1; // error
+ }
+
+ /**
+ * If parent has more than one children of which each node's localName is
+ * the same as of 'node', return the index of 'node' in the same type
+ * children list.
+ *
+ * @param node
+ * @return
+ */
+ public int getSameTypeNodeIndex(Node node) {
+ EditValidateUtil.validNode(node);
+ int i = 0;
+ while (node != null) {
+ Node sibling = node.getPreviousSibling();
+ if (sibling != null && sibling.getLocalName() != null
+ && sibling.getLocalName().equals(node.getLocalName())) {
+ i++;
+ }
+ node = sibling;
+ }
+ return i; // error
+ }
+
+ /**
+ * Start from position, skip transparent chars, and returns the first
+ * non-transparent char's index. based on 'forward', go previously or next .
+ *
+ * @param value
+ * @param position
+ * @param forward
+ * @return
+ */
+ public int getNextConcretePosition(String value, int position,
+ boolean forward) {
+ if (value == null) {
+ return -1;
+ }
+ if (value.length() == 0) {
+ return 0;
+ }
+ // validate
+ Assert.isTrue(position >= 0 && position <= value.length());
+ int i = -1;
+ if (forward) {
+ i = position;
+ while (i < value.length()
+ && (value.charAt(i) == SWT.CR || value.charAt(i) == SWT.LF)) {
+ i++;
+ }
+ return i;
+ } else {
+ i = position - 1;
+ while (i >= 0
+ && (value.charAt(i) == SWT.CR || value.charAt(i) == SWT.LF)) {
+ i--;
+ }
+ return i + 1;
+ }
+ }
+
+ /**
+ * Get two nodes' lowest common ancestor.
+ *
+ * @param node1
+ * @param node2
+ * @return
+ */
+ public Node getCommonAncestor(Node node1, Node node2) {
+ if (node1 == null || node2 == null) {
+ return null;
+ }
+
+ for (Node na = node1; na != null; na = na.getParentNode()) {
+ for (Node ta = node2; ta != null; ta = ta.getParentNode()) {
+ if (ta == na)
+ return ta;
+ }
+ }
+ return null; // not found
+ }
+
+ /**
+ * Get lowest common ancestor of two IDOMPositions' container nodes..
+ *
+ * @param p1
+ * @param p2
+ * @return
+ */
+ public Node getCommonAncestor(IDOMPosition p1, IDOMPosition p2) {
+ Node n1 = p1.getContainerNode();
+ Node n2 = p2.getContainerNode();
+ return getCommonAncestor(n1, n2);
+ }
+
+ /**
+ * Get lowest ancestor of a 'node' which is block type.
+ *
+ * @param node
+ * @return
+ */
+ public Node getBlockAncestor(Node node) {
+ if (!EditValidateUtil.validNode(node)) {
+ return null;
+ }
+ while (node != null && isChild(IHTMLConstants.TAG_BODY, node, true)) {
+ if (isBlockNode(node)) {
+ return node;
+ }
+ node = node.getParentNode();
+ }
+ return null;
+ }
+
+ /**
+ * To see whether a node is block type.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean isBlockNode(Node node) {
+ return !isInline(node);
+ }
+
+ public static boolean isTableCell(Node node) {
+ if (node instanceof INodeNotifier) {
+ Object adapter = ((INodeNotifier) node)
+ .getAdapterFor(ICSSStyle.class);
+ if (adapter != null) {
+ ICSSStyle style = (ICSSStyle) adapter;
+ String display = style.getDisplay();
+ return display.equalsIgnoreCase(ICSSPropertyID.VAL_TABLE_CELL);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * To see if a node's display type is inline.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean isInline(Node refNode) {
+ Node node = refNode;
+ EditPart part = Target.resolvePart(node);
+ if (part instanceof ElementEditPart) {
+ node = ((ElementEditPart) part).getTagConvert().getResultElement();
+ }
+ if (isText(node)) {
+ return true;
+ } else if (node instanceof INodeNotifier) {
+ Object adapter = ((INodeNotifier) node)
+ .getAdapterFor(ICSSStyle.class);
+ if (adapter != null) {
+ ICSSStyle style = (ICSSStyle) adapter;
+ String display = style.getDisplay();
+ return (display.equalsIgnoreCase(ICSSPropertyID.VAL_INLINE)
+ || //
+ display
+ .equalsIgnoreCase(ICSSPropertyID.VAL_INLINE_TABLE)
+ || //
+ display.equalsIgnoreCase(ICSSPropertyID.VAL_COMPACT) || //
+ display.equalsIgnoreCase(ICSSPropertyID.VAL_RUN_IN));
+ }
+ }
+ return false;
+ }
+
+ public static boolean isListItem(Node node) {
+ if (node instanceof INodeNotifier) {
+ Object adapter = ((INodeNotifier) node)
+ .getAdapterFor(ICSSStyle.class);
+ if (adapter != null) {
+ ICSSStyle style = (ICSSStyle) adapter;
+ String display = style.getDisplay();
+ return (display.equalsIgnoreCase(ICSSPropertyID.VAL_LIST_ITEM));
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Determine whether a node is a child of node that is named as 'name', if
+ * the node itself is named as 'name' return true also.
+ *
+ * @param names
+ * @param node
+ * @return
+ */
+ public static boolean isChild(String names[], Node node,
+ boolean ignoreCase, boolean noSame) {
+ if (node == null) {
+ return false;
+ }
+ if (noSame) {
+ node = node.getParentNode();
+ }
+ while (node != null && !isDocument(node)) {
+ String nodeName = node.getLocalName();
+ if (nodeName != null
+ && (ignoreCase
+ && Arrays.asList(names).contains(
+ nodeName.toLowerCase()) || !ignoreCase
+ && Arrays.asList(names).contains(nodeName))) {
+ return true;
+ }
+ node = node.getParentNode();
+ }
+ return false;
+ }
+
+ /**
+ * Determine whether a node is a child of node that is named as 'name', if
+ * the node itself is named as 'name' return true also.
+ *
+ * @param name
+ * @param node
+ * @return
+ */
+ public static boolean isChild(String name, Node node, boolean ignoreCase) {
+ if (node == null) {
+ return false;
+ }
+
+ while (node != null && node.getNodeType() != Node.DOCUMENT_NODE) {
+ String nodeName = node.getLocalName();
+ if (nodeName != null
+ && (ignoreCase && name.equalsIgnoreCase(nodeName) || !ignoreCase
+ && name.equalsIgnoreCase(nodeName))) {
+ return true;
+ }
+ node = node.getParentNode();
+ }
+ return false;
+ }
+
+ /**
+ * To see whether 'node' is 'ancestor's child.
+ *
+ * @param ancestor
+ * @param node
+ * @return
+ */
+ public static boolean isChild(Node ancestor, Node node) {
+ if (node == null || ancestor == null) {
+ return false;
+ }
+
+ if (isDocument(ancestor)) {
+ return true;
+ }
+ while (node != null && !isDocument(ancestor)) {
+ if (node == null) {
+ break;
+ }
+ if (node == ancestor) {
+ return true;
+ }
+ node = node.getParentNode();
+ }
+ return false;
+ }
+
+ /**
+ * Get next sibling node to position's container node.
+ *
+ * @param position
+ * @return
+ */
+ public Node getNextSibling(IDOMPosition position) {
+ if (position.isText()) {
+ return position.getContainerNode().getNextSibling();
+ } else {
+ return position.getNextSiblingNode();
+ }
+ }
+
+ /**
+ * Get previous sibling node to position's container node.
+ *
+ * @param position
+ * @return
+ */
+ public Node getPreviousSibling(IDOMPosition position) {
+ if (position.isText()) {
+ return position.getContainerNode().getPreviousSibling();
+ } else {
+ return position.getPreviousSiblingNode();
+ }
+ }
+
+ /**
+ * Get position's container node's parent.
+ *
+ * @param position
+ * @return
+ */
+ public Node getParent(IDOMPosition position) {
+ if (position.isText()) {
+ return position.getContainerNode().getParentNode();
+ } else {
+ return position.getContainerNode();
+ }
+ }
+
+ /**
+ * Get node's sibling according to 'forward' direction
+ *
+ * @param node
+ * @param forward
+ * @return
+ */
+ public Node getSibling(Node node, boolean forward) {
+ EditValidateUtil.validNode(node);
+ if (forward) {
+ return node.getNextSibling();
+ } else {
+ return node.getPreviousSibling();
+ }
+ }
+
+ /**
+ * Get position's container node's sibling.
+ *
+ * @param position
+ * @param forward
+ * @return
+ */
+ public Node getSibling(IDOMPosition position, boolean forward) {
+ if (forward) {
+ return getNextSibling(position);
+ } else {
+ return getPreviousSibling(position);
+ }
+ }
+
+ /**
+ * Get position's container node's editable items number. this is temp
+ * functions for future use.
+ *
+ * @param position
+ * @return
+ */
+ public int getSize(IDOMPosition position) {
+ EditValidateUtil.validPosition(position);
+ if (position.isText()) {
+ return ((Text) position.getContainerNode()).getLength();
+ } else {
+ if (position.getContainerNode().hasChildNodes()) {
+ return position.getContainerNode().getChildNodes().getLength();
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * Valid position and return text, if it contains text node.
+ *
+ * @param position
+ * @return
+ */
+ public Text getText(IDOMPosition position) {
+ if (position.isText()) {
+ if (position.getContainerNode() != null) {
+ return (Text) position.getContainerNode();
+ }
+ }
+ return null;
+ }
+
+ public static Document getDocumentNode(Node node) {
+ if (node != null) {
+ return isDocument(node) ? (Document) node : node.getOwnerDocument();
+ }
+ return null;
+ }
+
+ /**
+ * To see whether a node is empty, here we can insert rules to see whether
+ * it is empty, for delete operation, it could be deleted.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean isEmptyNode(Node node) {
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ return isTransparentText(node);
+ }
+ if (node.getChildNodes() == null
+ || node.getChildNodes().getLength() == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * To see whther a node is text node.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean isText(Node node) {
+ return node != null && node.getNodeType() == Node.TEXT_NODE;
+ }
+
+ /**
+ * To see whether a node is Document node.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean isDocument(Node node) {
+ return node != null && node.getNodeType() == Node.DOCUMENT_NODE;
+ }
+
+ private static boolean isHead(Node node) {
+ return node.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_HEAD);
+ }
+
+ /**
+ * Get style from parent node. from first paret 'firstF', we will traverse
+ * the tree up untile reaching Document node, get all style node's, we may
+ * insert rules here to stop the search at a before paricular node. Style
+ * nodes could <b>, <u>...
+ *
+ * @param children
+ * @param firstF
+ * @return
+ */
+ public void assignFather(Vector children, Node firstF) {
+ if (children.size() == 0) {
+ return;
+ }
+ if (firstF != null && !isDocument(firstF)) {
+ String name = firstF.getNodeName();
+ // To see whether it is a style node that is our anticipated node.
+ if (name != null && HTML_STYLE_NODES.contains(name.toLowerCase())) {
+ Node newParent = firstF.cloneNode(false);
+ while (children.size() > 0) {
+ newParent.appendChild((Node) children.remove(0));
+ }
+ children.add(newParent);
+ }
+ assignFather(children, firstF.getParentNode());
+ }
+ }
+
+ /**
+ * Get a node that is at Indexed position 'pos' in 'model'.
+ *
+ * @param model
+ * @param pos
+ * @return
+ */
+ public Object getPosNode(IStructuredModel model, int pos) {
+ IndexedRegion inode = model.getIndexedRegion(pos);
+ return inode;
+ }
+
+ /**
+ * If the pos is at right edge within container.
+ *
+ * @param model
+ * @param pos
+ * @return
+ */
+ public boolean isAtRightMostWithin(Node node, int pos) {
+ return getNodeEndNameStartIndex(node) == pos;
+ }
+
+ /**
+ * Create the node, if 'refNode' is null, then position is at the edge of
+ * 'container'. otherwize calculate refNode's related index in its parent's
+ * children list and return DOMPosition.
+ *
+ * @param container
+ * @param refNode
+ * @param forward
+ * @return
+ */
+ public IDOMPosition createDomposition(Node container, Node refNode,
+ boolean forward) {
+ if (refNode == null) {
+ if (forward && container.hasChildNodes()) {
+ return new DOMPosition(container, container.getChildNodes()
+ .getLength());
+ } else {
+ return new DOMPosition(container, 0);
+ }
+ } else {
+ Assert.isTrue(refNode.getParentNode() == container);
+ int index = getNodeIndex(refNode);
+ if (!forward) {
+ index++;
+ }
+ return new DOMPosition(container, index);
+ }
+ }
+
+ public static DesignRange convertToDesignRange(IStructuredModel fModel,
+ TextSelection textSelection) {
+ int start = textSelection.getOffset();
+ int end = textSelection.getLength() + start;
+ IDOMPosition startDomPos = EditModelQuery.getInstance()
+ .createDomposition((IDOMModel) fModel, start, false);
+ IDOMPosition endDomPos = EditModelQuery.getInstance()
+ .createDomposition((IDOMModel) fModel, end, false);
+ if (startDomPos == null) {
+ startDomPos = endDomPos;
+ } else if (endDomPos == null) {
+ endDomPos = startDomPos;
+ }
+ if (startDomPos != null) {
+ DesignPosition startPos = null, endPos = null;
+ startPos = DOMPositionHelper.toDesignPosition(startDomPos);
+ endPos = DOMPositionHelper.toDesignPosition(endDomPos);
+ if (startPos != null) {
+ return new DesignRange(startPos, endPos);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create IDOMPosition based on Indexed 'position' in model. If node at
+ * position is text, use position to calculate DOMPosition offset,
+ * otherwize, simply create position pointed to container's children list's
+ * edge.
+ *
+ * @param container
+ * @param position
+ * @return
+ */
+ public IDOMPosition createDomposition(IDOMModel model, int position,
+ boolean adjust) {
+ return createDomposition1(model, position, adjust);
+ }
+
+ /**
+ * Create IDOMPosition based on Indexed 'position' in model. If node at
+ * position is text, use position to calculate DOMPosition offset,
+ * otherwize, simply create position pointed to container's children list's
+ * edge.
+ *
+ * @param container
+ * @param position
+ * @return
+ */
+ public IDOMPosition createDomposition1(IDOMModel model, int position,
+ boolean adjust) {
+ try {
+ IMovementMediator validator = new InlineEditingNavigationMediator(
+ new ActionData(ActionData.INLINE_EDIT, null));
+ // get the container
+ Object object = getPosNode(model, position);
+ if (object == null && position > 0) {
+ // The end of file?
+ object = getPosNode(model, position - 1);
+ }
+ Node container = null;
+ if (object == null) {
+ // empty file?
+ return new DOMPosition(model.getDocument(), 0);
+ }
+ container = (Node) object;
+ Object oppNode = getPosNode(model, position - 1);
+ if (oppNode != null
+ && !EditModelQuery.isChild((Node) oppNode, container)
+ && //
+ !EditModelQuery.isInline(container)
+ && EditModelQuery.isInline((Node) oppNode)) {
+ container = (Node) oppNode;
+ }
+ int location = EditHelper.getInstance().getLocation(container,
+ position, false);
+ IDOMPosition result = null;
+ switch (location) {
+ case 1:
+ case 2:
+ result = new DOMRefPosition(container, false);
+ break;
+ case 4:
+ case 5:
+ result = new DOMRefPosition(container, true);
+ break;
+ case 3:
+ if (EditModelQuery.isText(container)) {
+ result = new DOMPosition(container, position
+ - EditModelQuery.getNodeStartIndex(container));
+ } else {
+ result = new DOMPosition(container, container
+ .getChildNodes().getLength());
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ // "Error in position creation"
+ _log.error("Error.EditModelQuery.0" + e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ * Calculate node's Indexed length in model.
+ *
+ * @param node
+ * @return
+ */
+ public static int getNodeLenth(Node node) {
+ if (node == null) {
+ return 0;
+ }
+ if (EditValidateUtil.validNode(node)) {
+ return ((IndexedRegion) node).getEndOffset()
+ - ((IndexedRegion) node).getStartOffset();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Return 'node' indexed start position Example: |<a></a>, the position is
+ * indicated by '|'
+ *
+ * @param node
+ * @return
+ */
+ public static int getNodeStartIndex(Node node) {
+ if (EditValidateUtil.validNode(node) && node instanceof IndexedRegion) {
+ return ((IndexedRegion) node).getStartOffset();
+ }
+ return -1;
+ }
+
+ /**
+ * Return 'node' indexed end position Example: <a></a>|, the position is
+ * indicated by '|'
+ *
+ * @param node
+ * @return
+ */
+ public static int getNodeEndIndex(Node node) {
+ if (EditValidateUtil.validNode(node) && node instanceof IndexedRegion) {
+ return ((IndexedRegion) node).getEndOffset();
+ }
+ return -1;
+ }
+
+ /**
+ * Get node at indexed position.
+ *
+ * @param position
+ * @return
+ */
+ public static Node getNodeAt(IStructuredModel model, int position) {
+ try {
+ IndexedRegion region = model.getIndexedRegion(position);
+ if (region instanceof Node) {
+ return (Node) region;
+ }
+ return null;
+ } catch (Exception e) {
+ // "Error in region node creation"
+ _log.error("Error.EditModelQuery.1", e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ * Return 'node' indexed start name's end position Example: <a>|aaa </a>,
+ * the position is indicated by '|'
+ *
+ * @param node
+ * @return
+ */
+ public static int getNodeStartNameEndIndex(Node node) {
+ if (isText(node)) {
+ return getNodeStartIndex(node);
+ }
+ if (EditValidateUtil.validNode(node) && node instanceof IDOMNode) {
+ IStructuredDocumentRegion region = ((IDOMNode) node)
+ .getStartStructuredDocumentRegion();
+ if (region != null) {
+ return region.getEndOffset();
+ }
+ // else
+ // {
+ // // if (node.hasChildNodes())
+ // // {
+ // // // Node should always have start name, so this part should
+ // never reach,
+ // // // the assert is for inner debug.
+ // // Assert.isTrue(false);
+ // // return getNodeStartIndex(node);
+ // // }
+ // }
+ }
+ // This should never happen.
+ return getNodeStartIndex(node);
+ }
+
+ /**
+ * Return 'node' indexed end name' start position Example: <a>aaa| </a>, the
+ * position is indicated by '|' If node is <a /> style or there is no </a>
+ * to pair with <a>, the function return -1.
+ *
+ * @param node
+ * @return
+ */
+ public static int getNodeEndNameStartIndex(Node node) {
+ if (isText(node)) {
+ return getNodeEndIndex(node);
+ }
+ if (EditValidateUtil.validNode(node) && node instanceof IDOMNode) {
+ IStructuredDocumentRegion region = ((IDOMNode) node)
+ .getEndStructuredDocumentRegion();
+ if (region != null) {
+ return region.getStartOffset();
+ }
+ // else
+ // {
+ // if (node.hasChildNodes())
+ // {
+ // return getNodeEndIndex(node);
+ // }
+ // }
+ }
+ return getNodeEndIndex(node);
+ }
+
+ /**
+ * To see if a node is <a/>style.
+ *
+ * @param node
+ * @return
+ */
+ public boolean isSingleRegionNode(Node node) {
+ if (getNodeEndNameStartIndex(node) == getNodeEndIndex(node)
+ && !node.hasChildNodes()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * To see if a node has child that is not transparent child only.
+ *
+ * @param node
+ * @return
+ */
+ public boolean hasNonTransparentChild(Node node) {
+ if (!node.hasChildNodes()) {
+ return false;
+ } else {
+ NodeList children = node.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Object child = children.item(i);
+ if (isText((Node) child)) {
+ if (!isTransparentText((Node) child)) {
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * To see if a node has child that is not transparent child only.
+ *
+ * @param node
+ * @return
+ */
+ public boolean hasNonTransparentChild(Node node, String[] excludes) {
+ if (!node.hasChildNodes()) {
+ return false;
+ } else {
+ NodeList children = node.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Object child = children.item(i);
+ if (isText((Node) child)) {
+ if (!isTransparentText((Node) child)) {
+ return true;
+ }
+ } else if (!Arrays.asList(excludes).contains(
+ ((Node) child).getLocalName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * To see whether tag has whitespace char.
+ *
+ * @param node
+ * @return
+ */
+ public boolean hasWhitespaceNeighbor(Node node) {
+ node = getNeighbor(node, true);
+ if (isWidget(node)) {
+ return false;
+ } else {
+ node = getFirstLeafChild(node);
+ return isTransparentText(node);
+ }
+
+ }
+
+ /**
+ * @param host
+ * @return
+ */
+ public static boolean isWidget(Object host) {
+ boolean result = false;
+ EditPart part = null;
+ if (host instanceof EditPart) {
+ part = (EditPart) host;
+ } else if (host instanceof Node) {
+ part = Target.resolvePart((Node) host);
+ if (part == null) {
+ part = new HTMLEditPartsFactory(
+ (IDOMDocument) getDocumentNode((Node) host))
+ .createEditPart(null, host);
+ }
+ }
+ if (part instanceof NodeEditPart) {
+ result = ((NodeEditPart) part).isWidget();
+ }
+ return result;
+ }
+
+ /**
+ * To combind whitespace chars, only one whitespace string should be create.
+ *
+ * @param node
+ * @return
+ */
+ public boolean isRedundantWightspaces(Node node) {
+ if (isTransparentText(node) && hasWhitespaceNeighbor(node)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean hasAncestor(Node node, String names[],
+ boolean ignoreCase) {
+ Assert.isTrue(names != null);
+ while (node != null && !EditModelQuery.isDocument(node)) {
+ if (isElement(node))
+ if (containItem(names, node, ignoreCase)) {
+ return true;
+ }
+ node = node.getParentNode();
+ }
+ return false;
+ }
+
+ /**
+ * To see if 'node' has ancestor that has name as 'name'
+ *
+ * @param node
+ * @param name
+ * @param ignoreCase
+ * @return
+ */
+ public static boolean hasAncestor(Node node, String name, boolean ignoreCase) {
+ Assert.isTrue(name != null);
+ while (node != null && !EditModelQuery.isDocument(node)) {
+ if (node.getNodeName() != null)
+ if ((ignoreCase && name.equalsIgnoreCase(node.getNodeName())) || //
+ (!ignoreCase && name.equals(node.getNodeName()))) {
+ return true;
+ }
+ node = node.getParentNode();
+ }
+ return false;
+ }
+
+ /**
+ * To see if 'node' has direct ancestors that has names listed in 'name[]'
+ *
+ * @param node
+ * @param name
+ * @param ignoreCase
+ * @return
+ */
+ public static List getAncestors(Node node, String top, boolean ignoreCase) {
+ List result = new ArrayList();
+ Assert.isTrue(node != null);
+ while (node != null && !EditModelQuery.isDocument(node)) {
+ result.add(node);
+ String name = node.getLocalName();
+ if (ignoreCase && top.equalsIgnoreCase(name) || //
+ (!ignoreCase && top.equals(name))) {
+ break;
+ }
+ node = node.getParentNode();
+ }
+ return result;
+ }
+
+ /**
+ * Copy old node's children to newNode.If the newNode is the father of the
+ * old node,then the old node's children will be inserted before the old
+ * node,otherwise,the old node's children just append to the newNode.
+ *
+ * @param old
+ * @param newNode
+ * @return
+ */
+ public static void copyChildren(Node old, Node newNode) {
+ Node child = old.getFirstChild();
+ while (child != null) {
+ Node next = child.getNextSibling();
+ child = old.removeChild(child);
+ if (old.getParentNode() == newNode) {
+ newNode.insertBefore(child, old);
+ } else {
+ newNode.appendChild(child);
+ }
+ child = next;
+ }
+ }
+
+ public static boolean isElement(Node node) {
+ return node.getNodeType() == Node.ELEMENT_NODE;
+ }
+
+ /**
+ * Return a offspring of ancestor, the offsprint has a name listed in
+ * childrenNames.
+ *
+ * @param ancestor
+ * @param childrenNames
+ * @param maxLevelToSearch:
+ * the max level from ancestor to the offspring in family tree.
+ * @param ignoreCase
+ * @return
+ */
+ public static Node getChild(Node ancestor, String childrenNames[],
+ int maxLevelToSearch, boolean ignoreCase) {
+ if (ancestor == null || maxLevelToSearch < 0) {
+ return null;
+ } else {
+ if (ancestor.getLocalName() != null
+ && ignoreCase
+ && Arrays.asList(childrenNames).contains(
+ ancestor.getLocalName().toLowerCase())
+ || !ignoreCase
+ && Arrays.asList(childrenNames).contains(
+ ancestor.getLocalName())) {
+ return ancestor;
+ }
+ }
+ NodeList children = ancestor.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node result = getChild(children.item(i), childrenNames,
+ maxLevelToSearch - 1, ignoreCase);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return a offspring of ancestor, the nodes on the tree are type of
+ * DeferredElementImpl, the offsprint has a name listed in childrenNames.
+ *
+ * @param ancestor
+ * @param childrenNames
+ * @param maxLevelToSearch:
+ * the max level from ancestor to the offspring in family tree.
+ * @param ignoreCase
+ * @return
+ */
+ public static Node getChildDeferredNode(Node ancestor,
+ String childrenNames[], int maxLevelToSearch, boolean ignoreCase) {
+ if (ancestor == null || maxLevelToSearch < 0) {
+ return null;
+ } else {
+ String nodeName = ancestor.getNodeName();
+ if (nodeName != null && ignoreCase
+ && Arrays.asList(childrenNames).contains(nodeName)
+ || !ignoreCase
+ && Arrays.asList(childrenNames).contains(nodeName)) {
+ return ancestor;
+ }
+ }
+ NodeList children = ancestor.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node result = getChildDeferredNode(children.item(i), childrenNames,
+ maxLevelToSearch - 1, ignoreCase);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ public static boolean hasTransparentNodeOnly(Node node) {
+ NodeList children = node.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ if (!EditModelQuery.isTransparentText((Node) children.item(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static Node getParent(String name, Node node, boolean ignoreCase) {
+ if (node == null) {
+ return null;
+ }
+
+ while (node != null && node.getNodeType() != Node.DOCUMENT_NODE) {
+ String nodeName = node.getLocalName();
+ if (nodeName != null
+ && (ignoreCase && name.equalsIgnoreCase(nodeName) || !ignoreCase
+ && name.equalsIgnoreCase(nodeName))) {
+ return node;
+ }
+ node = node.getParentNode();
+ }
+ return null;
+ }
+
+ /**
+ * get Elements with the same localName as the input localName under the
+ * rootNode,it is a recursive computation.
+ *
+ * @param rootNode
+ * @param localName
+ * @param caseSensitive
+ * @param list
+ * The input list to hold the matched elements.
+ */
+ public static void getElementByLocalName(Node rootNode, String localName,
+ boolean caseSensitive, List list) {
+ if (list == null) {
+ return;
+ }
+ NodeList nodeList = rootNode.getChildNodes();
+ if (nodeList != null && nodeList.getLength() > 0) {
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node node = nodeList.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ String nodeLocalName = node.getLocalName();
+ if (caseSensitive && localName.equals(nodeLocalName)) {
+ list.add(node);
+ } else if (!caseSensitive
+ && localName.equalsIgnoreCase(nodeLocalName)) {
+ list.add(node);
+ }
+ getElementByLocalName(node, localName, true, list);
+ }
+
+ }
+ }
+ }
+
+ public static boolean containItem(String[] tags, Node node,
+ boolean ignoreCase) {
+ if (ignoreCase) {
+ for (int i = 0, size = tags.length; i < size; i++) {
+ if (tags[i] == null) {
+ continue;
+ }
+ if (tags[i].equalsIgnoreCase(node.getNodeName())) {
+ return true;
+ }
+ }
+ } else {
+ for (int i = 0, size = tags.length; i < size; i++) {
+ if (tags[i] == null) {
+ continue;
+ }
+ if (tags[i].equals(node.getNodeName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditValidateUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditValidateUtil.java
new file mode 100644
index 000000000..c3f58ba02
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/EditValidateUtil.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * This class is used for debug purpose, and can be used to test some invalid
+ * status in the functions. Generally all the methods here will throw exception
+ * when invalid status happens.
+ *
+ * @author mengbo
+ */
+public class EditValidateUtil {
+ private static final Logger _logger = PDPlugin
+ .getLogger(EditValidateUtil.class);
+
+ private static final boolean ALERT = false;
+
+ private static final boolean REPORT = false;
+
+ /**
+ * A valid position means container node, offset are all valid.
+ *
+ * @param position
+ * @return
+ */
+ public static boolean validPosition(IDOMPosition position) {
+ try {
+ boolean result = true;
+ Assert.isTrue(position != null
+ && position.getContainerNode() != null
+ && position.getOffset() >= 0);
+ Node container = position.getContainerNode();
+ result &= validNode(container);
+ int offset = position.getOffset();
+ if (position.isText()) {
+ int length = ((Text) container).getLength();
+ Assert.isTrue(offset <= length);
+ } else {
+ if (position instanceof DOMPosition && offset > 0) {
+ Assert.isTrue(container.hasChildNodes()
+ && container.getChildNodes().getLength() >= offset);
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ // "error", "Error in validPosition"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.Position", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid position:"
+ _logger.error("Error.EditValidateUtil.Position", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ public static boolean validPosition(DesignPosition position) {
+ try {
+ boolean result = true;
+ Assert.isTrue(position != null
+ && position.getContainerPart() != null
+ && position.getContainerNode() != null
+ && position.getOffset() >= 0);
+ Node container = position.getContainerNode();
+ result &= validNode(container);
+ int offset = position.getOffset();
+ if (EditModelQuery.isText(container)) {
+ int length = ((Text) container).getLength();
+ Assert.isTrue(offset <= length);
+ } else {
+ if (position instanceof DesignRefPosition && offset > 0) {
+ Assert.isTrue(container.hasChildNodes()
+ && container.getChildNodes().getLength() >= offset);
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ // "error", "Error in validPosition"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.Position", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid position:"
+ _logger.error("Error.EditValidateUtil.Position", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Valid node is TextNode and it's valid node.
+ *
+ * @param node
+ * @return
+ */
+ public static boolean validText(Node node) {
+ try {
+ boolean result = true;
+ Assert.isTrue(node.getNodeType() == Node.TEXT_NODE);
+ Assert.isTrue(((Text) node).getData() != null);
+ result &= validNode(node);
+ return result;
+ } catch (Exception e) {
+ // "Error", "Error in validText"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.Text", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid Text:"
+ _logger.error("Error.EditValidateUtil.Text", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ /**
+ * A valid node is resided in the model tree
+ *
+ * @param node
+ * @return
+ */
+ public static boolean validNode(Node node) {
+ try {
+ Assert.isTrue(node instanceof IDOMNode);
+ Assert.isTrue((node.getNodeType() == Node.DOCUMENT_NODE)
+ || (node.getParentNode() != null));
+ // What's this?
+ return true;
+ } catch (Exception e) {
+ // "Error", "Error in validNode"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.Node", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid node:"
+ _logger.error("Error.EditValidateUtil.Node", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ /**
+ * A valid DOMRange contains valid IDOMPosition, and it should not be within
+ * node like 'HEAD'. The later one might not be suitble to valid in this
+ * util, it should be checked by some edit valid helper.
+ *
+ * @param range
+ * @return
+ */
+ public static boolean validRange(DOMRange range) {
+ try {
+ EditModelQuery modelQuery = EditModelQuery.getInstance();
+ boolean result = true;
+ IDOMPosition start = range.getStartPosition();
+ IDOMPosition end = range.getEndPosition();
+ result &= validPosition(start);
+ result &= validPosition(end);
+ Node startContainer = start.getContainerNode();
+ Node endContainer = end.getContainerNode();
+ // Assert.isTrue(isValidForEditing(modelQuery.getCommonAncestor(startContainer,
+ // endContainer)));
+ return result;
+ } catch (Exception e) {
+ // "Error", "Error in validRange"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.Range", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid Range:"
+ _logger.error("Error.EditValidateUtil.Range", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ public static boolean validStringIndex(Node text, int index) {
+ try {
+ Assert.isTrue(index >= 0 && ((Text) text).getLength() >= index);
+ return validText(text);
+ } catch (Exception e) {
+ // "Error", "Error in validStringIndex"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.StringIndex", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid Index in String:"
+ _logger.error("Error.EditValidateUtil.StringIndex", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ public static boolean validStringIndexOffset(Node text, int index,
+ int offset) {
+ try {
+ Assert.isTrue(index >= 0 && (index + offset) >= 0
+ && ((Text) text).getLength() >= (index + offset)
+ && ((Text) text).getLength() >= index);
+ return validText(text);
+ } catch (Exception e) {
+ // "error", "Error in validStringIndex"
+ if (ALERT) {
+ PDPlugin
+ .getAlerts()
+ .confirm(
+ "Alert.EditValidateUtil.Title", "Alert.EditValidateUtil.IndexOffset", e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (REPORT) {
+ // "Invalid index or offset in String:"
+ _logger.error("Error.EditValidateUtil.IndexOffset", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+ }
+
+ public static void dumpPosition(String message, IDOMPosition position,
+ boolean forward) {
+ // for future internal debug
+ // message(message);
+ // _logger.debug("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
+ // if (position != null)
+ // {
+ // Node container = position.getContainerNode();
+ // Node node = null;
+ // String text = null;
+ // if (getContainerLength(container) > 0)
+ // {
+ // if (!position.isText())
+ // {
+ // int index = forward ? position.getOffset() : position.getOffset() -
+ // 1;
+ // node = container.getChildNodes().item(index);
+ // }
+ // else
+ // {
+ // int index = forward ? position.getOffset() : position.getOffset() -
+ // 1;
+ // if (index >= 0 && index < getContainerLength(container))
+ // {
+ // text = ((Text) container).substringData(index, 1);
+ // }
+ // else
+ // {
+ // text = null;
+ // }
+ // }
+ // }
+ // _logger.debug("DOMPosition type?:" + (position instanceof
+ // DOMPosition) + " container name: " +
+ // position.getContainerNode().getLocalName() + " offset:" +
+ // position.getOffset()
+ // + " length:" + getContainerLength(position.getContainerNode()));
+ // if (node != null)
+ // {
+ // _logger.debug("node to operate:" + node.getLocalName());
+ // }
+ // if (text != null)
+ // {
+ // _logger.debug("text to operate:\"" + text + "\" length:" +
+ // text.length());
+ // }
+ // }
+ // _logger.debug("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+ }
+
+ private static int getContainerLength(Node node) {
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ return ((Text) node).getLength();
+ } else {
+ if (node.hasChildNodes()) {
+ return node.getChildNodes().getLength();
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ private static void message(String text) {
+ // internal debug
+ _logger.info("+++++ message:" + text);
+ }
+
+ public static boolean isValidForEditing(IDOMPosition pos, boolean forward) {
+ try {
+ if (pos == null) {
+ return false;
+ }
+ if (pos.isText()) {
+ return true;
+ } else {
+ Node container = pos.getContainerNode();
+ // only head can't be edited
+ if (EditModelQuery.isChild(IHTMLConstants.TAG_HEAD, container,
+ true)) {
+ return false;
+ }
+ Node sibling = EditModelQuery.getInstance().getSibling(pos,
+ forward);
+ if (sibling != null) {
+ if (EditModelQuery.isText(sibling)) {
+ return true;
+ }
+ Assert.isTrue(sibling.getLocalName() != null);
+ if (EditModelQuery.UNREMOVEBLE_TAGS.contains(sibling
+ .getLocalName().toLowerCase())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public static boolean isValidForEditing(Node node) {
+ if (EditModelQuery.isChild(IHTMLConstants.TAG_HEAD, node, true)) {
+ return false;
+ }
+ return true;
+ }
+
+ // Reserved for inner use.
+ //
+ // private static void errorNotice()
+ // {
+ // try
+ // {
+ // // FileInputStream fileau = new
+ // FileInputStream("C:\\WINNT\\Media\\ringout.wav");
+ // // AudioStream as = new AudioStream(fileau);
+ // // AudioPlayer.player.start(as);
+ // }
+ // catch (Exception e)
+ // {
+ // System.out.println("error in file open");
+ // }
+ //
+ // }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMPosition.java
new file mode 100644
index 000000000..bbff70600
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMPosition.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.w3c.dom.Node;
+
+/**
+ * An IDOMPosition represents a position in the DOM tree. There are multiple
+ * ways of identify a position in the tree, such as by saying a offset in
+ * parent, or before/after a particular node.
+ *
+ * NOTE: IDOMPosition and its child class should be implemented as literal. that
+ * is, they should not be changed after it is constructed.
+ *
+ * @author mengbo
+ */
+public interface IDOMPosition {
+ /**
+ *
+ * @param forward
+ * if true, same as getNextSiblingNode(), if false, same as
+ * getPreviousSiblingNode
+ * @return
+ */
+ public Node getSibling(boolean forward);
+
+ public Node getNextSiblingNode();
+
+ public Node getPreviousSiblingNode();
+
+ public Node getContainerNode();
+
+ public int getOffset();
+
+ public boolean isText();
+
+ /**
+ * "original" has been replace by "replacement" in the model. If this
+ * replacement will affect this IDOMPosition, then this method should return
+ * a new position that is valid after the replacement. If this replacement
+ * won't affect this position, then the original position should be
+ * returned.
+ *
+ * @param original
+ * @param replacement
+ * @return
+ */
+ public IDOMPosition handleReplacement(Node original, Node replacement);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMRefPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMRefPosition.java
new file mode 100644
index 000000000..0a57462b9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/IDOMRefPosition.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import org.w3c.dom.Node;
+
+/**
+ * A IDOMRefPosition locate a position by reference a node in the dom tree. It
+ * mean a position after node, before a node, or before anything in a node, or
+ * after anything in a node.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IDOMRefPosition extends IDOMPosition {
+ /**
+ *
+ * @return
+ */
+ public Node getReferenceNode();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/JSFValidatorSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/JSFValidatorSupport.java
new file mode 100644
index 000000000..fb1be85d7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/JSFValidatorSupport.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import javax.xml.namespace.QName;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.utils.BodyHelper;
+import org.eclipse.jst.pagedesigner.validation.caret.JSFRootContainerPositionRule;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * This is a temparary class, for automatically insert "view" and "form" tag
+ * when user drag from palette those controls that need them. it is still pretty
+ * hardcoded, in the future we may need some extendable mechanism.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class JSFValidatorSupport {
+ static private QName _qnameView = new QName(IJMTConstants.URI_JSF_CORE,
+ IJSFConstants.TAG_VIEW);
+
+ static private QName _qnameForm = new QName(IJMTConstants.URI_JSF_HTML,
+ IJSFConstants.TAG_FORM);
+
+ static private QName[] _views = new QName[] { _qnameView,
+ new QName(IJMTConstants.URI_JSF_CORE, IJSFConstants.TAG_SUBVIEW) };
+
+ /**
+ * If not inside a view/subview, then f:view will be created. If
+ * generateHForm is true, then will also generate h:form is no one exists.
+ *
+ * @param position
+ * @param uri
+ * @param tagName
+ * @param generateHForm
+ * @return
+ */
+ public static IDOMPosition prepareInsertJSFComponent(IDOMPosition position,
+ String uri, String tagName, boolean generateHForm) {
+ position = prepareView(position, uri, tagName);
+ if (position == null) {
+ return null;
+ }
+
+ if (generateHForm) {
+ return prepareForm(position);
+ } else {
+ return position;
+ }
+ }
+
+ /**
+ * @param position
+ * @param uri
+ * @param localname
+ * @return
+ */
+ public static IDOMPosition prepareInsertJSFComponent(IDOMPosition position,
+ String uri, String localname) {
+ return prepareInsertJSFComponent(position, uri, localname, false);
+ }
+
+ public static IDOMPosition prepareForm(IDOMPosition position) {
+ boolean hasform = ValidatorSupport.checkContainer(position, _qnameForm);
+ IDOMPosition newPosition = position;
+ if (!hasform) {
+ newPosition = ValidatorSupport
+ .insertContainer(position, _qnameForm);
+ if (newPosition == null) {
+ newPosition = position;
+ }
+ }
+ return newPosition;
+ }
+
+ /**
+ * If there is no view created, create one; If view exists, the caret
+ * movement rules will ensured the position is within view.
+ *
+ * @param position
+ * @return
+ */
+ public static IDOMPosition prepareView(IDOMPosition position, String uri,
+ String localname) {
+ Node view = null;
+ Document document = EditModelQuery.getDocumentNode(position
+ .getContainerNode());
+ if ((view = JSFRootContainerPositionRule.getBasicContainer(document)) == null) {
+ if (!(IJSFConstants.TAG_VIEW.equals(localname))) {
+ position = BodyHelper.insertBody(position, _qnameView, "f");
+ }
+ } else if (IJSFConstants.TAG_VIEW.equals(localname)) {
+ position = null;
+ }
+
+ return position;
+ }
+
+ /**
+ * @param position
+ * @return
+ */
+ public static IDOMPosition prepareView(IDOMPosition position) {
+ return prepareView(position, null, null);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/ValidatorSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/ValidatorSupport.java
new file mode 100644
index 000000000..340b67cdf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/ValidatorSupport.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom;
+
+import javax.xml.namespace.QName;
+
+import org.eclipse.jst.pagedesigner.adapters.IBodyInfo;
+import org.eclipse.jst.pagedesigner.adapters.internal.BodyInfo;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.jst.pagedesigner.utils.CommandUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * Simple utility class.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class ValidatorSupport {
+ public static boolean checkContainer(IDOMPosition position, QName qname) {
+ return checkContainer(position, new QName[] { qname });
+ }
+
+ public static boolean checkContainer(IDOMPosition position, QName qname[]) {
+ Node node = position.getContainerNode();
+ while (node != null) {
+ if (node instanceof Text) {
+ node = node.getParentNode();
+ continue;
+ }
+ if (node instanceof Element) {
+ Element ele = (Element) node;
+ String url = CMUtil.getElementNamespaceURI(ele);
+ String tag = ele.getLocalName();
+
+ for (int i = 0; i < qname.length; i++) {
+ if (tag.equalsIgnoreCase(qname[i].getLocalPart())) {
+ if (url == null) {
+ // this means something wrong. To be error tolerant,
+ // we treat it
+ // as if url is same
+ return true;
+ } else if (url.equals(qname[i].getNamespaceURI())) {
+ return true;
+ }
+ }
+ }
+
+ node = node.getParentNode();
+ continue;
+ }
+ break;
+ }
+ return false;
+ }
+
+ public static IDOMPosition insertContainer(IDOMPosition position,
+ QName container) {
+ PaletteItemDescriptor itemDes = new PaletteItemDescriptor();
+ itemDes.setURI(container.getNamespaceURI());
+ itemDes.setTagName(container.getLocalPart());
+ itemDes.setDefaultPrefix("h");
+ IDOMModel model = ((IDOMNode) position.getContainerNode()).getModel();
+ Element form = CommandUtil.excuteInsertion(itemDes, model, position);
+ if (form != null) {
+ DOMPosition pos = new DOMPosition(form, 0);
+ return pos;
+ } else {
+ return null;
+ }
+ }
+
+ public static IBodyInfo getBodyInfo() {
+ return BodyInfo.getInstance();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/ColStructure.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/ColStructure.java
new file mode 100644
index 000000000..b2495a88f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/ColStructure.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom.html;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ColStructure implements Comparable {
+ private int _column;
+
+ private int _colSpan;
+
+ public ColStructure(int column, int colSpan) {
+ this._column = column;
+ this._colSpan = colSpan;
+ }
+
+ public int getColSpan() {
+ return _colSpan;
+ }
+
+ public void setColSpan(int colSpan) {
+ this._colSpan = colSpan;
+ }
+
+ public int getColumn() {
+ return _column;
+ }
+
+ public void setColumn(int column) {
+ this._column = column;
+ }
+
+ public int compareTo(Object o) {
+ ColStructure cs = (ColStructure) o;
+ if (this._column > cs.getColumn()) {
+ return 1;
+ } else if (this._column == cs.getColumn()) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableChildElementPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableChildElementPosition.java
new file mode 100644
index 000000000..1b290efbf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableChildElementPosition.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom.html;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableChildElementPosition {
+ private int _rowIndex = -10;
+
+ private int _columnIndex = -10;
+
+ /**
+ * @return Returns the _columnIndex.
+ */
+ public int getColumnIndex() {
+ return _columnIndex;
+ }
+
+ /**
+ * @param index
+ * The _columnIndex to set.
+ */
+ public void setColumnIndex(int index) {
+ _columnIndex = index;
+ }
+
+ /**
+ * @return Returns the _rowIndex.
+ */
+ public int getRowIndex() {
+ return _rowIndex;
+ }
+
+ /**
+ * @param index
+ * The _rowIndex to set.
+ */
+ public void setRowIndex(int index) {
+ _rowIndex = index;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableUtil.java
new file mode 100644
index 000000000..dbcd45781
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/dom/html/TableUtil.java
@@ -0,0 +1,531 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.dom.html;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableUtil {
+ private Element _fakeCell = null;
+
+ private Element _table = null;
+
+ private List[] _trCellLists = null;
+
+ /**
+ * judge whether there is rowspan>1 cell in the tr
+ *
+ * @param tr
+ * TR element in a table
+ * @return
+ */
+ public static boolean hasRowSpanElement(Element tr) {
+ List list = DOMUtil.getElementChildren(tr);
+ Iterator itr = list.iterator();
+ while (itr.hasNext()) {
+ Element ele = (Element) itr.next();
+ int value = DOMUtil.getIntAttributeIgnoreCase(ele,
+ IHTMLConstants.ATTR_ROWSPAN, 1);
+ if (value > 1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * judge whether a tr is affected by row span cell in the previous trs.
+ *
+ * @param trList
+ * list holds all tr elements in a table
+ * @param tr
+ * @param index
+ * tr index in the DOM tree
+ * @return
+ */
+ public static boolean isAffectedByRowSpan(List trList, Element tr, int index) {
+ Node parent = tr.getParentNode();
+ int dex = index;
+ while (--dex >= 0) {
+ Element preTr = (Element) trList.get(dex);
+ if (preTr.getParentNode() != parent) {
+ break;
+ } else {
+ int maxRowSpan = countMaxRowSpan(preTr);
+ if (maxRowSpan > (index - dex)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * count all tr in the table
+ *
+ * @param element
+ * table
+ * @param list
+ * list to hold tr elements
+ */
+ public static void getTrElements(Element element, List list) {
+ NodeList nodeList = element.getChildNodes();
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node node = nodeList.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element ele = (Element) node;
+ if (ele.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_TR)) {
+ list.add(ele);
+ } else if (ele.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_THEAD)
+ || ele.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_TBODY)
+ || ele.getNodeName().equalsIgnoreCase(
+ IHTMLConstants.TAG_TFOOT)) {
+ getTrElements(ele, list);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * count row index in the code DOM tree according to the display index
+ *
+ * @param table
+ * @param displayIndex
+ * @return
+ */
+ public static int countRowIndexInDOMTree(Element table, int displayIndex) {
+
+ int footRows = countSectionRows(table, IHTMLConstants.TAG_TFOOT);
+ if (footRows == 0) {
+ return displayIndex;
+ }
+ int headRows = countSectionRows(table, IHTMLConstants.TAG_THEAD);
+ List list = new ArrayList();
+ getTrElements(table, list);
+ int bodyRows = list.size() - headRows - footRows;
+ // if display index is in TFOOT area
+ if (displayIndex >= (list.size() - footRows)) {
+ int index = displayIndex - bodyRows;
+ return index;
+ }
+ // if display index is in TBODY area
+ else if (displayIndex >= headRows) {
+ int index = displayIndex + footRows;
+ return index;
+ }
+ // if display index is in THEAD area
+ else {
+ return displayIndex;
+ }
+ }
+
+ /**
+ * get row count in the specified section
+ *
+ * @param table
+ * @param sectionName
+ * child element name of table, like THEAD or TFOOT
+ * @return
+ */
+ public static int countSectionRows(Element table, String sectionName) {
+ NodeList nodeList = table.getChildNodes();
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node node = nodeList.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element ele = (Element) node;
+ if (node.getNodeName().equalsIgnoreCase(sectionName)) {
+ List list = DOMUtil.getChildElementsByTagIgnoreCase(ele,
+ IHTMLConstants.TAG_TR);
+ if (list != null) {
+ return list.size();
+ }
+ }
+ }
+
+ }
+ return 0;
+ }
+
+ /**
+ * constructor
+ *
+ * @param table
+ */
+ public TableUtil(Element table) {
+ this._table = table;
+ this._trCellLists = fillTrCells();
+ }
+
+ /**
+ * get tr cells list
+ *
+ * @return
+ */
+ public List[] getTrCellLists() {
+ return this._trCellLists;
+ }
+
+ /**
+ * calculate row and column index for tr or td/th
+ *
+ * @param element
+ * tr or td/th
+ * @return
+ */
+ public TableChildElementPosition getPosition(Node node) {
+ TableChildElementPosition position = new TableChildElementPosition();
+ String tagName = node.getLocalName();
+ if (IHTMLConstants.TAG_TR.equalsIgnoreCase(tagName)) {
+ List list = new ArrayList();
+ getTrElements(this._table, list);
+ for (int i = 0, size = list.size(); i < size; i++) {
+ Element tr = (Element) list.get(i);
+ if (tr == node) {
+ position.setRowIndex(i);
+ break;
+ }
+ }
+ } else if (IHTMLConstants.TAG_TD.equalsIgnoreCase(tagName)
+ || IHTMLConstants.TAG_TH.equalsIgnoreCase(tagName)) {
+ Element tr = (Element) node.getParentNode();
+ TableChildElementPosition pos = getPosition(tr);
+ position.setRowIndex(pos.getRowIndex());
+ List[] lists = getTrCellLists();
+ List list = lists[pos.getRowIndex()];
+ for (int i = 0, size = list.size(); i < size; i++) {
+ Element td = (Element) list.get(i);
+ if (td == node) {
+ position.setColumnIndex(i);
+ break;
+ }
+ }
+ } else {
+ boolean hasTDParent = false;
+ Node childBackup = node;
+ while (!IHTMLConstants.TAG_TABLE.equalsIgnoreCase(childBackup
+ .getParentNode().getLocalName())) {
+ childBackup = childBackup.getParentNode();
+ String localName = childBackup.getLocalName();
+ if (IHTMLConstants.TAG_TD.equalsIgnoreCase(localName)
+ || IHTMLConstants.TAG_TH.equalsIgnoreCase(localName)) {
+ hasTDParent = true;
+ break;
+ }
+ }
+ if (hasTDParent) {
+ position = getPosition(childBackup);
+ }
+ }
+ return position;
+ }
+
+ /**
+ * get column count
+ *
+ * @return
+ */
+ public int getColumnCount() {
+ List[] lists = this._trCellLists;
+ if (lists != null) {
+ int max = 0;
+ for (int i = 0, size = lists.length; i < size; i++) {
+ List list = lists[i];
+ if (list.size() > max) {
+ max = list.size();
+ }
+ }
+ return max;
+ }
+ return 0;
+ }
+
+ /**
+ * judge whether there is columnspan>1 cell in the column
+ *
+ * @param columnIndex
+ * column index in a table
+ * @return
+ */
+ public boolean hasColumnSpanElement(int columnIndex) {
+ List cells = getColumnCells(columnIndex);
+ if (cells != null) {
+ Iterator itr = cells.iterator();
+ while (itr.hasNext()) {
+ Element cell = (Element) itr.next();
+ int value = DOMUtil.getIntAttributeIgnoreCase(cell,
+ IHTMLConstants.ATTR_COLSPAN, 1);
+ if (value > 1) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * judge whether the column has cell affected by column span cell in
+ * privious columns
+ *
+ * @param columnIndex
+ * @return
+ */
+ public boolean isAffectedByColSpan(int columnIndex) {
+ int index = columnIndex;
+ while (--index >= 0) {
+ List cells = getColumnCells(index);
+ int max = countMaxColSpan(cells);
+ if (max > (columnIndex - index)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * get cells in the specified column of the table
+ *
+ * @param columnIndex
+ * @return
+ */
+ public List getColumnCells(int columnIndex) {
+ List list = new ArrayList();
+
+ List[] lists = this._trCellLists;
+ for (int i = 0; i < lists.length; i++) {
+ List tempList = lists[i];
+ if (tempList.size() <= columnIndex) {
+ continue;
+ }
+ list.add(tempList.get(columnIndex));
+ }
+ return list;
+ }
+
+ /**
+ * count max row span in the tr
+ *
+ * @param tr
+ * @return
+ */
+ private static int countMaxRowSpan(Element tr) {
+ List list = DOMUtil.getElementChildren(tr);
+ int max = countMaxValue(list, IHTMLConstants.ATTR_ROWSPAN);
+ return max;
+ }
+
+ /**
+ * count max attr value
+ *
+ * @param list
+ * @param attr
+ * @return
+ */
+ private static int countMaxValue(List list, String attr) {
+ int max = 1;
+ Iterator itr = list.iterator();
+ while (itr.hasNext()) {
+ Element ele = (Element) itr.next();
+ int value = DOMUtil.getIntAttributeIgnoreCase(ele, attr, 1);
+ if (value > max) {
+ max = value;
+ }
+ }
+ return max;
+ }
+
+ /**
+ * count max col span in a column
+ *
+ * @param list
+ * @return
+ */
+ private int countMaxColSpan(List list) {
+ int max = countMaxValue(list, IHTMLConstants.ATTR_COLSPAN);
+ return max;
+ }
+
+ /**
+ * get fake element to fill tr cell
+ *
+ * @return
+ */
+ private Element getFakeElement() {
+ if (_fakeCell != null) {
+ return _fakeCell;
+ }
+ _fakeCell = this._table.getOwnerDocument().createElement("fake");
+ return _fakeCell;
+ }
+
+ /**
+ * initial every tr cells according to th and td under each tr element
+ *
+ * @param trList
+ * @return
+ */
+ private List[] initialTrCells(List trList) {
+ int size = trList.size();
+ List[] lists = new ArrayList[size];
+
+ if (trList != null) {
+ for (int i = 0, n = trList.size(); i < n; i++) {
+ lists[i] = new ArrayList();
+ Element tr = (Element) trList.get(i);
+ List domCells = DOMUtil.getElementChildren(tr);
+ Iterator itr = domCells.iterator();
+ while (itr.hasNext()) {
+ Element cell = (Element) itr.next();
+ lists[i].add(cell);
+ int colSpan = DOMUtil.getIntAttributeIgnoreCase(cell,
+ IHTMLConstants.ATTR_COLSPAN, 1);
+ while (--colSpan > 0) {
+ Element fakeElement = getFakeElement();
+ lists[i].add(fakeElement);
+ }
+ }
+ }
+
+ }
+
+ return lists;
+
+ }
+
+ /**
+ * after initial tr cells,fill tr with fake cells if necessary.
+ *
+ * @return
+ */
+ private List[] fillTrCells() {
+ List list = new ArrayList();
+ getTrElements(this._table, list);
+
+ List[] lists = initialTrCells(list);
+ int size = lists.length;
+
+ int headRows = countSectionRows(this._table, IHTMLConstants.TAG_THEAD);
+ if (headRows > 0) {
+ List[] headList = new ArrayList[headRows];
+ for (int i = 0; i < headRows; i++) {
+ headList[i] = lists[i];
+ }
+ fillSectionTrCells(headList);
+ }
+
+ int footRows = countSectionRows(this._table, IHTMLConstants.TAG_TFOOT);
+ if (footRows > 0) {
+ List[] footList = new ArrayList[footRows];
+ for (int i = 0; i < footRows; i++) {
+ footList[i] = lists[headRows + i];
+ }
+ fillSectionTrCells(footList);
+ }
+
+ int bodyRows = size - headRows - footRows;
+ if (bodyRows > 0) {
+ int bodyCount = 1;
+ int k = 0;
+ List bodys = new ArrayList();
+ Element tr = (Element) list.get(headRows + footRows);
+ Node node = tr.getParentNode();
+ for (int i = 1; i < bodyRows; i++) {
+ Element tempTr = (Element) list.get(headRows + footRows + i);
+ if (tempTr.getParentNode() != node) {
+ node = tempTr.getParentNode();
+ bodys.add(new Integer(i - k));
+ k = i;
+ bodyCount++;
+ }
+ }
+ bodys.add(new Integer(bodyRows - k));
+
+ for (int j = 0; j < bodyCount; j++) {
+ int num = ((Integer) bodys.get(j)).intValue();
+ List[] bodyList = new ArrayList[num];
+ int m = headRows + footRows;
+
+ for (int i = 0; i < num; i++) {
+ bodyList[i] = lists[m + i];
+ }
+ fillSectionTrCells(bodyList);
+ m = m + num;
+ }
+
+ }
+
+ return lists;
+ }
+
+ /**
+ * fill tr cells under each table section,like THEAD,TFOOT,TBODY.
+ *
+ * @param lists
+ */
+ private void fillSectionTrCells(List[] lists) {
+ Element cell = null;
+
+ if (lists != null) {
+ for (int i = 1, size = lists.length; i < size; i++) {
+ List insertPoints = new ArrayList();
+
+ for (int j = 0; j < i; j++) {
+ List list = lists[j];
+ for (int column = 0; column < list.size(); column++) {
+ cell = (Element) list.get(column);
+ if (cell.getTagName().equalsIgnoreCase("fake")) {
+ continue;
+ }
+ int rowSpan = DOMUtil.getIntAttributeIgnoreCase(cell,
+ IHTMLConstants.ATTR_ROWSPAN, 1);
+ if (rowSpan > (i - j)) {
+ int colSpan = DOMUtil.getIntAttributeIgnoreCase(
+ cell, IHTMLConstants.ATTR_COLSPAN, 1);
+ insertPoints.add(new ColStructure(column, colSpan));
+ }
+ }
+ }
+ // there are fake column cell need to be inserted into this tr
+ if (insertPoints.size() > 0) {
+ Collections.sort(insertPoints);
+ List trCells = lists[i];
+
+ Iterator itr = insertPoints.iterator();
+ while (itr.hasNext()) {
+ ColStructure cls = (ColStructure) itr.next();
+ int loop = cls.getColSpan();
+ int column = cls.getColumn();
+ while (loop-- != 0) {
+ trCells.add(column++, getFakeElement());
+ }
+
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/DesignerStructuredTextEditorJSP.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/DesignerStructuredTextEditorJSP.java
new file mode 100644
index 000000000..f4013ce24
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/DesignerStructuredTextEditorJSP.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jst.pagedesigner.dnd.internal.DesignerSourceDropTargetListener;
+import org.eclipse.ui.texteditor.ITextEditorDropTargetListener;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+
+/**
+ * @author mengbo
+ */
+public class DesignerStructuredTextEditorJSP extends StructuredTextEditor {
+ protected void initializeDrop(ITextViewer textViewer) {
+ // It seems if we don't skip this method, our drag drop listener will
+ // can't be enabled.
+ }
+
+ public IAction getAction(String actionID) {
+ try {
+ return super.getAction(actionID);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public Object getAdapter(Class required) {
+ if (ITextEditorDropTargetListener.class.equals(required)) {
+ DesignerSourceDropTargetListener listener = new DesignerSourceDropTargetListener(
+ (StructuredTextEditor) this);
+ return listener;
+ } else {
+ return super.getAdapter(required);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/HTMLEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/HTMLEditor.java
new file mode 100644
index 000000000..836489d52
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/HTMLEditor.java
@@ -0,0 +1,1009 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+
+import org.eclipse.core.internal.resources.ResourceException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.gef.DefaultEditDomain;
+import org.eclipse.gef.ui.palette.PaletteViewerProvider;
+import org.eclipse.gef.ui.views.palette.PalettePage;
+import org.eclipse.gef.ui.views.palette.PaletteViewerPage;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.dnd.internal.DesignerSourceMouseTrackAdapter;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.editors.palette.DesignerPaletteRoot;
+import org.eclipse.jst.pagedesigner.editors.palette.DesignerPaletteViewerProvider;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.IPageVariablesProvider;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.adapter.IDocumentPageVariableAdapter;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.preview.PreviewHandlerNew;
+import org.eclipse.jst.pagedesigner.preview.WindowsIEBrowser;
+import org.eclipse.jst.pagedesigner.tools.RangeSelectionTool;
+import org.eclipse.jst.pagedesigner.ui.common.PartActivationHandler;
+import org.eclipse.jst.pagedesigner.ui.common.sash.SashEditorPart;
+import org.eclipse.jst.pagedesigner.utils.PreviewUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IGotoMarker;
+import org.eclipse.ui.part.MultiPageSelectionProvider;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySheetPageContributor;
+import org.eclipse.wst.common.ui.provisional.editors.PostMultiPageEditorSite;
+import org.eclipse.wst.common.ui.provisional.editors.PostMultiPageSelectionProvider;
+import org.eclipse.wst.common.ui.provisional.editors.PostSelectionMultiPageEditorPart;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.sse.ui.internal.IExtendedMarkupEditor;
+import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.ui.internal.provisional.IDOMSourceEditingTextTools;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * The HTMLEditor is a multi paged editor. It will use the StructuredTextEditor
+ * as the chief editor, and delegate most operations to it.
+ *
+ * @author mengbo
+ */
+public class HTMLEditor extends PostSelectionMultiPageEditorPart implements
+ IPropertyListener, ITabbedPropertySheetPageContributor {
+ // private static final String PAGE_NAME_DESIGN = "Design"; //$NON-NLS-1$
+ // private static final String PAGE_NAME_SOURCE = "Source"; //$NON-NLS-1$
+ private final static String CONTRIBUTOR_ID = "org.eclipse.jst.pagedesigner.pageDesigner.tabPropertyContributor"; //$NON-NLS-1$
+
+ // four different modes for the designer when displayed in a sash editor.
+ public static final int MODE_SASH_VERTICAL = 0;
+
+ public static final int MODE_SASH_HORIZONTAL = 1;
+
+ public static final int MODE_DESIGNER = 2;
+
+ public static final int MODE_SOURCE = 3;
+
+ private Logger _log = PDPlugin.getLogger(HTMLEditor.class);
+
+ private boolean _sash = true;
+
+ private int _mode = 0;
+
+ private SashEditorPart _sashEditorPart = null;
+
+ private int _previewPageIndex;
+
+ /** The design viewer */
+ private SimpleGraphicalEditor _designViewer;
+
+ /** The text editor. */
+ private StructuredTextEditor _textEditor;
+
+ private PartActivationHandler _partListener;
+
+ private PaletteViewerPage _paletteViewerPage;
+
+ private DefaultEditDomain _editDomain;
+
+ private WindowsIEBrowser _browser;
+
+ private class TextInputListener implements ITextInputListener {
+ public void inputDocumentAboutToBeChanged(IDocument oldInput,
+ IDocument newInput) {
+ }
+
+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ if (_designViewer != null && newInput != null)
+ _designViewer.setModel(getModel());
+ }
+ }
+
+ public HTMLEditor() {
+ super();
+ }
+
+ /*
+ * This method is just to make firePropertyChanged accessbible from some
+ * (anonomous) inner classes.
+ */
+ protected void _firePropertyChange(int property) {
+ super.firePropertyChange(property);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.xtools.common.ui.properties.ITabbedPropertySheetPageContributor#getContributorId()
+ */
+ public String getContributorId() {
+ return CONTRIBUTOR_ID;
+ }
+
+ private void connectSashPage() {
+ ISelectionProvider selectionProvider = _sashEditorPart.getSite()
+ .getSelectionProvider();
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) selectionProvider)
+ .addPostSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ ((PostMultiPageSelectionProvider) getSite()
+ .getSelectionProvider())
+ .firePostSelectionChanged(event);
+ }
+ });
+ } else {
+ selectionProvider
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ ((MultiPageSelectionProvider) getSite()
+ .getSelectionProvider())
+ .fireSelectionChanged(event);
+ }
+ });
+ }
+ }
+
+ /**
+ * Creates the source page of the multi-page editor.
+ */
+ protected void sash_createAndAddDesignSourcePage() throws PartInitException {
+ // create source page
+ _textEditor = createTextEditor();
+ _textEditor.setEditorPart(this);
+ _textEditor.addPropertyListener(this);
+ // create design page
+ _designViewer = new SimpleGraphicalEditor(this, getEditDomain());
+
+ // create SashEditor
+ _sashEditorPart = new SashEditorPart() {
+ protected void createPages() throws PartInitException {
+ addPage(_designViewer, getEditorInput());
+ addPage(_textEditor, getEditorInput());
+ }
+ };
+ int sashIndex = addPage(_sashEditorPart, getEditorInput());
+
+ setPageText(sashIndex, PDPlugin.getResourceString("HTMLEditor.Design"));
+
+ // the update's critical, to get viewer selection manager and
+ // highlighting to work
+ _textEditor.update();
+
+ firePropertyChange(PROP_TITLE);
+
+ // Changes to the Text Viewer's document instance should also force an
+ // input refresh
+ // _textEditor.getTextViewer().addTextInputListener(new
+ // TextInputListener());
+ connectSashPage();
+ }
+
+ /**
+ * @see org.eclipse.ui.part.MultiPageEditorPart#createSite(org.eclipse.ui.IEditorPart)
+ */
+ protected IEditorSite createSite(IEditorPart editor) {
+ return new PostMultiPageEditorSite(this, editor);
+ }
+
+ protected void tabbed_createAndAddDesignSourcePage()
+ throws PartInitException {
+ // create source page
+ _textEditor = createTextEditor();
+ _textEditor.setEditorPart(this);
+ _textEditor.addPropertyListener(this);
+
+ // create design page
+ SimpleGraphicalEditor editor = new SimpleGraphicalEditor(this,
+ getEditDomain());
+
+ // add design page
+ int designPageIndex = addPage(editor, null);
+
+ _designViewer = editor;
+ // // note: By adding the design page as a Control instead of an
+ // // IEditorPart, page switches will indicate
+ // // a "null" active editor when the design page is made active
+ setPageText(designPageIndex, PDPlugin
+ .getResourceString("HTMLEditor.Design"));
+
+ // add source page
+ int sourcePageIndex = addPage(_textEditor, getEditorInput());
+ setPageText(sourcePageIndex, PDPlugin
+ .getResourceString("HTMLEditor.Source"));
+ // the update's critical, to get viewer selection manager and
+ // highlighting to work
+ _textEditor.update();
+
+ firePropertyChange(PROP_TITLE);
+
+ // Changes to the Text Viewer's document instance should also force an
+ // input refresh
+ // _textEditor.getTextViewer().addTextInputListener(new
+ // TextInputListener());
+ }
+
+ protected void createAndAddPreviewPage() throws PartInitException {
+ Composite composite = new Composite(getContainer(), 0);
+ FillLayout filllayout = new FillLayout();
+ composite.setLayout(filllayout);
+ _browser = new WindowsIEBrowser();
+ if (_browser != null) {
+ _browser.create(composite, SWT.NONE);
+ _previewPageIndex = addPage(composite);
+ // JSPSourceEditor.Page.Preview.PageText=Preview
+ setPageText(_previewPageIndex, PageDesignerResources.getInstance()
+ .getString("JSPSourceEditor.Page.Preview.PageText")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Connects the design viewer with the viewer selection manager. Should be
+ * done after createSourcePage() is done because we need to get the
+ * ViewerSelectionManager from the TextEditor. setModel is also done here
+ * because getModel() needs to reference the TextEditor.
+ */
+ protected void connectDesignPage() {
+ if (_designViewer != null) {
+ _designViewer.setModel(getModel());
+ // _designViewer.getSynchronizer().listenToModel(getModel());
+ ISelectionProvider designSelectionProvider = _designViewer
+ .getSite().getSelectionProvider();
+ if (designSelectionProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) designSelectionProvider)
+ .addPostSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(
+ SelectionChangedEvent event) {
+ if (getActiveEditor() != _textEditor) {
+ _designViewer.getSynchronizer()
+ .selectionChanged(event);
+ }
+ }
+ });
+ } else {
+ designSelectionProvider
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(
+ SelectionChangedEvent event) {
+ if (getActiveEditor() != _textEditor) {
+ _designViewer.getSynchronizer()
+ .selectionChanged(event);
+ }
+ }
+ });
+ }
+ ISelectionProvider textSelectionProvider = _textEditor.getSite()
+ .getSelectionProvider();
+ if (textSelectionProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) textSelectionProvider)
+ .addPostSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(
+ SelectionChangedEvent event) {
+ if (event.getSelection() instanceof TextSelection) {
+ TextSelection textSelection = ((TextSelection) event
+ .getSelection());
+ _designViewer
+ .getSynchronizer()
+ .textSelectionChanged(
+ textSelection.getOffset(),
+ textSelection.getOffset()
+ + textSelection
+ .getLength());
+ }
+ }
+ });
+ } else {
+ textSelectionProvider
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(
+ SelectionChangedEvent event) {
+ TextSelection textSelection = ((TextSelection) event
+ .getSelection());
+ _designViewer.getSynchronizer()
+ .textSelectionChanged(
+ textSelection.getOffset(),
+ textSelection.getOffset()
+ + textSelection
+ .getLength());
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Creates the pages of this multi-page editor.
+ * <p>
+ * Subclasses of <code>MultiPageEditor</code> must implement this method.
+ * </p>
+ */
+ protected void createPages() {
+ try {
+ // source page MUST be created before design page, now
+ if (_sash) {
+ sash_createAndAddDesignSourcePage();
+ } else {
+ tabbed_createAndAddDesignSourcePage();
+ }
+ connectDesignPage();
+ createAndAddPreviewPage();
+ DesignerSourceMouseTrackAdapter adapter = new DesignerSourceMouseTrackAdapter(
+ _textEditor, getEditDomain());
+ _textEditor.getTextViewer().getTextWidget().addMouseListener(
+ adapter);
+ _textEditor.getTextViewer().getTextWidget().addMouseMoveListener(
+ adapter);
+ } catch (PartInitException exception) {
+ //$NON-NLS-1$ = "An error has occurred when initializing the input for the the editor's source page."
+ if (_log != null) {
+ // throw new SourceEditingRuntimeException(
+ // "An error has occurred when initializing the input for the
+ // the editor's source page.");
+ }
+ }
+ // TODO: add a catch block here for any exception the design
+ // page throws and convert it into a more informative message.
+ }
+
+ /**
+ * Method createTextEditor.
+ *
+ * @return StructuredTextEditor
+ */
+ protected StructuredTextEditor createTextEditor() {
+ return new DesignerStructuredTextEditorJSP();
+ }
+
+ protected void disconnectDesignPage() {
+ if (_designViewer != null) {
+ _designViewer.setModel(null);
+ }
+ }
+
+ public void dispose() {
+ disconnectDesignPage();
+
+ IWorkbenchWindow window = getSite().getWorkbenchWindow();
+ window.getPartService().removePartListener(_partListener);
+ window.getShell().removeShellListener(_partListener);
+ getSite().getPage().removePartListener(_partListener);
+
+ if (_textEditor != null) {
+ _textEditor.removePropertyListener(this);
+ }
+
+ // moved to last when added window ... seems like
+ // we'd be in danger of losing some data, like site,
+ // or something.
+ super.dispose();
+
+ _log.info("Debug.HTMLEditor.0", null);
+ }
+
+ public void doSave(IProgressMonitor monitor) {
+ _textEditor.doSave(monitor);
+ }
+
+ /*
+ * (non-Javadoc) Saves the contents of this editor to another object. <p>
+ * Subclasses must override this method to implement the open-save-close
+ * lifecycle for an editor. For greater details, see <code> IEditorPart
+ * </code></p>
+ *
+ * @see IEditorPart
+ */
+ public void doSaveAs() {
+ _textEditor.doSaveAs();
+ }
+
+ private void editorInputIsAcceptable(IEditorInput input)
+ throws PartInitException {
+ if (input instanceof IFileEditorInput) {
+ // verify that it can be opened
+ CoreException[] coreExceptionArray = new CoreException[1];
+ if (fileDoesNotExist((IFileEditorInput) input, coreExceptionArray)) {
+ // todo use message formatter for {0}
+ Throwable coreException = coreExceptionArray[0];
+ if (coreException instanceof ResourceException) {
+ // I'm assuming this is always 'does not exist'
+ // we'll refresh local go mimic behavior of default
+ // editor, where the
+ // troublesome file is refreshed (and will cause it to
+ // 'disappear' from Navigator.
+ try {
+ ((IFileEditorInput) input).getFile()
+ .refreshLocal(IResource.DEPTH_ZERO,
+ new NullProgressMonitor());
+ } catch (CoreException ce) {
+ if (_log != null) {
+ _log.error("Error.HTMLEditor.0", ce); //$NON-NLS-1$
+ }
+ }
+ throw new PartInitException("Resource " + input.getName()
+ + " does not exist.");
+ } else {
+ throw new PartInitException("Editor could not be open on "
+ + input.getName());
+ }
+ }
+ } else if (input instanceof IStorageEditorInput) {
+ InputStream contents = null;
+ try {
+ contents = ((IStorageEditorInput) input).getStorage()
+ .getContents();
+ } catch (CoreException noStorageExc) {
+ // Error in geting storage contents
+ _log.error("Error.HTMLEditor.1", noStorageExc); //$NON-NLS-1$
+ }
+ if (contents == null) {
+ // throw new
+ // PartInitException(ResourceHandler.getString("32concat_EXC_",
+ // (new Object[] {
+ // input.getName()}))); //$NON-NLS-1$
+ throw new PartInitException("Editor could not be open on "
+ + input.getName());
+ } else {
+ ResourceUtils.ensureClosed(contents);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc) Initializes the editor part with a site and input. <p>
+ * Subclasses of <code> EditorPart </code> must implement this method.
+ * Within the implementation subclasses should verify that the input type is
+ * acceptable and then save the site and input. Here is sample code: </p><pre>
+ * if (!(input instanceof IFileEditorInput)) throw new
+ * PartInitException("Invalid Input: Must be IFileEditorInput");
+ * setSite(site); setInput(editorInput); </pre>
+ */
+ protected boolean fileDoesNotExist(IFileEditorInput input,
+ Throwable[] coreException) {
+ boolean result = false;
+ InputStream inStream = null;
+ if ((!(input.exists())) || (!(input.getFile().exists()))) {
+ result = true;
+ } else {
+ try {
+ inStream = input.getFile().getContents(true);
+ } catch (CoreException e) {
+ // very likely to be file not found
+ result = true;
+ coreException[0] = e;
+ // The core has exception
+ _log.error("Error.HTMLEditor.3", e); //$NON-NLS-1$
+ } finally {
+ if (input != null) {
+ ResourceUtils.ensureClosed(inStream);
+ }
+ }
+ }
+ return result;
+ }
+
+ public Object getAdapter(Class key) {
+ Object result = null;
+ if (key == IDesignViewer.class) {
+ result = _designViewer;
+ } else if (key == PalettePage.class) {
+ return getPaletteViewerPage();
+ } else if (key == IPropertySheetPage.class) {
+ // XXX: we can delegate this to the fTextEditor, but that use some
+ // more
+ // complicate mechanism, and don't work with page designer well, so
+ // do it simple now, fix later.
+ // return _textEditor.getAdapter(key);
+ return getPropertySheetPage();
+ } else if (key == IContentOutlinePage.class) {
+ if (_textEditor != null) {
+ result = _textEditor.getAdapter(key);
+ }
+ } else if (key == IPageVariablesProvider.class) {
+ Object obj = ((IDOMModel) getModel()).getDocument().getAdapterFor(
+ IDocumentPageVariableAdapter.class);
+ if (obj instanceof IPageVariablesProvider) {
+ return (IPageVariablesProvider) obj;
+ } else {
+ return null;
+ }
+ } else {
+ // DMW: I'm bullet-proofing this because
+ // its been reported (on 4.03 version) a null pointer sometimes
+ // happens here on startup, when an editor has been left
+ // open when workbench shutdown.
+ if (_textEditor != null) {
+ result = _textEditor.getAdapter(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * IExtendedMarkupEditor method XXX:No reference to the method.
+ */
+ public Node getCaretNode() {
+ if (getTextEditor() == null) {
+ return null;
+ }
+
+ ISourceEditingTextTools adapter = (ISourceEditingTextTools) _textEditor
+ .getAdapter(ISourceEditingTextTools.class);
+ if (adapter instanceof IDOMSourceEditingTextTools) {
+ IDOMSourceEditingTextTools domTools = (IDOMSourceEditingTextTools) adapter;
+ try {
+ return domTools.getNode(domTools.getCaretOffset());
+ } catch (BadLocationException e) {
+ _log.error("BadLocationException", e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * IExtendedSimpleEditor method
+ */
+ public int getCaretPosition() {
+ if (getTextEditor() == null) {
+ return -1;
+ }
+
+ // return getExtendedTextEditor().getCaretPosition();
+ Object apapter = _textEditor.getAdapter(ISourceEditingTextTools.class);
+ if (apapter != null) {
+ return ((ISourceEditingTextTools) apapter).getCaretOffset();
+ }
+ return -1;
+ }
+
+ /**
+ * IExtendedSimpleEditor method
+ */
+ public IDocument getDocument() {
+ if (getTextEditor() == null) {
+ return null;
+ }
+
+ Object apapter = _textEditor.getAdapter(ISourceEditingTextTools.class);
+ if (apapter != null) {
+ return ((ISourceEditingTextTools) apapter).getDocument();
+ }
+
+ return null;
+ }
+
+ /**
+ * IExtendedMarkupEditor method
+ */
+ public Document getDOMDocument() {
+ if (getTextEditor() == null) {
+ return null;
+ }
+
+ Object adapter = _textEditor.getAdapter(ISourceEditingTextTools.class);
+ if (adapter instanceof IDOMSourceEditingTextTools) {
+ return ((IDOMSourceEditingTextTools) adapter).getDOMDocument();
+ }
+ return null;
+ }
+
+ /**
+ * IExtendedSimpleEditor method
+ */
+ public IEditorPart getEditorPart() {
+ return this;
+ }
+
+ public IStructuredModel getModel() {
+ IStructuredModel model = null;
+ if (_textEditor != null) {
+ model = ((DesignerStructuredTextEditorJSP) _textEditor).getModel();
+ }
+ return model;
+ }
+
+ /**
+ * IExtendedMarkupEditor method
+ */
+ public List getSelectedNodes() {
+ if (getTextEditor() == null) {
+ return null;
+ }
+ // FIXME: when designer as current view, what to return?
+ return getExtendedTextEditor().getSelectedNodes();
+ }
+
+ public StructuredTextEditor getTextEditor() {
+ return _textEditor;
+ }
+
+ public IExtendedMarkupEditor getExtendedTextEditor() {
+ if (_textEditor instanceof IExtendedMarkupEditor) {
+ return (IExtendedMarkupEditor) _textEditor;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbenchPart.
+ */
+ public String getTitle() {
+ String title = null;
+ if (getTextEditor() == null) {
+ if (getEditorInput() != null) {
+ title = getEditorInput().getName();
+ }
+ } else {
+ title = getTextEditor().getTitle();
+ }
+ if (title == null) {
+ title = getPartName();
+ }
+ return title;
+ }
+
+ /*
+ * (non-Javadoc) Sets the cursor and selection state for this editor to the
+ * passage defined by the given marker. <p> Subclasses may override. For
+ * greater details, see <code> IEditorPart </code></p>
+ *
+ * @see IEditorPart
+ */
+ public void gotoMarker(IMarker marker) {
+ // (pa) 20020217 this was null when opening an editor that was
+ // already open
+ if (_textEditor != null) {
+ IGotoMarker markerGotoer = (IGotoMarker) _textEditor
+ .getAdapter(IGotoMarker.class);
+ markerGotoer.gotoMarker(marker);
+ }
+ }
+
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ super.init(site, input);
+ editorInputIsAcceptable(input);
+ try {
+ // super.init(site, input);
+ // setSite(site);
+ setInput(input);
+ if (_partListener == null) {
+ _partListener = new PartActivationHandler(this) {
+ public void handleActivation() {
+ safelySanityCheckState();
+ }
+ };
+ }
+ // we want to listen for our own activation
+ IWorkbenchWindow window = getSite().getWorkbenchWindow();
+ window.getPartService().addPartListener(_partListener);
+ window.getShell().addShellListener(_partListener);
+ } catch (Exception e) {
+ // Error in editor initialization
+ _log.error("Error.HTMLEditor.5", e); //$NON-NLS-1$
+ }
+ setPartName(input.getName());
+ }
+
+ /*
+ * (non-Javadoc) Returns whether the "save as" operation is supported by
+ * this editor. <p> Subclasses must override this method to implement the
+ * open-save-close lifecycle for an editor. For greater details, see <code>
+ * IEditorPart </code></p>
+ *
+ * @see IEditorPart
+ */
+ public boolean isSaveAsAllowed() {
+ return _textEditor != null && _textEditor.isSaveAsAllowed();
+ }
+
+ /*
+ * (non-Javadoc) Returns whether the contents of this editor should be saved
+ * when the editor is closed. <p> This method returns <code> true </code> if
+ * and only if the editor is dirty ( <code> isDirty </code> ). </p>
+ */
+ public boolean isSaveOnCloseNeeded() {
+ // overriding super class since it does a lowly isDirty!
+ if (_textEditor != null) {
+ return _textEditor.isSaveOnCloseNeeded();
+ }
+ return isDirty();
+ }
+
+ /**
+ * Posts the update code "behind" the running operation.
+ */
+ protected void postOnDisplayQue(Runnable runnable) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
+ if (windows != null && windows.length > 0) {
+ Display display = windows[0].getShell().getDisplay();
+ display.asyncExec(runnable);
+ } else {
+ runnable.run();
+ }
+ }
+
+ /**
+ * Indicates that a property has changed.
+ *
+ * @param source
+ * the object whose property has changed
+ * @param propId
+ * the id of the property which has changed; property ids are
+ * generally defined as constants on the source class
+ */
+ public void propertyChanged(Object source, int propId) {
+ switch (propId) {
+ // had to implement input changed "listener" so that
+ // strucutedText could tell it containing editor that
+ // the input has change, when a 'resource moved' event is
+ // found.
+ case IEditorPart.PROP_INPUT: {
+ if (source == _textEditor) {
+ if (_textEditor.getEditorInput() != getEditorInput()) {
+ setInput(_textEditor.getEditorInput());
+ // title should always change when input changes.
+ // create runnable for following post call
+ Runnable runnable = new Runnable() {
+ public void run() {
+ _firePropertyChange(IWorkbenchPart.PROP_TITLE);
+ }
+ };
+ // Update is just to post things on the display queue
+ // (thread). We have to do this to get the dirty
+ // property to get updated after other things on the
+ // queue are executed.
+ postOnDisplayQue(runnable);
+ }
+ }
+ break;
+ }
+ case IWorkbenchPart.PROP_TITLE: {
+ // // update the input if the title is changed. why? It seems input
+ // change event will be fired at last.
+ // if (source == _textEditor)
+ // {
+ // if (_textEditor.getEditorInput() != getEditorInput())
+ // {
+ // setInput(_textEditor.getEditorInput());
+ // }
+ // }
+ // break;
+ }
+ default: {
+ // propagate changes. Is this needed? Answer: Yes.
+ // PROP_PART_NAME, PROP_DIRTY etc.
+ if (source == _textEditor) {
+ firePropertyChange(propId);
+ }
+ break;
+ }
+ }
+
+ }
+
+ protected void safelySanityCheckState() {
+ // If we're called before editor is created, simply ignore since we
+ // delegate this function to our embedded TextEditor
+ if (getTextEditor() == null) {
+ return;
+ }
+
+ getTextEditor().safelySanityCheckState(getEditorInput());
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
+ */
+ protected void setInput(IEditorInput input) {
+ // If driven from the Source page, it's "model" may not be up to date
+ // with the input just yet. We'll rely on later notification from the
+ // TextViewer to set us straight
+ super.setInput(input);
+ if (_designViewer != null) {
+
+ _designViewer.setModel(getModel());
+ }
+ setPartName(input.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.EditorPart#isDirty()
+ */
+ public boolean isDirty() {
+ if (getTextEditor() == null) {
+ return false;
+ }
+ return getTextEditor().isDirty();
+ }
+
+ // IPropertySheetPage _propertySheetPage;
+
+ protected IPropertySheetPage getPropertySheetPage() {
+ return new org.eclipse.jst.pagedesigner.properties.DesignerTabbedPropertySheetPage(
+ this, this);
+ }
+
+ protected PaletteViewerPage getPaletteViewerPage() {
+ if (null == _paletteViewerPage) {
+ DefaultEditDomain editDomain = getEditDomain();
+ PaletteItemManager manager = PaletteItemManager
+ .getInstance(getCurrentProject(getEditorInput()));
+ manager.reset();
+ editDomain.setPaletteRoot(new DesignerPaletteRoot(manager));
+
+ PaletteViewerProvider provider = new DesignerPaletteViewerProvider(
+ editDomain);
+ _paletteViewerPage = new PaletteViewerPage(provider);
+ }
+ return _paletteViewerPage;
+ }
+
+ /**
+ * @return
+ */
+ public DefaultEditDomain getEditDomain() {
+ if (_editDomain == null) {
+ _editDomain = new DefaultEditDomain(this);
+
+ // XXX: if i don't do the following line, system will default use
+ // SelectionTool. Don't know where else to set this. Since it is
+ // kind of duplicate
+ // to the DesignerPaletteRoot.
+ _editDomain.setDefaultTool(new RangeSelectionTool());
+ _editDomain.loadDefaultTool();
+
+ // next config the _editDomain
+ // _editDomain.setPaletteRoot(new JSFPaletteRoot());
+ }
+ return _editDomain;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.MultiPageEditorPart#pageChange(int)
+ */
+ protected void pageChange(int newPageIndex) {
+ super.pageChange(newPageIndex);
+ if (newPageIndex == _previewPageIndex) {
+ // preview page activate, need to regenerate the preview text and
+ // display it.
+ StringBuffer result = new StringBuffer();
+ try {
+ // PreviewHandler.generatePreview(this.getModel(),
+ // this.getEditorInput(), result);
+ DocumentEditPart part = (DocumentEditPart) this._designViewer
+ .getGraphicViewer().getContents();
+ PreviewHandlerNew.generatePreview(part, result);
+ } catch (Exception ex) {
+ result = new StringBuffer();
+ result
+ .append(this.getModel().getStructuredDocument()
+ .getText());
+ // Error in page changing
+ _log.info("Error.HTMLEditor.6", ex); //$NON-NLS-1$
+ ex.printStackTrace();
+ }
+ File file = PreviewUtil.toFile(result, getEditorInput());
+ if (file != null) {
+ _browser.loadFile(file);
+ } else {
+ _browser.getBrowser().setUrl("about:blank"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * @return Returns the _designViewer.
+ */
+ public IDesignViewer getDesignViewer() {
+ return _designViewer;
+ }
+
+ /**
+ * @param mode
+ */
+ public void setDesignerMode(int mode) {
+ if (_sashEditorPart != null) {
+ switch (mode) {
+ case MODE_SASH_HORIZONTAL:
+ _sashEditorPart.setOrientation(SWT.HORIZONTAL);
+ break;
+ case MODE_DESIGNER:
+ _sashEditorPart.setMaximizedEditor(this._designViewer);
+ break;
+ case MODE_SOURCE:
+ _sashEditorPart.setMaximizedEditor(this._textEditor);
+ break;
+ case MODE_SASH_VERTICAL:
+ default:
+ _sashEditorPart.setOrientation(SWT.VERTICAL);
+ }
+ }
+ this._mode = mode;
+ }
+
+ public int getDesignerMode() {
+ return this._mode;
+ }
+
+ private IProject getCurrentProject(IEditorInput input) {
+ IProject curProject = null;
+ IFile inputFile = null;
+ if (input instanceof IFileEditorInput) {
+ inputFile = ((IFileEditorInput) input).getFile();
+ curProject = inputFile.getProject();
+ }
+ return curProject;
+ }
+
+ public IEditorPart getActiveEditor() {
+ IEditorPart result = null;
+ if (_sash) {
+ result = _sashEditorPart.getActiveEditor();
+ } else {
+ if (_designViewer.getGraphicViewer().getControl().isFocusControl()) {
+ result = _designViewer;
+ } else if (_textEditor.getTextViewer().getControl()
+ .isFocusControl()) {
+ result = _textEditor;
+ }
+ }
+ return result;
+ }
+
+ public String getPartName() {
+ if (_textEditor != null) {
+ return _textEditor.getPartName();
+ } else {
+ return super.getPartName();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/IDesignViewer.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/IDesignViewer.java
new file mode 100644
index 000000000..83f37be57
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/IDesignViewer.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+/**
+ * This is copied from the xmleditor plugin. Represents the design viewer that
+ * need can be used to show the design page.
+ *
+ * @author mengbo
+ */
+public interface IDesignViewer {
+ String getTitle();
+
+ void setModel(IStructuredModel model);
+
+ // void setViewerSelectionManager(ViewerSelectionManager
+ // viewerSelectionManager);
+
+ /**
+ * @return
+ */
+ public IHTMLGraphicalViewer getGraphicViewer();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/OutlineConfiguration.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/OutlineConfiguration.java
new file mode 100644
index 000000000..c667b0495
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/OutlineConfiguration.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jst.jsp.ui.views.contentoutline.JSPContentOutlineConfiguration;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+
+public class OutlineConfiguration extends JSPContentOutlineConfiguration {
+ private Object[] _selections = new Object[0];
+
+ public ISelection getSelection(TreeViewer viewer, ISelection selection) {
+ if ((viewer.getInput() instanceof IStructuredModel)
+ && (selection instanceof ITextSelection)) {
+ _selections = getSelectedObjects((IStructuredModel) viewer
+ .getInput(), (ITextSelection) selection);
+ if (_selections != null) {
+ return super.getSelection(viewer, new StructuredSelection(
+ _selections));
+ }
+ }
+ return super.getSelection(viewer, new StructuredSelection(_selections));
+ }
+
+ private Object[] getSelectedObjects(IStructuredModel model,
+ ITextSelection selection) {
+ Object[] selectedStructures = null;
+ if (model != null) {
+ IndexedRegion region = model
+ .getIndexedRegion(selection.getOffset());
+ int end = selection.getOffset() + selection.getLength();
+ if (region != null) {
+ if (end <= region.getEndOffset()) {
+ // single selection
+ selectedStructures = new Object[1];
+ selectedStructures[0] = region;
+ } else {
+ // multiple selection
+ int maxLength = model.getStructuredDocument().getLength();
+ List structures = new ArrayList(2);
+ while (region != null && region.getEndOffset() <= end
+ && region.getEndOffset() < maxLength) {
+ structures.add(region);
+ region = model
+ .getIndexedRegion(region.getEndOffset() + 1);
+ }
+ selectedStructures = structures.toArray();
+ }
+ }
+ }
+ if (selectedStructures == null) {
+ selectedStructures = new Object[0];
+ }
+ return selectedStructures;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/PageDesignerActionConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/PageDesignerActionConstants.java
new file mode 100644
index 000000000..9e17f4584
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/PageDesignerActionConstants.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import org.eclipse.gef.ui.actions.GEFActionConstants;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.ui.IWorkbenchActionConstants;
+
+/**
+ * @author mengbo
+ */
+public class PageDesignerActionConstants {
+ public static final String GROUP_UNDO = GEFActionConstants.GROUP_UNDO;
+
+ public static final String GROUP_EDIT = GEFActionConstants.GROUP_EDIT;
+
+ public static final String GROUP_CONTAINER = "org.eclipse.jst.pagedesigner.container"; //$NON-NLS-1$
+
+ public static final String GROUP_STYLE = "org.eclipse.jst.pagedesigner.style"; //$NON-NLS-1$
+
+ public static final String GROUP_SPECIAL = "org.eclipse.jst.pagedesigner.special"; //$NON-NLS-1$
+
+ public static final String MENUMGR_VIEW_ID = "org.eclipse.jst.pagedesigner.viewMenuMgr"; //$NON-NLS-1$
+
+ /**
+ * Adds standard group separators to the given MenuManager.
+ *
+ * @param menu
+ * the MenuManager
+ */
+ public static final void addStandardActionGroups(IMenuManager menu) {
+ menu.add(new Separator(GROUP_UNDO));
+ menu.add(new Separator(GROUP_EDIT));
+ menu.add(new Separator(GROUP_CONTAINER));
+ menu.add(new Separator(GROUP_STYLE));
+ menu.add(new Separator(GROUP_SPECIAL));
+ menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SelectionSynchronizer.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SelectionSynchronizer.java
new file mode 100644
index 000000000..bea341fde
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SelectionSynchronizer.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.utils.SelectionHelper;
+import org.eclipse.swt.custom.StyledText;
+
+/**
+ * This class handles selection synchronization between the designer and other
+ * parts. It listens event from both ViewerSelectionManager and the
+ * IDesignerView, and convert the events to each other.
+ * <p>
+ * SelectionSynchronizer will be registered on the ViewerSelectionManager,
+ * basically listens to selection change of other parts, and make the designer
+ * sync with them.
+ * <p>
+ * As ViewerSelectionManager is firing out both textSelectionChange and
+ * nodeSelectionChange, we only need to listen to one of them. As
+ * textSelectionChange provide more information than nodeSelectionChange, so
+ * we'll listen only to textSelectionChange.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class SelectionSynchronizer implements ISelectionChangedListener {
+ private boolean _firingChange = false;
+
+ private SimpleGraphicalEditor _editor;
+
+ /**
+ * @param editor
+ */
+ public SelectionSynchronizer(SimpleGraphicalEditor editor) {
+ _editor = editor;
+ }
+
+ protected boolean statusCheckOk() {
+ try {
+ StyledText text = _editor.getHTMLEditor().getTextEditor()
+ .getTextViewer().getTextWidget();
+ if (text == null || text.isDisposed()) {
+ return false;
+ }
+ return true;
+ } catch (NullPointerException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * This is for event from the designer.
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+
+ if (!_firingChange) {
+ // check current status
+ if (!statusCheckOk()) {
+ return;
+ }
+
+ _firingChange = true;
+ try {
+ // convert the designer selection into SSE selection
+ // (IStructureSelection of nodes
+ // or textSelection, and let the ViewerSelectionManager to
+ // handle it.
+ // if (selection instanceof IStructuredSelection)
+ // {
+ // IStructuredSelection nodeSel =
+ // SelectionHelper.convertFromDesignSelection((IStructuredSelection)selection);
+ // can't use DoubleClickEvent, since it requre a Viewer.
+ // _viewerSelectionManager.doubleClick(new
+ // DoubleClickEvent(null, nodeSel));
+ // }
+ // else if (selection instanceof DesignRange)
+ // {
+ // ITextSelection srcselection =
+ // SelectionHelper.convertFromDesignSelection((DesignRange)selection);
+ // event = new SelectionChangedEvent(_editor.getGraphicViewer(),
+ // srcselection);
+ // _viewerSelectionManager.selectionChanged(event);
+ // }
+ ITextSelection srcselection = SelectionHelper
+ .convertFromDesignSelectionToTextSelection(selection);
+
+ // ideally, we should let the text editor display the selection
+ // through calls to _viewerSelectionManager,
+ // but seemed _viewerSelectionManager don't support that, so we
+ // do workaround by calling the text editor (lium)
+ _editor.getHTMLEditor().getTextEditor().selectAndReveal(
+ srcselection.getOffset(), srcselection.getLength());
+ } finally {
+ _firingChange = false;
+ }
+ }
+ }
+
+ /**
+ * We are listening to the selection change in ViewerSelectionManager. The
+ * original source of the event could be source view or the outline view or
+ * other party that participate in the ViewerSelectionManager.
+ */
+ public void textSelectionChanged(int start, int end) {
+ if (!_firingChange) {
+ try {
+ _firingChange = true;
+
+ // XXX: workaround a SSE problem. In SSE, when user select a
+ // range, it will fire two textSelectionChange event
+ // the first one indicate the correct range, the second one is
+ // zero size for caret position.
+ // @see ViewerSelectionManagerImpl.caretMoved
+ // We try to ignore the second event by checking whether the
+ // current real selection is empty
+ if (start == end) {
+ ITextSelection sel = (ITextSelection) _editor
+ .getHTMLEditor().getTextEditor()
+ .getSelectionProvider().getSelection();
+ if (sel.getLength() != 0) {
+ return;
+ }
+ }
+
+ if (start > end) {
+ int temp = start;
+ start = end;
+ end = temp;
+ }
+ int offset = start;
+ int length = end - start;
+
+ ITextSelection oldSelection = SelectionHelper
+ .convertFromDesignSelectionToTextSelection(_editor
+ .getGraphicViewer().getSelection());
+ if (oldSelection != null && oldSelection.getOffset() == offset
+ && oldSelection.getLength() == length) {
+ return;
+ }
+
+ ISelection selection = SelectionHelper
+ .convertToDesignerSelection(this._editor
+ .getGraphicViewer(), offset, length);
+ _editor.getGraphicViewer().setSelection(selection);
+ } finally {
+ _firingChange = false;
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SimpleGraphicalEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SimpleGraphicalEditor.java
new file mode 100644
index 000000000..bbfc8dce2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/SimpleGraphicalEditor.java
@@ -0,0 +1,662 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.gef.DefaultEditDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gef.editparts.ScalableRootEditPart;
+import org.eclipse.gef.palette.PaletteRoot;
+import org.eclipse.gef.ui.actions.ActionRegistry;
+import org.eclipse.gef.ui.actions.UpdateAction;
+import org.eclipse.gef.ui.palette.PaletteViewer;
+import org.eclipse.gef.ui.palette.PaletteViewerProvider;
+import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.actions.container.ContainerActionGroup;
+import org.eclipse.jst.pagedesigner.actions.menuextension.CustomedContextMenuActionGroup;
+import org.eclipse.jst.pagedesigner.actions.menuextension.RunAction;
+import org.eclipse.jst.pagedesigner.actions.range.RangeActionGroup;
+import org.eclipse.jst.pagedesigner.actions.single.SingleElementActionGroup;
+import org.eclipse.jst.pagedesigner.commands.CopyAction;
+import org.eclipse.jst.pagedesigner.commands.CutAction;
+import org.eclipse.jst.pagedesigner.commands.DeleteAction;
+import org.eclipse.jst.pagedesigner.commands.PasteAction;
+import org.eclipse.jst.pagedesigner.dnd.internal.DesignerTemplateTransferDragSourceListener;
+import org.eclipse.jst.pagedesigner.dnd.internal.LocalSelectionDropTargetListener;
+import org.eclipse.jst.pagedesigner.dnd.internal.PDTemplateTransferDropTargetListener;
+import org.eclipse.jst.pagedesigner.dnd.internal.ResouceDropTargetListener;
+import org.eclipse.jst.pagedesigner.editors.actions.DesignerUndoRedoAction;
+import org.eclipse.jst.pagedesigner.editors.actions.RelatedViewActionGroup;
+import org.eclipse.jst.pagedesigner.editors.palette.DesignerPaletteCustomizer;
+import org.eclipse.jst.pagedesigner.editors.palette.DesignerPaletteViewerProvider;
+import org.eclipse.jst.pagedesigner.editors.palette.HTMLEditorPaletteFactory;
+import org.eclipse.jst.pagedesigner.jsp.core.internal.pagevar.DocumentPageVariableAdapter;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.adapter.PageVariableAdapterFactory;
+import org.eclipse.jst.pagedesigner.parts.CSSStyleAdapterFactory;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.parts.HTMLEditPartsFactory;
+import org.eclipse.jst.pagedesigner.parts.RefresherFactory;
+import org.eclipse.jst.pagedesigner.utils.SelectionHelper;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
+import org.eclipse.wst.sse.core.internal.PropagatingAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.undo.IDocumentSelectionMediator;
+import org.eclipse.wst.sse.core.internal.undo.UndoDocumentEvent;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+/**
+ * @author mengbo
+ */
+public class SimpleGraphicalEditor extends GraphicalEditor implements
+ IDesignViewer, IDocumentSelectionMediator {
+ private HTMLEditor _delegate;
+
+ private HTMLGraphicalViewer _viewer;
+
+ private IStructuredModel _model;
+
+ /** Palette component, holding the tools and shapes. */
+ private PaletteRoot _palette;
+
+ private SelectionSynchronizer _synchronizer = new SelectionSynchronizer(
+ this);
+
+ private IModelStateListener _internalModelListener = new IModelStateListener() {
+ public void modelAboutToBeChanged(IStructuredModel model) {
+ }
+
+ public void modelChanged(IStructuredModel model) {
+ updateActionsWhenModelChange();
+ }
+
+ public void modelDirtyStateChanged(IStructuredModel model,
+ boolean isDirty) {
+ }
+
+ public void modelResourceDeleted(IStructuredModel model) {
+ }
+
+ public void modelResourceMoved(IStructuredModel oldModel,
+ IStructuredModel newModel) {
+ }
+
+ public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
+ }
+
+ public void modelReinitialized(IStructuredModel structuredModel) {
+ }
+ };
+
+ public SimpleGraphicalEditor(HTMLEditor delegate,
+ DefaultEditDomain editdomain) {
+ _delegate = delegate;
+ this.setEditDomain(editdomain);
+ }
+
+ protected void createGraphicalViewer(Composite parent) {
+ _viewer = new HTMLGraphicalViewer(this);
+ Control control = _viewer.createControl(parent);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(control,
+ PDPlugin.getResourceString("SimpleGraphicalEditor.help.id"));
+ setGraphicalViewer(_viewer);
+ configureGraphicalViewer();
+ hookGraphicalViewer();
+ initializeGraphicalViewer();
+ initializeContextMenu();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditor#dispose()
+ */
+ public void dispose() {
+ if (_model != null) {
+ _model.getUndoManager().disconnect(this);
+ }
+
+ super.dispose();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditor#initializeGraphicalViewer()
+ */
+ protected void initializeGraphicalViewer() {
+ ScalableRootEditPart rootEditPart = new ScalableRootEditPart();
+ _viewer.setRootEditPart(rootEditPart);
+
+ _viewer.getViewport().setContentsTracksWidth(true);
+
+ _viewer.setKeyHandler(new GraphicalViewerKeyHandler(_viewer));
+
+ // initialize the viewer with input
+ // IStructuredModel sModel =
+ // StructuredModelManager.getModelManager().createUnManagedStructuredModelFor(ContentTypeIdForHTML.ContentTypeID_HTML);
+ // IDOMDocument designDoc = ((IDOMModel)sModel).getDocument();
+ // HTMLEditPartsFactory factory = new HTMLEditPartsFactory(designDoc);
+ HTMLEditPartsFactory factory = new HTMLEditPartsFactory(null);
+
+ _viewer.setEditPartFactory(factory);
+
+ // for sync with source view.
+
+ _viewer.addDropTargetListener(new LocalSelectionDropTargetListener(
+ _viewer));
+ _viewer.addDropTargetListener(new PDTemplateTransferDropTargetListener(
+ _viewer));
+ _viewer.addDropTargetListener(new ResouceDropTargetListener(_viewer));
+
+ // add double click support.
+ _viewer.getControl().addMouseListener(new MouseAdapter() {
+ public void mouseDoubleClick(MouseEvent e) {
+ try {
+ getSite().getPage().showView(IPageLayout.ID_PROP_SHEET);
+ } catch (PartInitException e1) {
+ // ignore
+ }
+ }
+ });
+ }
+
+ protected void initializeContextMenu() {
+ Control gviewer = _viewer.getControl();
+ MenuManager menuMgr = new MenuManager();
+ menuMgr.setRemoveAllWhenShown(true);
+ Menu menu = menuMgr.createContextMenu(gviewer);
+ gviewer.setMenu(menu);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager menuMgr) {
+ PageDesignerActionConstants.addStandardActionGroups(menuMgr);
+
+ menuMgr.add(new RunAction(SimpleGraphicalEditor.this._delegate,
+ RunAction.LAUNCH_MODE_RUN));
+ menuMgr.add(new RunAction(SimpleGraphicalEditor.this._delegate,
+ RunAction.LAUNCH_MODE_DEBUG));
+ // FIXME: for UNDO/REDO, maybe need also wrap them in
+ // DesignerCommand.
+ // otherwise don't have validate() called after the source
+ // change.
+ menuMgr.appendToGroup(PageDesignerActionConstants.GROUP_UNDO,
+ getAction(IWorkbenchActionDefinitionIds.UNDO));
+ menuMgr.appendToGroup(PageDesignerActionConstants.GROUP_UNDO,
+ getAction(IWorkbenchActionDefinitionIds.REDO));
+
+ menuMgr.appendToGroup(PageDesignerActionConstants.GROUP_EDIT,
+ getAction(IWorkbenchActionDefinitionIds.CUT));
+ menuMgr.appendToGroup(PageDesignerActionConstants.GROUP_EDIT,
+ getAction(IWorkbenchActionDefinitionIds.COPY));
+ menuMgr.appendToGroup(PageDesignerActionConstants.GROUP_EDIT,
+ getAction(IWorkbenchActionDefinitionIds.PASTE));
+ menuMgr.appendToGroup(PageDesignerActionConstants.GROUP_EDIT,
+ getAction(IWorkbenchActionDefinitionIds.DELETE));
+
+ ContainerActionGroup containerActionGroup = new ContainerActionGroup();
+ ActionContext context = new ActionContext(_viewer
+ .getSelection());
+ context.setInput(_viewer);
+ containerActionGroup.setContext(context);
+ containerActionGroup.fillContextMenu(menuMgr);
+ containerActionGroup.setContext(null);
+
+ // TableActionGroup tableActionGroup = new TableActionGroup();
+ // tableActionGroup.setContext(new
+ // ActionContext(_viewer.getSelection()));
+ // tableActionGroup.fillContextMenu(menuMgr);
+ // tableActionGroup.setContext(null);
+
+ RangeActionGroup rangeActionGroup = new RangeActionGroup();
+ context = new ActionContext(_viewer.getSelection());
+ context.setInput(_viewer);
+ rangeActionGroup.setContext(context);
+ rangeActionGroup.fillContextMenu(menuMgr);
+ rangeActionGroup.setContext(null);
+
+ SingleElementActionGroup singleActionGroup = new SingleElementActionGroup();
+ singleActionGroup.setContext(new ActionContext(_viewer
+ .getSelection()));
+ singleActionGroup.fillContextMenu(menuMgr);
+ singleActionGroup.setContext(null);
+
+ // IAction customize =
+ // graphicalActionRegistry.getAction(CustomizeJavaBeanAction.ACTION_ID);
+ // if (customize.isEnabled())
+ // menuMgr.appendToGroup(GEFActionConstants.GROUP_EDIT,
+ // customize);
+
+ RelatedViewActionGroup viewMenu = new RelatedViewActionGroup();
+ viewMenu.fillContextMenu(menuMgr);
+
+ CustomedContextMenuActionGroup customedMenu = new CustomedContextMenuActionGroup();
+ customedMenu.setContext(new ActionContext(_viewer
+ .getSelection()));
+ customedMenu.setModel(_model);
+ customedMenu.setParentControl(_viewer.getControl());
+ customedMenu.fillContextMenu(menuMgr);
+ customedMenu.setContext(null);
+ customedMenu.setParentControl(null);
+ customedMenu.setModel(null);
+ }
+ });
+ getSite().registerContextMenu(
+ "HTMLVisualEditor.contextMenu", menuMgr, _viewer); //$NON-NLS-1$
+ }
+
+ private void updateActionsWhenModelChange() {
+ // update undo/redo action
+ IAction action = this.getAction(IWorkbenchActionDefinitionIds.UNDO);
+ ((UpdateAction) action).update();
+
+ action = this.getAction(IWorkbenchActionDefinitionIds.REDO);
+ ((UpdateAction) action).update();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditor#createActions()
+ */
+ protected void createActions() {
+ super.createActions();
+ ActionRegistry registry = getActionRegistry();
+ ISharedImages sharedImages = PlatformUI.getWorkbench()
+ .getSharedImages();
+
+ IAction action;
+
+ action = new DesignerUndoRedoAction(true, this);
+ action.setImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
+ action.setDisabledImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_DISABLED));
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
+ action.setId(IWorkbenchActionDefinitionIds.UNDO);
+ getSite().getKeyBindingService().registerAction(action);
+ registry.registerAction(action);
+
+ action = new DesignerUndoRedoAction(false, this);
+ action.setImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
+ action.setDisabledImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_REDO_DISABLED));
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
+ action.setId(IWorkbenchActionDefinitionIds.REDO);
+ getSite().getKeyBindingService().registerAction(action);
+ registry.registerAction(action);
+
+ action = new DeleteAction(this);
+ action.setImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
+ action.setDisabledImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED));
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE);
+ action.setId(IWorkbenchActionDefinitionIds.DELETE);
+ getSite().getKeyBindingService().registerAction(action);
+ this.getSelectionActions().add(action.getId());
+ registry.registerAction(action);
+
+ action = new CopyAction(this);
+ action.setImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
+ action.setDisabledImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED));
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
+ action.setId(IWorkbenchActionDefinitionIds.COPY);
+ getSite().getKeyBindingService().registerAction(action);
+ this.getSelectionActions().add(action.getId());
+ registry.registerAction(action);
+
+ action = new CutAction(this);
+ action.setImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
+ action.setDisabledImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_CUT_DISABLED));
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT);
+ action.setId(IWorkbenchActionDefinitionIds.CUT);
+ getSite().getKeyBindingService().registerAction(action);
+ this.getSelectionActions().add(action.getId());
+ registry.registerAction(action);
+
+ action = new PasteAction(this);
+ action.setImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
+ action.setDisabledImageDescriptor(sharedImages
+ .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
+ action.setId(IWorkbenchActionDefinitionIds.PASTE);
+ getSite().getKeyBindingService().registerAction(action);
+ this.getSelectionActions().add(action.getId());
+ registry.registerAction(action);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void doSave(IProgressMonitor monitor) {
+ if (_delegate != null) {
+ _delegate.doSave(monitor);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISaveablePart#doSaveAs()
+ */
+ public void doSaveAs() {
+ if (_delegate != null) {
+ _delegate.doSaveAs();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISaveablePart#isDirty()
+ */
+ public boolean isDirty() {
+ if (_delegate != null) {
+ return _delegate.isDirty();
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
+ */
+ public boolean isSaveAsAllowed() {
+ if (_delegate != null) {
+ return _delegate.isSaveAsAllowed();
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.sybase.html.editor.IDesignViewer#setModel(com.ibm.sse.model.IStructuredModel)
+ */
+ public void setModel(IStructuredModel model) {
+ if (_model != null) {
+ if (_model.getUndoManager() != null)
+ _model.getUndoManager().disconnect(this);
+ _model.removeModelStateListener(_internalModelListener);
+ }
+
+ this._model = model;
+
+ if (_model != null) {
+ _model.addModelStateListener(_internalModelListener);
+ if (_model.getUndoManager() != null) {
+ _model.getUndoManager().connect(this);
+ updateActionsWhenModelChange();
+ }
+ }
+
+ if (model instanceof IDOMModel) {
+ IDOMDocument doc = ((IDOMModel) model).getDocument();
+ PropagatingAdapter adapter = (PropagatingAdapter) doc
+ .getAdapterFor(PropagatingAdapter.class);
+ if (adapter != null) {
+ INodeAdapterFactory factory = RefresherFactory.getInstance();
+ adapter.addAdaptOnCreateFactory(factory);
+ adapter.initializeForFactory(factory, doc);
+ // CSSStyleAdapterFactory fac2 =
+ // CSSStyleAdapterFactory.getInstance();
+ // adapter.addAdaptOnCreateFactory(fac2);
+ // adapter.initializeForFactory(fac2, doc);
+ }
+ ((IDOMModel) model).getFactoryRegistry().addFactory(
+ CSSStyleAdapterFactory.getInstance());
+
+ // _viewer.getDestDocumentForDesign().getModel().getFactoryRegistry().addFactory(CSSStyleAdapterFactory.getInstance());
+ ((IDOMModel) model).getFactoryRegistry().addFactory(
+ new PageVariableAdapterFactory());
+ doc.addAdapter(new DocumentPageVariableAdapter(doc));
+ _viewer.setContents(((IDOMModel) model).getDocument());
+ } else {
+ _viewer.setContents((EditPart) null);
+ }
+ }
+
+ protected SelectionSynchronizer getSynchronizer() {
+ return _synchronizer;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.sse.model.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditor#updateActions(java.util.List)
+ */
+ protected void updateActions(List actionIds) {
+ super.updateActions(actionIds);
+ }
+
+ public IAction getAction(Object id) {
+ // lium: following lines commented out, see comments in
+ // DesignerUndoRedoAction
+ // if (ITextEditorActionConstants.UNDO.equals(id) ||
+ // ITextEditorActionConstants.REDO.equals(id))
+ // {
+ // return _delegate.getTextEditor().getAction((String) id);
+ // }
+ return getActionRegistry().getAction(id);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getPalettePreferences()
+ */
+ protected FlyoutPreferences getPalettePreferences() {
+ return HTMLEditorPaletteFactory.createPalettePreferences();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getPaletteRoot()
+ */
+ protected PaletteRoot getPaletteRoot() {
+ if (_palette == null) {
+ _palette = HTMLEditorPaletteFactory
+ .createPalette(getCurrentProject(_delegate.getEditorInput()));
+ }
+ return _palette;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#createPaletteViewerProvider()
+ */
+ protected PaletteViewerProvider createPaletteViewerProvider() {
+ return new DesignerPaletteViewerProvider(getEditDomain()) {
+ protected void configurePaletteViewer(PaletteViewer viewer) {
+ super.configurePaletteViewer(viewer);
+ viewer.setCustomizer(new DesignerPaletteCustomizer());
+
+ // create a drag source listener for this palette viewer
+ // together with an appropriate transfer drop target listener,
+ // this will enable
+ // model element creation by dragging a
+ // CombinatedTemplateCreationEntries
+ // from the palette into the editor
+ // @see ShapesEditor#createTransferDropTargetListener()
+ viewer
+ .addDragSourceListener(new DesignerTemplateTransferDragSourceListener(
+ viewer));
+ }
+ };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.IDesignViewer#getGraphicViewer()
+ */
+ public IHTMLGraphicalViewer getGraphicViewer() {
+ return _viewer;
+ }
+
+ public HTMLEditor getHTMLEditor() {
+ return _delegate;
+ }
+
+ private IProject getCurrentProject(IEditorInput input) {
+ IProject curProject = null;
+ IFile inputFile = null;
+ if (input instanceof IFileEditorInput) {
+ inputFile = ((IFileEditorInput) input).getFile();
+ curProject = inputFile.getProject();
+ }
+ return curProject;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ if (_viewer != null) {
+ GraphicalViewer viewerViewer = getGraphicalViewer();
+ if (viewerViewer != null && viewerViewer.getControl() != null
+ && viewerViewer.getControl().isFocusControl()) {
+ updateActions(getSelectionActions());
+ if (selection instanceof IStructuredSelection && //
+ !(((IStructuredSelection) selection).getFirstElement() instanceof DocumentEditPart)) {
+ ((HTMLGraphicalViewer) viewerViewer)
+ .updateRangeSelection(selection);
+ }
+ }
+ } else {
+ super.selectionChanged(part, selection);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.undo.IDocumentSelectionMediator#getDocument()
+ */
+ public IDocument getDocument() {
+ if (_model != null) {
+ return _model.getStructuredDocument();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.undo.IDocumentSelectionMediator#undoOperationSelectionChanged(org.eclipse.wst.sse.core.internal.undo.UndoDocumentEvent)
+ */
+ public void undoOperationSelectionChanged(UndoDocumentEvent event) {
+ IDocumentSelectionMediator requester = event.getRequester();
+ if (this == requester) {
+ // ok, the undo/redo operation is initialized by designer page.
+ // we should set selection in designer.
+ // However, when this method is called, the modelChanged event is
+ // not fired yet, so the
+ // editpart hasn't refreshed yet. So we register a
+ // modelStateListener, and do the selection
+ // in modelChangedEvent. (lium)
+ final int offset = event.getOffset();
+ final int length = event.getLength();
+
+ _model.addModelStateListener(new IModelStateListener() {
+ public void modelAboutToBeChanged(IStructuredModel model) {
+ }
+
+ public void modelChanged(IStructuredModel model) {
+ _model.removeModelStateListener(this);
+ ISelection sel = SelectionHelper
+ .convertToDesignerSelection(getGraphicViewer(),
+ offset, length);
+ if (sel != null) {
+ getGraphicViewer().setSelection(sel);
+ }
+ }
+
+ public void modelDirtyStateChanged(IStructuredModel model,
+ boolean isDirty) {
+ }
+
+ public void modelResourceDeleted(IStructuredModel model) {
+ }
+
+ public void modelResourceMoved(IStructuredModel oldModel,
+ IStructuredModel newModel) {
+ }
+
+ public void modelAboutToBeReinitialized(
+ IStructuredModel structuredModel) {
+ }
+
+ public void modelReinitialized(IStructuredModel structuredModel) {
+ }
+ });
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.java
new file mode 100644
index 000000000..7aacf8a4e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ActionsMessages {
+ private static final String BUNDLE_NAME = "org.eclipse.jst.pagedesigner.editors.actions.ActionsMessages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private ActionsMessages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.properties
new file mode 100644
index 000000000..9907f3935
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ActionsMessages.properties
@@ -0,0 +1,27 @@
+DesignActionBarFactory.Underline=Underline
+DesignActionBarFactory.Italic=Italic
+DesignActionBarFactory.Bold=Bold
+DesignActionBarFactory.Small=Small
+DesignActionBarFactory.Big=Big
+DesignActionBarFactory.Paragraph=Paragraph
+DesignActionBarFactory.Underline.Text=Underline
+DesignActionBarFactory.Italic.Text=Italic
+DesignActionBarFactory.Bold.Text=Bold
+DesignActionBarFactory.Small.Text=Small
+DesignActionBarFactory.Big.Text=Big
+PaletteViewAction.Menu.PaletteView=Palette
+RelatedViewActionGroup.Menu.ShowView=Show View
+PropertiesViewAction.Menu.Properties=Properties
+DataBindingViewAction.Menu.DataBinding=DataBinding
+DesignerStyleActionGroup.CommandLabel.V=V
+DesignerStyleActionGroup.CommandLabel.H=H
+DesignerStyleActionGroup.CommandLabel.D=D
+DesignerStyleActionGroup.CommandLabel.S=S
+DesignerStyleActionGroup.CommandLabel.V.Tooltip=Show Design Page and Source Page as Horizontal Panes
+DesignerStyleActionGroup.CommandLabel.H.Tooltip=Show Design Page and Source Page as Vertical Panes
+DesignerStyleActionGroup.CommandLabel.D.Tooltip=Only Show Design Page
+DesignerStyleActionGroup.CommandLabel.S.Tooltip=Only Show Source Page
+DesignerUndoRedoAction.UNDO=Undo
+DesignerUndoRedoAction.REDO=Redo
+DesignerUndoRedoAction.UNDO_LABEL=Undo {0}
+DesignerUndoRedoAction.REDO_LABEL=Redo {0} \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ChangeStyleAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ChangeStyleAction.java
new file mode 100644
index 000000000..c7c835a6e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/ChangeStyleAction.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.commands.DesignerCommand;
+import org.eclipse.jst.pagedesigner.commands.range.ApplyStyleCommand;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewerListener;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * @author mengbo
+ */
+public abstract class ChangeStyleAction extends Action implements IUpdate {
+ protected IHTMLGraphicalViewer _viewer;
+
+ String _expectedTag;
+
+ String _expectedCSSProperty;
+
+ String _expectedCSSPropertyValue;
+
+ IHTMLGraphicalViewerListener _listener = new IHTMLGraphicalViewerListener() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewerListener#selectionAboutToChange()
+ */
+ public void selectionAboutToChange() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewerListener#selectionChangeFinished()
+ */
+ public void selectionChangeFinished() {
+ update();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ update();
+ }
+ };
+
+ /**
+ * @param text
+ * @param image
+ */
+ public ChangeStyleAction(String text, String name, ImageDescriptor image,
+ int style) {
+ super(text, style);
+ _expectedTag = name;
+ this.setImageDescriptor(image);
+ }
+
+ public void setViewer(IHTMLGraphicalViewer viewer) {
+ if (viewer == _viewer) {
+ return;
+ }
+ if (_viewer != null) {
+ _viewer.removeSelectionChangedListener(_listener);
+ }
+ _viewer = viewer;
+ if (_viewer != null) {
+ _viewer.addSelectionChangedListener(_listener);
+ }
+ update();
+ }
+
+ /**
+ *
+ */
+ public void update() {
+ if (_viewer == null) {
+ this.setChecked(false);
+ this.setEnabled(false);
+ return;
+ }
+ if (!_viewer.isInRangeMode()) {
+ // XXX: later we may support in range mode.
+ this.setChecked(false);
+ this.setEnabled(false);
+ return;
+ }
+ DesignRange range = _viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ this.setChecked(false);
+ this.setEnabled(false);
+ return;
+ }
+ updateStatus(RangeUtil.normalize(range));
+ }
+
+ /**
+ * @param range
+ */
+ private void updateStatus(DesignRange range) {
+ if (range.isEmpty()) {
+ this.setEnabled(false);
+ this.setChecked(false); // FIXME: not handling checked status yet.
+ } else {
+ this.setEnabled(true);
+ this.setChecked(false);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ if (_viewer == null || !_viewer.isInRangeMode()) {
+ return;
+ }
+ DesignRange range = _viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ return;
+ }
+ if (range.isEmpty())
+ return; // nothing to do to empty range.
+
+ // if currently checked, means unapply the style. If current not
+ // checked, means apply the style
+ boolean apply = !this.isChecked();
+ if (apply) {
+ applyStyle();
+ } else {
+ // not supported yet.
+ }
+ }
+
+ /**
+ *
+ */
+ private void applyStyle() {
+ DesignerCommand command = new ApplyStyleCommand(_viewer,
+ getExpectedTag(), getExpectedCSSProperty(),
+ getExpectedCSSPropertyValue());
+ command.execute();
+ }
+
+ /**
+ * @return
+ */
+ protected abstract String getExpectedCSSPropertyValue();
+
+ /**
+ * @return
+ */
+ protected abstract String getExpectedCSSProperty();
+
+ /**
+ * @return
+ */
+ protected String getExpectedTag() {
+ return _expectedTag;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DataBindingViewAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DataBindingViewAction.java
new file mode 100644
index 000000000..938481cf8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DataBindingViewAction.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DataBindingViewAction extends Action {
+ public final static String ID = "org.eclipse.jst.pagedesigner.editors.actions.DataBindingViewAction"; //$NON-NLS-1$
+
+ private static Logger _log = PDPlugin
+ .getLogger(DataBindingViewAction.class);
+
+ public DataBindingViewAction() {
+ setText(ActionsMessages
+ .getString("DataBindingViewAction.Menu.DataBinding")); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ try {
+ getPage().showView(
+ "org.eclipse.jst.pagedesigner.databinding.ui.views.DataBindingsView");//$NON-NLS-1$
+ } catch (PartInitException e) {
+ _log.error("Error opening the DataBindingView");
+ }
+
+ }
+
+ private IWorkbenchPage getPage() {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ return window.getActivePage();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignActionBarFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignActionBarFactory.java
new file mode 100644
index 000000000..7ff6c9378
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignActionBarFactory.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.actions.range.ChangeStyleAction;
+import org.eclipse.jst.pagedesigner.actions.range.DesignerToolBarAction;
+import org.eclipse.jst.pagedesigner.actions.range.HTagsInsertGroupAction;
+
+/**
+ * @author mengbo
+ */
+public class DesignActionBarFactory {
+ private static DesignActionBarFactory _instance;
+
+ private DesignActionBarFactory() {
+ }
+
+ public static DesignActionBarFactory getInstance() {
+ if (_instance == null) {
+ _instance = new DesignActionBarFactory();
+ }
+ return _instance;
+ }
+
+ public DesignerToolBarAction getStyleAction(String name) {
+ DesignerToolBarAction action = null;
+
+ if (name.equals(IHTMLConstants.TAG_U)) {
+ action = new ChangeStyleAction(ActionsMessages
+ .getString("DesignActionBarFactory.Underline.Text"), name,
+ PDPlugin.getDefault().getImageDescriptor(
+ "PD_Toolbar_underline.gif"), PDPlugin.getDefault()
+ .getImageDescriptor(
+ "PD_Toolbar_underline_disabled.gif"),
+ IAction.AS_CHECK_BOX);
+ action.setToolTipText(ActionsMessages
+ .getString("DesignActionBarFactory.Underline"));
+ } else if (name.equals(IHTMLConstants.TAG_I)) {
+ action = new ChangeStyleAction(ActionsMessages
+ .getString("DesignActionBarFactory.Italic.Text"), name,
+ PDPlugin.getDefault().getImageDescriptor(
+ "PD_Toolbar_italic.gif"), PDPlugin.getDefault()
+ .getImageDescriptor(
+ "PD_Toolbar_italic_disabled.gif"),
+ IAction.AS_CHECK_BOX);
+ action.setToolTipText(ActionsMessages
+ .getString("DesignActionBarFactory.Italic"));
+ } else if (name.equals(IHTMLConstants.TAG_B)) {
+ action = new ChangeStyleAction(ActionsMessages
+ .getString("DesignActionBarFactory.Bold.Text"), name,
+ PDPlugin.getDefault().getImageDescriptor(
+ "PD_Toolbar_bold.gif"),
+ PDPlugin.getDefault().getImageDescriptor(
+ "PD_Toolbar_bold_disabled.gif"),
+ IAction.AS_CHECK_BOX);
+ action.setToolTipText(ActionsMessages
+ .getString("DesignActionBarFactory.Bold"));
+ } else if (name.equals(IHTMLConstants.TAG_SMALL)) {
+ action = new ChangeStyleAction(ActionsMessages
+ .getString("DesignActionBarFactory.Small.Text"), name,
+ PDPlugin.getDefault().getImageDescriptor(
+ "PD_Toolbar_smallfont.gif"), PDPlugin.getDefault()
+ .getImageDescriptor(
+ "PD_Toolbar_smallfont_disabled.gif"),
+ IAction.AS_CHECK_BOX);
+ action.setToolTipText(ActionsMessages
+ .getString("DesignActionBarFactory.Small"));
+ } else if (name.equals(IHTMLConstants.TAG_BIG)) {
+ action = new ChangeStyleAction(ActionsMessages
+ .getString("DesignActionBarFactory.Big.Text"), name,
+ PDPlugin.getDefault().getImageDescriptor(
+ "PD_Toolbar_largefont.gif"), PDPlugin.getDefault()
+ .getImageDescriptor(
+ "PD_Toolbar_largefont_disabled.gif"),
+ IAction.AS_CHECK_BOX);
+ action.setToolTipText(ActionsMessages
+ .getString("DesignActionBarFactory.Big"));
+ } else if (name
+ .equalsIgnoreCase(DesignPageActionContributor.PARAGRAPH_ACTION_ID)) {
+ action = new HTagsInsertGroupAction(PDPlugin.getDefault()
+ .getImageDescriptor("PD_Toolbar_paragraph.gif"),
+ IAction.AS_DROP_DOWN_MENU);
+ action.setToolTipText(ActionsMessages
+ .getString("DesignActionBarFactory.Paragraph"));
+ }
+
+ return action;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignPageActionContributor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignPageActionContributor.java
new file mode 100644
index 000000000..31ad867fc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignPageActionContributor.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.actions.range.DesignerToolBarAction;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.jst.pagedesigner.editors.SimpleGraphicalEditor;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.part.EditorActionBarContributor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
+
+/**
+ * sub action contributor for the designer page.
+ *
+ * @author mengbo
+ */
+public class DesignPageActionContributor extends EditorActionBarContributor {
+ private static final Logger _log = PDPlugin
+ .getLogger(DesignPageActionContributor.class);
+
+ public static final String PARAGRAPH_ACTION_ID = "paragraph";
+
+ protected IEditorPart _editorPart;
+
+ protected void doRemove(IContributionManager manager, String id) {
+ try {
+ if (manager.find(id) != null) {
+ manager.remove(id);
+ }
+ } catch (Exception e) {
+ _log.info("Error:", e);
+ }
+ }
+
+ public void init(IActionBars bars, IWorkbenchPage page) {
+ super.init(bars);
+ init(bars);
+ }
+
+ public void init(IActionBars bars) {
+ IToolBarManager toolbar = bars.getToolBarManager();
+ initToolbar(toolbar);
+ }
+
+ /**
+ * @param toolbar
+ */
+ private void initToolbar(IToolBarManager toolbar) {
+ DesignActionBarFactory factory = DesignActionBarFactory.getInstance();
+
+ Action action = factory.getStyleAction(IHTMLConstants.TAG_U);
+ toolbar.add(action);
+
+ action = factory.getStyleAction(IHTMLConstants.TAG_B);
+ toolbar.add(action);
+
+ action = factory.getStyleAction(IHTMLConstants.TAG_I);
+ toolbar.add(action);
+
+ action = factory.getStyleAction(IHTMLConstants.TAG_SMALL);
+ toolbar.add(action);
+
+ action = factory.getStyleAction(IHTMLConstants.TAG_BIG);
+ toolbar.add(action);
+ // action = factory.getStyleAction(PARAGRAPH_ACTION_ID);
+ // toolbar.add(action);
+ }
+
+ protected void addActionWithId(IMenuManager menuManager, Action action,
+ String id) {
+ action.setId(id);
+ menuManager.add(action);
+ }
+
+ public void setViewerSpecificContributionsEnabled(boolean enabled) {
+ HTMLEditor htmlEditor = null;
+ if (_editorPart instanceof HTMLEditor) {
+ htmlEditor = (HTMLEditor) _editorPart;
+ } else if (_editorPart instanceof SimpleGraphicalEditor) {
+ htmlEditor = ((SimpleGraphicalEditor) _editorPart).getHTMLEditor();
+ }
+
+ if (htmlEditor == null)
+ return;
+
+ SimpleGraphicalEditor graphicalEditor = (SimpleGraphicalEditor) htmlEditor
+ .getDesignViewer();
+ IWorkbenchPartSite site = htmlEditor.getSite();
+ if (site instanceof IEditorSite) {
+ IActionBars actionBars = ((IEditorSite) site).getActionBars();
+
+ if (enabled) {
+ // // we always let the text editor to handle UNDO and REDO
+ // actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO,
+ // textEditor
+ // .getAction(ITextEditorActionConstants.UNDO));
+ // actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO,
+ // textEditor
+ // .getAction(ITextEditorActionConstants.REDO));
+ // lium: the above behavior changed, since we now use
+ // DesignerUndoRedoAction.
+ // see comments in DesignerUndoRedoAction
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.UNDO, graphicalEditor
+ .getAction(IWorkbenchActionDefinitionIds.UNDO));
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.REDO, graphicalEditor
+ .getAction(IWorkbenchActionDefinitionIds.REDO));
+
+ // cut/copy/paste is delegated to design actions
+ actionBars
+ .setGlobalActionHandler(
+ ITextEditorActionConstants.DELETE,
+ graphicalEditor
+ .getAction(IWorkbenchActionDefinitionIds.DELETE));
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.CUT, graphicalEditor
+ .getAction(IWorkbenchActionDefinitionIds.CUT));
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.COPY, graphicalEditor
+ .getAction(IWorkbenchActionDefinitionIds.COPY));
+ actionBars
+ .setGlobalActionHandler(
+ ITextEditorActionConstants.PASTE,
+ graphicalEditor
+ .getAction(IWorkbenchActionDefinitionIds.PASTE));
+ } else {
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.UNDO, null);
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.REDO, null);
+
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.DELETE, null);
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.CUT, null);
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.COPY, null);
+ actionBars.setGlobalActionHandler(
+ ITextEditorActionConstants.PASTE, null);
+ }
+ }
+ }
+
+ /**
+ * The active editor passed in could be the following: HTMLEditor,
+ * SimpleGraphicalEditor, null.
+ */
+ public void setActiveEditor(IEditorPart targetEditor) {
+ _editorPart = targetEditor;
+
+ // temp code.
+ if (targetEditor instanceof SimpleGraphicalEditor) {
+ IHTMLGraphicalViewer viewer = ((SimpleGraphicalEditor) targetEditor)
+ .getGraphicViewer();
+ setViewerOnActions(viewer);
+ } else if (targetEditor instanceof HTMLEditor) {
+ IHTMLGraphicalViewer viewer = ((HTMLEditor) targetEditor)
+ .getDesignViewer().getGraphicViewer();
+ setViewerOnActions(viewer);
+ } else {
+ setViewerOnActions(null);
+ }
+
+ // TODO... uncomment this and investigate NPE
+ //
+ // add the cut/copy/paste for text fields
+ // ActionHandlerPlugin.connectPart(editorPart);
+ }
+
+ private void setViewerOnActions(IHTMLGraphicalViewer viewer) {
+ IContributionItem[] items = getActionBars().getToolBarManager()
+ .getItems();
+ if (items != null) {
+ for (int i = 0; i < items.length; i++) {
+ if (items[i] instanceof ActionContributionItem) {
+ IAction action = ((ActionContributionItem) items[i])
+ .getAction();
+ if (action instanceof DesignerToolBarAction) {
+ ((DesignerToolBarAction) action).setViewer(viewer);
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.ui.IEditorActionBarContributor#dispose()
+ */
+ public void dispose() {
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerStyleActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerStyleActionGroup.java
new file mode 100644
index 000000000..a3d6fa903
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerStyleActionGroup.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import java.util.HashMap;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IKeyBindingService;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DesignerStyleActionGroup {
+ private static HashMap IMAGE_NAMES = new HashMap();
+
+ private static final String VERTICAL = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.V"); //$NON-NLS-1$
+
+ private static final String HORIZONTAL = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.H"); //$NON-NLS-1$
+
+ private static final String DESIGN = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.D"); //$NON-NLS-1$
+
+ private static final String SOURCE = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.S"); //$NON-NLS-1$
+
+ private static final String VERTICAL_TOOLTIP = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.V.Tooltip"); //$NON-NLS-1$
+
+ private static final String HORIZONTAL_TOOLTIP = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.H.Tooltip"); //$NON-NLS-1$
+
+ private static final String DESIGN_TOOLTIP = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.D.Tooltip"); //$NON-NLS-1$
+
+ private static final String SOURCE_TOOLTIP = ActionsMessages
+ .getString("DesignerStyleActionGroup.CommandLabel.S.Tooltip"); //$NON-NLS-1$
+ static {
+ IMAGE_NAMES.put(VERTICAL, "PD_Toolbar_vsplit.gif"); //$NON-NLS-1$
+ IMAGE_NAMES.put(HORIZONTAL, "PD_Toolbar_hsplit.gif"); //$NON-NLS-1$
+ IMAGE_NAMES.put(DESIGN, "PD_Toolbar_designer.gif"); //$NON-NLS-1$
+ IMAGE_NAMES.put(SOURCE, "PD_Toolbar_source.gif"); //$NON-NLS-1$
+ }
+
+ class ChangeDesignerStyleAction extends Action {
+ int _mode;
+
+ ChangeDesignerStyleAction(String text, ImageDescriptor image, int mode) {
+ super(text, IAction.AS_RADIO_BUTTON);
+ this.setImageDescriptor(image);
+ _mode = mode;
+ }
+
+ public int getMode() {
+ return _mode;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ if (_htmlEditor != null) {
+ _htmlEditor.setDesignerMode(_mode);
+ updateActionBars();
+ }
+ }
+ };
+
+ HTMLEditor _htmlEditor;
+
+ ChangeDesignerStyleAction[] _actions = null;
+
+ {
+ ChangeDesignerStyleAction _verAction = new ChangeDesignerStyleAction(
+ VERTICAL, PDPlugin.getDefault().getImageDescriptor(
+ (String) IMAGE_NAMES.get(VERTICAL)),
+ HTMLEditor.MODE_SASH_VERTICAL);
+ _verAction.setId("org.eclipse.jst.pagedesigner.vertical");
+ _verAction
+ .setActionDefinitionId("org.eclipse.jst.pagedesigner.vertical");
+ _verAction.setToolTipText(VERTICAL_TOOLTIP);
+
+ ChangeDesignerStyleAction _horAction = new ChangeDesignerStyleAction(
+ HORIZONTAL, PDPlugin.getDefault().getImageDescriptor(
+ (String) IMAGE_NAMES.get(HORIZONTAL)),
+ HTMLEditor.MODE_SASH_HORIZONTAL);
+ _horAction.setId("org.eclipse.jst.pagedesigner.horizotal");
+ _horAction
+ .setActionDefinitionId("org.eclipse.jst.pagedesigner.horizotal");
+ _horAction.setToolTipText(HORIZONTAL_TOOLTIP);
+
+ ChangeDesignerStyleAction _designAction = new ChangeDesignerStyleAction(
+ DESIGN, PDPlugin.getDefault().getImageDescriptor(
+ (String) IMAGE_NAMES.get(DESIGN)),
+ HTMLEditor.MODE_DESIGNER);
+ _designAction.setId("org.eclipse.jst.pagedesigner.design");
+ _designAction
+ .setActionDefinitionId("org.eclipse.jst.pagedesigner.design");
+ _designAction.setToolTipText(DESIGN_TOOLTIP);
+
+ ChangeDesignerStyleAction _sourceAction = new ChangeDesignerStyleAction(
+ SOURCE, PDPlugin.getDefault().getImageDescriptor(
+ (String) IMAGE_NAMES.get(SOURCE)),
+ HTMLEditor.MODE_SOURCE);
+ _sourceAction.setId("org.eclipse.jst.pagedesigner.source");
+ _sourceAction
+ .setActionDefinitionId("org.eclipse.jst.pagedesigner.source");
+ _sourceAction.setToolTipText(SOURCE_TOOLTIP);
+
+ _actions = new ChangeDesignerStyleAction[] { _verAction, _horAction,
+ _designAction, _sourceAction };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#updateActionBars()
+ */
+ public void updateActionBars() {
+ if (_htmlEditor == null) {
+ for (int i = 0; i < _actions.length; i++) {
+ _actions[i].setEnabled(false);
+ }
+ } else {
+ for (int i = 0; i < _actions.length; i++) {
+ _actions[i].setEnabled(true);
+ _actions[i].setChecked(_actions[i].getMode() == _htmlEditor
+ .getDesignerMode());
+ }
+ }
+ }
+
+ public void setHTMLEditor(HTMLEditor editor) {
+ this._htmlEditor = editor;
+ if (editor != null) {
+ IKeyBindingService keyBindingService = editor.getSite()
+ .getKeyBindingService();
+ for (int i = 0; i < _actions.length; i++) {
+ keyBindingService.registerAction(_actions[i]);
+ }
+ }
+ updateActionBars();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillActionBars(org.eclipse.ui.IActionBars)
+ */
+ public void fillActionBars(IActionBars actionBars) {
+ IToolBarManager toolbar = actionBars.getToolBarManager();
+ for (int i = 0; i < _actions.length; i++) {
+ toolbar.add(_actions[i]);
+ }
+ toolbar.add(new Separator());
+ }
+
+ public void dispose() {
+ if (_htmlEditor != null) {
+ IKeyBindingService keyBindingService = _htmlEditor.getSite()
+ .getKeyBindingService();
+ for (int i = 0; i < _actions.length; i++) {
+ keyBindingService.unregisterAction(_actions[i]);
+ }
+ }
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerUndoRedoAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerUndoRedoAction.java
new file mode 100644
index 000000000..c441f649c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/DesignerUndoRedoAction.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import java.text.MessageFormat;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.gef.ui.actions.UpdateAction;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.editors.SimpleGraphicalEditor;
+import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager;
+
+/**
+ * SSE has a IDocumentSelectionMediator mechanism, basically it let the viewer
+ * that invoke the redo/undo to reset the selection after redo/undo.
+ *
+ * To utilize this feature, we can't directly use the undo/redo action of the
+ * text editor for the designer, since in that way it will be the TextEditor to
+ * handle selection after redo/undo.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class DesignerUndoRedoAction extends Action implements UpdateAction {
+ private boolean _undo = true; // if false means redo
+
+ private SimpleGraphicalEditor _designer;
+
+ /**
+ *
+ */
+ public DesignerUndoRedoAction(boolean undo, SimpleGraphicalEditor designer) {
+ this._undo = undo;
+ this._designer = designer;
+
+ if (undo) {
+ setText(ActionsMessages.getString("DesignerUndoRedoAction.UNDO")); //$NON-NLS-1$
+ } else {
+ setText(ActionsMessages.getString("DesignerUndoRedoAction.REDO")); //$NON-NLS-1$
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.actions.UpdateAction#update()
+ */
+ public void update() {
+ IStructuredTextUndoManager undoManager = _designer.getHTMLEditor()
+ .getModel().getUndoManager();
+ if (_undo) {
+ Command c = undoManager.getUndoCommand();
+ this.setEnabled(undoManager.undoable());
+ if (c != null) {
+ String label = c.getLabel();
+ this
+ .setText(MessageFormat
+ .format(
+ ActionsMessages
+ .getString("DesignerUndoRedoAction.UNDO_LABEL"), new Object[] { label })); //$NON-NLS-1$
+ } else {
+ this.setText(ActionsMessages
+ .getString("DesignerUndoRedoAction.UNDO")); //$NON-NLS-1$
+ }
+ } else {
+ Command c = undoManager.getRedoCommand();
+ this.setEnabled(undoManager.redoable());
+ if (c != null) {
+ String label = c.getLabel();
+ this
+ .setText(MessageFormat
+ .format(
+ ActionsMessages
+ .getString("DesignerUndoRedoAction.REDO_LABEL"), new Object[] { label })); //$NON-NLS-1$
+ } else {
+ this.setText(ActionsMessages
+ .getString("DesignerUndoRedoAction.REDO")); //$NON-NLS-1$
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ IStructuredTextUndoManager undoManager = _designer.getHTMLEditor()
+ .getModel().getUndoManager();
+ if (_undo) {
+ undoManager.undo(_designer);
+ } else {
+ undoManager.redo(_designer);
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PageDesignerActionBarContributor2.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PageDesignerActionBarContributor2.java
new file mode 100644
index 000000000..50f166f96
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PageDesignerActionBarContributor2.java
@@ -0,0 +1,345 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.actions.container.ContainerActionGroup;
+import org.eclipse.jst.pagedesigner.actions.menuextension.CustomedContextMenuActionGroup;
+import org.eclipse.jst.pagedesigner.actions.range.RangeActionGroup;
+import org.eclipse.jst.pagedesigner.actions.single.SingleElementActionGroup;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.jst.pagedesigner.editors.SimpleGraphicalEditor;
+import org.eclipse.jst.pagedesigner.ui.common.sash.NestedEditorActionBarContributor;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.sse.ui.internal.ExtendedEditorActionBuilder;
+import org.eclipse.wst.sse.ui.internal.IExtendedContributor;
+import org.eclipse.wst.sse.ui.internal.ISourceViewerActionBarContributor;
+
+/**
+ * This is the actionbar contributor for HTML Editor. As HTMLEditor is
+ * multipaged, so this contributor will also handle on which page currently is
+ * activated.
+ *
+ * @author mengbo
+ */
+public class PageDesignerActionBarContributor2 extends
+ NestedEditorActionBarContributor implements IExtendedContributor {
+
+ protected DesignPageActionContributor _designViewerActionBarContributor = null;
+
+ protected ISourceViewerActionBarContributor _sourceViewerActionContributor = null;
+
+ protected HTMLEditor _htmlEditor = null;
+
+ // EditorExtension
+ private static final String EDITOR_ID = IJMTConstants.EDITORID_HTML;
+
+ private IExtendedContributor _extendedContributor;
+
+ DesignerStyleActionGroup _group = new DesignerStyleActionGroup();
+
+ private IHTMLGraphicalViewer _viewer = null;
+
+ private IStructuredModel _model = null;
+
+ public static Action action = new Action() {
+ };
+
+ public PageDesignerActionBarContributor2() {
+ super();
+
+ _sourceViewerActionContributor = new SourcePageActionContributor();
+ _designViewerActionBarContributor = new DesignPageActionContributor();
+
+ // Read action extensions.
+ ExtendedEditorActionBuilder builder = new ExtendedEditorActionBuilder();
+ _extendedContributor = builder.readActionExtensions(EDITOR_ID);
+ }
+
+ public void init(IActionBars actionBars) {
+ super.init(actionBars);
+
+ if (actionBars != null) {
+ initCommonActionBarContributor(actionBars);
+ initDesignViewerActionBarContributor(actionBars);
+ initSourceViewerActionContributor(actionBars);
+ }
+ }
+
+ /**
+ * @param actionBars
+ */
+ private void initCommonActionBarContributor(IActionBars actionBars) {
+ _group.fillActionBars(actionBars);
+ }
+
+ protected void initDesignViewerActionBarContributor(IActionBars actionBars) {
+ if (_designViewerActionBarContributor != null)
+ _designViewerActionBarContributor.init(actionBars, getPage());
+ }
+
+ protected void initSourceViewerActionContributor(IActionBars actionBars) {
+ if (_sourceViewerActionContributor != null)
+ _sourceViewerActionContributor.init(actionBars, getPage());
+ }
+
+ public void dispose() {
+ super.dispose();
+ if (_designViewerActionBarContributor != null) {
+ _designViewerActionBarContributor.dispose();
+ }
+ if (_sourceViewerActionContributor != null) {
+ _sourceViewerActionContributor.dispose();
+ }
+ if (_extendedContributor != null) {
+ _extendedContributor.dispose();
+ }
+ if (_group != null) {
+ _group.dispose();
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(IMenuManager)
+ */
+ public final void contributeToMenu(IMenuManager menu) {
+ super.contributeToMenu(menu);
+ addToMenu(menu);
+ if (_extendedContributor != null)
+ _extendedContributor.contributeToMenu(menu);
+ }
+
+ protected void addToMenu(IMenuManager menu) {
+ // IMenuManager menuMgr = new MenuManager(PD_EDITOR_MENU_LABEL,
+ // IJMTConstants.PD_EDITOR_MENU_ID);
+ // menu.insertBefore(IWorkbenchActionConstants.M_NAVIGATE, menuMgr);
+ //
+ // menuMgr.add(action);
+ // menuMgr.setRemoveAllWhenShown(true);
+ //
+ // menuMgr.addMenuListener(new IMenuListener()
+ // {
+ // public void menuAboutToShow(IMenuManager menuMgr)
+ // {
+ // PageDesignerActionConstants.addStandardActionGroups(menuMgr);
+ // RelatedViewActionGroup viewMenu = new RelatedViewActionGroup();
+ // viewMenu.fillContextMenu(menuMgr);
+ // updateEditorMenu(menuMgr);
+ // }
+ // });
+ }
+
+ /**
+ * @see IExtendedContributor#contributeToPopupMenu(IMenuManager)
+ */
+ public final void contributeToPopupMenu(IMenuManager menu) {
+ addToPopupMenu(menu);
+ if (_extendedContributor != null)
+ _extendedContributor.contributeToPopupMenu(menu);
+ }
+
+ protected void addToPopupMenu(IMenuManager menu) {
+ }
+
+ /**
+ * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToToolBar(IToolBarManager)
+ */
+ public final void contributeToToolBar(IToolBarManager toolBarManager) {
+ super.contributeToToolBar(toolBarManager);
+ addToToolBar(toolBarManager);
+ if (_extendedContributor != null)
+ _extendedContributor.contributeToToolBar(toolBarManager);
+ }
+
+ protected void addToToolBar(IToolBarManager toolBarManager) {
+ }
+
+ /**
+ * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToStatusLine(IStatusLineManager)
+ */
+ public final void contributeToStatusLine(IStatusLineManager manager) {
+ super.contributeToStatusLine(manager);
+ addToStatusLine(manager);
+ if (_extendedContributor != null)
+ _extendedContributor.contributeToStatusLine(manager);
+ }
+
+ protected void addToStatusLine(IStatusLineManager manager) {
+ }
+
+ /**
+ * @see IExtendedContributor#updateToolbarActions()
+ */
+ public void updateToolbarActions() {
+ if (_extendedContributor != null) {
+ _extendedContributor.updateToolbarActions();
+ }
+ _group.setHTMLEditor(_htmlEditor);
+ }
+
+ public void setActiveEditor(IEditorPart targetEditor) {
+ if (targetEditor instanceof HTMLEditor) {
+ _htmlEditor = (HTMLEditor) targetEditor;
+ StructuredTextEditor textEditor = _htmlEditor.getTextEditor();
+ this._model = textEditor.getModel();
+ }
+ super.setActiveEditor(targetEditor);
+ updateToolbarActions();
+ if (_extendedContributor != null)
+ _extendedContributor.setActiveEditor(targetEditor);
+ }
+
+ public void setInnerActivePage(IEditorPart activeEditor) {
+ // This contributor is designed for StructuredTextMultiPageEditorPart.
+ // To safe-guard this from problems caused by unexpected usage by
+ // other editors, the following
+ // check is added.
+ if (_htmlEditor != null) {
+ if (activeEditor instanceof StructuredTextEditor) {
+ activateSourcePage((StructuredTextEditor) activeEditor);
+ } else if (activeEditor instanceof SimpleGraphicalEditor) {
+ SimpleGraphicalEditor graphEditor = (SimpleGraphicalEditor) activeEditor;
+ activateDesignPage((SimpleGraphicalEditor) activeEditor);
+ this._viewer = graphEditor.getGraphicViewer();
+ } else {
+ // currently we don't have special action for preview.
+ deactivateSourceAndDesignPage(activeEditor);
+ this._viewer = null;
+ }
+ }
+
+ updateToolbarActions();
+
+ IActionBars actionBars = getActionBars();
+ if (actionBars != null) {
+ // update menu bar and tool bar
+ actionBars.updateActionBars();
+ }
+ }
+
+ /**
+ *
+ */
+ protected void deactivateSourceAndDesignPage(IEditorPart activeEditor) {
+ if (_designViewerActionBarContributor != null) {
+ _designViewerActionBarContributor.setActiveEditor(_htmlEditor);
+ _designViewerActionBarContributor
+ .setViewerSpecificContributionsEnabled(false);
+ }
+ if (_sourceViewerActionContributor != null) {
+ _sourceViewerActionContributor.setActiveEditor(_htmlEditor);
+ _sourceViewerActionContributor
+ .setViewerSpecificContributionsEnabled(false);
+ }
+ }
+
+ protected void activateDesignPage(SimpleGraphicalEditor activeEditor) {
+
+ if (_sourceViewerActionContributor != null /*
+ * &&
+ * _sourceViewerActionContributor
+ * instanceof
+ * ISourceViewerActionBarContributor
+ */) {
+ // previously I was trying setActiveEditor(null) here. But as in the
+ // super class will
+ // compare the editor with original one, if same then directly
+ // return. So will not disable
+ // those actions. (lium)
+ _sourceViewerActionContributor.setActiveEditor(_htmlEditor);
+ _sourceViewerActionContributor
+ .setViewerSpecificContributionsEnabled(false);
+ }
+
+ if (_designViewerActionBarContributor != null) {
+ _designViewerActionBarContributor.setActiveEditor(activeEditor);
+ _designViewerActionBarContributor
+ .setViewerSpecificContributionsEnabled(true);
+ }
+ }
+
+ protected void activateSourcePage(StructuredTextEditor activeEditor) {
+ if (_designViewerActionBarContributor != null /*
+ * &&
+ * _designViewerActionBarContributor
+ * instanceof
+ * IDesignViewerActionBarContributor
+ */) {
+ // _designViewerActionBarContributor only recogonize HTMLEditor and
+ // its own GraphicEditor. so not setting source editor to it.
+ _designViewerActionBarContributor.setActiveEditor(_htmlEditor);
+ _designViewerActionBarContributor
+ .setViewerSpecificContributionsEnabled(false);
+ }
+
+ if (_sourceViewerActionContributor != null /*
+ * &&
+ * _sourceViewerActionContributor
+ * instanceof
+ * ISourceViewerActionBarContributor
+ */) {
+ _sourceViewerActionContributor.setActiveEditor(activeEditor);
+ ((ISourceViewerActionBarContributor) _sourceViewerActionContributor)
+ .setViewerSpecificContributionsEnabled(true);
+ }
+ }
+
+ private void updateEditorMenu(IMenuManager menuMgr) {
+ if (this._viewer == null) {
+ return;
+ } else {
+ if (menuMgr != null) {
+ ContainerActionGroup containerActionGroup = new ContainerActionGroup();
+ ActionContext context = new ActionContext(this._viewer
+ .getSelection());
+ context.setInput(this._viewer);
+ containerActionGroup.setContext(context);
+ containerActionGroup.fillContextMenu(menuMgr);
+ containerActionGroup.setContext(null);
+
+ RangeActionGroup rangeActionGroup = new RangeActionGroup();
+ context = new ActionContext(this._viewer.getSelection());
+ context.setInput(this._viewer);
+ rangeActionGroup.setContext(context);
+ rangeActionGroup.fillContextMenu(menuMgr);
+ rangeActionGroup.setContext(null);
+
+ SingleElementActionGroup singleActionGroup = new SingleElementActionGroup();
+ singleActionGroup.setContext(new ActionContext(this._viewer
+ .getSelection()));
+ singleActionGroup.fillContextMenu(menuMgr);
+ singleActionGroup.setContext(null);
+
+ if (this._model != null) {
+ CustomedContextMenuActionGroup customedMenu = new CustomedContextMenuActionGroup();
+ customedMenu.setContext(new ActionContext(_viewer
+ .getSelection()));
+ customedMenu.setModel(_model);
+ customedMenu.setParentControl(_viewer.getControl());
+ customedMenu.fillContextMenu(menuMgr);
+ customedMenu.setContext(null);
+ customedMenu.setParentControl(null);
+ customedMenu.setModel(null);
+ }
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PaletteViewAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PaletteViewAction.java
new file mode 100644
index 000000000..cad7e3dc9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PaletteViewAction.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.gef.ui.views.palette.PaletteView;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PaletteViewAction extends Action {
+ public final static String ID = "org.eclipse.jst.pagedesigner.editors.actions.PaletteViewAction"; //$NON-NLS-1$
+
+ private static Logger _log = PDPlugin.getLogger(PaletteViewAction.class);
+
+ public PaletteViewAction() {
+ setText(ActionsMessages.getString("PaletteViewAction.Menu.PaletteView")); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ try {
+ getPage().showView(PaletteView.ID);
+ } catch (PartInitException e) {
+ _log.info("Open the Palette View", e);
+ }
+
+ }
+
+ private IWorkbenchPage getPage() {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ return window.getActivePage();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PropertiesViewAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PropertiesViewAction.java
new file mode 100644
index 000000000..60fa9daa9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/PropertiesViewAction.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author mengbo
+ */
+public class PropertiesViewAction extends Action {
+ public final static String ID = "org.eclipse.jst.pagedesigner.editors.actions.PropertiesViewAction"; //$NON-NLS-1$
+
+ private static Logger _log = PDPlugin.getLogger(PropertiesViewAction.class);
+
+ public PropertiesViewAction() {
+ setText(ActionsMessages
+ .getString("PropertiesViewAction.Menu.Properties")); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ try {
+ getPage().showView(IPageLayout.ID_PROP_SHEET);
+ } catch (PartInitException e) {
+ _log.info("Open the Properties View", e);
+ }
+
+ }
+
+ private IWorkbenchPage getPage() {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ return window.getActivePage();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/RelatedViewActionGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/RelatedViewActionGroup.java
new file mode 100644
index 000000000..bcc3bd41a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/RelatedViewActionGroup.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RelatedViewActionGroup extends ActionGroup {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ super.fillContextMenu(menu);
+
+ final IMenuManager viewMgr = new MenuManager(ActionsMessages
+ .getString("RelatedViewActionGroup.Menu.ShowView"),//$NON-NLS-1$
+ PageDesignerActionConstants.MENUMGR_VIEW_ID);
+ viewMgr.add(new Action() {
+
+ });
+ viewMgr.setRemoveAllWhenShown(true);
+ viewMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ String[] views = { "org.eclipse.ui.views.PropertySheet",
+ "org.eclipse.gef.ui.palette_view"};
+// "org.eclipse.jst.pagedesigner.databinding.ui.views.DataBindingsView" };
+ Map icons = getIconForView(views);
+ if (manager.find(PropertiesViewAction.ID) == null) {
+ Action action = new PropertiesViewAction();
+ action.setId(PropertiesViewAction.ID);
+ action.setImageDescriptor((ImageDescriptor) icons
+ .get(views[0]));
+ manager.add(action);
+ }
+ if (manager.find(PaletteViewAction.ID) == null) {
+ Action action = new PaletteViewAction();
+ action.setId(PaletteViewAction.ID);
+ action.setImageDescriptor((ImageDescriptor) icons
+ .get(views[1]));
+ manager.add(action);
+ }
+ /*
+ if (manager.find(DataBindingViewAction.ID) == null) {
+ Action action = new DataBindingViewAction();
+ action.setId(DataBindingViewAction.ID);
+ action.setImageDescriptor((ImageDescriptor) icons
+ .get(views[2]));
+ manager.add(action);
+ }
+ */
+ }
+ });
+ menu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, viewMgr);
+ }
+
+ private Map getIconForView(String[] viewids) {
+ List views = Arrays.asList(viewids);
+ Map icons = new HashMap();
+
+ IConfigurationElement[] elements = Platform.getExtensionRegistry()
+ .getConfigurationElementsFor("org.eclipse.ui.views");
+ for (int i = 0; i < elements.length; i++) {
+ String name = elements[i].getName();
+ String id = elements[i].getAttribute("id");
+ if ("view".equals(name) && views.contains(id)) {
+ String iconPath = elements[i].getAttribute("icon");
+ if (iconPath != null) {
+ icons.put(id, AbstractUIPlugin.imageDescriptorFromPlugin(
+ elements[i].getDeclaringExtension().getNamespace(),
+ iconPath));
+ } else {
+ icons.put(id, null);
+ }
+ if (icons.size() == viewids.length) {
+ break;
+ }
+ }
+ }
+ return icons;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/SourcePageActionContributor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/SourcePageActionContributor.java
new file mode 100644
index 000000000..7d48737e4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/actions/SourcePageActionContributor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.actions;
+
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.wst.xml.ui.internal.actions.ActionContributorXML;
+
+/**
+ * SourcePageActionContributor
+ *
+ * This class is for multi page editor's source page contributor.
+ *
+ * Use XMLEditorActionContributor for single page editor.
+ */
+public class SourcePageActionContributor extends ActionContributorXML {
+
+ private IActionBars fBars;
+
+ /**
+ * This method calls:
+ * <ul>
+ * <li><code>contributeToMenu</code> with <code>bars</code>' menu
+ * manager</li>
+ * <li><code>contributeToToolBar</code> with <code>bars</code>' tool
+ * bar manager</li>
+ * <li><code>contributeToStatusLine</code> with <code>bars</code>'
+ * status line manager</li>
+ * </ul>
+ * The given action bars are also remembered and made accessible via
+ * <code>getActionBars</code>.
+ *
+ * @param bars
+ * the action bars
+ *
+ */
+ public void init(IActionBars bars) {
+ fBars = bars;
+ contributeToMenu(bars.getMenuManager());
+ contributeToToolBar(bars.getToolBarManager());
+ contributeToStatusLine(bars.getStatusLineManager());
+ }
+
+ /**
+ * Returns this contributor's action bars.
+ *
+ * @return the action bars
+ */
+ public IActionBars getActionBars() {
+ return fBars;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.internal.ISourceViewerActionBarContributor#setViewerSpecificContributionsEnabled(boolean)
+ */
+ public void setViewerSpecificContributionsEnabled(boolean enabled) {
+ super.setViewerSpecificContributionsEnabled(enabled);
+ IEditorPart editor = getActiveEditorPart();
+ ITextEditor targetEditor = null;
+ if (editor instanceof ITextEditor) {
+ targetEditor = (ITextEditor) editor;
+ } else if (editor instanceof HTMLEditor) {
+ targetEditor = ((HTMLEditor) editor).getTextEditor();
+ }
+ if (targetEditor != null) {
+ if (enabled) {
+ getActionBars()
+ .setGlobalActionHandler(
+ ITextEditorActionConstants.UNDO,
+ targetEditor
+ .getAction(ITextEditorActionConstants.UNDO));
+ getActionBars()
+ .setGlobalActionHandler(
+ ITextEditorActionConstants.REDO,
+ targetEditor
+ .getAction(ITextEditorActionConstants.REDO));
+ } else {
+ getActionBars().setGlobalActionHandler(
+ ITextEditorActionConstants.UNDO, null);
+ getActionBars().setGlobalActionHandler(
+ ITextEditorActionConstants.REDO, null);
+ }
+
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/DelegatingZoomManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/DelegatingZoomManager.java
new file mode 100644
index 000000000..e8988ac3f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/DelegatingZoomManager.java
@@ -0,0 +1,374 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.pagedesigner;
+
+import org.eclipse.draw2d.ScalableFigure;
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.editparts.ZoomListener;
+import org.eclipse.gef.editparts.ZoomManager;
+import org.eclipse.jface.util.ListenerList;
+
+/**
+ * A delegating ZoomManager.
+ */
+public class DelegatingZoomManager extends ZoomManager implements ZoomListener {
+ /** the current ZoomManager all work is delegated to */
+ private final static int DEFAULT_ZOOM = 1;
+
+ private final static String ZOOM_AS_TEXT = "100%";
+
+ private final static String ZOOM_LEVEL_AS_TEXT = "100%";
+
+ private ZoomManager _currentZoomManager;
+
+ /** listeners */
+ private ListenerList _zoomListeners = new ListenerList(3);
+
+ /**
+ * Creates a new DelegatingZoomManager instance.
+ */
+ public DelegatingZoomManager() {
+ super((ScalableFigure) null, (Viewport) null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomListener#zoomChanged(double)
+ */
+ public void zoomChanged(double zoom) {
+ Object[] listeners = _zoomListeners.getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ ((ZoomListener) listeners[i]).zoomChanged(zoom);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#addZoomListener(org.eclipse.gef.editparts.ZoomListener)
+ */
+ public void addZoomListener(ZoomListener listener) {
+ _zoomListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#removeZoomListener(org.eclipse.gef.editparts.ZoomListener)
+ */
+ public void removeZoomListener(ZoomListener listener) {
+ _zoomListeners.remove(listener);
+ }
+
+ /**
+ * Sets the ZoomManager all work should be delegated to.
+ *
+ * @param zoomManager
+ */
+ public void setCurrentZoomManager(ZoomManager zoomManager) {
+ if (null != _currentZoomManager) {
+ _currentZoomManager.removeZoomListener(this);
+ }
+
+ _currentZoomManager = zoomManager;
+ if (null != _currentZoomManager) {
+ _currentZoomManager.addZoomListener(this);
+ zoomChanged(_currentZoomManager.getZoom());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#canZoomIn()
+ */
+ public boolean canZoomIn() {
+ if (null == _currentZoomManager) {
+ return false;
+ }
+ return _currentZoomManager.canZoomIn();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#canZoomOut()
+ */
+ public boolean canZoomOut() {
+ if (null == _currentZoomManager) {
+ return false;
+ }
+ return _currentZoomManager.canZoomOut();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getMaxZoom()
+ */
+ public double getMaxZoom() {
+ if (null == _currentZoomManager) {
+ return DEFAULT_ZOOM;
+ }
+
+ return _currentZoomManager.getMaxZoom();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getMinZoom()
+ */
+ public double getMinZoom() {
+ if (null == _currentZoomManager) {
+ return DEFAULT_ZOOM;
+ }
+ return _currentZoomManager.getMinZoom();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getNextZoomLevel()
+ */
+ public double getNextZoomLevel() {
+ if (null == _currentZoomManager) {
+ return DEFAULT_ZOOM;
+ }
+ return _currentZoomManager.getNextZoomLevel();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getPreviousZoomLevel()
+ */
+ public double getPreviousZoomLevel() {
+ if (null == _currentZoomManager) {
+ return DEFAULT_ZOOM;
+ }
+ return _currentZoomManager.getPreviousZoomLevel();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getScalableFigure()
+ */
+ public ScalableFigure getScalableFigure() {
+ if (null == _currentZoomManager) {
+ return null;
+ }
+
+ return _currentZoomManager.getScalableFigure();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getUIMultiplier()
+ */
+ public double getUIMultiplier() {
+ if (null == _currentZoomManager) {
+ return DEFAULT_ZOOM;
+ }
+
+ return _currentZoomManager.getUIMultiplier();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getViewport()
+ */
+ public Viewport getViewport() {
+ if (null == _currentZoomManager) {
+ return null;
+ }
+
+ return _currentZoomManager.getViewport();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getZoom()
+ */
+ public double getZoom() {
+ if (null == _currentZoomManager) {
+ return DEFAULT_ZOOM;
+ }
+
+ return _currentZoomManager.getZoom();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getZoomAsText()
+ */
+ public String getZoomAsText() {
+ if (null == _currentZoomManager) {
+ return ZOOM_AS_TEXT;
+ }
+ //$NON-NLS-1$
+
+ return _currentZoomManager.getZoomAsText();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getZoomLevels()
+ */
+ public double[] getZoomLevels() {
+ if (null == _currentZoomManager) {
+ return new double[] { DEFAULT_ZOOM };
+ }
+
+ return _currentZoomManager.getZoomLevels();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#getZoomLevelsAsText()
+ */
+ public String[] getZoomLevelsAsText() {
+ if (null == _currentZoomManager) {
+ return new String[] { ZOOM_LEVEL_AS_TEXT };
+ }
+
+ return _currentZoomManager.getZoomLevelsAsText();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#setUIMultiplier(double)
+ */
+ public void setUIMultiplier(double multiplier) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.setUIMultiplier(multiplier);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#setViewLocation(org.eclipse.draw2d.geometry.Point)
+ */
+ public void setViewLocation(Point p) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.setViewLocation(p);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#setZoom(double)
+ */
+ public void setZoom(double zoom) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.setZoom(zoom);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#setZoomAnimationStyle(int)
+ */
+ public void setZoomAnimationStyle(int style) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.setZoomAnimationStyle(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#setZoomAsText(java.lang.String)
+ */
+ public void setZoomAsText(String zoomString) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.setZoomAsText(zoomString);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#setZoomLevels(double[])
+ */
+ public void setZoomLevels(double[] zoomLevels) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.setZoomLevels(zoomLevels);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#zoomIn()
+ */
+ public void zoomIn() {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.zoomIn();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#zoomOut()
+ */
+ public void zoomOut() {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.zoomOut();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.ZoomManager#zoomTo(org.eclipse.draw2d.geometry.Rectangle)
+ */
+ public void zoomTo(Rectangle rect) {
+ if (null == _currentZoomManager) {
+ return;
+ }
+
+ _currentZoomManager.zoomTo(rect);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/IPageDesignerConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/IPageDesignerConstants.java
new file mode 100644
index 000000000..911d9d269
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/IPageDesignerConstants.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.pagedesigner;
+
+public interface IPageDesignerConstants {
+ /**
+ * JSP UI Component Tag Node
+ */
+ public static final String DEFAULT_TAG_NAME = "tagname";
+
+ public static final String ATTR_TYPE_CDATA = "CDATA";
+
+ public static final String ATTR_LOADBUNDLE_1 = "basename";
+
+ public static final String ATTR_LOADBUNDLE_2 = "var";
+
+ public static final String ATTR_PANELGRID_1 = "columns";
+
+ public static final String ATTR_PANELGRID_2 = "summary";
+
+ public static final String ATTR_PANELGRID_3 = "title";
+
+ public static final String ATTR_BUTTON_1 = "action";
+
+ public static final String ATTR_BUTTON_2 = "value";
+
+ public static final String ATTR_GRAPHICIMAGE_1 = "url";
+
+ public static final String ATTR_GRAPHICIMAGE_2 = "binding";
+
+ public static final String ATTR_OUTPUTTEXT_1 = "binding";
+
+ public static final String ATTR_OUTPUTTEXT_2 = "value";
+
+ public static final String ATTR_OUTPUTTEXT_3 = "styleClass";
+
+ public static final String ATTR_DATAWINDOW_1 = "dataWindowBean";
+
+ public static final String ATTR_DATAWINDOW_2 = "scriptName";
+
+ public static final String ATTR_INCLUDE = "page";
+
+ public static final String ATTR_TAGLIB_1 = "prefix";
+
+ public static final String ATTR_TAGLIB_2 = "uri";
+
+ public static final String RESOURCE_BUNDLE_MARK = "bundle";
+
+ public static final String ATTR_RESOURCE_BUNDLE = "value";
+
+ public static final String ATTR_FACET = "value";
+
+ public static final String TAG_VIEW_TYPE = "view";
+
+ public static final String TAG_FORM_TYPE = "form";
+
+ public static final String TAG_TEXT_TYPE = "text";
+
+ public static final String TAG_LOADBUNDLE_TYPE = "loadBundle";
+
+ public static final String TAG_PANELGRID_TYPE = "panelGrid";
+
+ public static final String TAG_IMAGE_TYPE = "image";
+
+ public String TAG_OUTPUTTEXT_TYPE = "outputText";
+
+ public String TAG_BUTTON_TYPE = "button";
+
+ public String TAG_DATAWINDOW_TYPE = "datawindow";
+
+ public String TAG_TAGLIB_TYPE = "taglib";
+
+ public String TAG_INCLUDE_TYPE = "include";
+
+ public String TAG_OTHERS_TYPE = "";
+
+ public String TAG_NAME_VIEW = "view";
+
+ public String TAG_NAME_FORM = "form";
+
+ public String TAG_NAME_PANELGRID = "panelGrid";
+
+ public String TAG_NAME_PANELGROUP = "panelGroup";
+
+ public String TAG_NAME_FACET = "facet";
+
+ public String TAG_NAME_DATAWINDOW = "dataWindow";
+
+ public String TAG_NAME_OUTPUTTEXT = "outputText";
+
+ public String TAG_NAME_INCLUDE = "include";
+
+ public String TAG_NAME_LOADBUNDLE = "loadBundle";
+
+ public String TAG_NAME_TAGLIB = "taglib";
+
+ public String TAG_NAME_GRAPHICIMAGE = "graphicImage";
+
+ public String TAG_NAME_COMMANDBUTTON = "commandButton";
+
+ public String REQUEST_TYPE_SELECT = "selection";
+
+ public static final int EOF = -1;
+
+ public char CHAR_TAB = '\t';
+
+ public char CHAR_N_RETURN = '\n';
+
+ public String STRING_N_RETURN = "\n";
+
+ public String STRING_BLANK = " ";
+
+ public char CHAR_BLANK = ' ';
+
+ public String FONT_NAME_HELVETICA = "Helvetica";
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/JSPEditorMessages.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/JSPEditorMessages.properties
new file mode 100644
index 000000000..4817ec09b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/JSPEditorMessages.properties
@@ -0,0 +1,13 @@
+JSFPalette.DefaultGroup.LabelJSFPallete=Controls
+JSPSourceEditor.Page.Preview.PageText=Preview
+
+CommonResourceDialog.statusMessage=Select an image file
+ResourcesOnClasspathDialog.statusMessage=Select a property file
+TreeViewerSelectionDialog.Title=Select a file
+RangeSelectionTool.CommandLabel.Insert=Insert
+
+DesignerPaletteCustomizerDialog.label.import=Import
+DesignerPaletteCustomizerDialog.label.export=Export
+
+DesignerSourceDropTargetListener.InserCommandLabel=Create New Item
+SourceViewLocalDropCommand.Label.InsertSyntax=Insert Syntax
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/MessageFormater.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/MessageFormater.java
new file mode 100644
index 000000000..4a1ccd965
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/MessageFormater.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.pagedesigner;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+
+/**
+ * @A tool class for message format
+ */
+public class MessageFormater {
+ private static Logger _log = PDPlugin.getLogger(MessageFormater.class);
+
+ /**
+ * *
+ *
+ * @param message:
+ * the parts for filling is {number}
+ * @param o1
+ * @return
+ */
+ public static String format(String message, Object o1) {
+ try {
+ Object[] args = new Object[] { o1 };
+ MessageFormat formatter = new MessageFormat(message);
+ return formatter.format(args);
+ } catch (Exception e) {
+ _log.error("Log.Error.MessageFormater.Format0", e); //$NON-NLS-1$
+ return "";
+ }
+ }
+
+ public static String format(String message, Object o1, Object o2) {
+ try {
+ Object[] args = new Object[] { o1, o2 };
+ MessageFormat formatter = new MessageFormat(message);
+ return formatter.format(args);
+ } catch (Exception e) {
+ _log.error("Log.Error.MessageFormater.Format0", e);
+ return "";
+ }
+ }
+
+ public static String format(String message, Object o1, Object o2, Object o3) {
+ try {
+ Object[] args = new Object[] { o1, o2, o3 };
+ MessageFormat formatter = new MessageFormat(message);
+ return formatter.format(args);
+ } catch (Exception e) {
+ _log.error("Log.Error.MessageFormater.Format0", e);
+ return "";
+ }
+ }
+
+ public static String format(String message, Object o[]) {
+ try {
+ MessageFormat formater = new MessageFormat(message);
+ return formater.format(o);
+ } catch (Exception e) {
+ _log.error("Log.Error.MessageFormater.Format0", e);
+ return "";
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/PageDesignerResources.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/PageDesignerResources.java
new file mode 100644
index 000000000..6009f4167
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/pagedesigner/PageDesignerResources.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.pagedesigner;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+
+/**
+ * @author mengbo
+ */
+public class PageDesignerResources extends ResourceUtils {
+ private static Logger _log = PDPlugin
+ .getLogger(PageDesignerResources.class);
+
+ private static PageDesignerResources _resource; // singleton
+
+ /**
+ * Empty Constructor.
+ */
+ protected PageDesignerResources() {
+ try {
+ _resources = ResourceBundle
+ .getBundle(IJMTConstants.PAGEDESIGNER_RESOURCE_BUNDLE_FILE);
+ // NOTE: this throws a runtime "MissingResourceException".
+ } catch (MissingResourceException ee) {
+ // catch this and the error is reported in setBundle.
+ // Log.Error.PageDesignerResources.Open=Error in getting source
+ // bundle
+ _log.error("Log.Error.PageDesignerResources.Open", ee); //$NON-NLS-1$
+ }
+ setBundle(_resources, IJMTConstants.PAGEDESIGNER_RESOURCE_BUNDLE_FILE);
+ }
+
+ public static PageDesignerResources getInstance() {
+ if (_resource == null) {
+ _resource = new PageDesignerResources();
+ }
+ return _resource;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizer.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizer.java
new file mode 100644
index 000000000..e7023d161
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizer.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.gef.palette.PaletteDrawer;
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.gef.ui.palette.PaletteCustomizer;
+import org.eclipse.gef.ui.palette.customize.PaletteSeparatorFactory;
+import org.eclipse.gef.ui.palette.customize.PaletteStackFactory;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+
+/**
+ * @author mengbo
+ */
+public class DesignerPaletteCustomizer extends PaletteCustomizer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#canMoveDown(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public boolean canMoveDown(PaletteEntry entry) {
+ if (!(entry instanceof PaletteDrawer)) {
+ return false;
+ }
+ return super.canMoveDown(entry);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#canMoveUp(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public boolean canMoveUp(PaletteEntry entry) {
+ if (!(entry instanceof PaletteDrawer)) {
+ return false;
+ }
+ if (entry.getParent().getChildren().indexOf(entry) == 1) {
+ return false;
+ }
+ return super.canMoveUp(entry);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#performMoveDown(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public void performMoveDown(PaletteEntry entry) {
+ if (entry instanceof PaletteDrawer) {
+ String id = entry.getId();
+ IPaletteItemCategory cat = PaletteItemManager.getInstance(
+ getCurrentProject()).getCategoryByURI(id);
+ PaletteItemManager.getInstance(getCurrentProject()).movedown(cat);
+ super.performMoveDown(entry);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#performMoveUp(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public void performMoveUp(PaletteEntry entry) {
+ if (entry instanceof PaletteDrawer) {
+ String id = entry.getId();
+ IPaletteItemCategory cat = PaletteItemManager.getInstance(
+ getCurrentProject()).getCategoryByURI(id);
+ PaletteItemManager.getInstance(getCurrentProject()).moveup(cat);
+ super.performMoveUp(entry);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#canDelete(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public boolean canDelete(PaletteEntry entry) {
+ return false;
+ }
+
+ public List getNewEntryFactories() {
+ List list = new ArrayList(4);
+ list.add(new PaletteSeparatorFactory());
+ list.add(new PaletteStackFactory());
+ return list;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#revertToSaved()
+ */
+ public void revertToSaved() {
+ // PaletteItemManager.getInstance(getCurrentProject()).
+ PaletteItemManager.getInstance(getCurrentProject()).reset();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteCustomizer#save()
+ */
+ public void save() {
+ PaletteItemManager.getInstance(getCurrentProject()).save();
+ PaletteItemManager.getInstance(getCurrentProject()).reset();
+ }
+
+ private IProject getCurrentProject() {
+ IProject curProject = null;
+ IEditorPart editor = PDPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ IEditorInput input = editor.getEditorInput();
+ IFile inputFile = null;
+ if (input instanceof IFileEditorInput) {
+ inputFile = ((IFileEditorInput) input).getFile();
+ curProject = inputFile.getProject();
+ }
+ return curProject;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizerDialog.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizerDialog.java
new file mode 100644
index 000000000..0f2f8d924
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteCustomizerDialog.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.gef.palette.PaletteRoot;
+import org.eclipse.gef.ui.palette.PaletteCustomizer;
+import org.eclipse.gef.ui.palette.customize.PaletteCustomizationAction;
+import org.eclipse.gef.ui.palette.customize.PaletteCustomizerDialog;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.utils.PluginImageHelper;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DesignerPaletteCustomizerDialog extends PaletteCustomizerDialog {
+ private static String DEFAULTEXTENSION = ".xml";//$NON-NLS-1$
+
+ public DesignerPaletteCustomizerDialog(Shell shell,
+ PaletteCustomizer customizer, PaletteRoot root) {
+ super(shell, customizer, root);
+
+ }
+
+ private PropertyChangeListener applyButtonUpdater = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent evt) {
+ Button applyButton = getButton(PaletteCustomizerDialog.APPLY_ID);
+ if (applyButton == null) {
+ return;
+ }
+ applyButton.setEnabled(true);
+ }
+ };
+
+ public int open() {
+ // save the current state before open
+ // save();
+
+ return super.open();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.customize.PaletteCustomizerDialog#setActiveEntry(org.eclipse.gef.palette.PaletteEntry)
+ */
+ protected void setActiveEntry(PaletteEntry entry) {
+ PaletteEntry pre = getSelectedPaletteEntry();
+ if (pre != null) {
+ pre.removePropertyChangeListener(applyButtonUpdater);
+ }
+ entry.addPropertyChangeListener(applyButtonUpdater);
+ super.setActiveEntry(entry);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.customize.PaletteCustomizerDialog#save()
+ */
+ protected void save() {
+ // TODO Auto-generated method stub
+ super.save();
+ Button applyButton = getButton(PaletteCustomizerDialog.APPLY_ID);
+ if (applyButton != null) {
+ applyButton.setEnabled(false);
+ }
+ }
+
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ // save();
+ }
+
+ private class ExportAction extends PaletteCustomizationAction {
+ public ExportAction() {
+ setEnabled(true);
+ setText(PageDesignerResources.getInstance().getString(
+ "DesignerPaletteCustomizerDialog.label.export")); //$NON-NLS-1$
+ setImageDescriptor(PluginImageHelper.getInstance()
+ .getImageDescriptor(DesignerPaletteImages.IMG_ELCL_EXPORT,
+ PDPlugin.getPluginId()));
+ setDisabledImageDescriptor(PluginImageHelper.getInstance()
+ .getImageDescriptor(DesignerPaletteImages.IMG_DLCL_EXPORT,
+ PDPlugin.getPluginId()));
+ setHoverImageDescriptor(PluginImageHelper.getInstance()
+ .getImageDescriptor(DesignerPaletteImages.IMG_CLCL_EXPORT,
+ PDPlugin.getPluginId()));
+ }
+
+ protected void handleExport() {
+ final FileDialog fileDialog = new FileDialog(PDPlugin
+ .getActiveWorkbenchShell());
+ fileDialog.setFileName("tag.xml"); //$NON-NLS-1$
+ String[] filterExtensions = new String[2];
+ filterExtensions[0] = "*.xml"; //$NON-NLS-1$
+ filterExtensions[1] = "*.*"; //$NON-NLS-1$
+ fileDialog.setFilterExtensions(filterExtensions);
+ String filename = fileDialog.open();
+ if (filename != null) {
+ if (!filename.endsWith(DEFAULTEXTENSION)) {
+ filename = filename + DEFAULTEXTENSION;
+ }
+ PaletteItemManager.getInstance(PDPlugin.getCurrentProject())
+ .setFilename(filename);
+ PaletteItemManager.getInstance(PDPlugin.getCurrentProject())
+ .save();
+ PaletteItemManager.getInstance(PDPlugin.getCurrentProject())
+ .setFilename(null);
+ updateActions();
+ }
+ }
+
+ public void run() {
+ handleExport();
+ }
+
+ public void update() {
+ boolean enabled = false;
+ PaletteEntry entry = getSelectedPaletteEntry();
+ if (entry != null) {
+ // if (getCustomizer() instanceof DesignerPaletteCustomizer)
+ // enabled = ((DesignerPaletteCustomizer)
+ // getCustomizer()).canExport(entry);
+ }
+ setEnabled(true);
+ }
+
+ }
+
+ private class ImportAction extends PaletteCustomizationAction {
+ public ImportAction() {
+ setEnabled(true);
+ setText(PageDesignerResources.getInstance().getString(
+ "DesignerPaletteCustomizerDialog.label.import")); //$NON-NLS-1$
+ setImageDescriptor(PluginImageHelper.getInstance()
+ .getImageDescriptor(DesignerPaletteImages.IMG_ELCL_IMPORT,
+ PDPlugin.getPluginId()));
+ setDisabledImageDescriptor(PluginImageHelper.getInstance()
+ .getImageDescriptor(DesignerPaletteImages.IMG_DLCL_IMPORT,
+ PDPlugin.getPluginId()));
+ setHoverImageDescriptor(PluginImageHelper.getInstance()
+ .getImageDescriptor(DesignerPaletteImages.IMG_CLCL_IMPORT,
+ PDPlugin.getPluginId()));
+ }
+
+ protected void handleImport() {
+ final FileDialog fileDialog = new FileDialog(PDPlugin
+ .getActiveWorkbenchShell());
+ fileDialog.setFileName("tag.xml"); //$NON-NLS-1$
+ String[] filterExtensions = new String[2];
+ filterExtensions[0] = "*.xml"; //$NON-NLS-1$
+ filterExtensions[1] = "*.*"; //$NON-NLS-1$
+ fileDialog.setFilterExtensions(filterExtensions);
+ String filename = fileDialog.open();
+ PaletteItemManager.getInstance(PDPlugin.getCurrentProject())
+ .setFilename(filename);
+ PaletteItemManager.getInstance(PDPlugin.getCurrentProject())
+ .reset();
+ PaletteItemManager.getInstance(PDPlugin.getCurrentProject())
+ .setFilename(null);
+ }
+
+ public void run() {
+ handleImport();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.customize.PaletteCustomizationAction#update()
+ */
+ public void update() {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ public Action getImportAction() {
+ return new ImportAction();
+ }
+
+ public Action getExportAction() {
+ return new ExportAction();
+ }
+
+ protected List createOutlineActions() {
+ List actions = super.createOutlineActions();
+ actions.remove(0);// remove new action
+ actions.remove(0);// remove delete action
+ actions.add(new ImportAction());
+ actions.add(new ExportAction());
+
+ return actions;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteImages.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteImages.java
new file mode 100644
index 000000000..8ed96f3a7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteImages.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+/**
+ * @author mengbo
+ */
+public class DesignerPaletteImages {
+ public static final String IMG_CLCL_IMPORT = "icons/palette/GENERIC/small/PD_Palette_Import_Hover.gif";
+
+ public static final String IMG_CLCL_EXPORT = "icons/palette/GENERIC/small/PD_Palette_Export_Hover.gif";
+
+ public static final String IMG_DLCL_IMPORT = "icons/palette/GENERIC/small/PD_Palette_Import_Disabled.gif";
+
+ public static final String IMG_DLCL_EXPORT = "icons/palette/GENERIC/small/PD_Palette_Export_Disabled.gif";
+
+ public static final String IMG_ELCL_IMPORT = "icons/palette/GENERIC/small/PD_Palette_Import.gif";
+
+ public static final String IMG_ELCL_EXPORT = "icons/palette/GENERIC/small/PD_Palette_Export.gif";
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteRoot.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteRoot.java
new file mode 100644
index 000000000..46556e418
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteRoot.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.gef.Tool;
+import org.eclipse.gef.palette.MarqueeToolEntry;
+import org.eclipse.gef.palette.PaletteDrawer;
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.gef.palette.PaletteGroup;
+import org.eclipse.gef.palette.PaletteRoot;
+import org.eclipse.gef.palette.SelectionToolEntry;
+import org.eclipse.gef.palette.ToolEntry;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemToolEntry;
+import org.eclipse.jst.pagedesigner.tools.RangeSelectionTool;
+
+/**
+ * @author mengbo
+ */
+public class DesignerPaletteRoot extends PaletteRoot {
+ private IPaletteItemManager _manager;
+
+ private final static ImageDescriptor DEFAULT_SMALL_ICON = PDPlugin
+ .getDefault().getImageDescriptor(
+ "palette/GENERIC/small/PD_Palette_Default.gif");
+
+ private final static ImageDescriptor DEFAULT_LARGE_ICON = PDPlugin
+ .getDefault().getImageDescriptor(
+ "palette/GENERIC/large/PD_Palette_Default.gif");
+
+ // _showAll will be initialized in init()
+ // private boolean _showAll;
+
+ /**
+ * Creates a new JSFPaletteRoot instance.
+ */
+ public DesignerPaletteRoot(IPaletteItemManager manager) {
+ // create root
+ super();
+
+ this._manager = manager;
+ setupBasicItems();
+ loadItems();
+
+ // TODO: register listener on the manager for toolpalette change event.
+
+ }
+
+ public IPaletteItemManager getPaletteManager() {
+ return this._manager;
+ }
+
+ protected void setupBasicItems() {
+ // Preferences prefs = PDPlugin.getDefault().getPluginPreferences();
+ // _showAll = prefs.getBoolean(IJMTConstants.PREF_PALETTE_SHOW_ALL);
+
+ // a group of default control tools
+ // JSFPalette.DefaultGroup.LabelJSFPallete=Controls
+ PaletteGroup controls = new PaletteGroup(PageDesignerResources
+ .getInstance().getString(
+ "JSFPalette.DefaultGroup.LabelJSFPallete")); //$NON-NLS-1$
+ add(controls);
+ // the selection tool
+ ToolEntry tool = new SelectionToolEntry() {
+ public Tool createTool() {
+ return new RangeSelectionTool();
+ }
+ };
+ controls.add(tool);
+
+ // use selection tool as default entry
+ setDefaultEntry(tool);
+
+ // the marquee selection tool
+ controls.add(new MarqueeToolEntry());
+ }
+
+ public void loadItems() {
+ // _showAll =
+ // PDPlugin.getDefault().getPluginPreferences().getBoolean(IJMTConstants.PREF_PALETTE_SHOW_ALL);
+ // remove other things first.
+ removeItems();
+
+ PaletteEntry entry;
+
+ List categories = _manager.getAllCategories();
+ List drawers = new ArrayList(categories.size());
+ for (int i = 0, m = categories.size(); i < m; i++) {
+ IPaletteItemCategory cat = (IPaletteItemCategory) categories.get(i);
+ PaletteDrawer drawer = new PaletteDrawer(cat.getLabel());
+ cat.setPaletteEntry(drawer);
+ drawer.setId(cat.getId());
+ drawer.setLabel(cat.getLabel());
+ drawer.setDescription(cat.getDescription());
+ drawer.setVisible(cat.isVisible());
+ drawer.setInitialState(cat.getInitialState());
+ // if (i==categories.size()-1)
+ // {
+ // drawer.setInitialState(PaletteDrawer.INITIAL_STATE_OPEN);
+ // }
+ // else
+ // {
+ // drawer.setInitialState(PaletteDrawer.INITIAL_STATE_CLOSED);
+ // }
+ List items = cat.getPaletteItems();
+ for (int j = 0, n = items.size(); j < n; j++) {
+ entry = createEntry((IPaletteItemDescriptor) items.get(j));
+ if (entry != null) {
+ drawer.add(entry);
+ }
+ }
+ drawers.add(drawer);
+ }
+ // ok, add all the drawers at once
+ this.addAll(drawers);
+ }
+
+ /**
+ * @param descriptor
+ * @return
+ */
+ private PaletteEntry createEntry(IPaletteItemDescriptor descriptor) {
+ // check expert flag.
+ // if (descriptor.isVisible() && !_showAll)
+ // return null;
+
+ // XXX: it is possible to let descriptor to implement certain interface
+ // to provide
+ // special palette entry other than the default one.
+ String label = descriptor.getLabel();
+ if (label == null || label.length() == 0) {
+ label = descriptor.getTagName();
+ }
+ String shortDesc = descriptor.getDescription();
+ if (shortDesc == null || shortDesc.length() == 0) {
+ shortDesc = label;
+ }
+ shortDesc = formatDescription(shortDesc);
+ ImageDescriptor iconSmall = descriptor.getSmallIcon();
+ if (iconSmall == null) {
+ iconSmall = getDefaultSmallIcon();
+ }
+ ImageDescriptor iconLarge = descriptor.getLargeIcon();
+ if (iconLarge == null) {
+ iconLarge = getDefaultLargeIcon();
+ }
+
+ // TODO: suggested prefix is null now. We may also put that into
+ // itemdescriptor
+ // CreationFactory factory = new
+ // NodeCreationFactory(descriptor.getURI(), descriptor.getTagName(),
+ // null, descriptor.getInitialAttributes());
+
+ // CreationToolEntry entry = new CreationToolEntry(label, shortDesc,
+ // factory, iconSmall, iconLarge);
+ ItemToolEntry entry = new ItemToolEntry(label, shortDesc, iconSmall,
+ iconLarge, descriptor);
+ entry.setId(descriptor.getId());
+
+ boolean isVisible = descriptor.isVisible();
+ entry.setVisible(isVisible);
+ // if (_showAll)
+ // {
+ // entry.setVisible(true);
+ // }
+ // else
+ // {
+ // entry.setVisible(descriptor.isVisible());
+ // }
+ descriptor.setPaletteEntry(entry);
+ return entry;
+ }
+
+ private String formatDescription(String desc) {
+ if (desc.indexOf("\n") != -1) {
+ String[] fragments = desc.split("\n");
+ StringBuffer result = new StringBuffer();
+ for (int i = 0, n = fragments.length; i < n; i++) {
+ result.append(fragments[i].trim()).append(' ');
+ }
+ desc = result.toString().trim();
+ }
+ return desc;
+ }
+
+ /**
+ * @return
+ */
+ private ImageDescriptor getDefaultLargeIcon() {
+ return DEFAULT_LARGE_ICON;
+ }
+
+ /**
+ * @return
+ */
+ private ImageDescriptor getDefaultSmallIcon() {
+ return DEFAULT_SMALL_ICON;
+ }
+
+ /**
+ * remove everything from the paletteroot
+ *
+ */
+ protected void removeItems() {
+ // we try to remove anything other than the basic
+ // group that have the selectentry and marqeeentry
+ List children = new ArrayList(getChildren());
+ children.remove(0); // remove the first one
+ for (int i = 0, n = children.size(); i < n; i++) {
+ this.remove((PaletteEntry) children.get(i));
+ }
+ }
+
+ /**
+ * refresh the palette, normally caused by preference change.
+ */
+ public void refresh() {
+ loadItems();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewer.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewer.java
new file mode 100644
index 000000000..f2edb7489
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewer.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.gef.palette.PaletteRoot;
+import org.eclipse.gef.ui.palette.PaletteViewer;
+import org.eclipse.gef.ui.palette.customize.PaletteCustomizerDialog;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * XXX: currently create this class is just for add/remove listener to
+ * preference change, so can refresh the palette.
+ *
+ * @author mengbo
+ * @author mengbo
+ * @version 1.5
+ */
+public class DesignerPaletteViewer extends PaletteViewer {
+ private PaletteCustomizerDialog _customizerDialog = null;
+
+ /**
+ *
+ */
+ public DesignerPaletteViewer() {
+ super();
+
+ this.enableVerticalScrollbar(true);
+ }
+
+ Preferences.IPropertyChangeListener listener = new Preferences.IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ PaletteRoot root = getPaletteRoot();
+ if (root instanceof DesignerPaletteRoot) {
+ ((DesignerPaletteRoot) root).refresh();
+ // XXX: setActiveTool to null to workaround GEF bug of NPE
+ // setActiveTool(null);
+ }
+ }
+ };
+
+ IEntryChangeListener _paletteModelListener = new IEntryChangeListener() {
+
+ public void modelChanged(List oldDefinitions, List newDefinitions) {
+ PaletteRoot root = getPaletteRoot();
+ if (root instanceof DesignerPaletteRoot) {
+ ((DesignerPaletteRoot) root).refresh();
+ }
+ }
+
+ };
+
+ IResourceChangeListener _resourceChangeListener = new IResourceChangeListener() {
+
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource resource = delta.getResource();
+ // FIXME need make performance better
+ if (resource.getType() == IResource.FILE
+ && (delta.getFlags() & IResourceDelta.CONTENT) != 0) {
+ String ext = ((IFile) resource).getFileExtension();
+ // resource.getFullPath().
+ if (ext != null
+ && ("tld".equalsIgnoreCase(ext) || "jar"
+ .equalsIgnoreCase(ext))) {
+ PaletteRoot root = getPaletteRoot();
+ if (root instanceof DesignerPaletteRoot) {
+ IPaletteItemManager imanager = ((DesignerPaletteRoot) root)
+ .getPaletteManager();
+ if (imanager instanceof PaletteItemManager) {
+ PaletteItemManager manager = (PaletteItemManager) imanager;
+ manager.reset();
+ }
+
+ }
+ }
+ }
+ return true;
+ }
+ };
+ try {
+ IResourceDelta delta = event.getDelta();
+ if (delta != null) {
+ delta.accept(visitor);
+ }
+ } catch (CoreException e) {
+ // ignore
+ }
+ }
+
+ };
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteViewer#hookControl()
+ */
+ protected void hookControl() {
+ super.hookControl();
+ PDPlugin.getDefault().getPluginPreferences().addPropertyChangeListener(
+ listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteViewer#unhookControl()
+ */
+ protected void unhookControl() {
+ PDPlugin.getDefault().getPluginPreferences()
+ .removePropertyChangeListener(listener);
+ // remove palette model change listener
+ PaletteRoot root = getPaletteRoot();
+ if (root instanceof DesignerPaletteRoot) {
+ IPaletteItemManager imanager = ((DesignerPaletteRoot) root)
+ .getPaletteManager();
+ if (imanager instanceof PaletteItemManager) {
+ PaletteItemManager manager = (PaletteItemManager) imanager;
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+ _resourceChangeListener);
+ manager.removeEntryChangeListener(_paletteModelListener);
+ PaletteItemManager.clearPaletteItemManager();
+ }
+ }
+ super.unhookControl();
+ }
+
+ public boolean isFileOpenedInProject(IProject project) {
+ IWorkbenchPage page = PDPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage();
+ IEditorReference[] editors = page.getEditorReferences();
+ for (int i = 0; i < editors.length; i++) {
+ IEditorPart part = (IEditorPart) editors[i].getPart(false);
+ if (part != null) {
+ IEditorInput input = part.getEditorInput();
+ IFile inputFile = null;
+ if (input != null && input instanceof IFileEditorInput) {
+ inputFile = ((IFileEditorInput) input).getFile();
+ IProject refProject = inputFile.getProject();
+ if (project == refProject) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public PaletteCustomizerDialog getCustomizerDialog() {
+ if (_customizerDialog == null) {
+ _customizerDialog = new DesignerPaletteCustomizerDialog(
+ getControl().getShell(), getCustomizer(), getPaletteRoot());
+ }
+ return _customizerDialog;
+ }
+
+ public void setPaletteRoot(PaletteRoot root) {
+ // TODO Auto-generated method stub
+ super.setPaletteRoot(root);
+ // add palette model change listener
+ // PaletteRoot root = getPaletteRoot();
+ if (root instanceof DesignerPaletteRoot) {
+ ((DesignerPaletteRoot) root).getPaletteManager()
+ .addEntryChangeListener(_paletteModelListener);
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ _resourceChangeListener);
+ }
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewerProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewerProvider.java
new file mode 100644
index 000000000..a7e51d156
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/DesignerPaletteViewerProvider.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import org.eclipse.gef.EditDomain;
+import org.eclipse.gef.ui.palette.PaletteContextMenuProvider;
+import org.eclipse.gef.ui.palette.PaletteViewer;
+import org.eclipse.gef.ui.palette.PaletteViewerProvider;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.dnd.internal.DesignerTemplateTransferDragSourceListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author mengbo
+ */
+public class DesignerPaletteViewerProvider extends PaletteViewerProvider {
+ /**
+ * @param graphicalViewerDomain
+ */
+ public DesignerPaletteViewerProvider(EditDomain graphicalViewerDomain) {
+ super(graphicalViewerDomain);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteViewerProvider#configurePaletteViewer(org.eclipse.gef.ui.palette.PaletteViewer)
+ */
+ protected void configurePaletteViewer(PaletteViewer viewer) {
+ // super.configurePaletteViewer(viewer);
+ viewer.setContextMenu(new PaletteContextMenuProvider(viewer) {
+ public void buildContextMenu(IMenuManager menu) {
+ super.buildContextMenu(menu);
+ }
+ });
+
+ // XXX: should only use the following when we use Template
+ viewer
+ .addDragSourceListener(new DesignerTemplateTransferDragSourceListener(
+ viewer));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.palette.PaletteViewerProvider#createPaletteViewer(org.eclipse.swt.widgets.Composite)
+ */
+ public PaletteViewer createPaletteViewer(Composite parent) {
+ PaletteViewer pViewer = new DesignerPaletteViewer();
+ pViewer.createControl(parent);
+ configurePaletteViewer(pViewer);
+ pViewer.setCustomizer(new DesignerPaletteCustomizer());
+ hookPaletteViewer(pViewer);
+
+ PlatformUI
+ .getWorkbench()
+ .getHelpSystem()
+ .setHelp(
+ parent,
+ PDPlugin
+ .getResourceString("DesignerPaletteViewerProvider.help.id"));
+
+ return pViewer;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/HTMLEditorPaletteFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/HTMLEditorPaletteFactory.java
new file mode 100644
index 000000000..1e49a468c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/HTMLEditorPaletteFactory.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.gef.palette.PaletteRoot;
+import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager;
+
+/**
+ * @author mengbo
+ */
+public class HTMLEditorPaletteFactory {
+ /** Default palette size. */
+ private static final int DEFAULT_PALETTE_SIZE = 125;
+
+ /** Preference ID used to persist the palette location. */
+ private static final String PALETTE_DOCK_LOCATION = "HTMLEditorPaletteFactory.Location";
+
+ /** Preference ID used to persist the palette size. */
+ private static final String PALETTE_SIZE = "HTMLEditorPaletteFactory.Size";
+
+ /** Preference ID used to persist the flyout palette's state. */
+ private static final String PALETTE_STATE = "HTMLEditorPaletteFactory.State";
+
+ /**
+ * Return a FlyoutPreferences instance used to save/load the preferences of
+ * a flyout palette.
+ */
+ public static FlyoutPreferences createPalettePreferences() {
+ // set default flyout palette preference values, in case the preference
+ // store
+ // does not hold stored values for the given preferences
+ getPreferenceStore().setDefault(PALETTE_DOCK_LOCATION, -1);
+ getPreferenceStore().setDefault(PALETTE_STATE, -1);
+ getPreferenceStore().setDefault(PALETTE_SIZE, DEFAULT_PALETTE_SIZE);
+
+ return new FlyoutPreferences() {
+ public int getDockLocation() {
+ return getPreferenceStore().getInt(PALETTE_DOCK_LOCATION);
+ }
+
+ public int getPaletteState() {
+ return getPreferenceStore().getInt(PALETTE_STATE);
+ }
+
+ public int getPaletteWidth() {
+ return getPreferenceStore().getInt(PALETTE_SIZE);
+ }
+
+ public void setDockLocation(int location) {
+ getPreferenceStore().setValue(PALETTE_DOCK_LOCATION, location);
+ }
+
+ public void setPaletteState(int state) {
+ getPreferenceStore().setValue(PALETTE_STATE, state);
+ }
+
+ public void setPaletteWidth(int width) {
+ getPreferenceStore().setValue(PALETTE_SIZE, width);
+ }
+ };
+ }
+
+ /**
+ * Returns the preference store for the PDPlugin.
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#getPreferenceStore()
+ */
+ private static IPreferenceStore getPreferenceStore() {
+ return PDPlugin.getDefault().getPreferenceStore();
+ }
+
+ /**
+ * Creates the PaletteRoot and adds all palette elements. Use this factory
+ * method to create a new palette for your graphical editor.
+ *
+ * @return a new PaletteRoot
+ */
+ public static PaletteRoot createPalette(IProject project) {
+ PaletteItemManager manager = PaletteItemManager.getInstance(project);
+ if (manager == null) {
+ return null;
+ }
+ manager.reset();
+ PaletteRoot palette = new DesignerPaletteRoot(manager);
+ return palette;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IEntryChangeListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IEntryChangeListener.java
new file mode 100644
index 000000000..2f4667eb2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IEntryChangeListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.List;
+
+/**
+ * @author mengbo
+ */
+public interface IEntryChangeListener {
+ /**
+ * @param oldDefinitions
+ * the old taglib definitions
+ * @param newDefinitions
+ * the new taglib definitions
+ */
+ void modelChanged(List oldDefinitions, List newDefinitions);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteConstants.java
new file mode 100644
index 000000000..0227125be
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteConstants.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+/**
+ * @author mengbo
+ */
+public interface IPaletteConstants {
+ public static final String BUNDLE_ID = "org.eclipse.jst.pagedesigner"; //$NON-NLS-1$
+
+ public static final String EXTENSION_POINT_ID = "ResourceContributions"; //$NON-NLS-1$
+
+ public static final String ROOT = "palette-item"; //$NON-NLS-1$
+
+ public static final String FILENAME = "/tag.xml"; //$NON-NLS-1$
+
+ public static final String TAGNAME = "tagName"; //$NON-NLS-1$
+
+ public static final String ITEM_TAG = "item"; //$NON-NLS-1$
+
+ public static final String ISVISIBLE = "hide"; //$NON-NLS-1$
+
+ public static final String EXPERT = "expert"; //$NON-NLS-1$
+
+ public static final String LARGEICON = "largeIcon"; //$NON-NLS-1$
+
+ public static final String SMALLICON = "smallIcon"; //$NON-NLS-1$
+
+ public static final String LABEL = "label"; //$NON-NLS-1$
+
+ public static final String INITIALSTATE = "initialState"; //$NON-NLS-1$
+
+ public static final String SHORTDESC = "shortDesc"; //$NON-NLS-1$
+
+ public static final String ID = "id"; //$NON-NLS-1$
+
+ public static final String CATEGORY_TAG = "category"; //$NON-NLS-1$
+
+ public static final String ATTRIBUTE_TAG = "attribute"; //$NON-NLS-1$
+
+ public static final String NAME = "name"; //$NON-NLS-1$
+
+ public static final String VALUE = "value"; //$NON-NLS-1$
+
+ public static final String ICONPREFIX = "iconPrefix"; //$NON-NLS-1$
+
+ public static final String URI = "uri"; //$NON-NLS-1$
+
+ public static final String TAGLIBEXT = "capability"; //$NON-NLS-1$
+
+ public static final String JARPROTO = "jar:file://"; //$NON-NLS-1$
+
+ public static final String FILEPROTO = "file://"; //$NON-NLS-1$
+
+ public static final String REQUIREHFORM = "requireHForm"; //$NON-NLS-1$
+
+ public static final String JSFCOMPONENTCATEGORY = "jsfComponentCategory"; //$NON-NLS-1$
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemCategory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemCategory.java
new file mode 100644
index 000000000..365cdcf14
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemCategory.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.List;
+
+/**
+ * @author mengbo
+ */
+public interface IPaletteItemCategory extends IPaletteItemEntry {
+
+ public String getURI();
+
+ /**
+ * return an list of items belong to this category.
+ *
+ * @return
+ */
+ public List getPaletteItems();
+
+ /**
+ * @param tagName
+ * @return
+ */
+ public IPaletteItemDescriptor getItemByTagName(String tagName);
+
+ /**
+ * @param tagName
+ * @return
+ */
+ public IPaletteItemDescriptor getItemByID(String id);
+
+ /**
+ * @param tagName
+ * @return
+ */
+ public IPaletteItemDescriptor createItem(String tagName);
+
+ /**
+ * @param descriptor
+ */
+ public void addPaletteItem(IPaletteItemDescriptor descriptor);
+
+ /**
+ * @param prefix
+ */
+ public void setDefaultPrefix(String prefix);
+
+ public String getDefaultPrefix();
+
+ public boolean isJSFComponentCategory();
+
+ public void setJSFComponentCategory(boolean b);
+
+}
+
+// TODO: we may add methods for add/remove items into this interface to support
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemDescriptor.java
new file mode 100644
index 000000000..b2b5ac918
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemDescriptor.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.Map;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public interface IPaletteItemDescriptor extends IPaletteItemEntry {
+
+ public String getURI();
+
+ public String getTagName();
+
+ public Map getInitialAttributes();
+
+ /**
+ * We use the model to get runtime prefix and apply to the node.
+ *
+ * @param model
+ * @return
+ */
+ public Node[] getTemplateSubNodes(IDOMModel model);
+
+ /**
+ * @param tagName
+ */
+ public void setTagName(String tagName);
+
+ /**
+ * @param uri
+ */
+ public void setURI(String uri);
+
+ /**
+ * @param defaultPrefix
+ */
+ public void setDefaultPrefix(String defaultPrefix);
+
+ /**
+ * get the default prefix.
+ *
+ * @return
+ */
+ public String getDefaultPrefix();
+
+ /**
+ * set whether this item require <h:form> to be automatically inserted.
+ *
+ */
+ public void setRequireHForm(boolean r);
+
+ /**
+ * get whether this item require <h:form> to be automatically inserted.
+ *
+ * @return
+ */
+ public boolean isRequireHForm();
+
+ /**
+ * Whether this item is JSF component (or other JSF core tags.)
+ *
+ * @return
+ */
+ public boolean isJSFComponent();
+
+ /**
+ * @param b
+ */
+ public void setJSFComponent(boolean b);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemEntry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemEntry.java
new file mode 100644
index 000000000..e9dd0676b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemEntry.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * @author mengbo
+ */
+public interface IPaletteItemEntry {
+ /**
+ * @return
+ */
+ public String getId();
+
+ /**
+ * @param id
+ */
+ public void setId(String id);
+
+ /**
+ * @return
+ */
+ public String getLabel();
+
+ /**
+ * @param lable
+ */
+ public void setLabel(String lable);
+
+ /**
+ * @return
+ */
+ public String getDescription();
+
+ /**
+ * @param desc
+ */
+ public void setDescription(String desc);
+
+ /**
+ * @return
+ */
+ public boolean isVisible();
+
+ /**
+ * @param visible
+ */
+ public void setVisible(boolean visible);
+
+ public PaletteEntry getPaletteEntry();
+
+ /**
+ * @param entry
+ */
+ public void setPaletteEntry(PaletteEntry entry);
+
+ public String getSmallIconString();
+
+ public ImageDescriptor getSmallIcon();
+
+ public String getLargeIconString();
+
+ public ImageDescriptor getLargeIcon();
+
+ public void setInitialState(int state);
+
+ public int getInitialState();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemManager.java
new file mode 100644
index 000000000..10f55036d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IPaletteItemManager.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.List;
+
+/**
+ * @author mengbo
+ */
+public interface IPaletteItemManager {
+ public List getAllCategories();
+
+ /**
+ * @param tldURI
+ * @return
+ */
+ public IPaletteItemCategory createCategory(String tldURI);
+
+ /**
+ * @param tldURI
+ * @return
+ */
+ public IPaletteItemCategory getCategoryByURI(String tldURI);
+
+ /**
+ * @param uri
+ * @param catlabel
+ * @return
+ */
+ public IPaletteItemCategory findOrCreateCategory(String uri, String catlabel);
+
+ /**
+ * Adds a listener to the list of those notified when the model contents are
+ * replaced
+ *
+ * @param listener -
+ * the listener to add
+ */
+ void addEntryChangeListener(IEntryChangeListener listener);
+
+ /**
+ * Adds a listener to the list of those notified when the model contents are
+ * replaced
+ *
+ * @param listener -
+ * the listener to remove
+ */
+ void removeEntryChangeListener(IEntryChangeListener listener);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IResourceManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IResourceManager.java
new file mode 100644
index 000000000..774e4480c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/IResourceManager.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ * @author mengbo
+ */
+public interface IResourceManager {
+
+ public String getType();
+
+ public List getResourceList(IProject project);
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/ShowAllAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/ShowAllAction.java
new file mode 100644
index 000000000..f115bfe3c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/ShowAllAction.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+
+/**
+ * @author mengbo
+ */
+public class ShowAllAction extends Action {
+ Preferences _preferences = null;
+
+ /**
+ * @param pluginPreferences
+ */
+ public ShowAllAction(Preferences pluginPreferences) {
+ super(PDPlugin.getResourceString("ShowAllAction.ActionLabel.ShowAll")); //$NON-NLS-1$
+ _preferences = pluginPreferences;
+ boolean showAll = _preferences
+ .getBoolean(IJMTConstants.PREF_PALETTE_SHOW_ALL);
+ this.setChecked(showAll);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ boolean showAll = _preferences
+ .getBoolean(IJMTConstants.PREF_PALETTE_SHOW_ALL);
+ // toggle the show all status. preference will fire out change event,
+ // and palettes
+ // receive this event will refresh
+ _preferences.setValue(IJMTConstants.PREF_PALETTE_SHOW_ALL, !showAll);
+ this.setChecked(!showAll);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/DocumentFactoryTLD.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/DocumentFactoryTLD.java
new file mode 100644
index 000000000..e23257fee
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/DocumentFactoryTLD.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette.impl;
+
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDocumentFactoryTLD;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+
+/**
+ * @author mengbo
+ */
+public class DocumentFactoryTLD extends CMDocumentFactoryTLD {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDocumentFactoryTLD#buildCMDocumentFromJar(java.lang.String,
+ * java.lang.String)
+ */
+ public CMDocument buildCMDocumentFromJar(String jarFileName,
+ String contentFileName) {
+ // TODO Auto-generated method stub
+ return super.buildCMDocumentFromJar(jarFileName, contentFileName);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteElementTemplateHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteElementTemplateHelper.java
new file mode 100644
index 000000000..e5e1161bc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteElementTemplateHelper.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class PaletteElementTemplateHelper {
+ private static final String TEMPLATE_ITEM_NAME = "template";
+
+ private static final String PREFIX_ATTRIBUTE = "uri";
+
+ private static Logger _log = PDPlugin
+ .getLogger(PaletteElementTemplateHelper.class);
+
+ public static NodeList readTemplate(Element item) {
+ if (item != null) {
+ Node node = EditModelQuery.getChildDeferredNode(item,
+ new String[] { TEMPLATE_ITEM_NAME }, 1, true);
+ return node != null ? node.cloneNode(true).getChildNodes() : null;
+ }
+ return null;
+ }
+
+ /**
+ * This method is used to process template element which is read from .xmi
+ * file and generate default element.
+ *
+ * @param model
+ * @param element
+ * @param itemDes
+ */
+ public static void applyTemplate(IDOMModel model, Element element,
+ IPaletteItemDescriptor itemDes) {
+ if (element == null || element.getLocalName() == null) {
+ return;
+ }
+ Node[] nl = itemDes.getTemplateSubNodes(model);
+ if (nl != null) {
+ for (int i = 0, n = nl.length; i < n; i++) {
+ element.appendChild(nl[i]);
+ }
+ }
+ }
+
+ /**
+ * Use the actrual prefixs of jsf html and jsf core to set the prefix of
+ * each node declared in template.
+ *
+ * @param prefixH
+ * @param prefixC
+ * @param nl
+ * @param document
+ * @return
+ */
+ public static Node[] applyPrefixes(String prefixH, String prefixC,
+ NodeList nl, Document document) {
+ List result = new ArrayList();
+ for (int i = 0, n = nl.getLength(); i < n; i++) {
+ Node node = cloneNodeDeep(document, nl.item(i), prefixH, prefixC);
+ if (nl.item(i) instanceof Element) {
+ result.add(node);
+ }
+ }
+ return (Node[]) result.toArray(new Node[result.size()]);
+ }
+
+ /**
+ * TODO: Later we may add some logic to reference the tld file through tag
+ * name to resolve the prefixs directly.
+ *
+ * @param model
+ * @param prefixH
+ * @param prefixC
+ * @param node
+ * @return
+ */
+ private static void internalApplyPrefixes(String prefixH, String prefixC,
+ Element refNode, Element node) {
+ if (node != null && refNode != null) {
+ String prefix = refNode.getAttribute(PREFIX_ATTRIBUTE); //$NON-NLS-1$
+ if (prefix != null) {
+ if (prefix.equalsIgnoreCase(IJMTConstants.URI_JSF_HTML)) //$NON-NLS-1$
+ {
+ node.setPrefix(prefixH);
+ } else if (prefix.equalsIgnoreCase(IJMTConstants.URI_JSF_CORE)) //$NON-NLS-1$
+ {
+ node.setPrefix(prefixC);
+ }
+ }
+ }
+ }
+
+ public static Node cloneNodeDeep(Document destDoc, Node sourceNode,
+ String prefixH, String prefixC) {
+ switch (sourceNode.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ Element sourceEle = (Element) sourceNode;
+ Element resultEle = destDoc.createElement(sourceEle.getTagName());
+ internalApplyPrefixes(prefixH, prefixC, sourceEle, resultEle);
+ NamedNodeMap attrs = sourceEle.getAttributes();
+ for (int i = 0, size = attrs.getLength(); i < size; i++) {
+ Attr a = (Attr) attrs.item(i);
+ if (!PREFIX_ATTRIBUTE.equalsIgnoreCase(a.getNodeName())) {
+ resultEle.setAttribute(a.getName(), a.getValue());
+ }
+ }
+ NodeList children = sourceEle.getChildNodes();
+ for (int i = 0, size = children.getLength(); i < size; i++) {
+ Node n = children.item(i);
+ Node d = cloneNodeDeep(destDoc, n, prefixH, prefixC);
+ if (d != null) {
+ resultEle.appendChild(d);
+ }
+ }
+ return resultEle;
+ case Node.TEXT_NODE:
+ Text txt = destDoc.createTextNode(sourceNode.getNodeValue());
+ if (txt instanceof IDOMText && sourceNode instanceof IDOMText) {
+ try {
+ ((IDOMText) txt).setSource(((IDOMText) sourceNode)
+ .getSource());
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ return txt;
+ case Node.CDATA_SECTION_NODE:
+ return destDoc.createCDATASection(sourceNode.getNodeValue());
+ default:
+ return null; // not support.
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteHelper.java
new file mode 100644
index 000000000..02c9663fe
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteHelper.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette.impl;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.common.utils.StringUtil;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteConstants;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemManager;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLElementDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * Helper class.
+ *
+ * @author mengbo
+ */
+public class PaletteHelper {
+ public static void configPaletteItemsByTLD(IPaletteItemManager manager,
+ TLDDocument tldDoc) {
+ String tldURI = tldDoc.getUri();
+ if (tldURI == null) {
+ return;
+ }
+ IPaletteItemCategory category = manager.getCategoryByURI(tldURI);
+ if (category == null) {
+ category = manager.createCategory(tldURI);
+ }
+ // category is in what user selected in Component Support Property Page
+ // ,so set state to be Visible
+ category.setVisible(true);
+
+ String prefix = category.getDefaultPrefix();
+ if (prefix == null || prefix.length() == 0) {
+ category.setDefaultPrefix(tldDoc.getShortname());
+ }
+ String label = category.getLabel();
+ if (label == null || label.length() == 0) {
+ category.setLabel(tldDoc.getDisplayName());
+ }
+ loadFromCMDocument(category, tldDoc);
+ }
+
+ /**
+ * basically, this method will read information from the CMDocument. It will
+ * check the existing items in the registry. If the corresponding tag is not
+ * in palette manager, then it will create one, and mark the newly created
+ * item as "expert". Otherwise, it will check whether the tld contains more
+ * information than the palette manager, and adding those information to it
+ * (such as description, icons for tags)
+ *
+ * @param manager
+ * @param tldDoc
+ */
+ public static void loadFromCMDocument(IPaletteItemCategory category,
+ CMDocument cmdoc) {
+ CMNamedNodeMap nodeMap = cmdoc.getElements();
+ for (int i = 0, size = nodeMap.getLength(); i < size; i++) {
+ CMElementDeclaration eledecl = (CMElementDeclaration) nodeMap
+ .item(i);
+ String tagName = eledecl.getElementName();
+ IPaletteItemDescriptor item;
+ if (tagName.equalsIgnoreCase(IHTMLConstants.TAG_INPUT)) {
+ StringBuffer name = new StringBuffer(category.getURI());
+ name.append(":").append(tagName).append(":").append(tagName);
+ item = category.getItemByID(name.toString());
+ } else {
+ item = category.getItemByTagName(tagName);
+ }
+ if (item == null) {
+ item = category.createItem(tagName);
+ StringBuffer name = new StringBuffer(category.getURI());
+ name.append(":").append(tagName).append(":").append(tagName);
+ item.setId(name.toString());
+ // for newly created item, set expert to true.
+ item.setVisible(true);
+ item.setURI(category.getURI());
+ if (category.getURI().equals(IJMTConstants.URI_HTML))//$NON-NLS-1$
+ {
+ item.setVisible(false);
+ }
+ }
+ configItem(item, eledecl);
+ item.setDefaultPrefix(category.getDefaultPrefix());
+ }
+ }
+
+ /**
+ * @param item
+ * @param eledecl
+ */
+ private static void configItem(IPaletteItemDescriptor item,
+ CMElementDeclaration eledecl) {
+ if (eledecl instanceof HTMLElementDeclaration) {
+ configHTMLItem(item, (HTMLElementDeclaration) eledecl);
+ } else if (eledecl instanceof TLDElementDeclaration) {
+ configTLDItem(item, (TLDElementDeclaration) eledecl);
+ }
+ }
+
+ /**
+ * @param item
+ * @param declaration
+ */
+ private static void configTLDItem(IPaletteItemDescriptor item,
+ TLDElementDeclaration declaration) {
+ String olddesc = item.getDescription();
+ if (olddesc == null || olddesc.length() == 0) {
+ String des = declaration.getDescription();
+ des = StringUtil.filterConvertString(des);
+ item.setDescription(des);
+ }
+ }
+
+ /**
+ * @param item
+ * @param declaration
+ */
+ private static void configHTMLItem(IPaletteItemDescriptor item,
+ HTMLElementDeclaration declaration) {
+ }
+
+ public static void readConfigFromPlugin(IPaletteItemManager manager) {
+ IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+ IExtensionPoint point = extensionRegistry
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_PALETTEITEMCONFIG);
+ if (point != null) {
+ IConfigurationElement[] elements = point.getConfigurationElements();
+ Arrays.sort(elements, new Comparator() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Comparator#compare(java.lang.Object,
+ * java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ IConfigurationElement d1 = (IConfigurationElement) o1;
+ IConfigurationElement d2 = (IConfigurationElement) o2;
+ return d1
+ .getAttribute(
+ IJMTConstants.ATTRIBUTE_INDEX_PALETTEITEMCONFIG)
+ .compareToIgnoreCase(
+ d2
+ .getAttribute(IJMTConstants.ATTRIBUTE_INDEX_PALETTEITEMCONFIG));
+ }
+ });
+ for (int i = 0, size = elements.length; i < size; i++) {
+ IConfigurationElement ce = elements[i];
+ String id = ce.getDeclaringExtension().getNamespaceIdentifier();
+ Bundle bundle = Platform.getBundle(id);
+ String path = ce
+ .getAttribute(IJMTConstants.ATTRIBUTE_PATH_PALETTEITEMCONFIG);
+ readConfig(manager, bundle, path);
+ }
+ }
+
+ }
+
+ static void readConfig(IPaletteItemManager manager, Bundle bundle,
+ String path) {
+ try {
+ if (bundle.getEntry(path) == null) {
+ return;
+ }
+ InputStream stream = bundle.getEntry(path).openStream();
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder();
+ Document doc = builder.parse(stream);
+ ResourceUtils.ensureClosed(stream);
+
+ NodeList categories = doc
+ .getElementsByTagName(IPaletteConstants.CATEGORY_TAG);
+ for (int i = 0, ilength = categories.getLength(); i < ilength; i++) {
+ Element cat = (Element) categories.item(i);
+ String prefix = cat.getAttribute(IPaletteConstants.ICONPREFIX);
+ String uri = cat.getAttribute(IPaletteConstants.URI);
+ String catlabel = cat.getAttribute(IPaletteConstants.LABEL);
+ IPaletteItemCategory category = manager.findOrCreateCategory(
+ uri, catlabel);
+ String jsfComponentCategory = cat
+ .getAttribute(IPaletteConstants.JSFCOMPONENTCATEGORY);
+ boolean bJSF = Boolean.TRUE.toString().equalsIgnoreCase(
+ jsfComponentCategory);
+ if (bJSF) {
+ // avoid override. maybe someother place has already set it
+ // to be true.
+ category.setJSFComponentCategory(bJSF);
+ }
+
+ NodeList items = cat
+ .getElementsByTagName(IPaletteConstants.ITEM_TAG);
+
+ for (int j = 0, jlength = items.getLength(); j < jlength; j++) {
+ Element item = (Element) items.item(j);
+ PaletteItemDescriptor descriptor = new PaletteItemDescriptor();
+ descriptor.setJSFComponent(category
+ .isJSFComponentCategory());
+ descriptor.setURI(uri);
+
+ String tagName = item
+ .getAttribute(IPaletteConstants.TAGNAME);
+ descriptor.setTagName(tagName);
+
+ String label = item.getAttribute(IPaletteConstants.LABEL);
+ descriptor.setLabel(label);
+
+ StringBuffer id = new StringBuffer(uri);
+ id.append(":").append(tagName).append(":").append(label);
+ descriptor.setId(id.toString());
+
+ String shortDesc = item
+ .getAttribute(IPaletteConstants.SHORTDESC);
+ descriptor.setDescription(shortDesc);
+
+ String smallIcon = item
+ .getAttribute(IPaletteConstants.SMALLICON);
+ descriptor.setSmallIcon(getImageDescriptor(bundle, prefix,
+ smallIcon));
+
+ String largeIcon = item
+ .getAttribute(IPaletteConstants.LARGEICON);
+ descriptor.setLargeIcon(getImageDescriptor(bundle, prefix,
+ largeIcon));
+
+ String expert = item.getAttribute(IPaletteConstants.EXPERT);
+ boolean isVisible = !Boolean.TRUE.toString()
+ .equalsIgnoreCase(expert); //$NON-NLS-1$
+ descriptor.setVisible(isVisible);
+
+ String requireHForm = item
+ .getAttribute(IPaletteConstants.REQUIREHFORM);
+ boolean r = Boolean.TRUE.toString().equalsIgnoreCase(
+ requireHForm);
+ descriptor.setRequireHForm(r);
+
+ NodeList attributes = item
+ .getElementsByTagName(IPaletteConstants.ATTRIBUTE_TAG);
+ if (attributes.getLength() > 0) {
+ Map attrMap = new HashMap();
+ for (int k = 0, klength = attributes.getLength(); k < klength; k++) {
+ Element attr = (Element) attributes.item(k);
+ String name = attr
+ .getAttribute(IPaletteConstants.NAME);
+ String value = attr
+ .getAttribute(IPaletteConstants.VALUE);
+ attrMap.put(name, value);
+ }
+ descriptor.setInitialAttributes(attrMap);
+ }
+
+ descriptor.setTemplateSubNodes(PaletteElementTemplateHelper
+ .readTemplate(item));
+ category.addPaletteItem(descriptor);
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * @param plugin
+ * @param prefix
+ * @param smallIcon2
+ * @return
+ */
+ private static ImageDescriptor getImageDescriptor(Bundle bundle,
+ String prefix, String u) {
+ if (u == null || u.length() == 0) {
+ return null;
+ }
+ String path = (prefix == null ? "" : prefix) + u;
+ URL url = bundle.getEntry(path);
+ return ImageDescriptor.createFromURL(url);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemCategory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemCategory.java
new file mode 100644
index 000000000..4cd590ba4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemCategory.java
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.gef.palette.PaletteDrawer;
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+
+/**
+ * @author mengbo
+ */
+public class PaletteItemCategory implements IPaletteItemCategory {
+ private String _id;
+
+ private String _uri;
+
+ private String _label;
+
+ private String _description;
+
+ private boolean _isVisible = true;
+
+ private List _descriptors = new ArrayList();
+
+ private String _prefix;
+
+ private PaletteEntry _entry;
+
+ private ImageDescriptor _smallIcon;
+
+ private ImageDescriptor _largeIcon;
+
+ private String _smallIconString;
+
+ private String _largeIconString;
+
+ private int _initState = PaletteDrawer.INITIAL_STATE_CLOSED;
+
+ private boolean _jsfComponentCategory = false;
+
+ /**
+ *
+ */
+ public PaletteItemCategory(String uri, String label) {
+ _uri = uri;
+ _label = label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#getCategoryLabel()
+ */
+ public String getCategoryLabel() {
+ return _label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#getPaletteItems()
+ */
+ public List getPaletteItems() {
+ if (_descriptors != null) {
+ Collections.sort(_descriptors, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ if (o1 != null && o2 != null) {
+ String label1 = ((IPaletteItemDescriptor) o1)
+ .getLabel();
+ if (label1 == null) {
+ label1 = ((IPaletteItemDescriptor) o1).getTagName();
+ }
+ String label2 = ((IPaletteItemDescriptor) o2)
+ .getLabel();
+ if (label2 == null) {
+ label2 = ((IPaletteItemDescriptor) o2).getTagName();
+ }
+ if (label1 != null && label2 != null) {
+ int cc = label2.compareTo(label1);
+ return (cc < 0 ? 1 : cc > 0 ? -1 : 0);
+ }
+ }
+ return -1;
+ }
+ });
+ }
+ return _descriptors;
+ }
+
+ /**
+ * @param item
+ */
+ public void addPaletteItem(IPaletteItemDescriptor item) {
+ _descriptors.add(item);
+ // TODO: fire change event.
+ }
+
+ /**
+ * @return
+ */
+ public String getURI() {
+ return _uri;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#getItemByTagName(java.lang.String)
+ */
+ public IPaletteItemDescriptor getItemByTagName(String tagName) {
+ if (_descriptors == null) {
+ return null;
+ }
+ for (int i = 0, n = _descriptors.size(); i < n; i++) {
+ IPaletteItemDescriptor item = (IPaletteItemDescriptor) _descriptors
+ .get(i);
+ if (item != null && tagName.equals(item.getTagName())) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#getItemByID(java.lang.String)
+ * id format [uri:tagname:label] example : [html:input:Radio Button]
+ */
+ public IPaletteItemDescriptor getItemByID(String id) {
+ if (_descriptors == null) {
+ return null;
+ }
+ for (int i = 0, n = _descriptors.size(); i < n; i++) {
+ IPaletteItemDescriptor item = (IPaletteItemDescriptor) _descriptors
+ .get(i);
+ if (item != null && id.equals(item.getId())) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#createItem(java.lang.String)
+ */
+ public IPaletteItemDescriptor createItem(String tagName) {
+ IPaletteItemDescriptor item = new PaletteItemDescriptor();
+ item.setTagName(tagName);
+ item.setJSFComponent(this.isJSFComponentCategory());
+ this.addPaletteItem(item);
+ return item;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#setCategoryLabel(java.lang.String)
+ */
+ public void setCategoryLabel(String displayName) {
+ this._label = displayName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#setDefaultPrefix(java.lang.String)
+ */
+ public void setDefaultPrefix(String prefix) {
+ this._prefix = prefix;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#getDefaultPrefix()
+ */
+ public String getDefaultPrefix() {
+ return _prefix;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#getPaletteEntry()
+ */
+ public PaletteEntry getPaletteEntry() {
+ return _entry;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#setPaletteEntry(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public void setPaletteEntry(PaletteEntry entry) {
+ this._entry = entry;
+ /*
+ * if (entry.getDescription()==null && this.getDescription()!=null) {
+ * entry.setDescription(this.getDescription()); } if
+ * (entry.getId()==null && this.getId()!=null) {
+ * entry.setId(this.getId()); } if (entry.getLabel()==null &&
+ * this.getLabel()!=null) { entry.setLabel(this.getLabel()); }
+ *
+ * entry.setVisible(this.isVisible());
+ */
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getId()
+ */
+ public String getId() {
+ if (_id == null) {
+ _id = _uri;
+ }
+ return _id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setId(java.lang.String)
+ */
+ public void setId(String id) {
+ this._id = id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getLabel()
+ */
+ public String getLabel() {
+ return _label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setlabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this._label = label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getDescription()
+ */
+ public String getDescription() {
+ return _description;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setDescription(java.lang.String)
+ */
+ public void setDescription(String desc) {
+ this._description = desc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#isVisible()
+ */
+ public boolean isVisible() {
+ return _isVisible;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setVisible(boolean)
+ */
+ public void setVisible(boolean visible) {
+ this._isVisible = visible;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getSmallIconString()
+ */
+ public String getSmallIconString() {
+ return this._smallIconString;
+ }
+
+ public void setSmallIconString(String icon) {
+ this._smallIconString = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getLargeIconString()
+ */
+ public String getLargeIconString() {
+ return this._largeIconString;
+ }
+
+ public void setLargeIconString(String icon) {
+ this._largeIconString = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getSmallIcon()
+ */
+ public ImageDescriptor getSmallIcon() {
+ return this._smallIcon;
+ }
+
+ public void setSmallIcon(ImageDescriptor icon) {
+ this._smallIcon = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getLargeIcon()
+ */
+ public ImageDescriptor getLargeIcon() {
+ return this._largeIcon;
+ }
+
+ public void setLargeIcon(ImageDescriptor icon) {
+ this._largeIcon = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setInitialState(int)
+ */
+ public void setInitialState(int state) {
+ _initState = state;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getInitialState()
+ */
+ public int getInitialState() {
+ return _initState;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory#isJSFComponentCategory()
+ */
+ public boolean isJSFComponentCategory() {
+ return this._jsfComponentCategory;
+ }
+
+ public void setJSFComponentCategory(boolean b) {
+ this._jsfComponentCategory = b;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemDescriptor.java
new file mode 100644
index 000000000..663ef7f04
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemDescriptor.java
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.gef.palette.PaletteDrawer;
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ */
+public class PaletteItemDescriptor implements IPaletteItemDescriptor {
+ private Map _map;
+
+ private String _id;
+
+ private String _tagName;
+
+ private String _uri;
+
+ private boolean _isVisible = true;
+
+ private String _description;
+
+ private String _label;
+
+ private ImageDescriptor _smallIcon;
+
+ private ImageDescriptor _largeIcon;
+
+ private String _smallIconString;
+
+ private String _largeIconString;
+
+ private String _prefix;
+
+ private boolean _requireHForm = false; // default to false
+
+ private PaletteEntry _entry;
+
+ private int _initState = PaletteDrawer.INITIAL_STATE_CLOSED;
+
+ private NodeList _templateSubNodes;
+
+ private boolean _jsfComponent = false;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getSmallIcon()
+ */
+ public ImageDescriptor getSmallIcon() {
+ return this._smallIcon;
+ }
+
+ public void setSmallIcon(ImageDescriptor icon) {
+ this._smallIcon = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getLargeIcon()
+ */
+ public ImageDescriptor getLargeIcon() {
+ return this._largeIcon;
+ }
+
+ public void setLargeIcon(ImageDescriptor icon) {
+ this._largeIcon = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getURI()
+ */
+ public String getURI() {
+ return this._uri;
+ }
+
+ public void setURI(String uri) {
+ this._uri = uri;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getTagName()
+ */
+ public String getTagName() {
+ return this._tagName;
+ }
+
+ public void setTagName(String tag) {
+ this._tagName = tag;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getInitialAttributes()
+ */
+ public Map getInitialAttributes() {
+ return this._map;
+ }
+
+ public void setInitialAttributes(Map map) {
+ this._map = map;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#setDefaultPrefix(java.lang.String)
+ */
+ public void setDefaultPrefix(String defaultPrefix) {
+ this._prefix = defaultPrefix;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getDefaultPrefix()
+ */
+ public String getDefaultPrefix() {
+ return this._prefix;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getSmallIconString()
+ */
+ public String getSmallIconString() {
+ return this._smallIconString;
+ }
+
+ public void setSmallIconString(String icon) {
+ this._smallIconString = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getLargeIconString()
+ */
+ public String getLargeIconString() {
+ return this._largeIconString;
+ }
+
+ public void setLargeIconString(String icon) {
+ this._largeIconString = icon;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#getPaletteEntry()
+ */
+ public PaletteEntry getPaletteEntry() {
+ return this._entry;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#setPaletteEntry(org.eclipse.gef.palette.PaletteEntry)
+ */
+ public void setPaletteEntry(PaletteEntry entry) {
+ this._entry = entry;
+ /*
+ * if (entry.getDescription()==null && this.getDescription()!=null) {
+ * entry.setDescription(this.getDescription()); } if
+ * (entry.getId()==null && this.getId()!=null) {
+ * entry.setId(this.getId()); } if (entry.getLabel()==null &&
+ * this.getLabel()!=null) { entry.setLabel(this.getLabel()); }
+ * entry.setVisible(this.isVisible());
+ */
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getId()
+ */
+ public String getId() {
+ if (_id == null) {
+ _id = _tagName;
+ }
+ return _id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setId(java.lang.String)
+ */
+ public void setId(String id) {
+ this._id = id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setlabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this._label = label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getDescription()
+ */
+ public String getDescription() {
+ return _description;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setDescription(java.lang.String)
+ */
+ public void setDescription(String desc) {
+ this._description = desc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#isVisible()
+ */
+ public boolean isVisible() {
+ return _isVisible;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setVisible(boolean)
+ */
+ public void setVisible(boolean visible) {
+ this._isVisible = visible;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getLabel()
+ */
+ public String getLabel() {
+ return _label;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#isRequireHForm()
+ */
+ public boolean isRequireHForm() {
+ return this._requireHForm;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#setRequireHForm()
+ */
+ public void setRequireHForm(boolean r) {
+ this._requireHForm = r;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor#isJSFComponent()
+ */
+ public boolean isJSFComponent() {
+ if (IJMTConstants.URI_JSF_CORE.equals(this._uri)
+ || IJMTConstants.URI_JSF_HTML.equals(this._uri)) {
+ return true;
+ }
+ return this._jsfComponent;
+ }
+
+ public void setJSFComponent(boolean b) {
+ this._jsfComponent = b;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#setInitialState(int)
+ */
+ public void setInitialState(int state) {
+ _initState = state;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry#getInitialState()
+ */
+ public int getInitialState() {
+ // TODO Auto-generated method stub
+ return _initState;
+ }
+
+ /**
+ * Returns the template nodes with prefixs resolved from IDOMModel.
+ *
+ * @return Returns the _templateSubNodes.
+ */
+ public Node[] getTemplateSubNodes(IDOMModel model) {
+ if (_templateSubNodes == null) {
+ return null;
+ }
+ if (!this.getURI().equalsIgnoreCase(IJMTConstants.URI_JSF_HTML) && //
+ !getURI().equalsIgnoreCase(IJMTConstants.URI_JSF_CORE)) {
+ List nodes = new ArrayList();
+ for (int i = 0, n = _templateSubNodes.getLength(); i < n; i++) {
+ String prefixH = JSPUtil.getPrefix(model,
+ IJMTConstants.URI_JSF_HTML);
+ String prefixC = JSPUtil.getPrefix(model,
+ IJMTConstants.URI_JSF_CORE);
+ Node node = PaletteElementTemplateHelper.cloneNodeDeep(model
+ .getDocument(), _templateSubNodes.item(i), prefixH,
+ prefixC);
+ nodes.add(node);
+ }
+ return (Node[]) nodes.toArray(new Node[nodes.size()]);
+ } else {
+ Node[] result = null;
+ if (model != null) {
+ NodeList nl = _templateSubNodes;
+ if (nl != null) {
+ String prefixH = JSPUtil.getPrefix(model,
+ IJMTConstants.URI_JSF_HTML);
+ String prefixC = JSPUtil.getPrefix(model,
+ IJMTConstants.URI_JSF_CORE);
+
+ Assert.isTrue(prefixH != null && prefixC != null);
+ result = PaletteElementTemplateHelper.applyPrefixes(
+ prefixH, prefixC, nl, model.getDocument());
+ }
+ }
+ return result;
+ }
+ }
+
+ /**
+ * This method should be called by config file initialization class only.
+ *
+ * @param subNodes
+ * The _templateSubNodes to set.
+ */
+ public void setTemplateSubNodes(NodeList subNodes) {
+ _templateSubNodes = subNodes;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemManager.java
new file mode 100644
index 000000000..8c60c463a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editors/palette/impl/PaletteItemManager.java
@@ -0,0 +1,978 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editors.palette.impl;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.gef.palette.PaletteDrawer;
+import org.eclipse.gef.palette.PaletteEntry;
+import org.eclipse.jst.j2ee.internal.deployables.J2EEFlexProjDeployable;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.WebrootUtil;
+import org.eclipse.jst.pagedesigner.editors.palette.IEntryChangeListener;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteConstants;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemEntry;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemManager;
+import org.eclipse.jst.pagedesigner.editors.palette.IResourceManager;
+import org.eclipse.jst.pagedesigner.utils.XMLUtil;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLCMDocumentFactory;
+import org.eclipse.wst.xml.core.internal.contentmodel.ContentModelManager;
+import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMDocType;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * @author mengbo
+ */
+public class PaletteItemManager implements IPaletteItemManager,
+ IPaletteConstants {
+ private static Logger _log = PDPlugin.getLogger(PaletteItemManager.class);
+
+ private static Map _managers = new HashMap();
+
+ private static TLDDocument jsfcoreTLD = null;
+
+ private static TLDDocument jsfhtmlTLD = null;
+
+ private List _categories = new ArrayList();
+
+ // if _curProject is null, then is the default manager.
+ private IProject _curProject = null;
+
+ private Map _paletteEntryMap = new HashMap();
+
+ private String _filename;
+
+ protected IEntryChangeListener[] _listeners;
+
+ // the default manager is for those _curProject == null
+ private static PaletteItemManager _defaultManager = null;
+
+ /** the resource tracker instance */
+ private ResourceTracker _resourceTracker = null;
+
+ private class ResourceTracker implements IResourceChangeListener,
+ IResourceDeltaVisitor {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+ */
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDelta delta = event.getDelta();
+
+ try {
+ if (delta != null)
+ delta.accept(this);
+ } catch (CoreException exception) {
+ // ResourcePageEditor.Error.ResourceChange = Failed in the
+ // resource change.
+ _log
+ .error("ResourcePageEditor.Error.ResourceChange",
+ exception);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
+ */
+ public boolean visit(IResourceDelta delta) {
+ if (delta == null) {
+ return true;
+ }
+
+ reset();
+ return false;
+ }
+ }
+
+ /**
+ * Returns the resource tracker instance
+ *
+ * @return - Returns the resource tracker instance
+ */
+ private ResourceTracker getResourceTracker() {
+ if (null == _resourceTracker) {
+ _resourceTracker = new ResourceTracker();
+
+ }
+
+ return _resourceTracker;
+ }
+
+ public static synchronized PaletteItemManager getInstance(IProject project) {
+ if (project == null) {
+ // sometimes when the editor is editing a file in jar file, may not
+ // be able to
+ // get the project.
+ return getDefaultPaletteItemManager();
+ }
+ PaletteItemManager manager = (PaletteItemManager) _managers
+ .get(project);
+ if (manager == null) {
+ manager = new PaletteItemManager(project);
+ _managers.put(project, manager);
+ }
+ return manager;
+ }
+
+ /**
+ *
+ */
+ public void dispose() {
+ IWorkspace ws = ResourcesPlugin.getWorkspace();
+
+ if (_resourceTracker != null) {
+ ws.removeResourceChangeListener(_resourceTracker);
+ }
+ }
+
+ public IProject getCurProject() {
+ return _curProject;
+ }
+
+ public static synchronized void removePaletteItemManager(
+ PaletteItemManager manager) {
+ manager.dispose();
+ _managers.remove(manager.getCurProject());
+ }
+
+ public static synchronized void clearPaletteItemManager() {
+ _managers.clear();
+ }
+
+ /**
+ * @return
+ */
+ private static PaletteItemManager getDefaultPaletteItemManager() {
+ if (_defaultManager == null) {
+ _defaultManager = new PaletteItemManager(null);
+ }
+ return _defaultManager;
+ }
+
+ /**
+ *
+ */
+ private PaletteItemManager(IProject project) {
+ _curProject = project;
+ init();
+ _curProject.getWorkspace().addResourceChangeListener(
+ getResourceTracker());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.sybase.stf.jmt.pagedesigner.editors.palette.IPaletteItemManager#getAllCategories()
+ */
+ public List getAllCategories() {
+ return _categories;
+ }
+
+ protected void init() {
+ if (_categories == null) {
+ _categories = new ArrayList();
+ }
+ _categories.clear();
+ PaletteHelper.readConfigFromPlugin(this);
+ PaletteHelper.loadFromCMDocument(findOrCreateCategory(
+ IJMTConstants.URI_HTML, null), HTMLCMDocumentFactory
+ .getCMDocument(CMDocType.HTML_DOC_TYPE));
+ PaletteHelper.loadFromCMDocument(findOrCreateCategory(
+ IJMTConstants.URI_JSP, null), HTMLCMDocumentFactory
+ .getCMDocument(CMDocType.JSP11_DOC_TYPE));
+ // if (jsfcoreTLD != null)
+ // {
+ // PaletteHelper.configPaletteItemsByTLD(this, jsfcoreTLD);
+ // }
+ // if (jsfhtmlTLD != null)
+ // {
+ // PaletteHelper.configPaletteItemsByTLD(this, jsfhtmlTLD);
+ // }
+
+ // the default system definied category(from plugin) is invisible
+ // except HTML and JSP category
+ for (int i = 0, size = _categories.size(); i < size; i++) {
+ IPaletteItemCategory category = (IPaletteItemCategory) _categories
+ .get(i);
+ category.setVisible(false);
+ if (category.getURI().equals(IJMTConstants.URI_HTML)) {
+ category.setVisible(true);
+ }
+ if (category.getURI().equals(IJMTConstants.URI_JSP)) {
+ category.setVisible(true);
+ }
+ }
+
+ // initForPluginExtension();
+ initFromProject(_curProject);
+ List newCategories = new ArrayList();
+ for (int i = 0, size = _categories.size(); i < size; i++) {
+ IPaletteItemCategory category = (IPaletteItemCategory) _categories
+ .get(i);
+ if (category.isVisible()) {
+ newCategories.add(category);
+ }
+ }
+ _categories.clear();
+ _categories = newCategories;
+ configureState();
+ }
+
+ public void reset() {
+ init();
+ fireModelChanged(null, null);
+ }
+
+ private void initFromProject(IProject project) {
+
+ registerTldFromClasspath(project);
+
+ IFolder webroot = WebrootUtil.getWebContentFolder(project);
+ IFolder webinf = webroot.getFolder(IFileFolderConstants.FOLDER_WEBINF);
+ // search tld file in web-inf folder
+ initFormFolder(webinf);
+ }
+
+ /**
+ * Search Classpath entry list to find if the entry is jar libraray and the
+ * libray have the tld descriptor, if have ,build a palette category mapping
+ * the tld descriptor.
+ *
+ * @param project
+ */
+ private void registerTldFromClasspath(IProject project) {
+ J2EEFlexProjDeployable jdeploy = new J2EEFlexProjDeployable(project);
+ IPath[] paths = jdeploy.getClasspath();
+ for (int i = 0; i < paths.length; i++) {
+ IPath path = paths[i];
+ String jarFile = path.toOSString();
+ if (jarFile.toLowerCase().endsWith(".jar")) {
+ ZipFile zFile = null;
+ // Need to check if the jar file has a .tld file anywhere under
+ // the
+ // META-INF directory. If there is, add a taglib for the uri
+ // that
+ // is inside the TLD file.
+ try {
+ zFile = new ZipFile(jarFile);
+ ZipEntry[] entries = findTLDEntriesInZip(zFile);
+
+ for (int z = 0; z < entries.length; z++) {
+ ZipEntry entry = entries[z];
+ if (entry != null) {
+ // most entries can be skipped this way
+ String entryName = entry.getName();
+ if (entryName == null
+ || entryName.indexOf("META-INF") < 0 || !entryName.toLowerCase().endsWith("tld")) //$NON-NLS-1$
+ {
+ continue;
+ }
+ DocumentFactoryTLD factory = new DocumentFactoryTLD();
+ TLDDocument doc = (TLDDocument) factory
+ .buildCMDocumentFromJar(jarFile, entry
+ .getName());
+ PaletteHelper.configPaletteItemsByTLD(this, doc);
+ }
+ }
+ zFile.close();
+ } catch (IOException e) {
+ }
+
+ }
+ }
+ }
+
+ private void initFormFolder(IFolder folder) {
+ // webinf.get
+ IResource[] members;
+ try {
+ members = folder.members();
+ for (int i = 0; i < members.length; i++) {
+ IResource res = members[i];
+ if (res instanceof IFolder) {
+ initFormFolder((IFolder) res);
+ }
+ if ("tld".equalsIgnoreCase(res.getFileExtension())) {
+ TLDDocument doc = (TLDDocument) ContentModelManager
+ .getInstance().createCMDocument(
+ res.getLocation().toOSString(), "tld"); //$NON-NLS-1$
+ PaletteHelper.configPaletteItemsByTLD(this, doc);
+ }
+ }
+ } catch (CoreException e) {
+ }
+
+ }
+
+ public static ZipEntry[] findTLDEntriesInZip(ZipFile zFile) {
+ Enumeration entries = zFile.entries();
+ ArrayList results = new ArrayList();
+
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ if (!entry.isDirectory()) {
+ // Look for the first .tld file found in the META-INF directory.
+ results.add(entry);
+ }
+ }
+ return (ZipEntry[]) results.toArray(new ZipEntry[results.size()]);
+ }
+
+ /**
+ *
+ */
+ private void initForPluginExtension() {
+ IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+
+ IExtensionPoint point = extensionRegistry.getExtensionPoint(
+ IPaletteConstants.BUNDLE_ID,
+ IPaletteConstants.EXTENSION_POINT_ID);
+
+ IConfigurationElement[] elements = point.getConfigurationElements();
+ for (int i = 0; i < elements.length; i++) {
+ try {
+ IConfigurationElement element = elements[i];
+ Object obj = element.createExecutableExtension("class"); //$NON-NLS-1$
+
+ if (obj instanceof IResourceManager && _curProject != null) {
+ IResourceManager manager = (IResourceManager) obj;
+ List resources = manager.getResourceList(_curProject);
+ for (Iterator iter = resources.iterator(); iter.hasNext();) {
+ String path = (String) iter.next();
+ try {
+ URL url = new URL(path);
+ url = Platform.asLocalURL(url);
+ String filepath = url.toExternalForm();
+ filepath = filepath.replace('\\', '/');
+ TLDDocument doc = null;
+
+ if (path.indexOf("!") > 0) //$NON-NLS-1$
+ {
+
+ DocumentFactoryTLD factory = new DocumentFactoryTLD();
+ String jarFile = path.substring(0, path
+ .indexOf("!")); //$NON-NLS-1$
+ if (jarFile.startsWith(JARPROTO)) {
+ jarFile = jarFile.substring(JARPROTO
+ .length());
+ }
+ String contentName = path.substring(path
+ .indexOf("!") + 1, path.length()); //$NON-NLS-1$
+ if (contentName.startsWith("/")) {
+ contentName = contentName.substring(1);
+ }
+ // first get resource from project, if not exist
+ // , from eclipse plugin.
+ String jarpathofproject = null;
+ try {
+ jarpathofproject = jarFile.substring(0,
+ jarFile.toUpperCase().indexOf(
+ ".JAR") + 4);
+ jarpathofproject = jarpathofproject
+ .substring(jarpathofproject
+ .lastIndexOf("/") + 1);
+ jarpathofproject = getRelativeProjectFile(
+ _curProject,
+ IFileFolderConstants.FOLDER_WEBINF
+ + "/"
+ + IFileFolderConstants.FOLDER_LIB
+ + "/" + jarpathofproject);
+ } catch (Exception e) {
+ jarpathofproject = null;
+ }
+ if (jarpathofproject != null) {
+ jarpathofproject = jarpathofproject
+ .replace('\\', '/');
+ doc = (TLDDocument) factory
+ .buildCMDocumentFromJar(
+ jarpathofproject,
+ contentName);
+ } else {
+ doc = (TLDDocument) factory
+ .buildCMDocumentFromJar(jarFile,
+ contentName);
+ }
+ } else {
+ if (filepath.startsWith(FILEPROTO))// if
+ // filepath
+ // starts
+ // with
+ // "file://"
+ // will have
+ // problem
+ // to be
+ // paremeter.
+ {
+ filepath = filepath.substring(FILEPROTO
+ .length());
+ }
+ String tldpathofproject = null;
+ try {
+ tldpathofproject = filepath.substring(0,
+ filepath.toUpperCase().indexOf(
+ ".TLD") + 4);
+ tldpathofproject = tldpathofproject
+ .substring(tldpathofproject
+ .lastIndexOf("/") + 1);
+ tldpathofproject = getRelativeProjectFile(
+ _curProject,
+ IFileFolderConstants.FOLDER_WEBINF
+ + "/"
+ + IFileFolderConstants.FOLDER_TAGLIB
+ + "/" + tldpathofproject);
+ } catch (Exception e) {
+ tldpathofproject = null;
+ }
+ if (tldpathofproject != null) {
+ tldpathofproject = tldpathofproject
+ .replace('\\', '/');
+ doc = (TLDDocument) ContentModelManager
+ .getInstance().createCMDocument(
+ tldpathofproject, "tld"); //$NON-NLS-1$
+ } else {
+ doc = (TLDDocument) ContentModelManager
+ .getInstance().createCMDocument(
+ filepath, "tld"); //$NON-NLS-1$
+ }
+ }
+
+ PaletteHelper.configPaletteItemsByTLD(this, doc);
+ } catch (MalformedURLException e1) {
+ _log
+ .error(
+ "PaletteItemManager.initForPluginExtension.error.MalformedURLException", e1); //$NON-NLS-1$
+ }
+
+ catch (IOException e2) {
+ _log
+ .error(
+ "PaletteItemManager.initForPluginExtension.error.IOException", e2); //$NON-NLS-1$
+ }
+ }
+ }
+ } catch (CoreException e) {
+ _log
+ .error(
+ "PaletteItemManager.initForPluginExtension.error.InstantiationException", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private void configureState() {
+ loadPaletteItemState();
+ for (Iterator iter = _categories.iterator(); iter.hasNext();) {
+ IPaletteItemCategory element = (IPaletteItemCategory) iter.next();
+
+ String id = element.getId();
+ IPaletteItemCategory entry = (IPaletteItemCategory) _paletteEntryMap
+ .get(id);
+ if (entry != null) {
+ element.setVisible(entry.isVisible());
+ element.setId(entry.getId());
+ element.setDescription(entry.getDescription());
+ element.setLabel(entry.getLabel());
+ element.setInitialState(entry.getInitialState());
+ }
+ List cList = element.getPaletteItems();
+ for (Iterator iterator = cList.iterator(); iterator.hasNext();) {
+ IPaletteItemDescriptor cItem = (IPaletteItemDescriptor) iterator
+ .next();
+ String cid = cItem.getId();
+ String clabel = cItem.getLabel();
+ if (clabel == null) {
+ clabel = cItem.getTagName();
+ }
+ IPaletteItemCategory cEntry = (IPaletteItemCategory) _paletteEntryMap
+ .get(cid);// cEntry of type IPaletteItemCategory just
+ // IPaletteItemEntry Implement
+ if (cEntry != null) {
+ cItem.setVisible(cEntry.isVisible());
+ cItem.setId(cEntry.getId());
+ cItem.setDescription(cEntry.getDescription());
+ cItem.setLabel(cEntry.getLabel());
+ }
+ }
+ }
+ }
+
+ /**
+ * @param uri2
+ * @return
+ */
+ public IPaletteItemCategory findOrCreateCategory(String uri, String label) {
+ for (Iterator iter = _categories.iterator(); iter.hasNext();) {
+ PaletteItemCategory cate = (PaletteItemCategory) iter.next();
+ if (uri.equals(cate.getURI())) {
+ return cate;
+ }
+ }
+ PaletteItemCategory r = new PaletteItemCategory(uri, label);
+ _categories.add(r);
+ // TODO: fire event?
+ return r;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.sybase.stf.jmt.pagedesigner.editors.palette.IPaletteItemManager#createCategory(java.lang.String)
+ */
+ public IPaletteItemCategory createCategory(String tldURI) {
+ PaletteItemCategory r = new PaletteItemCategory(tldURI, tldURI);
+ _categories.add(r);
+ return r;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.sybase.stf.jmt.pagedesigner.editors.palette.IPaletteItemManager#getCategoryByURI(java.lang.String)
+ */
+ public IPaletteItemCategory getCategoryByURI(String tldURI) {
+ for (Iterator iter = _categories.iterator(); iter.hasNext();) {
+ IPaletteItemCategory cat = (IPaletteItemCategory) iter.next();
+ if (tldURI.equals(cat.getURI())) {
+ return cat;
+ }
+ }
+ return null;
+ }
+
+ public void moveup(IPaletteItemCategory cat) {
+ int i = _categories.indexOf(cat);
+ IPaletteItemCategory upCat = (IPaletteItemCategory) _categories
+ .get(i - 1);
+ movedown(upCat);
+ }
+
+ public void movedown(IPaletteItemCategory cat) {
+ int i = _categories.indexOf(cat);
+ _categories.add(i + 2, cat);
+ _categories.remove(i);
+ }
+
+ public String getFilename() {
+ if (_filename == null || _filename.trim().equals("")) {
+ String name = null;
+ try {
+ Bundle bundle = Platform.getBundle(PDPlugin.getPluginId());
+ name = Platform.getStateLocation(bundle).toString() + FILENAME; //$NON-NLS-1$
+ } catch (Exception e) {
+ name = FILENAME;
+ }
+ name = name.replace('/', File.separatorChar);
+ name = name.replace('\\', File.separatorChar);
+ return name;
+ } else {
+ _filename = _filename.replace('/', File.separatorChar);
+ _filename = _filename.replace('\\', File.separatorChar);
+ return _filename;
+ }
+ }
+
+ public void setFilename(String filename) {
+ _filename = filename;
+ }
+
+ /**
+ * Save palette item state
+ */
+ public void save() {
+ Document document = XMLUtil.getDocumentBuilder().getDOMImplementation()
+ .createDocument(null, IPaletteConstants.ROOT, null);
+ try {
+ FileOutputStream ostream = null;
+ String defaultfilename = getFilename();
+ int index = defaultfilename.lastIndexOf(File.separator);
+ String foldername = defaultfilename.substring(0, index); //$NON-NLS-1$
+ File folder = new File(foldername);
+ if (folder != null && !folder.exists()) {
+ folder.mkdir();
+ }
+ ostream = new FileOutputStream(getFilename());
+ Map categoryMap = new HashMap();
+ Element root = document.getDocumentElement();
+ if (root != null) {
+ NodeList clist = root.getChildNodes();
+ for (int i = 0, length = clist.getLength(); i < length; i++) {
+ Node cNode = clist.item(i);
+ NamedNodeMap attrs = cNode.getAttributes();
+ if (attrs != null) {
+ Node attrNode = attrs.getNamedItem(ID);
+ if (attrNode != null) {
+ String value = attrNode.getNodeValue();
+ categoryMap.put(value, cNode);
+ }
+ }
+ }
+ }
+
+ for (Iterator iter = _categories.iterator(); iter.hasNext();) {
+ IPaletteItemCategory category = (IPaletteItemCategory) iter
+ .next();
+ PaletteEntry entry = category.getPaletteEntry();
+ Element categoryElement = document.createElement(CATEGORY_TAG);
+ Node existNode = (Node) categoryMap.get(entry.getId());
+ if (existNode != null) {
+ root.removeChild(existNode);
+ }
+ if (entry != null) {
+ if (entry.getId() != null) {
+ categoryElement.setAttribute(ID, entry.getId());
+ }
+
+ if (entry.getDescription() != null) {
+ categoryElement.setAttribute(SHORTDESC, entry
+ .getDescription());
+ }
+ if (entry.getLabel() != null) {
+ categoryElement.setAttribute(LABEL, entry.getLabel());
+ }
+ if (entry.getSmallIcon() != null
+ && entry.getSmallIcon().toString() != null) {
+ categoryElement.setAttribute(SMALLICON, entry
+ .getSmallIcon().toString());
+ }
+ if (entry.getLargeIcon() != null
+ && entry.getLargeIcon().toString() != null) {
+ categoryElement.setAttribute(LARGEICON, entry
+ .getLargeIcon().toString());
+ }
+ if (entry instanceof PaletteDrawer) {
+ int state = ((PaletteDrawer) entry).getInitialState();
+ categoryElement.setAttribute(INITIALSTATE, String
+ .valueOf(state));
+ }
+ if (entry.isVisible()) {
+ categoryElement.setAttribute(ISVISIBLE, Boolean.FALSE
+ .toString());
+ } else {
+ categoryElement.setAttribute(ISVISIBLE, Boolean.TRUE
+ .toString());
+ }
+
+ }
+ List tags = category.getPaletteItems();
+ for (Iterator iterator = tags.iterator(); iterator.hasNext();) {
+ IPaletteItemDescriptor tag = (IPaletteItemDescriptor) iterator
+ .next();
+ Element tagElement = document.createElement(ITEM_TAG);
+ if (tag.getTagName() != null) {
+ tagElement.setAttribute(TAGNAME, tag.getTagName());
+ }
+ if (tag.getLabel() != null) {
+ tagElement.setAttribute(LABEL, tag.getLabel());
+ }
+ if (tag.getDescription() != null) {
+ tagElement
+ .setAttribute(SHORTDESC, tag.getDescription());
+ }
+ if (tag.getSmallIconString() != null) {
+ tagElement.setAttribute(SMALLICON, tag
+ .getSmallIconString());
+ }
+ if (tag.getLargeIconString() != null) {
+ tagElement.setAttribute(LARGEICON, tag
+ .getLargeIconString());
+ }
+ PaletteEntry tagEntry = tag.getPaletteEntry();
+ if (tagEntry != null) {
+ if (tagEntry.getId() != null) {
+ tagElement.setAttribute(ID, tagEntry.getId());
+ }
+ if (tagEntry.getDescription() != null) {
+ tagElement.setAttribute(SHORTDESC, tagEntry
+ .getDescription());
+ }
+ if (tagEntry.getLabel() != null) {
+ tagElement.setAttribute(LABEL, tagEntry.getLabel());
+ }
+ if (tagEntry.isVisible()) {
+ tagElement.setAttribute(ISVISIBLE, Boolean.FALSE
+ .toString());
+ } else {
+ tagElement.setAttribute(ISVISIBLE, Boolean.TRUE
+ .toString());
+ }
+
+ }
+ categoryElement.appendChild(tagElement);
+ }
+ document.getDocumentElement().appendChild(categoryElement);
+ }
+ XMLUtil.serialize(document, ostream);
+ ostream.close();
+ } catch (IOException e) {
+ _log.error("PaletteItemManager.save.error.IOException", e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Load the list of categories that aren't to be visible
+ *
+ * @return
+ */
+ protected void loadPaletteItemState() {
+ _paletteEntryMap.clear();
+ List newOrderCatList = new ArrayList();
+ Document document = null;
+ try {
+ DocumentBuilder builder = XMLUtil.getDocumentBuilder();
+ if (builder != null) {
+ document = builder.parse(getFilename());
+ } else {
+ _log
+ .error("PaletteItemManager.loadPaletteItemState.error.getDocumentBuilderFail");// $
+ // //$NON-NLS-1$
+ }
+ } catch (FileNotFoundException e) {
+ // typical of new workspace, don't log it
+ document = null;
+ } catch (IOException e) {
+ // TaglibManager could not load hidden state
+ _log
+ .error(
+ "PaletteItemManager.loadPaletteItemState.error.IOException", e.toString(), e); //$NON-NLS-1$
+ } catch (SAXException e) {
+ // TaglibManager could not load hidden state
+ _log
+ .error(
+ "PaletteItemManager.loadPaletteItemState.error.SAXException", e.toString(), e); //$NON-NLS-1$
+ }
+ if (document != null) {
+ // List names = new ArrayList(0);
+ Element root = document.getDocumentElement();
+ if (root != null) {
+ NodeList catetorylist = root.getChildNodes();
+ for (int i = 0, n = catetorylist.getLength(); i < n; i++) {
+ Node childNode = catetorylist.item(i);
+ if (childNode.getNodeType() == Node.ELEMENT_NODE
+ && childNode.getNodeName().equals(
+ IPaletteConstants.CATEGORY_TAG)) {
+ Element categoryElement = (Element) childNode;
+
+ IPaletteItemEntry cat = createPaletteCategoryFromElement(categoryElement);
+ _paletteEntryMap.put(cat.getId(), cat);
+ IPaletteItemEntry newCat = getCategoryByURI(cat.getId());
+ if (newCat != null) {
+ newOrderCatList.add(newCat);
+ }
+
+ NodeList tagList = categoryElement.getChildNodes();
+ for (int j = 0, m = tagList.getLength(); j < m; j++) {
+ Node tagNode = tagList.item(j);
+ if (tagNode.getNodeType() == Node.ELEMENT_NODE
+ && tagNode.getNodeName().equals(
+ IPaletteConstants.ITEM_TAG)) {
+ Element tagElement = (Element) tagNode;
+ IPaletteItemEntry tag = createPaletteCategoryFromElement(tagElement);
+ _paletteEntryMap.put(tag.getId(), tag);
+ }
+ }
+ }
+ }
+
+ // add left categories(not in state file) to the last
+ for (Iterator iter = _categories.iterator(); iter.hasNext();) {
+ IPaletteItemCategory cat = (IPaletteItemCategory) iter
+ .next();
+ if (!newOrderCatList.contains(cat)) {
+ newOrderCatList.add(cat);
+ }
+ }
+
+ if (newOrderCatList.size() > 0) {
+ _categories = newOrderCatList;
+ }
+ }
+ }
+ }
+
+ /**
+ * @param categoryElement
+ * @return
+ */
+ private IPaletteItemEntry createPaletteCategoryFromElement(
+ Element categoryElement) {
+ String id = null;
+ String label = null;
+ String desc = null;
+ String uri = null;
+ boolean isVisible = true;
+ String state = null;
+ if (categoryElement.hasAttribute(IPaletteConstants.ID)) {
+ id = categoryElement.getAttribute(IPaletteConstants.ID);
+ }
+ if (categoryElement.hasAttribute(IPaletteConstants.SHORTDESC)) {
+ desc = categoryElement.getAttribute(IPaletteConstants.SHORTDESC);
+ }
+ if (categoryElement.hasAttribute(IPaletteConstants.LABEL)) {
+ label = categoryElement.getAttribute(IPaletteConstants.LABEL);
+ }
+ if (categoryElement.hasAttribute(IPaletteConstants.URI)) {
+ uri = categoryElement.getAttribute(IPaletteConstants.URI);
+ }
+ if (categoryElement.hasAttribute(IPaletteConstants.INITIALSTATE)) {
+ state = categoryElement
+ .getAttribute(IPaletteConstants.INITIALSTATE);
+ }
+ if (categoryElement.hasAttribute(IPaletteConstants.ISVISIBLE)) {
+ String visible = categoryElement
+ .getAttribute(IPaletteConstants.ISVISIBLE);
+ if ("true".equalsIgnoreCase(visible))//$NON-NLS-1$
+ {
+ isVisible = false;
+ }
+ }
+
+ PaletteItemCategory cat = new PaletteItemCategory(uri, label);
+ cat.setId(id);
+ cat.setDescription(desc);
+ cat.setVisible(isVisible);
+ int initState = PaletteDrawer.INITIAL_STATE_CLOSED;
+ try {
+ initState = Integer.parseInt(state);
+ } catch (Exception e) {
+ // ignore
+ }
+ cat.setInitialState(initState);
+ return cat;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.sybase.stf.jmt.pagedesigner.editors.palette.IPaletteItemManager#addEntryChangeListener(com.sybase.stf.jmt.pagedesigner.editors.palette.IEntryChangeListener)
+ */
+ public void addEntryChangeListener(IEntryChangeListener listener) {
+
+ if (_listeners == null) {
+ _listeners = new IEntryChangeListener[] { listener };
+ } else {
+ IEntryChangeListener[] newListeners = new IEntryChangeListener[_listeners.length + 1];
+ newListeners[0] = listener;
+ System.arraycopy(_listeners, 0, newListeners, 1, _listeners.length);
+ _listeners = newListeners;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.sybase.stf.jmt.pagedesigner.editors.palette.IPaletteItemManager#removeEntryChangeListener(com.sybase.stf.jmt.pagedesigner.editors.palette.IEntryChangeListener)
+ */
+ public void removeEntryChangeListener(IEntryChangeListener listener) {
+ if (_listeners == null) {
+ return;
+ }
+ if (_listeners.length == 1) {
+ _listeners = null;
+ } else {
+ List newListenersList = new ArrayList(Arrays.asList(_listeners));
+ newListenersList.remove(listener);
+ IEntryChangeListener[] newListeners = new IEntryChangeListener[newListenersList
+ .size() - 1];
+ newListeners = (IEntryChangeListener[]) newListenersList
+ .toArray(newListeners);
+ _listeners = newListeners;
+ }
+ }
+
+ /**
+ * Notify model change event
+ *
+ * @param oldDefinitions
+ * @param newDefinitions
+ */
+ private void fireModelChanged(List oldDefinitions, List newDefinitions) {
+ if (_listeners == null) {
+ return;
+ }
+ for (int i = 0; i < _listeners.length; i++) {
+ _listeners[i].modelChanged(oldDefinitions, newDefinitions);
+ }
+ }
+
+ /**
+ * Return location path of the file which the relative path to web project
+ * contextroot equal param path.
+ *
+ * @param project
+ * web project
+ * @param path
+ * relative path(example: WEB-INF/web.xml)
+ * @return
+ */
+ public String getRelativeProjectFile(IProject project, String path) {
+ IVirtualComponent wbModule = ComponentCore.createComponent(_curProject);
+ if (wbModule != null) {
+ IVirtualFile reFile = wbModule.getRootFolder().getFile(path);
+ if (reFile.exists()) {
+ return reFile.getUnderlyingFile().getLocation().toOSString()
+ + "/";
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnHelper.java
new file mode 100644
index 000000000..c69e687b8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnHelper.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableLayout2;
+
+/**
+ * @author mengbo
+ */
+public class ColumnHelper {
+ public static Rectangle getColumnBounds(GraphicalEditPart editPart,
+ IFigure target) {
+ Insets insets = target.getInsets();
+ Rectangle bounds = editPart.getFigure().getBounds().getCopy();
+
+ if (editPart.getParent() != null) {
+ IFigure figure = ((GraphicalEditPart) editPart.getParent())
+ .getFigure();
+ if (figure instanceof CSSFigure) {
+ CSSFigure cssFigure = (CSSFigure) figure;
+ LayoutManager layoutManager = cssFigure.getLayoutManager();
+ if (layoutManager instanceof CSSTableLayout2) {
+ CSSTableLayout2 tableLayout = (CSSTableLayout2) layoutManager;
+ bounds.y = tableLayout.getHSpacing();
+ bounds.height = figure.getClientArea().height
+ - tableLayout.getHSpacing() * 2;
+ }
+ }
+ }
+ bounds = new PrecisionRectangle(bounds.getResized(-1, -1));
+ editPart.getFigure().translateToAbsolute(bounds);
+ target.translateToRelative(bounds);
+ bounds.translate(-insets.left, -insets.top);
+ bounds.resize(insets.getWidth() + 1, insets.getHeight() + 1);
+ return bounds;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnResizableEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnResizableEditPolicy.java
new file mode 100644
index 000000000..dd11d84d4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ColumnResizableEditPolicy.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Locator;
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Handle;
+import org.eclipse.gef.SharedCursors;
+import org.eclipse.gef.handles.MoveHandle;
+import org.eclipse.gef.handles.ResizeHandle;
+import org.eclipse.gef.tools.SelectEditPartTracker;
+import org.eclipse.swt.graphics.Cursor;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class ColumnResizableEditPolicy extends ElementResizableEditPolicy {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#createSelectionHandles()
+ */
+ protected List createSelectionHandles() {
+ String elementName = ((Element) getHost().getModel()).getLocalName();
+ if ("column".equalsIgnoreCase(elementName)) {
+ List list = new ArrayList();
+
+ GraphicalEditPart part = (GraphicalEditPart) getHost();
+ MoveHandle handle = new MoveHandle(part, new ColumnHandleLocator(
+ part));
+ list.add(handle);
+
+ SelectEditPartTracker tracker = new SelectEditPartTracker(getHost());
+ list.add(createHandle(part, PositionConstants.SOUTH_EAST, tracker,
+ SharedCursors.ARROW));
+ list.add(createHandle(part, PositionConstants.SOUTH_WEST, tracker,
+ SharedCursors.ARROW));
+ list.add(createHandle(part, PositionConstants.NORTH_WEST, tracker,
+ SharedCursors.ARROW));
+ list.add(createHandle(part, PositionConstants.NORTH_EAST, tracker,
+ SharedCursors.ARROW));
+ return list;
+
+ }
+ return super.createSelectionHandles();
+ }
+
+ private Handle createHandle(GraphicalEditPart owner, int direction,
+ DragTracker tracker, Cursor cursor) {
+ ResizeHandle handle = new ResizeHandle(owner, new ColumnCornerLocator(
+ owner, direction), cursor);
+ handle.setCursor(cursor);
+ handle.setDragTracker(tracker);
+ return handle;
+ }
+
+ private class ColumnHandleLocator implements Locator {
+ private GraphicalEditPart editPart;
+
+ public ColumnHandleLocator(GraphicalEditPart editPart) {
+ this.editPart = editPart;
+ }
+
+ public void relocate(IFigure target) {
+ target.setBounds(ColumnHelper.getColumnBounds(editPart, target));
+ }
+ }
+
+ private class ColumnCornerLocator implements Locator {
+ private double relativeX;
+
+ private double relativeY;
+
+ private GraphicalEditPart editPart;
+
+ /**
+ * Constructs a RelativeLocator with the given reference figure and
+ * relative location. The location is a constant from
+ * {@link PositionConstants} used as a convenient and readable way to
+ * set both the relativeX and relativeY values.
+ *
+ * @param reference
+ * the reference figure
+ * @param location
+ * one of NORTH, NORTH_EAST, etc.
+ */
+ public ColumnCornerLocator(GraphicalEditPart editPart, int location) {
+ this.editPart = editPart;
+ switch (location & PositionConstants.NORTH_SOUTH) {
+ case PositionConstants.NORTH:
+ relativeY = 0;
+ break;
+ case PositionConstants.SOUTH:
+ relativeY = 1.0;
+ break;
+ default:
+ relativeY = 0.5;
+ }
+
+ switch (location & PositionConstants.EAST_WEST) {
+ case PositionConstants.WEST:
+ relativeX = 0;
+ break;
+ case PositionConstants.EAST:
+ relativeX = 1.0;
+ break;
+ default:
+ relativeX = 0.5;
+ }
+ }
+
+ /**
+ * Relocates the target using the relative offset locations.
+ *
+ * @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure)
+ */
+ public void relocate(IFigure target) {
+ Rectangle targetBounds = ColumnHelper.getColumnBounds(editPart,
+ target);
+
+ Dimension targetSize = target.getPreferredSize();
+
+ targetBounds.x += (int) (targetBounds.width * relativeX - ((targetSize.width + 1) / 2));
+ targetBounds.y += (int) (targetBounds.height * relativeY - ((targetSize.height + 1) / 2));
+ targetBounds.setSize(targetSize);
+ target.setBounds(targetBounds);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DesignerElementEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DesignerElementEditPolicy.java
new file mode 100644
index 000000000..d374946cd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DesignerElementEditPolicy.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.gef.editpolicies.ComponentEditPolicy;
+
+/**
+ * @author mengbo
+ */
+public class DesignerElementEditPolicy extends ComponentEditPolicy {
+
+ // /*
+ // * (non-Javadoc)
+ // *
+ // * @see
+ // org.eclipse.gef.editpolicies.ComponentEditPolicy#createDeleteCommand(org.eclipse.gef.requests.GroupRequest)
+ // */
+ // protected Command createDeleteCommand(GroupRequest deleteRequest)
+ // {
+ // // Object model = getHost().getModel();
+ // // ;
+ // // Node parent = null;
+ // // if (model instanceof Node)
+ // // {
+ // // parent = ((Node) model).getParentNode();
+ // // }
+ // // EditDomain domain = getHost().getViewer().getEditDomain();
+ // // IEditorPart editor = null;
+ // // //FIXME: must do this cast?
+ // // if (domain instanceof DefaultEditDomain)
+ // // {
+ // // editor = ((DefaultEditDomain) domain).getEditorPart();
+ // // }
+ // // if (editor instanceof HTMLEditor)
+ // // {
+ // // DeleteNodeCommand deleteCmd = new DeleteNodeCommand(((HTMLEditor)
+ // editor).getTextEditor().getTextViewer());
+ // // deleteCmd.setParent(parent);
+ // // deleteCmd.setChild((Node) getHost().getModel());
+ // // return deleteCmd;
+ // // }
+ // // else
+ // // {
+ // // return null;
+ // // }
+ // }
+ //
+ // /*
+ // * (non-Javadoc)
+ // *
+ // * @see org.eclipse.gef.EditPolicy#getCommand(org.eclipse.gef.Request)
+ // */
+ // public Command getCommand(Request request)
+ // {
+ // if (request.getType() == DesignCutAction.CUT_TYPE && request instanceof
+ // GroupRequest)
+ // {
+ // return createCutCommand((GroupRequest) request);
+ // }
+ // else if (request.getType() == DesignPasteAction.PASTE_TYPE && request
+ // instanceof GroupRequest)
+ // {
+ // return createPasteCommand((GroupRequest) request);
+ // }
+ // return super.getCommand(request);
+ // }
+ //
+ // protected Command createCutCommand(GroupRequest cutRequest)
+ // {
+ // Object model = getHost().getModel();
+ // ;
+ // Node parent = null;
+ // if (model instanceof Node)
+ // {
+ // parent = ((Node) model).getParentNode();
+ // }
+ // EditDomain domain = getHost().getViewer().getEditDomain();
+ // IEditorPart editor = null;
+ // //FIXME: must do this cast?
+ // if (domain instanceof DefaultEditDomain)
+ // {
+ // editor = ((DefaultEditDomain) domain).getEditorPart();
+ // }
+ // if (editor instanceof HTMLEditor)
+ // {
+ // CutNodeCommand cutCmd = new CutNodeCommand(((HTMLEditor)
+ // editor).getTextEditor().getTextViewer());
+ // cutCmd.setParent(parent);
+ // cutCmd.setChild((Node) getHost().getModel());
+ // return cutCmd;
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+ //
+ // protected Command createPasteCommand(GroupRequest cutRequest)
+ // {
+ // Object model = getHost().getModel();
+ // ;
+ // Node parent = null;
+ // if (model instanceof Node)
+ // {
+ // parent = ((Node) model).getParentNode();
+ // }
+ // EditDomain domain = getHost().getViewer().getEditDomain();
+ // IEditorPart editor = null;
+ // //FIXME: must do this cast?
+ // if (domain instanceof DefaultEditDomain)
+ // {
+ // editor = ((DefaultEditDomain) domain).getEditorPart();
+ // }
+ // if (editor instanceof HTMLEditor)
+ // {
+ // PasteNodeCommand pasteCmd = new PasteNodeCommand(((HTMLEditor)
+ // editor).getTextEditor().getTextViewer());
+ // pasteCmd.setParent(parent);
+ // pasteCmd.setChild((Node) getHost().getModel());
+ // return pasteCmd;
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DragMoveEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DragMoveEditPolicy.java
new file mode 100644
index 000000000..9331fb2a0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/DragMoveEditPolicy.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.RectangleFigure;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.UnexecutableCommand;
+import org.eclipse.gef.editpolicies.GraphicalEditPolicy;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.jst.pagedesigner.commands.CloneNodeCommand;
+import org.eclipse.jst.pagedesigner.commands.MoveNodeCommand;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.DnDPositionValidator;
+import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DragMoveEditPolicy extends GraphicalEditPolicy {
+ private RectangleFigure _feedbackFigure;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ public Command getCommand(Request request) {
+ if (!(request instanceof ChangeBoundsRequest)) {
+ return null;
+ }
+
+ ChangeBoundsRequest r = (ChangeBoundsRequest) request;
+
+ // we only support move/copy a single node.
+ if (!MoveSupport.isSingleNode(r)) {
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ // the edit policy only handle at the target part, so only care about
+ // the
+ // target part request.
+ final Object type = r.getType();
+ if (type != REQ_ADD && type != REQ_CLONE && type != REQ_MOVE_CHILDREN) {
+
+ return null;
+ }
+
+ Node draggedNode = MoveSupport.getDraggedNode(r);
+ Node hostNode = ((NodeEditPart) getHost()).getIDOMNode();
+
+ if (DOMUtil.isAncester(draggedNode, hostNode)) {
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ // System.out.println();
+ // System.out.println("r.type = " + r.getType());
+ // System.out.println("Host: " + hostNode);
+ // System.out.println("Dragged: " + draggedNode);
+
+ DesignPosition position = findPosition(r);
+ if (position == null || !position.isValid()) {
+ return null;
+ }
+
+ // can't move/copy into self.
+ Node node = position.getContainerNode();
+ if (DOMUtil.isAncester(draggedNode, node)) {
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ // ok, we are about to move/copy into the specified position.
+ IDOMPosition domposition = DOMPositionHelper.toDOMPosition(position);
+
+ if (REQ_CLONE.equals(type)) {
+ return new CloneNodeCommand((IHTMLGraphicalViewer) getHost()
+ .getViewer(), domposition, draggedNode);
+ } else {
+ return new MoveNodeCommand((IHTMLGraphicalViewer) getHost()
+ .getViewer(), domposition, draggedNode);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getTargetEditPart(org.eclipse.gef.Request)
+ */
+ public EditPart getTargetEditPart(Request request) {
+ if (request instanceof ChangeBoundsRequest) {
+ return this.getHost();
+ }
+ return super.getTargetEditPart(request);
+ }
+
+ DesignPosition findPosition(ChangeBoundsRequest r) {
+ IPositionMediator mediator = new DnDPositionValidator(new ActionData(
+ ActionData.COMPONENT_MOVE, r.getEditParts()));
+ DesignPosition position = EditPartPositionHelper.findEditPartPosition(
+ getHost(), r.getLocation(), mediator);
+ return position;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void eraseTargetFeedback(Request request) {
+ if (_feedbackFigure != null) {
+ removeFeedback(_feedbackFigure);
+ _feedbackFigure = null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#showTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void showTargetFeedback(Request request) {
+ if (request instanceof ChangeBoundsRequest) {
+ ChangeBoundsRequest r = (ChangeBoundsRequest) request;
+
+ Object type = r.getType();
+ if (type != REQ_ADD && type != REQ_CLONE
+ && type != REQ_MOVE_CHILDREN) {
+ return;
+ }
+ EditPart host = getHost();
+ DesignPosition position = findPosition(r);
+ if (position != null) {
+ Rectangle rect = EditPartPositionHelper
+ .convertToAbsoluteCaretRect(position);
+
+ // to avoid enlarge feedback pane.
+ rect = rect.intersect(getFeedbackLayer().getBounds());
+ showFeedbackRect(rect);
+ }
+ }
+ }
+
+ protected RectangleFigure getFeedbackFigure() {
+ if (this._feedbackFigure == null) {
+ _feedbackFigure = new RectangleFigure();
+ _feedbackFigure.setFill(true);
+ _feedbackFigure.setOutline(true);
+ _feedbackFigure.setLineWidth(1);
+ _feedbackFigure.setForegroundColor(ColorConstants.red);
+ _feedbackFigure.setBounds(new Rectangle(0, 0, 0, 0));
+ _feedbackFigure.setXOR(true);
+ addFeedback(_feedbackFigure);
+ }
+ return _feedbackFigure;
+ }
+
+ protected void showFeedbackRect(Rectangle rect) {
+ RectangleFigure pf = getFeedbackFigure();
+ pf.translateToRelative(rect);
+ pf.setBounds(rect);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ElementResizableEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ElementResizableEditPolicy.java
new file mode 100644
index 000000000..216ac5539
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ElementResizableEditPolicy.java
@@ -0,0 +1,464 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.RectangleFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.RequestConstants;
+import org.eclipse.gef.SharedCursors;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editpolicies.ResizableEditPolicy;
+import org.eclipse.gef.handles.NonResizableHandleKit;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gef.requests.LocationRequest;
+import org.eclipse.gef.requests.SelectionRequest;
+import org.eclipse.gef.tools.SelectEditPartTracker;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeStyleCommand;
+import org.eclipse.jst.pagedesigner.common.utils.StringUtil;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.BlockBox;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.MultiLineLabel;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemCategory;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.requests.LocationModifierRequest;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ElementResizableEditPolicy extends ResizableEditPolicy {
+ private static final Insets INSETS_1 = new Insets(1, 1, 1, 1);
+
+ private static final int THRESHHOLD = 3;
+
+ private static final Insets INSETS_CONST = new Insets(THRESHHOLD,
+ THRESHHOLD, THRESHHOLD, THRESHHOLD);
+
+ private boolean _showLabelFeedback = true;
+
+ private IFigure[] _hoverFeedbackFigure;
+
+ public static Color HOVER_FEEDBACK_COLOR = ColorConstants.darkBlue;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#showTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void showTargetFeedback(Request request) {
+ if (RequestConstants.REQ_SELECTION_HOVER.equals(request.getType())) {
+ if (_hoverFeedbackFigure != null) {
+ for (int i = 0; i < _hoverFeedbackFigure.length; i++) {
+ removeFeedback(_hoverFeedbackFigure[i]);
+ }
+ _hoverFeedbackFigure = null;
+ }
+ _hoverFeedbackFigure = showHoverFeedback(request);
+ } else {
+ super.showTargetFeedback(request);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void eraseTargetFeedback(Request request) {
+ if (RequestConstants.REQ_SELECTION_HOVER.equals(request.getType())) {
+ if (_hoverFeedbackFigure != null) {
+ for (int i = 0; i < _hoverFeedbackFigure.length; i++) {
+ removeFeedback(_hoverFeedbackFigure[i]);
+ }
+ _hoverFeedbackFigure = null;
+ }
+ } else {
+ super.eraseTargetFeedback(request);
+ }
+ }
+
+ /**
+ * @param request
+ */
+ private IFigure[] showHoverFeedback(Request request) {
+ if (!shouldUseObjectMode(request) && !isStyleTags(getHost())) {
+ return null;
+ }
+
+ IFigure figure = this.getHostFigure();
+ Rectangle[] rects;
+ if (figure instanceof CSSFigure) {
+ rects = ((CSSFigure) figure).getFragmentsBounds();
+ } else {
+ rects = new Rectangle[] { figure.getBounds() };
+ }
+ IFigure[] figures = new IFigure[rects.length
+ + (_showLabelFeedback ? 1 : 0)];
+ for (int i = 0; i < rects.length; i++) {
+ RectangleFigure fig = new RectangleFigure();
+ fig.setFill(false);
+ fig.setOutline(true);
+ fig.setLineWidth(1);
+ fig.setForegroundColor(HOVER_FEEDBACK_COLOR);
+ addFeedback(fig);
+
+ Rectangle r = rects[i].getCopy();
+ figure.translateToAbsolute(r);
+ fig.translateToRelative(r);
+ fig.setBounds(r);
+
+ figures[i] = fig;
+ }
+ if (_showLabelFeedback) {
+ Label label = new MultiLineLabel();
+ label.setOpaque(true);
+ label.setBackgroundColor(ColorConstants.yellow);
+ // label.setBorder(new LineBorder(HOVER_FEEDBACK_COLOR, 1));
+ label.setForegroundColor(HOVER_FEEDBACK_COLOR);
+ label.setText(getTooltipText());
+ addFeedback(label);
+ // use last rect's bottom left as the label's left top
+ Point leftTop = new Point(rects[rects.length - 1].getBottomLeft());
+ figure.translateToAbsolute(leftTop);
+ label.translateToRelative(leftTop);
+ Dimension d = label.getPreferredSize();
+ Rectangle rect = new Rectangle(leftTop, d);
+
+ // to avoid enlarge feedback pane.
+ rect = rect.intersect(getFeedbackLayer().getBounds());
+ label.setBounds(rect);
+
+ figures[rects.length] = label;
+ }
+ return figures;
+ }
+
+ private String getTooltipText() {
+ Element element = (Element) this.getHost().getModel();
+ StringBuffer text = new StringBuffer();
+ text.append("<").append(element.getTagName()).append(">");
+
+ PaletteItemManager manager = PaletteItemManager
+ .getInstance(getProject(element));
+ if (manager != null) {
+ IPaletteItemCategory category = manager.findOrCreateCategory(CMUtil
+ .getElementNamespaceURI(element), null);
+ if (category != null) {
+ String name = element.getLocalName();
+ if (category.getURI().equals(IJMTConstants.URI_JSP)) {
+ name = element.getTagName();
+ }
+ IPaletteItemDescriptor descriptor = category
+ .getItemByTagName(name);
+ if (category.getURI().equals(IJMTConstants.URI_HTML)
+ && IHTMLConstants.TAG_INPUT.equalsIgnoreCase(name)) {
+ String type = element
+ .getAttribute(IHTMLConstants.ATTR_TYPE);
+ if (IHTMLConstants.TYPE_SUBMIT.equalsIgnoreCase(type)) {
+ descriptor = category.getItemByID("html:INPUT:Button");
+ } else if (IHTMLConstants.TYPE_CHECKBOX
+ .equalsIgnoreCase(type)) {
+ descriptor = category
+ .getItemByID("html:INPUT:Check Box");
+ } else if (IHTMLConstants.TYPE_RADIO.equalsIgnoreCase(type)) {
+ descriptor = category
+ .getItemByID("html:INPUT:Radio Button");
+ } else if (IHTMLConstants.TYPE_IMAGE.equalsIgnoreCase(type)) {
+ descriptor = category
+ .getItemByID("html:INPUT:Image Button");
+ } else if (IHTMLConstants.TYPE_PASSWORD
+ .equalsIgnoreCase(type)) {
+ descriptor = category
+ .getItemByID("html:INPUT:Password Field");
+ } else if (IHTMLConstants.TYPE_TEXT.equalsIgnoreCase(type)) {
+ descriptor = category
+ .getItemByID("html:INPUT:Text Field");
+ } else if (IHTMLConstants.TYPE_HIDDEN
+ .equalsIgnoreCase(type)) {
+ descriptor = category
+ .getItemByID("html:INPUT:Hidden Field");
+ }
+ }
+
+ if (descriptor != null) {
+ text.append("\n").append(
+ StringUtil.filterConvertString(descriptor
+ .getDescription()));
+ }
+ }
+ }
+
+ if (text.toString().endsWith("\n")) {
+ return text.substring(0, text.length() - 1);
+ }
+ return text.toString();
+ }
+
+ private IProject getProject(Element element) {
+ if (element instanceof IDOMElement) {
+ IDOMModel model = ((IDOMElement) element).getModel();
+ IFile file = StructuredModelUtil.getFileFor(model);
+ if (file != null) {
+ return file.getProject();
+ }
+ }
+ return null;
+ }
+
+ private boolean isStyleTags(EditPart part) {
+ if (part != null && part.getModel() instanceof Node) {
+ return EditModelQuery.HTML_STYLE_NODES.contains(((Node) part
+ .getModel()).getNodeName());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param request
+ * @return
+ */
+ public boolean shouldUseObjectMode(Request request) {
+ ElementEditPart part = (ElementEditPart) this.getHost();
+ if (isStyleTags(part)) {
+ return false;
+ }
+ if (part.isWidget()
+ || (!part.canHaveDirectTextChild() && !part
+ .haveNonWhitespaceTextChild())) {
+ return true;
+ }
+ if (request instanceof SelectionRequest
+ && ((SelectionRequest) request).isControlKeyPressed()) {
+ return true;
+ }
+ if (request instanceof LocationModifierRequest
+ && ((LocationModifierRequest) request).isControlKeyPressed()) {
+ return true;
+ }
+
+ // for other elements
+ if (request instanceof LocationRequest) {
+ Point location = ((LocationRequest) request).getLocation()
+ .getCopy();
+ part.getFigure().translateToRelative(location);
+ return shouldUseObjectMode(location);
+ } else {
+ return false; // should not happen
+ }
+ }
+
+ /**
+ * @param location
+ * @return
+ */
+ private boolean shouldUseObjectMode(Point location) {
+ // when the location is close to the border/padding of the element, then
+ // we think it is default to
+ // object mode selection.
+ CSSFigure figure = (CSSFigure) this.getHostFigure();
+ if (figure.getFragmentsBounds().length != 1) {
+ return false;
+ }
+ Rectangle bounds = figure.getBounds().getCopy();
+ Insets insets = figure.getInsets();
+ bounds.crop(insets);
+ if (insets.top > THRESHHOLD && insets.left > THRESHHOLD
+ && insets.right > THRESHHOLD && insets.bottom > THRESHHOLD) {
+ return !bounds.contains(location);
+ }
+
+ // since the figure insets could be 0, so we expand it a little, thus
+ // even the point is
+ // a little inside the content area, we still think it is selection the
+ // object.
+ if (bounds.height < 3 * THRESHHOLD || bounds.width < 3 * THRESHHOLD) {
+ bounds.crop(INSETS_1);
+ } else {
+ bounds.crop(INSETS_CONST);
+ }
+ return !bounds.contains(location);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#createSelectionHandles()
+ */
+ protected List createSelectionHandles() {
+ // we have three different kinds of handles.
+ // 1. Those element that is resizable.
+ // 2. Those element that is rectangle but not resizable.
+ // 3. Those element that is not rectangle (fragments)
+
+ IFigure figure = this.getHostFigure();
+ if (figure instanceof CSSFigure && getHost() instanceof ElementEditPart) {
+ CSSFigure cssfigure = (CSSFigure) figure;
+ List fragments = cssfigure.getFragmentsForRead();
+
+ // XXX: only one fragment and is blockbox, then we think it is
+ // resizable by figure
+ // should move this test to somewhere else.
+ if (fragments != null && fragments.size() == 1
+ && fragments.get(0) instanceof BlockBox) {
+ if (((ElementEditPart) getHost()).isResizable()) {
+ // super is Resizable policy, will create a resize handles.
+ return super.createSelectionHandles();
+ } else {
+ return createNonResizeHandles();
+ }
+ } else {
+ return createFragmentsHandles();
+ }
+ } else {
+ // second case
+ return createNonResizeHandles();
+ }
+ }
+
+ /**
+ * @return
+ */
+ private List createFragmentsHandles() {
+ List list = new ArrayList();
+ list.add(new FragmentHandle((GraphicalEditPart) getHost()));
+ return list;
+ }
+
+ /**
+ * @return
+ */
+ private List createNonResizeHandles() {
+ // following code copied from NonResizableEditPolicy
+ List list = new ArrayList();
+ if (isDragAllowed()) {
+ NonResizableHandleKit.addHandles((GraphicalEditPart) getHost(),
+ list);
+ } else {
+ NonResizableHandleKit.addHandles((GraphicalEditPart) getHost(),
+ list, new SelectEditPartTracker(getHost()),
+ SharedCursors.ARROW);
+ }
+
+ return list;
+ }
+
+ /**
+ * child class could override this method.
+ *
+ * @param width
+ * @param height
+ * @return
+ */
+ protected Command getResizeCommand(IDOMElement element, int width,
+ int height) {
+ Map map = new HashMap();
+ if (width > 0) {
+ map.put("width", width + "px");
+ }
+ if (height > 0) {
+ map.put("height", height + "px");
+ }
+ if (map.isEmpty()) {
+ return null;
+ } else {
+ return new ChangeStyleCommand(element, map);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#getResizeCommand(org.eclipse.gef.requests.ChangeBoundsRequest)
+ */
+ protected Command getResizeCommand(ChangeBoundsRequest request) {
+ ElementEditPart part = (ElementEditPart) this.getHost();
+
+ Rectangle rect = part.getFigure().getBounds();
+ rect = request.getTransformedRectangle(rect);
+ int width = rect.width;
+ int height = rect.height;
+
+ // since the user dragged rectangle included border/padding of the
+ // element. And if the element's
+ // width/height style setting don't include border padding, then we need
+ // to set the element's width/height
+ // style property a little smaller.
+ if (part.getFigure() instanceof CSSFigure) {
+ CSSFigure cssfigure = (CSSFigure) part.getFigure();
+ ICSSStyle style = cssfigure.getCSSStyle();
+ if (style != null && !style.isSizeIncludeBorderPadding()) {
+ width -= (style.getBorderInsets().getWidth() + style
+ .getPaddingInsets().getWidth());
+ height -= (style.getBorderInsets().getHeight() + style
+ .getPaddingInsets().getHeight());
+ }
+ }
+ return getResizeCommand((IDOMElement) part.getIDOMNode(), width, height);
+ }
+
+ /**
+ * Shows or updates feedback for a change bounds request.
+ *
+ * @param request
+ * the request
+ */
+ protected void showChangeBoundsFeedback(ChangeBoundsRequest request) {
+ IFigure feedback = getDragSourceFeedbackFigure();
+
+ PrecisionRectangle rect = new PrecisionRectangle(
+ getInitialFeedbackBounds().getCopy());
+ getHostFigure().translateToAbsolute(rect);
+ rect.translate(request.getMoveDelta());
+ rect.resize(request.getSizeDelta());
+
+ // to avoid enlarge feedback pane.
+ // when draging a editpart inside designer to move/copy it, we do not
+ // want to
+ // enlarge the canvas, since that may resulting in relayout.
+ rect = (PrecisionRectangle) rect.intersect(getFeedbackLayer()
+ .getBounds());
+
+ feedback.translateToRelative(rect);
+ feedback.setBounds(rect);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentCornerHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentCornerHandle.java
new file mode 100644
index 000000000..ad3bd8745
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentCornerHandle.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.handles.SquareHandle;
+import org.eclipse.jst.pagedesigner.tableedit.EmptyLocator;
+
+/**
+ * A Handle used to mark the fragment.
+ */
+public class FragmentCornerHandle extends SquareHandle {
+ FragmentCornerHandle(GraphicalEditPart owner) {
+ super(owner, new EmptyLocator());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.AbstractHandle#createDragTracker()
+ */
+ protected DragTracker createDragTracker() {
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentHandle.java
new file mode 100644
index 000000000..d242d7b6a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/FragmentHandle.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.Locator;
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Handle;
+import org.eclipse.gef.handles.AbstractHandle;
+import org.eclipse.gef.tools.DragEditPartsTracker;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowBox;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class FragmentHandle extends AbstractHandle implements Handle {
+ public FragmentHandle(GraphicalEditPart owner) {
+ super(owner, new FragmentLocator());
+ this.setOpaque(false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#paint(org.eclipse.draw2d.Graphics)
+ */
+ public void paint(Graphics graphics) {
+ graphics.setClip(this.getBounds().getCopy().expand(7, 7));
+ super.paint(graphics);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.AbstractHandle#createDragTracker()
+ */
+ protected DragTracker createDragTracker() {
+ DragEditPartsTracker tracker = new DragEditPartsTracker(getOwner());
+ tracker.setDefaultCursor(getCursor());
+ return tracker;
+ }
+
+ public void refresh() {
+ Insets insets = getOwnerFigure().getInsets();
+ Rectangle bounds;
+
+ // set the bounds of this figure, so it could cover all children.
+ bounds = getOwnerFigure().getBounds();
+ bounds = new PrecisionRectangle(bounds.getResized(-1, -1));
+ getOwnerFigure().translateToAbsolute(bounds);
+ this.translateToRelative(bounds);
+ this.setBounds(bounds);
+
+ this.removeAll();
+ // ok, recreate all children.
+ CSSFigure cssfigure = (CSSFigure) getOwner().getFigure();
+ List fragments = cssfigure.getFragmentsForRead();
+ for (int i = 0, size = fragments.size(); i < size; i++) {
+ // the rectangle.
+ Figure childFigure = new BorderFigure();
+ childFigure.setBorder(new LineBorder(1));
+ this.add(childFigure);
+
+ FlowBox box = (FlowBox) fragments.get(i);
+ Rectangle rect = new Rectangle(box._x, box._y, box.getWidth(), box
+ .getHeight());
+ cssfigure.translateToAbsolute(rect);
+
+ childFigure.translateToRelative(rect);
+ childFigure.setBounds(rect);
+
+ createCornerHandles(cssfigure, box);
+ }
+ }
+
+ /**
+ *
+ */
+ private void createCornerHandles(CSSFigure reference, FlowBox referencebox) {
+ createHandle(reference, referencebox, PositionConstants.SOUTH_EAST);
+ createHandle(reference, referencebox, PositionConstants.SOUTH_WEST);
+ createHandle(reference, referencebox, PositionConstants.NORTH_WEST);
+ createHandle(reference, referencebox, PositionConstants.NORTH_EAST);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#containsPoint(int, int)
+ */
+ public boolean containsPoint(int x, int y) {
+ List children = this.getChildren();
+ for (int i = 0, n = children.size(); i < n; i++) {
+ if (((IFigure) children.get(i)).containsPoint(x, y)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param north_east
+ */
+ private void createHandle(CSSFigure reference, FlowBox referencebox,
+ int location) {
+ double relativeX, relativeY;
+ switch (location & PositionConstants.NORTH_SOUTH) {
+ case PositionConstants.NORTH:
+ relativeY = 0;
+ break;
+ case PositionConstants.SOUTH:
+ relativeY = 1.0;
+ break;
+ default:
+ relativeY = 0.5;
+ }
+
+ switch (location & PositionConstants.EAST_WEST) {
+ case PositionConstants.WEST:
+ relativeX = 0;
+ break;
+ case PositionConstants.EAST:
+ relativeX = 1.0;
+ break;
+ default:
+ relativeX = 0.5;
+ }
+
+ FragmentCornerHandle target = new FragmentCornerHandle(getOwner());
+ this.add(target);
+
+ // for corner small box.
+ Rectangle targetBounds = new Rectangle(referencebox._x,
+ referencebox._y, referencebox.getWidth(), referencebox
+ .getHeight());
+ targetBounds = new PrecisionRectangle(targetBounds);
+ reference.translateToAbsolute(targetBounds);
+ target.translateToRelative(targetBounds);
+ // targetBounds.resize(1, 1);
+
+ Dimension targetSize = target.getPreferredSize();
+
+ targetBounds.x += (int) (targetBounds.width * relativeX - ((targetSize.width + 1) / 2));
+ targetBounds.y += (int) (targetBounds.height * relativeY - ((targetSize.height + 1) / 2));
+ targetBounds.setSize(targetSize);
+ target.setBounds(targetBounds);
+ }
+
+ public static class FragmentLocator implements Locator {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure)
+ */
+ public void relocate(IFigure target) {
+ ((FragmentHandle) target).refresh();
+ }
+ }
+
+ public static class BorderFigure extends Figure {
+ public static final int INNER_PAD = 2;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.IFigure#containsPoint(int, int)
+ */
+ public boolean containsPoint(int x, int y) {
+ if (!super.containsPoint(x, y))
+ return false;
+ return !Rectangle.SINGLETON.setBounds(getBounds()).shrink(
+ INNER_PAD, INNER_PAD).contains(x, y);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ITableEditAdapter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ITableEditAdapter.java
new file mode 100644
index 000000000..82e9a34f5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/ITableEditAdapter.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ITableEditAdapter {
+ public int getColumnCount();
+
+ public int getRowCount();
+
+ public void insertColumn(int atPosition);
+
+ public void insertRow(int rowPosition);
+
+ /**
+ * @param columnIndex
+ * @return
+ */
+ public int getColumnResizeStart(int columnIndex);
+
+ /**
+ * @return
+ */
+ public int getColumnResizeWidth();
+
+ /**
+ * @param columnIndex
+ * @return
+ */
+ public int getColumnStart(int columnIndex);
+
+ /**
+ * @param columnIndex
+ * @return
+ */
+ public int getColumnWidth(int columnIndex);
+
+ /**
+ * @param rowIndex
+ * @return
+ */
+ public int getRowStart(int rowIndex);
+
+ /**
+ * @param rowIndex
+ * @return
+ */
+ public int getRowHeight(int rowIndex);
+
+ /**
+ * @param rowIndex
+ * @return
+ */
+ public int getRowResizeStart(int rowIndex);
+
+ /**
+ * @return
+ */
+ public int getRowResizeWidth();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/JSFDropEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/JSFDropEditPolicy.java
new file mode 100644
index 000000000..14af9bd88
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/JSFDropEditPolicy.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editpolicies.GraphicalEditPolicy;
+import org.eclipse.jst.pagedesigner.commands.PDDropRequest;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class JSFDropEditPolicy extends GraphicalEditPolicy {
+ String _attrName;
+
+ public JSFDropEditPolicy(String attrname) {
+ _attrName = attrname;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getTargetEditPart(org.eclipse.gef.Request)
+ */
+ public EditPart getTargetEditPart(Request request) {
+ if (request instanceof PDDropRequest) {
+ return getHost();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ public Command getCommand(Request request) {
+ if (request instanceof PDDropRequest) {
+ PDDropRequest r = (PDDropRequest) request;
+ final String s = (String) r.getCurrentEvent().data;
+ return new Command() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.commands.Command#execute()
+ */
+ public void execute() {
+ // XXX: should check whether alreayd set the attribute,
+ // maybe
+ // should also popup dialog etc.
+ ((Element) getHost().getModel()).setAttribute(_attrName, s);
+ }
+ };
+ }
+
+ return super.getCommand(request);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void eraseTargetFeedback(Request request) {
+ //
+ super.eraseTargetFeedback(request);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#showTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void showTargetFeedback(Request request) {
+ super.showTargetFeedback(request);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LinkEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LinkEditPolicy.java
new file mode 100644
index 000000000..fd93c9006
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LinkEditPolicy.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editpolicies.GraphicalEditPolicy;
+import org.eclipse.jst.pagedesigner.actions.link.LinkRequest;
+import org.eclipse.jst.pagedesigner.actions.link.MakeLinkCommand;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class LinkEditPolicy extends GraphicalEditPolicy {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.EditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ public Command getCommand(Request request) {
+ EditPart part = this.getHost();
+ IHTMLGraphicalViewer viewer = null;
+ if (part instanceof TextEditPart) {
+ part = (TextEditPart) part;
+ viewer = (IHTMLGraphicalViewer) part.getViewer();
+ }
+ if (request instanceof LinkRequest) {
+ LinkRequest req = (LinkRequest) request;
+ String identifier = req.getIdentifier();
+ DesignRange range = req.getDesignRange();
+ Command command = new MakeLinkCommand(identifier, viewer, part,
+ range);
+ return command;
+ }
+ return super.getCommand(request);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LocationHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LocationHelper.java
new file mode 100644
index 000000000..09a94f002
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/LocationHelper.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowBox;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
+import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class LocationHelper {
+ /**
+ * @param p
+ * @param result
+ * @param tagName
+ * @param skip
+ * @return
+ */
+ public static boolean findInsertLocation(GraphicalEditPart host, Point p,
+ GraphicalEditPart[] result, String tagName, Node skip) {
+ if (isHostInsideSkip(host, skip))
+ return false;
+
+ while (isValidHost(host) && !canHostContainTag(host, tagName)) {
+ if (host.getParent() instanceof GraphicalEditPart)
+ host = (GraphicalEditPart) host.getParent();
+ else
+ host = null;
+ }
+ if (!isValidHost(host))
+ return false;
+
+ // ok, next we try to find a insertion point inside host
+ result[0] = host;
+ List children = host.getChildren();
+ if (children.isEmpty()) {
+ result[1] = null;
+ return true;
+ }
+ GraphicalEditPart ref = null;
+ for (int i = 0, size = children.size(); i < size; i++) {
+ GraphicalEditPart child = (GraphicalEditPart) children.get(i);
+ Rectangle rect = getAbsoluteBounds(child);
+
+ if (rect.contains(p)) {
+ IFigure figure = child.getFigure();
+ if (figure instanceof ICSSFigure) {
+ List frags = ((ICSSFigure) figure).getFragmentsForRead();
+ if (frags.size() > 1) // more than one frags, so is a zig
+ // zag.
+ {
+ // check whether is before the first box.
+ FlowBox box = (FlowBox) frags.get(0);
+ Rectangle rect1 = getAbsoluteBounds(figure, box);
+ if (rect1.x > p.x && rect1.y + rect1.height > p.y) {
+ // p is at left/above the first box. so we think p
+ // is before this child
+ result[1] = child;
+ return true;
+ }
+ // check whether is after the last box
+ box = (FlowBox) frags.get(frags.size() - 1);
+ rect1 = getAbsoluteBounds(figure, box);
+ if (rect1.x < p.x && rect1.y < p.y) {
+ continue;
+ }
+ }
+ }
+ // ok, treat as the point in a rect figure, see which side is
+ // closer.
+ if (p.x > rect.x + rect.width / 2) {
+ continue;
+ } else {
+ result[1] = child;
+ return true;
+ }
+ } else if (rect.x + rect.width < p.x || rect.y + rect.height < p.y) {
+ // p is at right or below rect. so the point is "after" the
+ // rect.
+ continue;
+ } else {
+ // ok, p is "before" rect.
+ result[1] = child;
+ return true;
+ }
+ }
+ // we search through all.
+ result[1] = null;
+ return true;
+ }
+
+ /**
+ * @param figure
+ * @param box
+ * @return
+ */
+ public static Rectangle getAbsoluteBounds(IFigure figure, FlowBox box) {
+ Rectangle r = new Rectangle(box._x, box._y, box.getWidth(), box
+ .getHeight());
+ figure.translateToAbsolute(r);
+ return r;
+ }
+
+ /**
+ * @param child
+ * @return
+ */
+ public static Rectangle getAbsoluteBounds(GraphicalEditPart child) {
+ Rectangle bounds = child.getFigure().getBounds().getCopy();
+ child.getFigure().translateToAbsolute(bounds);
+ return bounds;
+ }
+
+ /**
+ * @param host
+ * @param tagName
+ * @return
+ */
+ private static boolean canHostContainTag(GraphicalEditPart host,
+ String tagName) {
+ if (host == null)
+ return false;
+ Node node = (Node) host.getModel();
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ ModelQuery modelQuery = getModelQuery(node);
+ if (modelQuery != null) {
+ CMElementDeclaration elementDecl = modelQuery
+ .getCMElementDeclaration((Element) node);
+ if (elementDecl == null) {
+ return true;
+ }
+ if (elementDecl.getContentType() == CMElementDeclaration.EMPTY)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param host
+ * @return
+ */
+ private static boolean isValidHost(GraphicalEditPart host) {
+ return host != null
+ && (host instanceof ElementEditPart || host instanceof DocumentEditPart);
+ }
+
+ /**
+ * @param host
+ * @param skip
+ * @return
+ */
+ private static boolean isHostInsideSkip(GraphicalEditPart host, Node skip) {
+ if (skip == null)
+ return false;
+
+ // XXX: not done.
+ return false;
+ }
+
+ protected static ModelQuery getModelQuery(Node node) {
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ return ModelQueryUtil.getModelQuery((Document) node);
+ } else {
+ return ModelQueryUtil.getModelQuery(node.getOwnerDocument());
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/MoveSupport.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/MoveSupport.java
new file mode 100644
index 000000000..f7f5aca09
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/MoveSupport.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import java.util.List;
+
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class MoveSupport {
+ /**
+ * Check whether the move operation only drags a single node.
+ *
+ * @param request
+ * @return
+ */
+ public static boolean isSingleNode(ChangeBoundsRequest request) {
+ List parts = request.getEditParts();
+ if (parts == null || parts.size() != 1
+ || !(parts.get(0) instanceof NodeEditPart)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * this method must be called after isSingleNode
+ *
+ * @param request
+ * @return
+ */
+ public static NodeEditPart getDraggedPart(ChangeBoundsRequest request) {
+ List parts = request.getEditParts();
+ NodeEditPart part = (NodeEditPart) parts.get(0);
+ return part;
+ }
+
+ /**
+ * this method must be called after isSingleNode
+ *
+ * @param request
+ * @return
+ */
+ public static Node getDraggedNode(ChangeBoundsRequest request) {
+ return getDraggedPart(request).getIDOMNode();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PDEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PDEditPolicy.java
new file mode 100644
index 000000000..48f407674
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PDEditPolicy.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+/**
+ * @author mengbo
+ */
+public interface PDEditPolicy {
+ String PDDROP_ROLE = "PDDropEditPolicy"; //$NON-NLS-1$
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PolicyHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PolicyHelper.java
new file mode 100644
index 000000000..cd032d107
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/editpolicies/PolicyHelper.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.editpolicies;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class PolicyHelper {
+ private static Logger _log = PDPlugin.getLogger(PolicyHelper.class);
+
+ public static IStatusLineManager getStatusLineManager(EditPart part) {
+ EditPartViewer v = part.getViewer();
+ if (v instanceof HTMLGraphicalViewer) {
+ HTMLGraphicalViewer htmlviewer = (HTMLGraphicalViewer) v;
+ IStatusLineManager m = htmlviewer.getStatusLineManager();
+ if (m == null) {
+ _log.info("Warn.PolicyHelper.0", null); //$NON-NLS-1$
+ }
+ return m;
+ }
+ _log.info("Warn.PolicyHelper.1", null); //$NON-NLS-1$
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/AbstractElementEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/AbstractElementEdit.java
new file mode 100644
index 000000000..07e9a8acc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/AbstractElementEdit.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit;
+
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class AbstractElementEdit implements IElementEdit {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#createEditPolicies(org.eclipse.jst.pagedesigner.parts.ElementEditPart)
+ */
+ public void createEditPolicies(ElementEditPart part) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#handleModelChange(org.w3c.dom.Element,
+ * org.eclipse.jst.pagedesigner.parts.ElementEditPart)
+ */
+ public boolean handleModelChange(Element ele, ElementEditPart part,
+ boolean recursive) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#fillContextMenu(org.eclipse.jface.action.IMenuManager,
+ * org.w3c.dom.Element)
+ */
+ public void fillContextMenu(IMenuManager contextMenu, Element ele) {
+ // default do nothing, child class could override.
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#fillContainerContextMenu(org.eclipse.jface.action.IMenuManager,
+ * org.eclipse.jst.pagedesigner.parts.ElementEditPart,
+ * org.eclipse.jst.pagedesigner.parts.NodeEditPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean fillContainerContextMenu(IMenuManager contextMenu,
+ ElementEditPart elePart, NodeEditPart nodePart,
+ ISelection innerSelection) {
+ return false;
+ }
+
+ /**
+ * Child class should override this method if they have different way for
+ * resizing. e.g. DataWindow use "width/height" attribute, not "style".
+ * Also, the default ResizeCommand will adjust "style", so if child class
+ * override this method, they should also use different command.
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy#getResizeCommand(ChangeBoundsRequest)
+ */
+ public boolean isResizable(Element ele) {
+ CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
+ if (decl != null) {
+ // XXX: default implementation, if this element support "style"
+ // attribute,
+ // then we think it support resize.
+ return decl.getAttributes().getNamedItem("style") != null;
+ }
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java
new file mode 100644
index 000000000..4733fa8fa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ElementEditFacRegistryReader {
+ static IElementEditFactory[] _handlers = null;
+
+ public static synchronized IElementEditFactory[] getAllHandlers() {
+ if (_handlers == null) {
+ _handlers = readAllHandlers();
+ }
+ return _handlers;
+
+ }
+
+ private static IElementEditFactory[] readAllHandlers() {
+ List result = new ArrayList();
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+ IExtension[] extensions = extensionPoint.getExtensions();
+
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension ext = extensions[i];
+ IConfigurationElement[] dropHandlers = ext
+ .getConfigurationElements();
+
+ for (int j = 0; j < dropHandlers.length; j++) {
+ if (dropHandlers[j].getName().equals(
+ IJMTConstants.ELEMENT_EDIT_FACTORY)) {
+ dropHandlers[j].getAttribute("class");
+ Object obj;
+ try {
+ obj = dropHandlers[j]
+ .createExecutableExtension("class");
+
+ if (obj instanceof IElementEditFactory) {
+ result.add(obj);
+ }
+ } catch (CoreException e) {
+ // ignore the exception
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ IElementEditFactory[] ret = new IElementEditFactory[result.size()];
+ result.toArray(ret);
+ return ret;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java
new file mode 100644
index 000000000..f67917e0f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.elementedit.html.HTMLElementEditFactory;
+import org.eclipse.jst.pagedesigner.elementedit.jsp.JSPElementEditFactory;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ElementEditFactoryRegistry {
+ List _factories = new ArrayList();
+
+ private static ElementEditFactoryRegistry _instance;
+
+ /**
+ *
+ */
+ private ElementEditFactoryRegistry() {
+ _factories.add(new HTMLElementEditFactory());
+ _factories.add(new JSPElementEditFactory());
+
+ IElementEditFactory facs[] = ElementEditFacRegistryReader
+ .getAllHandlers();
+ if (facs != null) {
+ for (int i = 0; i < facs.length; i++) {
+ addFactory(facs[i]);
+ }
+ }
+ }
+
+ public void addFactory(IElementEditFactory fac) {
+ _factories.add(fac);
+ }
+
+ public IElementEdit createElementEdit(Element ele) {
+ String uri = CMUtil.getElementNamespaceURI(ele);
+ // first round, match uri
+ for (int i = 0, size = _factories.size(); i < size; i++) {
+ IElementEditFactory fac = (IElementEditFactory) _factories.get(i);
+ String facuri = fac.getSupportedURI();
+ if (facuri != null && facuri.equals(uri)) {
+ IElementEdit elementEdit = fac.createElementEdit(ele);
+ if (elementEdit != null) {
+ return elementEdit;
+ }
+ }
+ }
+ // second round
+ for (int i = 0, size = _factories.size(); i < size; i++) {
+ IElementEditFactory fac = (IElementEditFactory) _factories.get(i);
+ String facuri = fac.getSupportedURI();
+ if (facuri == null) {
+ IElementEdit elementEdit = fac.createElementEdit(ele);
+ if (elementEdit != null) {
+ return elementEdit;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static ElementEditFactoryRegistry getInstance() {
+ if (_instance == null) {
+ _instance = new ElementEditFactoryRegistry();
+ }
+ return _instance;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEdit.java
new file mode 100644
index 000000000..3a671c58d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEdit.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.w3c.dom.Element;
+
+/**
+ * IElementEdit support additional edit support to an element
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IElementEdit {
+ public void createEditPolicies(ElementEditPart part);
+
+ /**
+ * The element (or its decendent) changed.
+ *
+ * @param ele
+ * @param part
+ * @return
+ */
+ public boolean handleModelChange(Element ele, ElementEditPart part,
+ boolean recursive);
+
+ /**
+ * Add special menu items for the particular element to the context menu.
+ *
+ * @param contextMenu
+ */
+ public void fillContextMenu(IMenuManager contextMenu, Element ele);
+
+ /**
+ * This method is called when current selection is inside "ele". And this
+ * method should fill in menu items relating to the "ele" context and the
+ * current "innerSelection". For example, this "ele" could be a table,
+ * "innerSelection" could be something inside a cell. Then could fill in
+ * actions relating to the table and the cell, such as "add row before",
+ * "delete current column", etc.
+ *
+ * @param contextMenu
+ * @param elePart
+ * the elementeditpart corresponding to this ElementEdit
+ * @param nodePart
+ * the smallest part covers the current selection. nodePart will
+ * always be a decedent of the elePart.
+ * @param innerSelection
+ * the selection
+ * @return true if added actions.
+ */
+ public boolean fillContainerContextMenu(IMenuManager contextMenu,
+ ElementEditPart elePart, NodeEditPart nodePart,
+ ISelection innerSelection);
+
+ /**
+ * whether the corresponding element support resize. If it does, then the
+ * corresponding policy installed through <code>createEditPolicies</code>
+ * should handle resize.
+ *
+ * @return
+ */
+ public boolean isResizable(Element ele);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEditFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEditFactory.java
new file mode 100644
index 000000000..8479739fe
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/IElementEditFactory.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit;
+
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IElementEditFactory {
+ /**
+ *
+ * @param element
+ * @return null if this factory don't support this element
+ */
+ public IElementEdit createElementEdit(Element element);
+
+ /**
+ * get the URI namespace that this factory support. "null" means this
+ * factory can be used as default factory.
+ *
+ * @return null if this factory don't have a specific URI to support.
+ */
+ public String getSupportedURI();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/HTMLElementEditFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/HTMLElementEditFactory.java
new file mode 100644
index 000000000..b9b2c702c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/HTMLElementEditFactory.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit.html;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEditFactory;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class HTMLElementEditFactory implements IElementEditFactory {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEditFactory#createElementEdit(org.w3c.dom.Element)
+ */
+ public IElementEdit createElementEdit(Element element) {
+ String tag = element.getTagName();
+ if ("table".equalsIgnoreCase(tag)) {
+ return new TableElementEdit();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEditFactory#getSupportedURI()
+ */
+ public String getSupportedURI() {
+ return IJMTConstants.URI_HTML;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/TableElementEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/TableElementEdit.java
new file mode 100644
index 000000000..6c624a326
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/html/TableElementEdit.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit.html;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.actions.single.SelectEditPartAction;
+import org.eclipse.jst.pagedesigner.commands.html.TableDeleteColumnCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableDeleteHeaderFooterCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableDeleteRowCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableInsertColumnCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableInsertHeaderFooterCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableInsertRowCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableResizeColumnCommand;
+import org.eclipse.jst.pagedesigner.commands.html.TableResizeRowCommand;
+import org.eclipse.jst.pagedesigner.dom.html.TableChildElementPosition;
+import org.eclipse.jst.pagedesigner.dom.html.TableUtil;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.jst.pagedesigner.elementedit.AbstractElementEdit;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.tableedit.DeleteHeaderFooterAction;
+import org.eclipse.jst.pagedesigner.tableedit.DeleteHeaderFooterRequest;
+import org.eclipse.jst.pagedesigner.tableedit.DeleteRowColumnAction;
+import org.eclipse.jst.pagedesigner.tableedit.InsertHeaderFooterAction;
+import org.eclipse.jst.pagedesigner.tableedit.InsertHeaderFooterRequest;
+import org.eclipse.jst.pagedesigner.tableedit.InsertRowColumnAction;
+import org.eclipse.jst.pagedesigner.tableedit.TableInsertRequest;
+import org.eclipse.jst.pagedesigner.tableedit.TableResizableEditPolicy;
+import org.eclipse.jst.pagedesigner.tableedit.TableResizeRequest;
+import org.eclipse.jst.pagedesigner.tableedit.TableRowColumnDeleteRequest;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableElementEdit extends AbstractElementEdit {
+ public static Action action = new Action() {
+ };
+
+ private static int FAKE_INDEX = -10;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#fillContextMenu(org.eclipse.jface.action.IMenuManager,
+ * org.w3c.dom.Element)
+ */
+ public void fillContextMenu(IMenuManager contextMenu, Element ele) {
+ final IMenuManager tableMenu = new MenuManager(PDPlugin
+ .getResourceString("ElementEdit.Submenu.Table"));//$NON-NLS-1$
+ tableMenu.add(action);
+ final ElementEditPart tablePart = (ElementEditPart) ((IDOMElement) ele)
+ .getAdapterFor(EditPart.class);
+ // ok, we passed the checking, now let's create the actions.
+ tableMenu.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ tableMenu.removeAll();
+ fillTableMenu(tablePart, FAKE_INDEX, FAKE_INDEX, tableMenu);
+ }
+ });
+
+ contextMenu.appendToGroup(PageDesignerActionConstants.GROUP_CONTAINER,
+ tableMenu);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.AbstractElementEdit#fillContainerContextMenu(org.eclipse.jface.action.IMenuManager,
+ * org.eclipse.jst.pagedesigner.parts.ElementEditPart,
+ * org.eclipse.jst.pagedesigner.parts.NodeEditPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean fillContainerContextMenu(IMenuManager contextMenu,
+ final ElementEditPart tablePart, NodeEditPart nodePart,
+ ISelection innerSelection) {
+ boolean superret = super.fillContainerContextMenu(contextMenu,
+ tablePart, nodePart, innerSelection);
+
+ Element table = (Element) tablePart.getModel();
+ Node node = (Node) nodePart.getModel();
+
+ TableChildElementPosition position = new TableUtil(table)
+ .getPosition(node);
+ final int cellRow = position.getRowIndex();
+ final int cellColumn = position.getColumnIndex();
+
+ final IMenuManager tableMenu = new MenuManager(PDPlugin
+ .getResourceString("ElementEdit.Submenu.Table"));//$NON-NLS-1$
+ tableMenu.add(action);
+ // ok, we passed the checking, now let's create the actions.
+ tableMenu.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ tableMenu.removeAll();
+ fillTableMenu(tablePart, cellRow, cellColumn, tableMenu);
+ }
+ });
+
+ contextMenu.appendToGroup(PageDesignerActionConstants.GROUP_CONTAINER,
+ tableMenu);
+ return true;
+ }
+
+ /**
+ * @param tablePart
+ * @param cellRow
+ * @param cellColumn
+ * @param tableMenu
+ */
+ private void fillTableMenu(ElementEditPart tablePart, int cellRow,
+ int cellColumn, IMenuManager tableMenu) {
+ SelectEditPartAction action = new SelectEditPartAction(
+ PDPlugin.getResourceString("ElementEdit.Submenu.SelectTable"), tablePart);//$NON-NLS-1$
+ tableMenu.add(action);
+
+ tableMenu.add(new Separator());
+
+ {
+ InsertRowColumnAction insertRowBeforeAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.InsertRowBefore"),//$NON-NLS-1$
+ tablePart, cellRow, true, true);
+ tableMenu.add(insertRowBeforeAction);
+
+ InsertRowColumnAction insertRowAfterAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.InsertRowAfter"),//$NON-NLS-1$
+ tablePart, cellRow, true, false);
+ tableMenu.add(insertRowAfterAction);
+
+ tableMenu.add(new Separator());
+ }
+
+ {
+ InsertRowColumnAction insertColumnBeforeAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.InsertColumnBefore"),//$NON-NLS-1$
+ tablePart, cellColumn, false, true);
+ tableMenu.add(insertColumnBeforeAction);
+
+ InsertRowColumnAction insertColumnAfterAction = new InsertRowColumnAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.InsertColumnAfter"),//$NON-NLS-1$
+ tablePart, cellColumn, false, false);
+ tableMenu.add(insertColumnAfterAction);
+
+ tableMenu.add(new Separator());
+ }
+
+ {
+ DeleteRowColumnAction deleteRowAction = new DeleteRowColumnAction(
+ PDPlugin.getResourceString("ElementEdit.Submenu.DeleteRow"),//$NON-NLS-1$
+ tablePart, cellRow, true);
+ tableMenu.add(deleteRowAction);
+
+ DeleteRowColumnAction deleteColumnAction = new DeleteRowColumnAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.DeleteColumn"),//$NON-NLS-1$
+ tablePart, cellColumn, false);
+ tableMenu.add(deleteColumnAction);
+ tableMenu.add(new Separator());
+ }
+
+ {
+ InsertHeaderFooterAction headerAction = new InsertHeaderFooterAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.InsertHeader"), tablePart, true);//$NON-NLS-1$
+ tableMenu.add(headerAction);
+ InsertHeaderFooterAction footerAction = new InsertHeaderFooterAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.InsertFooter"), tablePart, false);//$NON-NLS-1$
+ tableMenu.add(footerAction);
+ DeleteHeaderFooterAction delHeaderAction = new DeleteHeaderFooterAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.DeleteHeader"), tablePart, true);//$NON-NLS-1$
+ tableMenu.add(delHeaderAction);
+ DeleteHeaderFooterAction delFooterAction = new DeleteHeaderFooterAction(
+ PDPlugin
+ .getResourceString("ElementEdit.Submenu.DeleteFooter"), tablePart, false);//$NON-NLS-1$
+ tableMenu.add(delFooterAction);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#createEditPolicies(org.eclipse.jst.pagedesigner.parts.ElementEditPart)
+ */
+ public void createEditPolicies(ElementEditPart part) {
+ part.installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE,
+ new TableResizePolicy(part));
+ }
+
+ static class TableResizePolicy extends TableResizableEditPolicy {
+ ElementEditPart _part;
+
+ public TableResizePolicy(ElementEditPart part) {
+ _part = part;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ public Command getCommand(Request request) {
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) _part
+ .getViewer();
+ Element table = (Element) _part.getIDOMNode();
+ if (request instanceof TableResizeRequest) {
+ TableResizeRequest trq = (TableResizeRequest) request;
+ if (trq.isRow()) {
+ return new TableResizeRowCommand(viewer, table, trq
+ .getIndex(), trq.getDelta());
+ } else {
+ return new TableResizeColumnCommand(viewer, table, trq
+ .getIndex(), trq.getDelta());
+ }
+ } else if (request instanceof TableInsertRequest) {
+ TableInsertRequest tableInsertRequest = (TableInsertRequest) request;
+ int index = tableInsertRequest.getIndex()
+ + (tableInsertRequest.isBefore() ? 0 : 1);
+ if (tableInsertRequest.isRow()) {
+ return new TableInsertRowCommand(viewer, table, index,
+ tableInsertRequest.isBefore());
+ } else {
+ return new TableInsertColumnCommand(viewer, table, index);
+ }
+ } else if (request instanceof TableRowColumnDeleteRequest) {
+ TableRowColumnDeleteRequest deleteReq = (TableRowColumnDeleteRequest) request;
+ if (deleteReq.isRow()) {
+ return new TableDeleteRowCommand(viewer, table, deleteReq
+ .getIndex());
+ } else {
+ return new TableDeleteColumnCommand(viewer, table,
+ deleteReq.getIndex());
+ }
+ } else if (request instanceof InsertHeaderFooterRequest) {
+ InsertHeaderFooterRequest hfRequest = (InsertHeaderFooterRequest) request;
+ return new TableInsertHeaderFooterCommand(viewer, table,
+ hfRequest.isHeader());
+ } else if (request instanceof DeleteHeaderFooterRequest) {
+ DeleteHeaderFooterRequest hfRequest = (DeleteHeaderFooterRequest) request;
+ return new TableDeleteHeaderFooterCommand(viewer, table,
+ hfRequest.isHeader());
+ }
+ return super.getCommand(request);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/JSPElementEditFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/JSPElementEditFactory.java
new file mode 100644
index 000000000..3ab3b5e09
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/JSPElementEditFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit.jsp;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEditFactory;
+import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class JSPElementEditFactory implements IElementEditFactory {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEditFactory#createElementEdit(org.w3c.dom.Element)
+ */
+ public IElementEdit createElementEdit(Element element) {
+ String tag = element.getLocalName();
+ if (IJSPCoreConstants.TAG_DIRECTIVE_TAGLIB.equalsIgnoreCase(tag)) {
+ return new TaglibElementEdit();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEditFactory#getSupportedURI()
+ */
+ public String getSupportedURI() {
+ return IJMTConstants.URI_JSP;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibElementEdit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibElementEdit.java
new file mode 100644
index 000000000..22d9ef5a3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibElementEdit.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit.jsp;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.editors.PageDesignerActionConstants;
+import org.eclipse.jst.pagedesigner.elementedit.AbstractElementEdit;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TaglibElementEdit extends AbstractElementEdit {
+ private TaglibURIAction action;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.elementedit.IElementEdit#fillContextMenu(org.eclipse.jface.action.IMenuManager,
+ * org.w3c.dom.Element)
+ */
+ public void fillContextMenu(IMenuManager contextMenu, Element ele) {
+ super.fillContextMenu(contextMenu, ele);
+
+ TaglibURIAction action = getAction();
+
+ action.setURI(ele.getAttribute(ICSSPropertyID.ATTR_URI));
+
+ if (ele instanceof Element) {
+ action.setElement((Element) ele);
+ }
+ contextMenu.appendToGroup(PageDesignerActionConstants.GROUP_SPECIAL,
+ action);
+ }
+
+ private TaglibURIAction getAction() {
+ if (action == null) {
+ action = new TaglibURIAction();
+ }
+ return action;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibURIAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibURIAction.java
new file mode 100644
index 000000000..ba3512c18
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/jsp/TaglibURIAction.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.elementedit.jsp;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TaglibURIAction extends Action {
+ private String URI;
+
+ private Element element;
+
+ public TaglibURIAction() {
+ setText(PDPlugin.getResourceString("ElementEdit.Submenu.Taglib"));//$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#isEnabled()
+ */
+ public boolean isEnabled() {
+ if (element == null || URI == null || "".equals(URI))//$NON-NLS-1$
+ {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ String fileName = getResolvedURL(getElement(), URI);
+
+ if (fileName != null && fileName.length() > 0) {
+ IPath includedPath = new Path(fileName);
+ includedPath.makeAbsolute();
+
+ IFile file = getFile(includedPath);
+ if (file != null && file.exists()) {
+ try {
+ IDE.openEditor(getPage(), file);
+ return;
+ } catch (PartInitException e) {
+ PDPlugin.getAlerts().warning(
+ "Message.Warning.Title", e.getLocalizedMessage());//$NON-NLS-1$
+ }
+ }
+ }
+ PDPlugin.getAlerts().warning(
+ "Message.Warning.Title", "Taglib.OpenFile.ERROR");//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private IWorkbenchPage getPage() {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ return window.getActivePage();
+ }
+
+ /**
+ * @param uri
+ */
+ public void setURI(String uri) {
+ this.URI = uri;
+ }
+
+ private IFile getFile(IPath includedPath) {
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ IProject[] projects = workspaceRoot.getProjects();
+
+ for (int i = 0, length = projects.length; i < length; i++) {
+ IPath path = projects[i].getLocation();
+ path = path.makeAbsolute();
+ if (path != null && path.isPrefixOf(includedPath)) {
+ // -1 so we still have the project path
+ includedPath = includedPath.removeFirstSegments(path
+ .segmentCount() - 1);
+ return ResourcesPlugin.getWorkspace().getRoot().getFile(
+ includedPath);
+ }
+ }
+ return null;
+ }
+
+ private String getResolvedURL(Element element, String attrName) {
+ URIResolver resolver = null;
+ if (element instanceof IDOMNode) {
+ resolver = ((IDOMNode) element).getModel().getResolver();
+ }
+ if (null == resolver) {
+ return null;
+ }
+ String src = URI;
+ if (src != null && src.length() > 0) {
+ return resolver.getLocationByURI(src);
+ }
+ return null;
+ }
+
+ /**
+ * @return Returns the element.
+ */
+ public Element getElement() {
+ return element;
+ }
+
+ /**
+ * @param element
+ * The element to set.
+ */
+ public void setElement(Element element) {
+ this.element = element;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/extensionpoint/IContextMenuItemContributor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/extensionpoint/IContextMenuItemContributor.java
new file mode 100644
index 000000000..5f892ad01
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/extensionpoint/IContextMenuItemContributor.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.extensionpoint;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+/**
+ * @author mengbo
+ */
+public interface IContextMenuItemContributor {
+ void setURI(String uri);
+
+ String getURI();
+
+ void fillContextMenu(IMenuManager manager, ISelection selection,
+ IStructuredModel model, Control parentUI);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/AbstractFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/AbstractFigureHandler.java
new file mode 100644
index 000000000..d0c731e2d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/AbstractFigureHandler.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class AbstractFigureHandler implements IFigureHandler {
+ private CSSFigure _figure;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ return (type == IFigureHandler.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ }
+
+ protected ICSSStyle getCSSStyle(Element node) {
+ ICSSStyle style = null;
+ if (node instanceof IDOMElement) {
+ style = (ICSSStyle) ((IDOMElement) node)
+ .getAdapterFor(ICSSStyle.class);
+ }
+ if (style == null) {
+ return DefaultStyle.getInstance();
+ } else {
+ return style;
+ }
+ }
+
+ protected void setCurrentFigure(CSSFigure oldFigure) {
+ this._figure = oldFigure;
+ }
+
+ public CSSFigure getFigure() {
+ return this._figure;
+ }
+
+ /**
+ * child class could override this method
+ */
+ public void dispose() {
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/BRFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/BRFigureHandler.java
new file mode 100644
index 000000000..78f3fecb2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/BRFigureHandler.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.layout.CSSBrFlowLayout;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSLayout;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class BRFigureHandler extends AbstractFigureHandler {
+ protected CSSLayout getFixedCSSLayout(CSSFigure figure) {
+ return new CSSBrFlowLayout(figure);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.figurehandler.IFigureHandler#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+
+ public void updateFigure(Element node, CSSFigure oldFigure) {
+ oldFigure.setCSSStyle(getCSSStyle(node));
+ oldFigure.setFixedLayoutManager(getFixedCSSLayout(oldFigure));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/DefaultFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/DefaultFigureHandler.java
new file mode 100644
index 000000000..82cc075dc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/DefaultFigureHandler.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DefaultFigureHandler extends AbstractFigureHandler {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.figurehandler.IFigureHandler#updateFigure(org.w3c.dom.Element,
+ * org.eclipse.jst.pagedesigner.css2.layout.CSSFigure)
+ */
+ public void updateFigure(Element node, CSSFigure oldFigure) {
+ setCurrentFigure(oldFigure);
+ ICSSStyle style = getCSSStyle(node);
+ oldFigure.setCSSStyle(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.figurehandler.IFigureHandler#isWidget()
+ */
+ public boolean isWidget() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/FigureFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/FigureFactory.java
new file mode 100644
index 000000000..72a6c0b04
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/FigureFactory.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSTextFigure;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class FigureFactory {
+ // public static IFigure createFigure(Element ele, boolean deep)
+ // {
+ // IFigureHandler handler = createAndAdapt(ele);
+ // IFigure figure = handler.createFigure(ele);
+ //
+ // if (deep && !handler.isWidget())
+ // {
+ // NodeList children = ele.getChildNodes();
+ // for (int i = 0, size = children.getLength(); i < size; i++)
+ // {
+ // createFigureDeep(figure, children.item(i));
+ // }
+ // }
+ // return figure;
+ // }
+
+ /**
+ * @param figure
+ * @param node
+ */
+ private static void createFigureDeep(IFigure parentFigure, final Node node) {
+ if (node instanceof Element) {
+ IFigureHandler handler = createAndAdapt((Element) node);
+ if (handler instanceof HiddenFigureHandler) {
+ // for deep hidden element, we don't create figure for them.
+ // this will remove the small <> icon for data window.
+ return;
+ }
+ CSSFigure figure = new CSSFigure();
+ handler.updateFigure((Element) node, figure);
+ // IFigure figure = handler.createFigure((Element) node);
+ parentFigure.add(figure);
+ if (!handler.isWidget()) {
+ NodeList children = node.getChildNodes();
+
+ for (int i = 0, size = children.getLength(); i < size; i++) {
+ createFigureDeep(figure, children.item(i));
+ }
+ }
+ } else if (node instanceof Text) {
+ final String data = HTMLUtil.compactWhitespaces((Text) node, node
+ .getNodeValue());
+ // XXX: seemed there is some bug in handling whitespace (unnecessary
+ // take additional space)
+ // so skip it here.
+ if (data.trim().length() == 0) {
+ return;
+ }
+ // XXX: currently creating of CSSTextFigure is distributed both here
+ // and TextEditPart. We may want to unify them later.
+ CSSTextFigure figure = new CSSTextFigure(new ICSSTextProvider() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider#getCSSStyle()
+ */
+ public ICSSStyle getCSSStyle() {
+ INodeNotifier notifier = (INodeNotifier) node
+ .getParentNode();
+ return (ICSSStyle) notifier.getAdapterFor(ICSSStyle.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider#getTextData()
+ */
+ public String getTextData() {
+ return data;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider#getSelectedRange()
+ */
+ public int[] getSelectedRange() {
+ // text figure created here will not be real text in
+ // original doc.
+ // so don't support their selection.
+ return null;
+ }
+ });
+ parentFigure.add(figure);
+ }
+ }
+
+ public static IFigure updateDeepFigure(Element ele, Element old,
+ CSSFigure figure) {
+ recursiveDisposeAndUnadapt(old);
+ List figureChildren = figure.getChildren();
+ for (int i = figureChildren.size() - 1; i >= 0; i--) {
+ figure.remove((IFigure) figureChildren.get(i));
+ }
+
+ IFigureHandler handler = createAndAdapt(ele);
+ handler.updateFigure(ele, figure);
+ if (!handler.isWidget()) {
+ NodeList children = ele.getChildNodes();
+ for (int i = 0, size = children.getLength(); i < size; i++) {
+ createFigureDeep(figure, children.item(i));
+ }
+ }
+ return figure;
+ }
+
+ public static void updateNonDeepFigure(Element ele, CSSFigure figure) {
+ IFigureHandler handler = getHandler(ele);
+ if (handler == null) {
+ handler = createAndAdapt(ele);
+ }
+ handler.updateFigure(ele, figure);
+ }
+
+ static void recursiveDisposeAndUnadapt(Element ele) {
+ disposeAndUnadapt(ele);
+ NodeList nl = ele.getChildNodes();
+ for (int i = 0, size = nl.getLength(); i < size; i++) {
+ Node n = nl.item(i);
+ if (n instanceof Element) {
+ recursiveDisposeAndUnadapt((Element) n);
+ }
+ }
+ }
+
+ static void disposeAndUnadapt(Element ele) {
+ IFigureHandler handler = getHandler(ele);
+ if (handler != null) {
+ handler.dispose();
+ ((IDOMElement) ele).removeAdapter(handler);
+ }
+ }
+
+ static IFigureHandler getHandler(Element ele) {
+ if (ele instanceof IDOMElement) {
+ IDOMElement xmlele = (IDOMElement) ele;
+ return (IFigureHandler) xmlele.getAdapterFor(IFigureHandler.class);
+ }
+ return null;
+ }
+
+ static IFigureHandler createAndAdapt(Element ele) {
+ IFigureHandler handler = createFigureHandler(ele);
+ if (ele instanceof IDOMElement) {
+ ((IDOMElement) ele).addAdapter(handler);
+ }
+ return handler;
+ }
+
+ static IFigureHandler createFigureHandler(Element ele) {
+ String tag = ele.getTagName();
+ if ("input".equalsIgnoreCase(tag)) {
+ return new InputFigureHandler();
+ } else if ("select".equalsIgnoreCase(tag)) {
+ return new SelectFigureHandler();
+ } else if ("img".equalsIgnoreCase(tag)) {
+ return new ImgFigureHandler();
+ } else if ("object".equalsIgnoreCase(tag)) {
+ return new ObjectFigureHandler();
+ } else if ("textarea".equalsIgnoreCase(tag)) {
+ return new TextareaFigureHandler();
+ } else if ("br".equalsIgnoreCase(tag)) {
+ return new BRFigureHandler();
+ } else if (!HTMLUtil.isVisualHtmlElement(tag)) {
+ return new HiddenFigureHandler(getSharedHTMLImage(tag));
+ } else {
+ return new DefaultFigureHandler();
+ }
+ }
+
+ /**
+ * @param tag
+ * @return
+ */
+ private static Image getSharedHTMLImage(String tag) {
+ Image image = PDPlugin.getDefault().getImage(
+ "palette/HTML/small/HTML_" + tag.toUpperCase() + ".gif");
+ ImageData imageData = image.getImageData();
+ if (imageData.width < 16 || imageData.height < 16) {
+ return PDPlugin.getDefault().getImage(
+ "palette/GENERIC/small/PD_Palette_Default.gif");
+ }
+ return image;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/HiddenFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/HiddenFigureHandler.java
new file mode 100644
index 000000000..0d94757f9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/HiddenFigureHandler.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.jst.pagedesigner.css2.widget.ImageWidgetProvider;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class HiddenFigureHandler extends WidgetFigureHandler {
+ Image _image;
+
+ public HiddenFigureHandler(Image image) {
+ _image = image;
+ }
+
+ protected ICSSWidgetProvider initializeWidgetProvider(Element ele) {
+ return new ImageWidgetProvider(getImage(), DefaultStyle.getInstance());
+ }
+
+ /**
+ * @return
+ */
+ private Image getImage() {
+ return _image;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/IFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/IFigureHandler.java
new file mode 100644
index 000000000..8283a4812
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/IFigureHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.w3c.dom.Element;
+
+/**
+ * IFigureHandler is similiar to EditPart in some sence. Each IFigureHandler is
+ * adapted to an HTML element node, and provide a figure for it.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IFigureHandler extends INodeAdapter {
+ public void updateFigure(Element node, CSSFigure oldFigure);
+
+ public void dispose();
+
+ public boolean isWidget();
+
+ public CSSFigure getFigure();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ImgFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ImgFigureHandler.java
new file mode 100644
index 000000000..46ca9ac66
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ImgFigureHandler.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.ImageWidgetProvider;
+import org.eclipse.jst.pagedesigner.utils.ImageResolver;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class ImgFigureHandler extends WidgetFigureHandler {
+ protected Image _image;
+
+ /**
+ * child class can override this method.
+ *
+ * @param node
+ */
+ protected void initializeImage(Element node) {
+ if (_image != null) {
+ _image.dispose();
+ }
+ _image = ImageResolver.initializeImage(node, "src");
+ }
+
+ public void dispose() {
+ if (_image != null) {
+ _image.dispose();
+ _image = null;
+ }
+ }
+
+ protected ICSSWidgetProvider initializeWidgetProvider(Element ele) {
+ initializeImage(ele);
+ ImageWidgetProvider provider = new ImageWidgetProvider(_image,
+ getCSSStyle(ele));
+ return provider;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/InputFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/InputFigureHandler.java
new file mode 100644
index 000000000..81823c8f3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/InputFigureHandler.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.ButtonWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.CheckboxWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.HiddenProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.ImageWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.InputFileWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.RadioWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.TextInputWidgetProvider;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.eclipse.jst.pagedesigner.utils.ImageResolver;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class InputFigureHandler extends WidgetFigureHandler {
+ private Image _image;
+
+ void initializeImage(Element node) {
+ if (_image != null) {
+ _image.dispose();
+ }
+ _image = ImageResolver.initializeImage(node, "src");
+ }
+
+ ImageWidgetProvider getImageProvider(Element node) {
+ initializeImage(node);
+ ImageWidgetProvider provider = new ImageWidgetProvider(_image,
+ getCSSStyle(node));
+ return provider;
+ }
+
+ ICSSWidgetProvider getButtonProvider(Element node) {
+ ButtonWidgetProvider provider = new ButtonWidgetProvider(
+ getCSSStyle(node));
+ provider.setValue(getButtonValue(node));
+ return provider;
+ }
+
+ ICSSWidgetProvider getFileProvider(Element node) {
+ // ICSSWidgetProvider textprovider = getTextInputProvider();
+ // // XXX: should we use the defaultstyle for the button?
+ // ButtonWidgetProvider browsebutton = new
+ // ButtonWidgetProvider(getCSSStyle());
+ // browsebutton.setValue("Browse...");
+ // CompositeWidgetProvider provider = new
+ // CompositeWidgetProvider(getCSSStyle(), textprovider, browsebutton,
+ // false);
+ // return provider;
+ ICSSWidgetProvider textprovider = getTextInputProvider(node);
+ // XXX: should we use the defaultstyle for the button?
+ ButtonWidgetProvider browsebutton = new ButtonWidgetProvider(
+ getCSSStyle(node));
+ browsebutton.setValue("Browse...");
+ InputFileWidgetProvider provider = new InputFileWidgetProvider(
+ getCSSStyle(node), textprovider, browsebutton);
+ return provider;
+ }
+
+ /**
+ * should not return null
+ *
+ * @return
+ */
+ protected Image getHiddenImage() {
+ return PDPlugin.getDefault().getImage(
+ "palette/GENERIC/small/PD_Palette_Default.gif");
+ }
+
+ ICSSWidgetProvider getHiddenProvider(Element node) {
+ return new HiddenProvider(getHiddenImage(), node);
+ }
+
+ ICSSWidgetProvider getPasswordProvider(Element node) {
+ TextInputWidgetProvider provider = new TextInputWidgetProvider(
+ getCSSStyle(node), TextInputWidgetProvider.PWD_SIZE);
+ provider.setSize(getSize(node));
+ provider.setValue("********");
+ return provider;
+ }
+
+ ICSSWidgetProvider getTextInputProvider(Element node) {
+ TextInputWidgetProvider provider = new TextInputWidgetProvider(
+ getCSSStyle(node));
+ provider.setSize(getSize(node));
+ provider.setValue(getValue(node));
+ return provider;
+ }
+
+ private int getSize(Element node) {
+ String s = DOMUtil.getAttributeIgnoreCase(node, "size");
+ try {
+ if (s != null) {
+ return Integer.parseInt(s);
+ } else {
+ return 0;
+ }
+ } catch (Exception ex) {
+ return 0;
+ }
+ }
+
+ /**
+ * @return
+ */
+ private String getValue(Element node) {
+ return DOMUtil.getAttributeIgnoreCase(node, "value");
+ }
+
+ private String getButtonValue(Element node) {
+ String value = getValue(node);
+ if (value == null) {
+ String type = DOMUtil.getAttributeIgnoreCase(node,
+ ICSSPropertyID.ATTR_TYPE);
+ if (type.equalsIgnoreCase(ICSSPropertyID.VAL_SUBMIT)) {
+ return "Submit Query";
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_RESET)) {
+ return "Reset";
+ }
+ }
+ return value;
+ }
+
+ /**
+ * @return
+ */
+ protected ICSSWidgetProvider initializeWidgetProvider(Element node) {
+ reset();
+
+ String type = DOMUtil.getAttributeIgnoreCase(node,
+ ICSSPropertyID.ATTR_TYPE);
+
+ if (type == null) {
+ return getTextInputProvider(node);
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_SUBMIT)
+ || type.equalsIgnoreCase(ICSSPropertyID.VAL_RESET)
+ || type.equalsIgnoreCase(ICSSPropertyID.VAL_BUTTON)) {
+ return getButtonProvider(node);
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_IMAGE)) {
+ return getImageProvider(node);
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_FILE)) {
+ return getFileProvider(node);
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_RADIO)) {
+ RadioWidgetProvider provider = new RadioWidgetProvider(
+ getCSSStyle(node));
+ provider.setChecked(node.hasAttribute("checked"));
+ return provider;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_CHECKBOX)) {
+ CheckboxWidgetProvider provider = new CheckboxWidgetProvider(
+ getCSSStyle(node));
+ provider.setChecked(node.hasAttribute("checked"));
+ return provider;
+ } else if (type.equalsIgnoreCase(ICSSPropertyID.VAL_HIDDEN)) {
+ return getHiddenProvider(node);
+ }
+ if (type.equalsIgnoreCase(ICSSPropertyID.VAL_PASSWORD)) {
+ return getPasswordProvider(node);
+ } else {
+ return getTextInputProvider(node);
+ }
+ }
+
+ /**
+ *
+ */
+ private void reset() {
+ if (_image != null) {
+ _image.dispose();
+ _image = null;
+ }
+ }
+
+ public void dispose() {
+ reset();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ObjectFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ObjectFigureHandler.java
new file mode 100644
index 000000000..a608387ae
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/ObjectFigureHandler.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ObjectFigureHandler extends ImgFigureHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.figurehandler.ImgFigureHandler#initializeImage()
+ */
+ protected void initializeImage(Element node) {
+ if (_image == null) {
+ _image = new Image(null, PDPlugin.getDefault().getImage(
+ "palette/HTML/small/HTML_OBJECT.gif").getImageData());
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/SelectFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/SelectFigureHandler.java
new file mode 100644
index 000000000..8967cfe22
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/SelectFigureHandler.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.ComboWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.ListWidgetProvider;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class SelectFigureHandler extends WidgetFigureHandler {
+
+ public String[] getOptionLabels(Element node) {
+ List options = DOMUtil.getChildElementsByTagIgnoreCase(node,
+ IHTMLConstants.TAG_OPTION);
+ String[] ret = new String[options.size()];
+ for (int i = 0; i < ret.length; i++) {
+ Element option = (Element) options.get(i);
+ ret[i] = DOMUtil.getTextElementValue(option);
+ }
+ return ret;
+ }
+
+ public String getSelectedLabels(Element node) {
+ List options = DOMUtil.getChildElementsByTagIgnoreCase(node,
+ IHTMLConstants.TAG_OPTION);
+ String result = null;
+ for (int i = 0, n = options.size(); i < n; i++) {
+ Element option = (Element) options.get(i);
+ if (option.hasAttribute(IHTMLConstants.ATTR_SELECTED)) {
+ result = DOMUtil.getTextElementValue(option);
+ }
+ }
+ return result;
+ }
+
+ protected boolean isMultiple(Element node) {
+ return DOMUtil
+ .getAttributeIgnoreCase(node, ICSSPropertyID.VAL_MULTIPLE) != null;
+ }
+
+ /**
+ * @return
+ */
+ protected ICSSWidgetProvider initializeWidgetProvider(Element node) {
+ String[] labels = getOptionLabels(node);
+ String rows = DOMUtil.getAttributeIgnoreCase(node,
+ IHTMLConstants.ATTR_SIZE);
+ int rowsInt = 0;
+ try {
+ if (rows != null) {
+ rowsInt = Integer.parseInt(rows);
+ }
+ } catch (Exception ex) {
+ // ignore
+ }
+ if (isMultiple(node) || rowsInt > 1) {
+ ListWidgetProvider provider = new ListWidgetProvider(
+ getCSSStyle(node));
+ provider.setOptions(labels);
+ provider.setRows(rowsInt);
+ return provider;
+ } else {
+ ComboWidgetProvider provider = new ComboWidgetProvider(
+ getCSSStyle(node));
+ provider.setOptions(labels);
+ provider.setSelectedLabel(getSelectedLabels(node));
+ return provider;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/TextareaFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/TextareaFigureHandler.java
new file mode 100644
index 000000000..d92eee69b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/TextareaFigureHandler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.eclipse.jst.pagedesigner.css2.widget.TextAreaWidgetProvider;
+import org.eclipse.jst.pagedesigner.utils.DOMUtil;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TextareaFigureHandler extends WidgetFigureHandler {
+ protected ICSSWidgetProvider initializeWidgetProvider(Element node) {
+ TextAreaWidgetProvider provider = new TextAreaWidgetProvider(
+ getCSSStyle(node));
+ String s = DOMUtil.getAttributeIgnoreCase(node, "cols");
+ if (s != null) {
+ try {
+ provider.setColumns(Integer.parseInt(s));
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ s = DOMUtil.getAttributeIgnoreCase(node, "rows");
+ if (s != null) {
+ try {
+ provider.setRows(Integer.parseInt(s));
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ s = DOMUtil.getTextElementValue(node);
+ if (s != null) {
+ provider.setValue(s);
+ }
+ return provider;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/WidgetFigureHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/WidgetFigureHandler.java
new file mode 100644
index 000000000..3f3fa2889
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/figurehandler/WidgetFigureHandler.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.figurehandler;
+
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSWidgetLayout;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSWidgetProvider;
+import org.w3c.dom.Element;
+
+public abstract class WidgetFigureHandler extends AbstractFigureHandler {
+
+ public WidgetFigureHandler() {
+ super();
+ }
+
+ public void updateFigure(Element node, CSSFigure oldFigure) {
+ setCurrentFigure(oldFigure);
+ ICSSWidgetProvider provider = initializeWidgetProvider(node);
+ oldFigure.setCSSStyle(provider.getCSSStyle());
+ oldFigure
+ .setFixedLayoutManager(new CSSWidgetLayout(oldFigure, provider));
+ }
+
+ protected abstract ICSSWidgetProvider initializeWidgetProvider(Element ele);
+
+ public boolean isWidget() {
+ return true;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationEditPolicy.java
new file mode 100644
index 000000000..ea9da263f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationEditPolicy.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.itemcreation;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.RectangleFigure;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editpolicies.GraphicalEditPolicy;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.CreateItemCommand;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.tools.ExposeHelper;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.DnDPositionValidator;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * @author mengbo
+ */
+public class ItemCreationEditPolicy extends GraphicalEditPolicy {
+ private RectangleFigure _feedbackFigure;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ public Command getCommand(Request request) {
+ if (request instanceof ItemCreationRequest) {
+ ItemCreationRequest r = (ItemCreationRequest) request;
+ DesignPosition position = EditPartPositionHelper
+ .findEditPartPosition(getHost(), r.getLocation(),
+ new DnDPositionValidator(new ActionData(
+ ActionData.PALETTE_DND, request)));
+ IDOMPosition domposition = null;
+ if (position == null) {
+ return null;
+ } else {
+ domposition = DOMPositionHelper.toDOMPosition(position);
+ }
+ if (domposition == null) {
+ return null;
+ }
+ return new CreateItemCommand(
+ PDPlugin
+ .getResourceString("ItemCreationEditPolicy.CommandLabel.CreateItem"),//$NON-NLS-1$
+ getViewer(getHost()), domposition, r.getItemDescriptor());
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getTargetEditPart(org.eclipse.gef.Request)
+ */
+ public EditPart getTargetEditPart(Request request) {
+ if (request instanceof ItemCreationRequest) {
+ ItemCreationRequest r = (ItemCreationRequest) request;
+ DesignPosition position = EditPartPositionHelper
+ .findEditPartPosition(getHost(), r.getLocation(),
+ new DnDPositionValidator(new ActionData(
+ ActionData.PALETTE_DND, request)));
+
+ if (position == null) {
+ return null;
+ }
+
+ EditPart container = position.getContainerPart();
+ return container;
+ }
+ return null;
+ }
+
+ /**
+ * @param host
+ * @return
+ */
+ private IHTMLGraphicalViewer getViewer(EditPart host) {
+ return (IHTMLGraphicalViewer) ((GraphicalEditPart) host).getViewer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void eraseTargetFeedback(Request request) {
+ if (_feedbackFigure != null) {
+ removeFeedback(_feedbackFigure);
+ _feedbackFigure = null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#showTargetFeedback(org.eclipse.gef.Request)
+ */
+ public void showTargetFeedback(Request request) {
+ if (request instanceof ItemCreationRequest) {
+ ItemCreationRequest r = (ItemCreationRequest) request;
+ DesignPosition position = EditPartPositionHelper
+ .findEditPartPosition(getHost(), r.getLocation(),
+ new DnDPositionValidator(new ActionData(
+ ActionData.PALETTE_DND, request)));
+
+ if (position == null) {
+ return;
+ }
+ Rectangle rect = EditPartPositionHelper
+ .convertToAbsoluteCaretRect(position);
+ showFeedbackRect(rect);
+ if (getHost() instanceof GraphicalEditPart) {
+ ExposeHelper exposeHelper = new ExposeHelper(
+ getViewer(getHost()));
+ exposeHelper.adjustVertical(r.getLocation());
+ }
+ }
+ }
+
+ protected RectangleFigure getFeedbackFigure() {
+ if (_feedbackFigure == null) {
+ _feedbackFigure = new RectangleFigure();
+ _feedbackFigure.setFill(true);
+ _feedbackFigure.setXOR(true);
+ _feedbackFigure.setOutline(true);
+ _feedbackFigure.setLineWidth(1);
+ _feedbackFigure.setForegroundColor(ColorConstants.red);
+ _feedbackFigure.setBounds(new Rectangle(0, 0, 0, 0));
+ addFeedback(_feedbackFigure);
+ }
+ return _feedbackFigure;
+ }
+
+ protected void showFeedbackRect(Rectangle rect) {
+ RectangleFigure pf = getFeedbackFigure();
+ pf.translateToRelative(rect);
+ pf.setBounds(rect);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationRequest.java
new file mode 100644
index 000000000..9d49c129d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationRequest.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.itemcreation;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.requests.DropRequest;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+
+/**
+ * @author mengbo
+ */
+public class ItemCreationRequest extends Request implements DropRequest {
+ public static final String REQ_ITEM_CREATION = "Item Creation";
+
+ private Point _location;
+
+ private IPaletteItemDescriptor _itemDescriptor;
+
+ /**
+ *
+ */
+ public ItemCreationRequest() {
+ super(REQ_ITEM_CREATION);
+ }
+
+ /**
+ * @param type
+ */
+ public ItemCreationRequest(Object type) {
+ super(type);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.requests.DropRequest#getLocation()
+ */
+ public Point getLocation() {
+ return _location;
+ }
+
+ /**
+ * Sets the location where the new object will be placed.
+ *
+ * @param location
+ * the location
+ */
+ public void setLocation(Point location) {
+ this._location = location;
+ }
+
+ public void setItemDescriptor(IPaletteItemDescriptor desc) {
+ this._itemDescriptor = desc;
+ }
+
+ public IPaletteItemDescriptor getItemDescriptor() {
+ return this._itemDescriptor;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationTool.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationTool.java
new file mode 100644
index 000000000..ce67db653
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemCreationTool.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.itemcreation;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.SharedCursors;
+import org.eclipse.gef.SnapToHelper;
+import org.eclipse.gef.requests.CreateRequest;
+import org.eclipse.gef.requests.CreationFactory;
+import org.eclipse.gef.tools.TargetingTool;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.swt.graphics.Cursor;
+
+/**
+ * This Tool is used to create items. It is to replace the default CreationTool
+ * of GEF. We are not using CreationToolEntry for creating item, since the
+ * default GEF implementation require creating of the object before drop into
+ * the view. We do not want to create the XML element (and possibly its taglib
+ * declaration) before the drop is really performed.)
+ *
+ * @author mengbo
+ */
+public class ItemCreationTool extends TargetingTool {
+ IPaletteItemDescriptor _itemDescriptor;
+
+ private CreationFactory factory;
+
+ private SnapToHelper helper;
+
+ /**
+ * Default constructor. Sets the default and disabled cursors.
+ */
+ public ItemCreationTool(IPaletteItemDescriptor item) {
+ setDefaultCursor(SharedCursors.CURSOR_TREE_ADD);
+ setDisabledCursor(SharedCursors.NO);
+
+ this._itemDescriptor = item;
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#calculateCursor()
+ */
+ protected Cursor calculateCursor() {
+ /*
+ * Fix for Bug# 66010 The following two lines of code were added for the
+ * case where a tool is activated via the keyboard (that code hasn't
+ * been released yet). However, they were causing a problem as described
+ * in 66010. Since the keyboard activation code is not being released
+ * for 3.0, the following lines are being commented out.
+ */
+ // if (isInState(STATE_INITIAL))
+ // return getDefaultCursor();
+ return super.calculateCursor();
+ }
+
+ /**
+ * Creates a {@link CreateRequest}and sets this tool's factory on the
+ * request.
+ *
+ * @see org.eclipse.gef.tools.TargetingTool#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ ItemCreationRequest request = new ItemCreationRequest();
+ request.setItemDescriptor(this._itemDescriptor);
+ return request;
+ }
+
+ /**
+ * @see org.eclipse.gef.Tool#deactivate()
+ */
+ public void deactivate() {
+ super.deactivate();
+ helper = null;
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#getCommandName()
+ */
+ protected String getCommandName() {
+ return ItemCreationRequest.REQ_ITEM_CREATION;
+ }
+
+ /**
+ * Cast the target request to a CreateRequest and returns it.
+ *
+ * @return the target request as a CreateRequest
+ * @see TargetingTool#getTargetRequest()
+ */
+ protected ItemCreationRequest getCreateRequest() {
+ return (ItemCreationRequest) getTargetRequest();
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#getDebugName()
+ */
+ protected String getDebugName() {
+ return "Item Creation Tool";//$NON-NLS-1$
+ }
+
+ /**
+ * The creation tool only works by clicking mouse button 1 (the left mouse
+ * button in a right-handed world). If any other button is pressed, the tool
+ * goes into an invalid state. Otherwise, it goes into the drag state,
+ * updates the request's location and calls
+ * {@link TargetingTool#lockTargetEditPart(EditPart)}with the edit part
+ * that was just clicked on.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)
+ */
+ protected boolean handleButtonDown(int button) {
+ if (button != 1) {
+ setState(STATE_INVALID);
+ handleInvalidInput();
+ return true;
+ }
+ if (stateTransition(STATE_INITIAL, STATE_DRAG)) {
+ if (getTargetEditPart() != null) {
+ getCreateRequest().setLocation(getLocation());
+ lockTargetEditPart(getTargetEditPart());
+ // Snap only when size on drop is employed
+ helper = (SnapToHelper) getTargetEditPart().getAdapter(
+ SnapToHelper.class);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * If the tool is currently in a drag or drag-in-progress state, it goes
+ * into the terminal state, performs some cleanup (erasing feedback,
+ * unlocking target edit part), and then calls {@link #performCreation(int)}.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
+ */
+ protected boolean handleButtonUp(int button) {
+ if (stateTransition(STATE_DRAG | STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) {
+ eraseTargetFeedback();
+ unlockTargetEditPart();
+ performCreation(button);
+ }
+
+ setState(STATE_TERMINAL);
+ handleFinished();
+
+ return true;
+ }
+
+ /**
+ * Updates the request, sets the current command, and asks to show feedback.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress()
+ */
+ protected boolean handleDragInProgress() {
+ if (isInState(STATE_DRAG_IN_PROGRESS)) {
+ updateTargetRequest();
+ setCurrentCommand(getCommand());
+ showTargetFeedback();
+ }
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()
+ */
+ protected boolean handleDragStarted() {
+ return stateTransition(STATE_DRAG, STATE_DRAG_IN_PROGRESS);
+ }
+
+ /**
+ * If the user is in the middle of creating a new edit part, the tool erases
+ * feedback and goes into the invalid state when focus is lost.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleFocusLost()
+ */
+ protected boolean handleFocusLost() {
+ if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {
+ eraseTargetFeedback();
+ setState(STATE_INVALID);
+ handleFinished();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.TargetingTool#handleHover()
+ */
+ protected boolean handleHover() {
+ if (isInState(STATE_INITIAL))
+ updateAutoexposeHelper();
+ return true;
+ }
+
+ /**
+ * Updates the request and mouse target, gets the current command and asks
+ * to show feedback.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleMove()
+ */
+ protected boolean handleMove() {
+ updateTargetRequest();
+ updateTargetUnderMouse();
+ setCurrentCommand(getCommand());
+ showTargetFeedback();
+ return true;
+ }
+
+ /**
+ * Executes the current command and selects the newly created object. The
+ * button that was released to cause this creation is passed in, but since
+ * {@link #handleButtonDown(int)}goes into the invalid state if the button
+ * pressed is not button 1, this will always be button 1.
+ *
+ * @param button
+ * the button that was pressed
+ */
+ protected void performCreation(int button) {
+ executeCurrentCommand();
+ // selectAddedObject();
+ }
+
+ // /*
+ // * Add the newly created object to the viewer's selected objects.
+ // */
+ // private void selectAddedObject() {
+ // final Object model = getCreateRequest().getNewObject();
+ // if (model == null)
+ // return;
+ // EditPartViewer viewer = getCurrentViewer();
+ // Object editpart = viewer.getEditPartRegistry().get(model);
+ // if (editpart instanceof EditPart) {
+ // viewer.flush();
+ // viewer.select((EditPart)editpart);
+ // }
+ // }
+
+ /**
+ * Sets the location (and size if the user is performing size-on-drop) of
+ * the request.
+ *
+ * @see org.eclipse.gef.tools.TargetingTool#updateTargetRequest()
+ */
+ protected void updateTargetRequest() {
+ ItemCreationRequest req = getCreateRequest();
+ req.setLocation(getLocation());
+ // if (isInState(STATE_DRAG_IN_PROGRESS)) {
+ // Point loq = getStartLocation();
+ // req.setLocation(bounds.getLocation());
+ // req.getExtendedData().clear();
+ // if (!getCurrentInput().isAltKeyDown() && helper != null) {
+ // PrecisionRectangle baseRect = new PrecisionRectangle(bounds);
+ // PrecisionRectangle result = baseRect.getPreciseCopy();
+ // helper.snapRectangle(req, PositionConstants.NSEW,
+ // baseRect, result);
+ // req.setLocation(result.getLocation());
+ // req.setSize(result.getSize());
+ // }
+ // } else {
+ // req.setLocation(getLocation());
+ // }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemToolEntry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemToolEntry.java
new file mode 100644
index 000000000..3eca4addf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/itemcreation/ItemToolEntry.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.itemcreation;
+
+import org.eclipse.gef.Tool;
+import org.eclipse.gef.palette.ToolEntry;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+
+/**
+ * ItemToolEntry is used to create an item. We are not using CreationToolEntry
+ * for creating item, since the default GEF implementation require creating of
+ * the object before drop into the view. We do not want to create the XML
+ * element (and possibly its taglib declaration) before the drop is really
+ * performed.)
+ *
+ * @author mengbo
+ */
+public class ItemToolEntry extends ToolEntry {
+ private IPaletteItemDescriptor _itemDesc;
+
+ /**
+ * @param label
+ * @param shortDesc
+ * @param iconSmall
+ * @param iconLarge
+ */
+ public ItemToolEntry(String label, String shortDesc,
+ ImageDescriptor iconSmall, ImageDescriptor iconLarge,
+ IPaletteItemDescriptor itemDesc) {
+ super(label, shortDesc, iconSmall, iconLarge);
+ this._itemDesc = itemDesc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.palette.ToolEntry#createTool()
+ */
+ public Tool createTool() {
+ return new ItemCreationTool(_itemDesc);
+ }
+
+ public IPaletteItemDescriptor getItemDesc() {
+ return _itemDesc;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/AttributeDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/AttributeDescriptor.java
new file mode 100644
index 000000000..e99147c9e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/AttributeDescriptor.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.jst.pagedesigner.common.utils.StringUtil;
+
+/**
+ * @author mengbo
+ */
+public class AttributeDescriptor implements IAttributeDescriptor {
+ private String _attributeName;
+
+ private String _category;
+
+ private String _valueType;
+
+ private String _typeParameter;
+
+ private String _labelString;
+
+ private String _defaultValue;
+
+ private String _description;
+
+ private Map _parameterMap;
+
+ private Map _options;
+
+ private boolean _required;
+
+ /**
+ *
+ */
+ public AttributeDescriptor() {
+ super();
+ }
+
+ public AttributeDescriptor(String attrName) {
+ this.setAttributeName(attrName);
+ }
+
+ public void setAttributeName(String attributeName) {
+ this._attributeName = attributeName;
+ }
+
+ public void setCategory(String category) {
+ this._category = category;
+ }
+
+ public void setValueType(String valueType) {
+ this._valueType = valueType;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IAttributeDescriptor#getAttributeName()
+ */
+ public String getAttributeName() {
+ return _attributeName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IAttributeDescriptor#getDescription()
+ */
+ public String getDescription() {
+ return _description;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IAttributeDescriptor#getCategory()
+ */
+ public String getCategory() {
+ return _category;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IAttributeDescriptor#getValueType()
+ */
+ public String getValueType() {
+ return _valueType;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IAttributeDescriptor#getOptions()
+ */
+ public Map getOptions() {
+ return _options;
+ }
+
+ public void setDescription(String description) {
+ _description = description;
+ }
+
+ public void setOptions(Map map, String defaultValue) {
+ _options = map;
+ _defaultValue = defaultValue;
+ }
+
+ /**
+ * @return Returns the typeParameter.
+ */
+ public String getTypeParameter() {
+ return _typeParameter;
+ }
+
+ /**
+ * @param typeParameter
+ * The typeParameter to set.
+ */
+ public void setTypeParameter(String typeParameter) {
+ this._typeParameter = typeParameter;
+ _parameterMap = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor#getLabelString()
+ */
+ public String getLabelString() {
+ if (_labelString == null) {
+ _labelString = StringUtil.splitVariable(getAttributeName());
+ }
+ return _labelString;
+ }
+
+ /**
+ * @param labelString
+ * The labelString to set.
+ */
+ public void setLabelString(String labelString) {
+ this._labelString = labelString;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor#getParameterByName(java.lang.String)
+ */
+ public String getParameterByName(String name) {
+ if (_parameterMap == null) {
+ parseParameter();
+ }
+ Object value = _parameterMap.get(name);
+ return value == null ? "" : value.toString();
+ }
+
+ /**
+ *
+ */
+ private void parseParameter() {
+ _parameterMap = new HashMap();
+ if (_typeParameter == null) {
+ return;
+ }
+ StringTokenizer tokenizer = new StringTokenizer(_typeParameter, "||");
+ while (tokenizer.hasMoreTokens()) {
+ String parameterEntry = tokenizer.nextToken();
+ int index = parameterEntry.indexOf('=');
+ if (index != -1) {
+ _parameterMap.put(parameterEntry.substring(0, index),
+ parameterEntry.substring(index + 1));
+ }
+ }
+ }
+
+ public String getDefaultValue() {
+ return _defaultValue;
+ }
+
+ public void setDefaultValue(String value) {
+ _defaultValue = value;
+ }
+
+ public boolean isRequired() {
+ return _required;
+ }
+
+ public void setRequired(boolean required) {
+ this._required = required;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/BindingHandlerDelegate.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/BindingHandlerDelegate.java
new file mode 100644
index 000000000..3987fb7d9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/BindingHandlerDelegate.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BindingHandlerDelegate implements IBindingHandler {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IBindingHandler#handleBinding(org.eclipse.swt.widgets.Shell,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement,
+ * java.lang.String)
+ */
+ public String handleBinding(Shell shell, IDOMNode ancester,
+ IDOMElement element, String currentValue) {
+ IBindingHandler handler = getDelegatedHandler(ancester, element);
+ if (handler != null) {
+ return handler
+ .handleBinding(shell, ancester, element, currentValue);
+ } else {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IBindingHandler#isEnabled(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)
+ */
+ // public boolean isEnabled(IDOMNode ancester, IDOMElement element)
+ // {
+ // IBindingHandler handler = getDelegatedHandler(ancester, element);
+ // return (handler == null) ? false : handler.isEnabled(ancester, element);
+ // }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IBindingHandler#isEnabled(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement,
+ * java.lang.String, java.lang.String,
+ * org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor)
+ */
+ public boolean isEnabled(IDOMNode ancester, IDOMElement element,
+ String uri, String tagName, IAttributeDescriptor attr) {
+ IBindingHandler handler = getDelegatedHandler(ancester, element);
+ return (handler == null) ? false : handler.isEnabled(ancester, element,
+ uri, tagName, attr);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IBindingHandler#getImage()
+ */
+ public Image getImage() {
+ return PDPlugin.getDefault().getImage("PD_Binding.gif");
+ }
+
+ public Image getDisabledImage() {
+ return PDPlugin.getDefault().getImage("PD_Binding_disabled.gif");
+ }
+
+ private IBindingHandler getDelegatedHandler(IDOMNode ancester,
+ IDOMElement element) {
+ IProject project = getProject(ancester, element);
+ if (project != null) {
+ Object obj = project.getAdapter(IBindingHandler.class);
+ if (obj instanceof IBindingHandler) {
+ return (IBindingHandler) obj;
+ }
+ }
+
+ return null;
+ }
+
+ private IProject getProject(IDOMNode ancester, IDOMElement element) {
+ IDOMModel model = getModel(ancester, element);
+ if (model != null) {
+ return StructuredModelUtil.getProjectFor(model);
+ } else {
+ return null;
+ }
+ }
+
+ private IDOMModel getModel(IDOMNode ancester, IDOMElement element) {
+ if (ancester != null) {
+ return ancester.getModel();
+ } else if (element != null) {
+ return element.getModel();
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/EditorCreator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/EditorCreator.java
new file mode 100644
index 000000000..a09d2763d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/EditorCreator.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.meta.internal.DefaultEditorCreator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class EditorCreator {
+ static EditorCreator _instance;
+
+ static IBindingHandler _defaultHandler = new BindingHandlerDelegate();
+
+ public static interface CellEditorHolder {
+ public CellEditor createCellEditor(Composite parent);
+ }
+
+ /**
+ * Create a dialog field without databinding using the specified attribute
+ * descriptor.
+ *
+ * @param attr
+ * @return
+ */
+ public abstract DialogField createDialogField(IAttributeDescriptor attr);
+
+ /**
+ * Create a dialog field that will have databinding support. Basically, this
+ * method will create a normal dialog field using the attribute descriptor,
+ * then make a wrapper on it.
+ *
+ * @param uri
+ * the namespace uri
+ * @param tagName
+ * the local tag name
+ * @param attr
+ * @param handler
+ * if null, system default mechanism will be used.
+ * @return
+ */
+ public abstract DialogField createDialogFieldWithWrapper(String uri,
+ String tagName, IAttributeDescriptor attr, IBindingHandler handler);
+
+ /**
+ * Create a cell editor.
+ *
+ * @param parent
+ * @param attr
+ * @param element
+ * @return
+ */
+ public abstract CellEditor createCellEditor(Composite parent,
+ IAttributeDescriptor attr, IDOMElement element);
+
+ /**
+ * Create a cell editor that will have databinding support.
+ *
+ * @param parent
+ * @param attr
+ * @param element
+ * @param handler
+ * if null, system default mechanism will be used.
+ * @return
+ */
+ public abstract CellEditor createCellEditorWithWrapper(Composite parent,
+ IAttributeDescriptor attr, IDOMElement element,
+ IBindingHandler handler);
+
+ /**
+ * Create a cell edtior that will have databinding support. This method
+ * don't provide an attribute descriptor, but it provide a CellEditorHolder
+ * to create whatever normal cell editor it wants.
+ *
+ * @param parent
+ * @param attr
+ * could be null
+ * @param holder
+ * @param element
+ * @param handler
+ * if null, system default mechanism will be used.
+ * @return
+ */
+ public abstract CellEditor createCellEditorWithWrapper(Composite parent,
+ IAttributeDescriptor attr, CellEditorHolder holder,
+ IDOMElement element, IBindingHandler handler);
+
+ public static EditorCreator getInstance() {
+ if (_instance == null) {
+ _instance = new DefaultEditorCreator();
+ }
+ return _instance;
+ }
+
+ public IBindingHandler getSystemDefaultBindingHandler() {
+ return _defaultHandler;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeCellEditorFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeCellEditorFactory.java
new file mode 100644
index 000000000..77114a598
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeCellEditorFactory.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.swt.widgets.Composite;
+import org.w3c.dom.Element;
+
+/**
+ * Factory for creating CellEditors to edit element attributes.
+ *
+ * @author mengbo
+ */
+public interface IAttributeCellEditorFactory {
+ /**
+ * create cell editor
+ *
+ * @param parent
+ * @param attr
+ * @param ele
+ * @return null means failed to create cell editor
+ */
+ public CellEditor createCellEditor(Composite parent,
+ IAttributeDescriptor attr, Element ele);
+
+ /**
+ * Normally, the DialogField for an attribute may appear in the following
+ * places.
+ * <ol>
+ * <li>In the Quick Editor properties view, used to edit an element.
+ * <li>In a dialog to edit an element
+ * <li>In a dialog, to create an element
+ * </ol>
+ *
+ * It is the caller's responsibility to add valueChanged listener to the
+ * dialog field to decide how to apply the value.
+ *
+ * It is also the caller's responsibility to set the initial value of the
+ * field.
+ *
+ * The field should always be an instanceof <code>ISupportTextValue</code>,
+ * it could also optionally implement <code>IElementContextable</code>
+ *
+ * @param attr
+ * the attribute descriptor, meta data
+ * @return A dialog field. null means this factory can't create one.
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue
+ */
+ public DialogField createDialogField(IAttributeDescriptor attr);
+
+ /**
+ * The value types supported by this factory.
+ *
+ * @return null means this factory can behave as default factory.
+ */
+ public String[] getSupportedValueTypes();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeDescriptor.java
new file mode 100644
index 000000000..16532190e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IAttributeDescriptor.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+import java.util.Map;
+
+/**
+ *
+ * @author mengbo
+ */
+public interface IAttributeDescriptor {
+ public static final String PARAMETER_SUFFIX = "suffix";
+
+ public static final String PARAMETER_STYLE = "style";
+
+ public static final String PARAMETER_SUPER_TYPE = "superType";
+
+ public static final String PARAMETER_SEPARATOR = "separator";
+
+ public static final String PARAMETER_DEFAULT = "default";
+
+ /**
+ * get the name of the attribute.
+ *
+ * @return
+ */
+ public String getAttributeName();
+
+ /**
+ * Returns a brief description of this property. This localized string is
+ * shown to the user when this property is selected. and it is used as
+ * tooltip of the property now.
+ *
+ * @return a brief description, or <code>null</code> if none
+ */
+ public String getDescription();
+
+ /**
+ * return the category for this attribute.
+ *
+ * @return
+ */
+ public String getCategory();
+
+ /**
+ * value type is used to construct the cell editor.
+ *
+ * @return
+ */
+ public String getValueType();
+
+ /**
+ * Some value type contains additional parameter information. For example,
+ * if valueType is CLASSNAME, the typeParameter could be super
+ * interface/super class name.
+ *
+ * NOTE: if valueType is ENUMERATION, caller should use
+ * <code>getOptions()</code>
+ *
+ * @return null if there is no type parameter.
+ */
+ public String getTypeParameter();
+
+ public String getParameterByName(String name);
+
+ /**
+ * when the value type is "enumeration", this method will be called to
+ * construct the drop downlist.
+ *
+ * The Map will be (key->display string)
+ *
+ * @return
+ */
+ public Map getOptions();
+
+ /**
+ * Gets the default value of Options
+ *
+ * @return
+ */
+ public String getDefaultValue();
+
+ /**
+ * A human readable string as the label of the attribute.
+ *
+ * @return
+ */
+ public String getLabelString();
+
+ /**
+ * Indicate whether the attribute is required.
+ *
+ * @return
+ */
+ public boolean isRequired();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IBindingHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IBindingHandler.java
new file mode 100644
index 000000000..a93a7804b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IBindingHandler.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IBindingHandler {
+ /**
+ * This handler should open a dialog to accept user input.
+ *
+ * @param shell
+ * @param ancester
+ * @param element
+ * @param currentValue
+ * @return null means user canceled the operation.
+ */
+ public String handleBinding(Shell shell, IDOMNode ancester,
+ IDOMElement element, String currentValue);
+
+ /**
+ * Whether should the binding be enabled for the specified element context.
+ * element could be null.
+ *
+ * @param ancester
+ * @param element
+ * @param uri
+ * @param tagName
+ * @param attr
+ * could be null.
+ * @return
+ */
+ public boolean isEnabled(IDOMNode ancester, IDOMElement element,
+ String uri, String tagName, IAttributeDescriptor attr);
+
+ /**
+ * given the meta data of an attribute, to see whether should enable binding
+ * handler for it.
+ *
+ * @param uri
+ * @param tagName
+ * @param attr
+ * @return
+ */
+ // public boolean isEnabled(String uri, String tagName, IAttributeDescriptor
+ // attr);
+ /**
+ * Image used for the small button.
+ *
+ * @return
+ */
+ public Image getImage();
+
+ public Image getDisabledImage();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/ICMRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/ICMRegistry.java
new file mode 100644
index 000000000..060795a11
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/ICMRegistry.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+/**
+ *
+ * @author mengbo
+ */
+public interface ICMRegistry {
+ /**
+ * get the URI supported by this registry.
+ *
+ * @return null if this is the global registry that support all the URI.
+ */
+ public String getSupportedURI();
+
+ /**
+ * get element descriptor by URI and tagname.
+ *
+ * @param uri
+ * @param tagname
+ * @return
+ */
+ public IElementDescriptor getElementDescriptor(String uri, String tagname);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IElementDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IElementDescriptor.java
new file mode 100644
index 000000000..78a819ca2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IElementDescriptor.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+/**
+ *
+ * @author mengbo
+ */
+public interface IElementDescriptor {
+ /**
+ * get the tagname
+ *
+ * @return
+ */
+ public String getTagName();
+
+ /**
+ * get the namespace URI
+ *
+ * @return
+ */
+ public String getNamespaceURI();
+
+ /**
+ * get all attribute descriptors
+ *
+ * @return
+ */
+ public IAttributeDescriptor[] getAttributeDescriptors();
+
+ public IAttributeDescriptor getAttributeDescriptor(String attributeName);
+
+ /**
+ * get attribute descriptor by name
+ *
+ * @param attrname
+ * @return
+ */
+ // public IAttributeDescriptor getAttributeDescriptor(String attrname);
+ /**
+ * get reference. The ElementDescriptor being referenced may provide more
+ * information. For example, &lt;h:inputText&gt; may reference
+ * &lt;input&gt;. So those attribute descriptor not provided by
+ * &lt;h:inputText&gt; could still be provided by &lt;input&gt;.
+ *
+ * @return
+ */
+ public IElementDescriptor getReference();
+
+ /**
+ * if this element have eclipse help topic, then could use this method to
+ * return a context id.
+ *
+ * @return could be null
+ */
+ public String getHelpContextID();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IValueType.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IValueType.java
new file mode 100644
index 000000000..f6e930cb4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/IValueType.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta;
+
+/**
+ * All value types will be upcased.
+ *
+ * @author mengbo
+ */
+public interface IValueType {
+ // shared for html and jsf
+ public static final String CSSSTYLE = "CSSSTYLE";
+
+ public static final String CSSCLASS = "CSSCLASS";
+
+ public static final String CSSID = "CSSID";
+
+ public static final String ENUMERATED = "ENUMERATED";
+
+ public static final String BOOLEAN = "BOOLEAN";
+
+ public static final String RELATIVEPATH = "RELATIVEPATH";
+
+ public static final String WEBPATH = "WEBPATH";
+
+ public static final String COLOR = "COLOR";
+
+ public static final String NAMED_BOOLEAN = "NAMED-BOOLEAN";
+
+ // for jsf only
+ public static final String METHODBINDING = "METHODBINDING";
+
+ public static final String CLASSNAME = "CLASSNAME";
+
+ // new types
+ public static final String LINK = "LINK";
+
+ public static final String JAVASCRIPT = "JAVASCRIPT";
+
+ public static final String PROPERTYBINDING = "PROPERTYBINDING";
+
+ public static final String TIMEZONE = "TIMEZONE";
+
+ public static final String CLASSPATH_RESOURCE = "CLASSPATH_RESOURCE";
+
+ public static final String CURRENCYCODE = "CURRENCYCODE";
+
+ public static final String LOCALE = "LOCALE";
+
+ public static final String MULTICHOICE = "MULTICHOICE";
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CMRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CMRegistry.java
new file mode 100644
index 000000000..2b12bb0b0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CMRegistry.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.meta.ICMRegistry;
+import org.eclipse.jst.pagedesigner.meta.IElementDescriptor;
+import org.osgi.framework.Bundle;
+
+/**
+ * XXX: temp implementation. In the future, will need add more things to allow
+ * other plugins to contribute things.
+ *
+ * @author mengbo
+ */
+public class CMRegistry implements ICMRegistry {
+ static Logger _log = PDPlugin.getLogger(CMRegistry.class);
+
+ private Map _htmlMap = new HashMap();
+
+ private Map _jspMap = new HashMap();
+
+ private List _contributedRegistries = new ArrayList();
+
+ private static CMRegistry _instance = null;
+
+ public static ICMRegistry getInstance() {
+ if (_instance == null) {
+ _instance = new CMRegistry();
+ }
+ return _instance;
+ }
+
+ /**
+ *
+ */
+ private CMRegistry() {
+ ProgressMonitorDialog progress = new ProgressMonitorDialog(null);
+ try {
+ progress.run(true, false, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor)
+ throws InvocationTargetException {
+ try {
+ monitor
+ .beginTask(
+ PDPlugin
+ .getResourceString("CMRegistry.ReadConfigration"),
+ IProgressMonitor.UNKNOWN);
+ monitor
+ .subTask(PDPlugin
+ .getResourceString("CMRegistry.HTMLConfigration"));
+ loadCM("configs/cm/html.xml", _htmlMap);
+ monitor
+ .subTask(PDPlugin
+ .getResourceString("CMRegistry.JSPConfigration"));
+ loadCM("configs/cm/jsp.xml", _jspMap);
+ monitor
+ .subTask(PDPlugin
+ .getResourceString("CMRegistry.OtherConfigration"));
+ readExtensions();
+ } catch (IOException ex) {
+ // ignore
+ } finally {
+ monitor.done();
+ }
+ }
+ });
+ } catch (InvocationTargetException e) {
+ // ignore
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+
+ /**
+ *
+ */
+ private void readExtensions() {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_CMREGISTRY);
+ IConfigurationElement[] eles = extensionPoint
+ .getConfigurationElements();
+
+ for (int i = 0; i < eles.length; i++) {
+ if (eles[i].getName().equals("registry")) {
+ String uri = eles[i].getAttribute("uri");
+ if (uri == null || uri.length() == 0) {
+ // no uri, skip
+ continue;
+ }
+ String configFile = eles[i].getAttribute("configFile");
+ if (configFile != null && configFile.length() > 0) {
+ String bundleName = eles[i].getDeclaringExtension()
+ .getNamespace();
+ try {
+ Bundle bundle = Platform.getBundle(bundleName);
+ URL cmFileUrl = bundle.getEntry(configFile);
+ SimpleCMRegistry reg = new SimpleCMRegistry(uri,
+ cmFileUrl);
+ _contributedRegistries.add(reg);
+ } catch (Exception ex) {
+ // will not happen. skip
+ ex.printStackTrace();
+ }
+ }
+ String className = eles[i].getAttribute("class");
+ if (className != null && className.length() > 0) {
+ try {
+ Object obj = eles[i].createExecutableExtension("class");
+
+ if (obj instanceof ICMRegistry) {
+ _contributedRegistries.add(obj);
+ }
+ } catch (CoreException e) {
+ // ignore the exception
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.ICMRegistry#getSupportedURI()
+ */
+ public String getSupportedURI() {
+ return null;
+ }
+
+ private void loadCM(String fileName, Map map) throws IOException {
+ try {
+ URL url = PDPlugin.getDefault().getBundle().getEntry(fileName);
+ ElementDescReader reader = new ElementDescReader(url);
+ reader.readElements(map);
+ } catch (Exception e) {
+ _log.error("Error loading " + fileName + ": " + e.getMessage());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.ICMRegistry#getElementDescriptor(java.lang.String,
+ * java.lang.String)
+ */
+ public IElementDescriptor getElementDescriptor(String uri, String tagname) {
+ if (uri == null) {
+ uri = IJMTConstants.URI_HTML;
+ }
+ if (IJMTConstants.URI_HTML.equals(uri)) {
+ IElementDescriptor desc = getHTMLElementDescriptor(tagname);
+ if (desc != null) {
+ return desc;
+ }
+ }
+ if (IJMTConstants.URI_JSP.equals(uri)) {
+ return getJSPElementDescriptor(tagname);
+ }
+ for (int i = 0, size = _contributedRegistries.size(); i < size; i++) {
+ ICMRegistry reg = (ICMRegistry) _contributedRegistries.get(i);
+ if (uri.equals(reg.getSupportedURI())) {
+ IElementDescriptor ret = reg.getElementDescriptor(uri, tagname);
+ if (ret != null) {
+ return ret;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private IElementDescriptor getHTMLElementDescriptor(String tagname) {
+ return (IElementDescriptor) _htmlMap.get(tagname.toLowerCase());
+ }
+
+ private IElementDescriptor getJSPElementDescriptor(String tagname) {
+ return (IElementDescriptor) _jspMap.get(tagname.toLowerCase());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CategoryNameComparator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CategoryNameComparator.java
new file mode 100644
index 000000000..1696c7c81
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CategoryNameComparator.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.util.Comparator;
+import java.util.HashSet;
+
+import org.eclipse.jst.pagedesigner.properties.ITabbedPropertiesConstants;
+
+/**
+ * @author mengbo
+ */
+public class CategoryNameComparator implements Comparator {
+ static HashSet _pairs = new HashSet();
+
+ private static CategoryNameComparator _instance = new CategoryNameComparator();
+
+ static class Pair {
+ String s1;
+
+ String s2;
+
+ Pair(String a, String b) {
+ s1 = a;
+ s2 = b;
+ }
+
+ public int hashCode() {
+ return s1.hashCode() + s2.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof Pair) {
+ Pair p = (Pair) o;
+ return s1.equals(p.s1) && s2.equals(p.s2);
+ }
+ return false;
+ }
+ }
+
+ public static void addPair(String s1, String s2) {
+ _pairs.add(new Pair(s1, s2));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ if (o1.equals(o2))
+ return 0;
+
+ if (ITabbedPropertiesConstants.OTHER_CATEGORY.equals(o1))
+ return 1;
+ if (ITabbedPropertiesConstants.OTHER_CATEGORY.equals(o2))
+ return -1;
+
+ Pair p = new Pair((String) o1, (String) o2);
+ if (_pairs.contains(p))
+ return -1;
+ return 1;
+ }
+
+ public static CategoryNameComparator getInstance() {
+ return _instance;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFacRegistryReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFacRegistryReader.java
new file mode 100644
index 000000000..20b98a9e6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFacRegistryReader.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.meta.IAttributeCellEditorFactory;
+
+/**
+ * Read the registry to find out all the CellEditorFactory.
+ *
+ * @author mengbo
+ */
+public class CellEditorFacRegistryReader {
+ static IAttributeCellEditorFactory[] _factories = null;
+
+ public static synchronized IAttributeCellEditorFactory[] getAllFactories() {
+ if (_factories == null) {
+ _factories = readAllFactories();
+ }
+ return _factories;
+
+ }
+
+ private static IAttributeCellEditorFactory[] readAllFactories() {
+ List result = new ArrayList();
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(),
+ IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+ IExtension[] extensions = extensionPoint.getExtensions();
+
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension ext = extensions[i];
+ IConfigurationElement[] facs = ext.getConfigurationElements();
+
+ for (int j = 0; j < facs.length; j++) {
+ if (facs[j].getName().equals(
+ IJMTConstants.ATTRIBUTE_CELLEDITOR_FACTORY)) {
+ facs[j].getAttribute("class");
+ Object obj;
+ try {
+ obj = facs[j].createExecutableExtension("class");
+
+ if (obj instanceof IAttributeCellEditorFactory) {
+ result.add(obj);
+ }
+ } catch (CoreException e) {
+ // ignore the exception
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ IAttributeCellEditorFactory[] ret = new IAttributeCellEditorFactory[result
+ .size()];
+ result.toArray(ret);
+ return ret;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFactoryRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFactoryRegistry.java
new file mode 100644
index 000000000..0b221e41c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/CellEditorFactoryRegistry.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue;
+import org.eclipse.jst.pagedesigner.common.dialogfield.StringDialogField;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.meta.IAttributeCellEditorFactory;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IValueType;
+import org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorFactory;
+import org.eclipse.swt.widgets.Composite;
+import org.w3c.dom.Element;
+
+/**
+ * CellEditorFactoryRegistry also read information from plugin.xml extension to
+ * allow other plugins to contribute new kinds of cell editors.
+ *
+ * @author mengbo
+ */
+public class CellEditorFactoryRegistry {
+ private static final Logger _log = PDPlugin
+ .getLogger(CellEditorFactoryRegistry.class);
+
+ private static CellEditorFactoryRegistry _instance;
+
+ private Map _factoryMap = new HashMap();
+
+ private List _defaultFactories = new ArrayList();
+
+ public static CellEditorFactoryRegistry getInstance() {
+ if (_instance == null) {
+ _instance = new CellEditorFactoryRegistry();
+ }
+ return _instance;
+ }
+
+ private CellEditorFactoryRegistry() {
+ IAttributeCellEditorFactory[] facs = CellEditorFacRegistryReader
+ .getAllFactories();
+ if (facs != null) {
+ for (int i = 0; i < facs.length; i++) {
+ addCellEditorFactory(facs[i]);
+ }
+ }
+ addCellEditorFactory(new CellEditorFactory());
+ }
+
+ public void addCellEditorFactory(IAttributeCellEditorFactory fac) {
+ String[] types = fac.getSupportedValueTypes();
+ if (types == null || types.length == 0) {
+ _defaultFactories.add(fac);
+ } else {
+ for (int i = 0; i < types.length; i++) {
+ _factoryMap.put(types[i].toUpperCase(), fac);
+ }
+ }
+ }
+
+ public CellEditor createCellEditor(Composite parent,
+ IAttributeDescriptor attr, Element element) {
+ String type = attr.getValueType();
+ if (type == null || type.length() == 0)
+ return null;
+ type = type.toUpperCase();
+
+ CellEditor result = null;
+ IAttributeCellEditorFactory fac = (IAttributeCellEditorFactory) _factoryMap
+ .get(type);
+ if (fac != null) {
+ result = fac.createCellEditor(parent, attr, element);
+ }
+ if (result == null) {
+ for (int i = 0, size = _defaultFactories.size(); i < size; i++) {
+ result = ((IAttributeCellEditorFactory) _defaultFactories
+ .get(i)).createCellEditor(parent, attr, element);
+ if (result != null)
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @param attr
+ * @param context
+ * @param ele
+ * @return will never be null
+ */
+ public DialogField createDialogField(IAttributeDescriptor attr) {
+ String type = attr.getValueType();
+ if (type == null || type.length() == 0) {
+ DialogField result = createTextDialogField(attr);
+ result.setLabelText(attr.getLabelString() + ":"); //$NON-NLS-1$
+ return result;
+ }
+ type = type.toUpperCase();
+
+ DialogField result = null;
+ IAttributeCellEditorFactory fac = (IAttributeCellEditorFactory) _factoryMap
+ .get(type);
+ if (fac != null) {
+ result = fac.createDialogField(attr);
+ }
+ if (result == null) {
+ for (int i = 0, size = _defaultFactories.size(); i < size; i++) {
+ result = ((IAttributeCellEditorFactory) _defaultFactories
+ .get(i)).createDialogField(attr);
+ if (result != null) {
+ break;
+ }
+ }
+ }
+ if (result == null) {
+ result = createTextDialogField(attr);
+ }
+ if (!(result instanceof ISupportTextValue)) {
+ result = createTextDialogField(attr);
+ }
+ result.setLabelText(attr.getLabelString() + ":"); //$NON-NLS-1$
+ return result;
+ }
+
+ /**
+ * @param attr
+ * @param context
+ * @param ele
+ * @return
+ */
+ public DialogField createTextDialogField(IAttributeDescriptor attr) {
+ StringDialogField field = new StringDialogField();
+ field.setLabelText(attr.getLabelString());
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ }
+
+ /**
+ * This is NOT a product method. It should only be used by testing code.
+ *
+ * @return
+ */
+ public String[] getAllValueTypes() {
+ Set valueTypes = new HashSet();
+ for (Iterator iter = _factoryMap.values().iterator(); iter.hasNext();) {
+ IAttributeCellEditorFactory fac = (IAttributeCellEditorFactory) iter
+ .next();
+ String[] supportedTypes = fac.getSupportedValueTypes();
+
+ if (supportedTypes != null) {
+ for (int i = 0; i < supportedTypes.length; i++) {
+ valueTypes.add(supportedTypes[i]);
+ }
+ }
+ }
+ // add those default ones.
+ Field[] fields = IValueType.class.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ int modifiers = fields[i].getModifiers();
+ if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
+ if (fields[i].getType() == String.class) {
+ try {
+ valueTypes.add((String) fields[i].get(null));
+ } catch (IllegalArgumentException ex) {
+ // "Error in fields retrieving:"
+ _log.info("CellEditorFactoryRegistry.Info.2", ex); //$NON-NLS-1$
+ } catch (IllegalAccessException ex) {
+ // "Error in fields retrieving:"
+ _log.info("CellEditorFactoryRegistry.Info.3", ex); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ String[] ret = new String[valueTypes.size()];
+ valueTypes.toArray(ret);
+ return ret;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/DefaultEditorCreator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/DefaultEditorCreator.java
new file mode 100644
index 000000000..3d639ba79
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/DefaultEditorCreator.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.meta.EditorCreator;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IBindingHandler;
+import org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper;
+import org.eclipse.jst.pagedesigner.ui.dialogfields.DialogFieldWrapper;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DefaultEditorCreator extends EditorCreator {
+ static IAttributeDescriptor _staticAttr;
+
+ static IDOMElement _staticElement;
+
+ static IBindingHandler _staticHandler;
+
+ static CellEditorHolder _staticHolder;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator#createCellEditor(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor,
+ * org.w3c.dom.Element)
+ */
+ public CellEditor createCellEditor(Composite parent,
+ IAttributeDescriptor attr, IDOMElement element) {
+ return CellEditorFactoryRegistry.getInstance().createCellEditor(parent,
+ attr, element);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator#createDialogField(org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor)
+ */
+ public DialogField createDialogField(IAttributeDescriptor attr) {
+ return CellEditorFactoryRegistry.getInstance().createDialogField(attr);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator#createCellEditorWithWrapper(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor,
+ * org.w3c.dom.Element,
+ * org.eclipse.jst.pagedesigner.meta.IBindingHandler,
+ * org.eclipse.swt.graphics.Image)
+ */
+ public CellEditor createCellEditorWithWrapper(Composite parent,
+ IAttributeDescriptor attr, final IDOMElement element,
+ IBindingHandler handler1) {
+ final IBindingHandler handler = (handler1 == null ? getSystemDefaultBindingHandler()
+ : handler1);
+ String uri = CMUtil.getElementNamespaceURI(element);
+ String tagName = element.getLocalName();
+ if (!handler.isEnabled(element, element, uri, tagName, attr)) {
+ // should not enabled, so directly return original cell editor
+ return createCellEditor(parent, attr, element);
+ }
+ try {
+ // since "createWrappedCellEditor()" and "getBindingImage()" is
+ // called from the constructor of CellEditorWrapper, at that time,
+ // can't reference this DefaultEditorCreator and final fields yet,
+ // so use static variable for it.
+ _staticAttr = attr;
+ _staticElement = element;
+ _staticHandler = handler;
+
+ return new CellEditorWrapper(parent) {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper#createWrappedCellEditor(org.eclipse.swt.widgets.Composite)
+ */
+ protected CellEditor createWrappedCellEditor(Composite cell) {
+ return EditorCreator.getInstance().createCellEditor(cell,
+ _staticAttr, _staticElement);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper#openDialogBox(org.eclipse.swt.widgets.Control)
+ */
+ protected Object openDialogBox(Control cellEditorWindow) {
+ return handler.handleBinding(cellEditorWindow.getShell(),
+ element, element, convertToString(this.getValue()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper#getBindingImage()
+ */
+ protected Image getBindingImage() {
+ return _staticHandler.getImage();
+ }
+ };
+ } finally {
+ _staticAttr = null;
+ _staticElement = null;
+ _staticHandler = null;
+ _staticHolder = null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator#createCellEditorWithWrapper(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor,
+ * org.eclipse.jst.pagedesigner.meta.EditorCreator.CellEditorHolder,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement,
+ * org.eclipse.jst.pagedesigner.meta.IBindingHandler)
+ */
+ public CellEditor createCellEditorWithWrapper(Composite parent,
+ IAttributeDescriptor attr, CellEditorHolder holder,
+ final IDOMElement element, IBindingHandler handler1) {
+ final IBindingHandler handler = (handler1 == null ? getSystemDefaultBindingHandler()
+ : handler1);
+ String uri = CMUtil.getElementNamespaceURI(element);
+ String tagName = element.getLocalName();
+ if (!handler.isEnabled(element, element, uri, tagName, attr)) {
+ // should not enabled, so directly return original cell editor
+ return holder.createCellEditor(parent);
+ }
+ try {
+ // since "createWrappedCellEditor()" and "getBindingImage()" is
+ // called from the constructor of CellEditorWrapper, at that time,
+ // can't reference this DefaultEditorCreator and final fields yet,
+ // so use static variable for it.
+ _staticElement = element;
+ _staticHandler = handler;
+ _staticHolder = holder;
+
+ return new CellEditorWrapper(parent) {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper#createWrappedCellEditor(org.eclipse.swt.widgets.Composite)
+ */
+ protected CellEditor createWrappedCellEditor(Composite cell) {
+ return _staticHolder.createCellEditor(cell);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper#openDialogBox(org.eclipse.swt.widgets.Control)
+ */
+ protected Object openDialogBox(Control cellEditorWindow) {
+ return handler.handleBinding(cellEditorWindow.getShell(),
+ element, element, convertToString(this.getValue()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper#getBindingImage()
+ */
+ protected Image getBindingImage() {
+ return _staticHandler.getImage();
+ }
+ };
+ } finally {
+ _staticAttr = null;
+ _staticElement = null;
+ _staticHandler = null;
+ _staticHolder = null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator#createDialogFieldWithWrapper(java.lang.String,
+ * java.lang.String,
+ * org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor,
+ * org.eclipse.jst.pagedesigner.meta.IBindingHandler)
+ */
+ public DialogField createDialogFieldWithWrapper(String uri, String tagName,
+ IAttributeDescriptor attr, IBindingHandler handler1) {
+ final IBindingHandler handler = (handler1 == null ? getSystemDefaultBindingHandler()
+ : handler1);
+ DialogField field = createDialogField(attr);
+ // if (field instanceof StringButtonDialogField)
+ // {
+ // ((StringButtonDialogField) field).setButtonLabel("...");
+ // }
+ DialogFieldWrapper wrapper = new DialogFieldWrapper(field, handler
+ .getImage(), handler.getDisabledImage(), uri, tagName, attr,
+ handler);
+ wrapper.setDatabindingEnabled(true);
+
+ return wrapper;
+ }
+
+ private String convertToString(Object value) {
+ if (value == null) {
+ return null;
+ } else {
+ return value.toString();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescReader.java
new file mode 100644
index 000000000..28e1b34c4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescReader.java
@@ -0,0 +1,433 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.meta.AttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * @author mengbo
+ */
+public class ElementDescReader {
+ private static Logger _log = PDPlugin.getLogger(ElementDescReader.class);
+
+ private Map _definedCategoryMap = new HashMap();
+
+ private Map _definedAttributeMap = new HashMap();
+
+ private URL _url;
+
+ private String[] _optimizedLocales = null;
+
+ public ElementDescReader(URL url) {
+ this._url = url;
+ }
+
+ /**
+ * Read xml information and fill the map
+ *
+ * @param stream
+ * xml file stream
+ * @param map
+ * @throws ParserConfigurationException
+ * @throws FactoryConfigurationError
+ * @throws SAXException
+ * @throws IOException
+ */
+ public void readElements(Map map) throws ParserConfigurationException,
+ FactoryConfigurationError, SAXException, IOException {
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder();
+ InputStream stream = this._url.openStream();
+ Document doc = builder.parse(stream);
+ ResourceUtils.ensureClosed(stream);
+
+ Element taglib = doc.getDocumentElement();
+ String nameSpace = taglib.getAttribute("uri");
+
+ NodeList list = doc.getElementsByTagName("tag");
+ if (list != null && list.getLength() != 0) {
+ int size = list.getLength();
+ for (int i = 0; i < size; i++) {
+ Element tag = (Element) list.item(i);
+ ElementDescriptor desc = new ElementDescriptor();
+ desc.setTagName(tag.getAttribute("name"));
+ desc.setNamespaceURI(nameSpace);
+
+ // support for help context id.
+ desc.setHelpContextID(tag.getAttribute("helpContextId"));
+
+ NodeList children = tag.getChildNodes();
+ // first calculate category and refered category quantity
+ NodeList cateNodes = tag.getElementsByTagName("category");
+ NodeList referedCateNodes = tag
+ .getElementsByTagName("referedcategory");
+ int cateNum = 0;
+ if (cateNodes != null) {
+ cateNum += cateNodes.getLength();
+ }
+ if (referedCateNodes != null) {
+ cateNum += referedCateNodes.getLength();
+ }
+
+ if (cateNum > 0) {
+ int length = children.getLength();
+ String[] cates = new String[cateNum];
+ List attrList = new ArrayList();
+ int realCate = 0;
+ for (int j = 0; j < length; j++) {
+ Node node = children.item(j);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = (Element) node;
+ String tagName = element.getTagName();
+ if ("category".equals(tagName)
+ || "referedcategory".equals(tagName)) {
+ String categoryName = element
+ .getAttribute("name");
+ if (categoryName != null
+ && !"".equals(categoryName)) {
+ cates[realCate++] = categoryName;
+ parseCategory(element, element, attrList);
+ } else {
+ Element definedCategory = handleReference(
+ doc, element, true);
+ String labelKey = definedCategory
+ .getAttribute("displaylabel");
+ if (labelKey != null
+ && !"".equals(labelKey)) {
+ cates[realCate++] = getValue(labelKey);
+ } else {
+ cates[realCate++] = calculateDisplayLabel(definedCategory);
+ }
+
+ parseCategory(element, definedCategory,
+ attrList);
+ }
+ }
+ }
+
+ }
+
+ // for sort categories
+ for (int m = 0, len = cates.length; m < len; m++) {
+ for (int j = m + 1; j < len; j++) {
+ CategoryNameComparator.addPair(cates[m], cates[j]);
+ }
+ }
+ desc.setAttributeDescriptors(attrList);
+ }
+
+ map.put(desc.getTagName(), desc);
+ }
+ }
+ }
+
+ private String calculateDisplayLabel(Element definedElement) {
+ String label = definedElement.getAttribute("displaylabel");
+ return getValue(label);
+ }
+
+ private void parseCategory(Element category, Element definedCategory,
+ List attrList) {
+ String cateLabel = calculateDisplayLabel(definedCategory);
+ // if the category is a referedcategory tag
+ if (category != definedCategory) {
+ String labelKey = category.getAttribute("displaylabel");
+ if (labelKey != null && !"".equals(labelKey)) {
+ cateLabel = getValue(labelKey);
+ }
+ }
+ handleAttributes(definedCategory, cateLabel, attrList);
+ if (category == definedCategory) {
+ return;
+ }
+
+ // the category should be a referedcategory tag
+ // include/add more attributes to category
+ NodeList includes = category.getElementsByTagName("includeattrs");
+ if (includes != null && includes.getLength() != 0) {
+ Element includeAttrsTag = (Element) includes.item(0);
+ handleAttributes(includeAttrsTag, cateLabel, attrList);
+
+ // handle attribute override
+ HashMap tempMap = new HashMap();
+ Iterator itor = attrList.iterator();
+ while (itor.hasNext()) {
+ AttributeDescriptor adp = (AttributeDescriptor) itor.next();
+ tempMap.put(adp.getAttributeName(), adp);
+ }
+ int listSize = attrList.size();
+ int mapSize = tempMap.size();
+ if (listSize != mapSize) {
+ attrList.clear();
+ Set set = tempMap.keySet();
+ Iterator setor = set.iterator();
+ while (setor.hasNext()) {
+ String atName = (String) setor.next();
+ AttributeDescriptor ad = (AttributeDescriptor) tempMap
+ .get(atName);
+ attrList.add(ad);
+ }
+ }
+
+ }
+
+ // exclude attributes from category
+ NodeList excludes = category.getElementsByTagName("excludeattrs");
+ if (excludes != null && excludes.getLength() != 0) {
+ String displayNames = ((Element) excludes.item(0))
+ .getAttribute("refs");
+ StringTokenizer tokenizer = new StringTokenizer(displayNames, ", ");
+
+ while (tokenizer.hasMoreTokens()) {
+ String name = tokenizer.nextToken();
+ Iterator itr = attrList.iterator();
+ while (itr.hasNext()) {
+ IAttributeDescriptor atr = (IAttributeDescriptor) itr
+ .next();
+ String atrName = atr.getAttributeName();
+ if (name.equals(atrName)) {
+ attrList.remove(atr);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * handle all attribute element and referedattribute element under the root
+ * element
+ *
+ * @param root
+ * @param cateLabel
+ * @param list
+ */
+ private void handleAttributes(Element root, String cateLabel, List attrList) {
+ NodeList allNodes = root.getChildNodes();
+ NodeList attrNodes = root.getElementsByTagName("attribute");
+ NodeList referedattrNodes = root
+ .getElementsByTagName("referedattribute");
+ int attrNum = 0;
+ if (attrNodes != null) {
+ attrNum += attrNodes.getLength();
+ }
+ if (referedattrNodes != null) {
+ attrNum += referedattrNodes.getLength();
+ }
+
+ if (attrNum > 0) {
+ int incAttrLength = allNodes.getLength();
+ for (int i = 0; i < incAttrLength; i++) {
+ Node node = allNodes.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element incAttr = (Element) node;
+ String tagName = incAttr.getTagName();
+ if ("attribute".equals(tagName)
+ || "referedattribute".equals(tagName)) {
+ String incAtrName = incAttr.getAttribute("name");
+ Element refAttr = incAttr;
+ if (incAtrName == null || "".equals(incAtrName)) {
+ incAttr = handleReference(root.getOwnerDocument(),
+ incAttr, false);
+ }
+ AttributeDescriptor attrDesc = parseAttribute(
+ cateLabel, incAttr);
+ String overrideName = refAttr
+ .getAttribute("overridename");
+ if (overrideName != null
+ && !"".equalsIgnoreCase(overrideName)) {
+ attrDesc.setAttributeName(overrideName);
+ }
+ String ovDisplayLabel = refAttr
+ .getAttribute("displaylabel");
+ if (ovDisplayLabel != null
+ && !"".equalsIgnoreCase(ovDisplayLabel)) {
+ attrDesc.setLabelString(getValue(ovDisplayLabel));
+ }
+ attrList.add(attrDesc);
+ }
+
+ }
+
+ }
+ }
+ }
+
+ private Element handleReference(Document doc, Element refElment,
+ boolean isCategory) {
+ String refName = refElment.getAttribute("ref");
+ if (isCategory) {
+ if (_definedCategoryMap.get(refName) != null) {
+ Element definedCategory = (Element) _definedCategoryMap
+ .get(refName);
+ return definedCategory;
+ }
+ } else {
+ if (_definedAttributeMap.get(refName) != null) {
+ Element definedAttribute = (Element) _definedAttributeMap
+ .get(refName);
+ return definedAttribute;
+ }
+ }
+
+ NodeList catgs = null;
+ if (isCategory) {
+ NodeList defineCates = doc.getElementsByTagName("categories");
+ Element firstCate = (Element) defineCates.item(0);
+ catgs = firstCate.getElementsByTagName("category");
+ } else {
+ NodeList defineCates = doc.getElementsByTagName("attributes");
+ Element firstCate = (Element) defineCates.item(0);
+ catgs = firstCate.getElementsByTagName("attribute");
+ }
+ int cateLen = catgs.getLength();
+ Element definedElement = null;
+ for (int n = 0; n < cateLen; n++) {
+ String cateName = ((Element) catgs.item(n)).getAttribute("name");
+ if (refName.equals(cateName) && !"".equals(refName)) {
+ definedElement = (Element) catgs.item(n);
+ break;
+ }
+ }
+ if (isCategory) {
+ _definedCategoryMap.put(refName, definedElement);
+ } else {
+ _definedAttributeMap.put(refName, definedElement);
+ }
+ return definedElement;
+ }
+
+ private AttributeDescriptor parseAttribute(String categoryName,
+ Element attribute) {
+ AttributeDescriptor attrDesc = new AttributeDescriptor();
+ attrDesc.setCategory(categoryName);
+
+ attrDesc.setAttributeName(attribute.getAttribute("name"));
+ attrDesc.setDescription(attribute.getAttribute("description"));
+ attrDesc.setValueType(attribute.getAttribute("type"));
+ attrDesc.setRequired(attribute.hasAttribute("required"));
+ attrDesc.setTypeParameter(attribute.getAttribute("typeparam"));
+ String labelKey = attribute.getAttribute("displaylabel");
+ attrDesc.setLabelString(getValue(labelKey));
+
+ NodeList optionNodes = attribute.getElementsByTagName("option");
+ if (optionNodes != null && optionNodes.getLength() != 0) {
+ HashMap optionMap = new HashMap();
+ int opLength = optionNodes.getLength();
+ String defaultValue = null;
+ for (int m = 0; m < opLength; m++) {
+ Element optNode = (Element) optionNodes.item(m);
+ String key = optNode.getAttribute("key");
+ String value = optNode.getAttribute("value");
+ if (value == null || value.length() == 0) {
+ value = key;
+ }
+ if (optNode.hasAttribute("default")) {
+ defaultValue = value;
+ }
+ optionMap.put(key, value);
+ }
+ attrDesc.setOptions(optionMap, defaultValue);
+ }
+
+ return attrDesc;
+ }
+
+ private String getValue(String key) {
+ if (key != null && key.startsWith("%")) {
+ String cmStr = this._url.toString();
+ String propBaseStr = cmStr.substring(0, cmStr.lastIndexOf("."));
+
+ String[] localeOptions = LocaleFallback.fallBack(Locale
+ .getDefault());
+ String[] options = localeOptions;
+ if (_optimizedLocales != null) {
+ options = _optimizedLocales;
+ }
+ for (int i = 0, size = options.length; i < size; i++) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(propBaseStr);
+ sb.append(options[i]);
+ sb.append(".properties");
+ String str = sb.toString();
+
+ ResourceBundle rb = null;
+ try {
+ URL propUrl = new URL(str);
+ rb = new PropertyResourceBundle(propUrl.openStream());
+ } catch (Exception e1) {
+ // we don't handle the exception here,since it is in a
+ // fallback route,it is possible of not exist
+ // _log.info("Info.ElementDescReader.ReadPropertyFile",
+ // str);
+ continue;
+ }
+ if (_optimizedLocales == null) {
+ setOptimizedLocales(localeOptions, i);
+ }
+
+ String rbKey = key.substring(1);
+ String value = null;
+ try {
+ value = rb.getString(rbKey);
+ } catch (Exception e) {
+ _log.info("Info.ElementDescReader.ReadPropertyFile.Key",
+ rbKey, str, null);
+ continue;
+ }
+
+ if (value != null) {
+ return value;
+ }
+
+ }
+ return null;
+ }
+ return key;
+ }
+
+ private void setOptimizedLocales(String[] originalLocales, int startPoint) {
+ int size = originalLocales.length - startPoint;
+ _optimizedLocales = new String[size];
+ for (int i = 0; i < size; i++) {
+ _optimizedLocales[i] = originalLocales[i + startPoint];
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescriptor.java
new file mode 100644
index 000000000..8a87c0099
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/ElementDescriptor.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IElementDescriptor;
+
+/**
+ * @author mengbo
+ */
+public class ElementDescriptor implements IElementDescriptor {
+ String _tagName;
+
+ String _namespaceURI;
+
+ IAttributeDescriptor[] _attrs;
+
+ private String _helpContextID;
+
+ /**
+ *
+ */
+ public ElementDescriptor() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IElementDescriptor#getTagName()
+ */
+ public String getTagName() {
+ return _tagName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IElementDescriptor#getNamespaceURI()
+ */
+ public String getNamespaceURI() {
+ return _namespaceURI;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IElementDescriptor#getAttributeDescriptors()
+ */
+ public IAttributeDescriptor[] getAttributeDescriptors() {
+ return _attrs;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.cm.IElementDescriptor#getReference()
+ */
+ public IElementDescriptor getReference() {
+ return null;
+ }
+
+ public void setNamespaceURI(String namespaceURI) {
+ this._namespaceURI = namespaceURI;
+ }
+
+ public void setTagName(String tagName) {
+ this._tagName = tagName;
+ }
+
+ public void setAttributeDescriptors(List attrs) {
+ if (attrs == null || attrs.isEmpty()) {
+ _attrs = new IAttributeDescriptor[0];
+ } else {
+ _attrs = new IAttributeDescriptor[attrs.size()];
+ attrs.toArray(_attrs);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IElementDescriptor#getAttributeDescriptor(java.lang.String)
+ */
+ public IAttributeDescriptor getAttributeDescriptor(String attributeName) {
+ if (_attrs != null) {
+ for (int i = 0; i < _attrs.length; i++) {
+ IAttributeDescriptor descriptor = _attrs[i];
+ if (descriptor.getAttributeName().equalsIgnoreCase(
+ attributeName)) {
+ return descriptor;
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IElementDescriptor#getHelpContextID()
+ */
+ public String getHelpContextID() {
+ return _helpContextID;
+ }
+
+ public void setHelpContextID(String contextid) {
+ _helpContextID = contextid;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/LocaleFallback.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/LocaleFallback.java
new file mode 100644
index 000000000..96cd87a3b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/LocaleFallback.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class LocaleFallback {
+ private static Map map = new HashMap();
+
+ public static synchronized String[] fallBack(Locale locale) {
+ if (map.get(locale) != null) {
+ return (String[]) map.get(locale);
+ }
+ // first compute the fallback locales according to the input locale
+ List inputLocaleList = calculateLocaleNames(locale);
+ String[] ins = reverseList(inputLocaleList);
+ // then compute the fallback locales accroding to the system default
+ // locale
+ int defsSize = 0;
+ String[] defs = null;
+ if (!locale.equals(Locale.getDefault())) {
+ List defLocaleList = calculateLocaleNames(Locale.getDefault());
+ defs = reverseList(defLocaleList);
+ defsSize = defs.length;
+ }
+
+ int insSize = ins.length;
+ int size = insSize + defsSize;
+
+ String[] options = new String[size + 1];
+ for (int i = 0; i < size; i++) {
+ if (i < insSize) {
+ options[i] = ins[i];
+ } else {
+ options[i] = defs[i - insSize];
+ }
+ }
+ // last add blank string in order to search the base file
+ options[size] = "";
+ map.put(locale, options);
+
+ return options;
+
+ }
+
+ private static List calculateLocaleNames(Locale locale) {
+ List list = new ArrayList();
+ StringBuffer item;
+
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+
+ int languageLength = language.length();
+ int countryLength = country.length();
+ int variantLength = variant.length();
+
+ if (languageLength == 0 && countryLength == 0 && variantLength == 0) {
+ // The locale is "", "", "".
+ return list;
+ } else {
+ item = new StringBuffer();
+ item = item.append('_').append(language);
+ list.add(item.toString());
+ }
+
+ if (countryLength == 0 && variantLength == 0) {
+ return list;
+ } else {
+ item.append('_').append(country);
+ list.add(item.toString());
+ }
+
+ if (variantLength == 0) {
+ return list;
+ } else {
+ item.append('_').append(variantLength);
+ list.add(item.toString());
+ }
+
+ return list;
+ }
+
+ private static String[] reverseList(List list) {
+ int size = list.size();
+ String[] vals = new String[size];
+ for (int i = 0; i < size; i++) {
+ vals[i] = (String) list.get(size - 1 - i);
+ }
+ return vals;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/SimpleCMRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/SimpleCMRegistry.java
new file mode 100644
index 000000000..6c198f4f1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/meta/internal/SimpleCMRegistry.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.meta.internal;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.jst.pagedesigner.meta.ICMRegistry;
+import org.eclipse.jst.pagedesigner.meta.IElementDescriptor;
+import org.xml.sax.SAXException;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class SimpleCMRegistry implements ICMRegistry {
+ String _uri;
+
+ Map _map = new HashMap();
+
+ /**
+ * @throws IOException
+ * @throws SAXException
+ * @throws FactoryConfigurationError
+ * @throws ParserConfigurationException
+ *
+ */
+ public SimpleCMRegistry(String uri, URL cmFileUrl)
+ throws ParserConfigurationException, FactoryConfigurationError,
+ SAXException, IOException {
+ this._uri = uri;
+ ElementDescReader reader = new ElementDescReader(cmFileUrl);
+ reader.readElements(_map);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.ICMRegistry#getSupportedURI()
+ */
+ public String getSupportedURI() {
+ return _uri;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.ICMRegistry#getElementDescriptor(java.lang.String,
+ * java.lang.String)
+ */
+ public IElementDescriptor getElementDescriptor(String uri, String tagname) {
+ if (uri.equals(_uri)) {
+ return (IElementDescriptor) _map.get(tagname);
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/CSSStyleAdapterFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/CSSStyleAdapterFactory.java
new file mode 100644
index 000000000..d0734e48f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/CSSStyleAdapterFactory.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.style.AbstractStyle;
+import org.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CSSStyleAdapterFactory extends AbstractAdapterFactory {
+ static Class ADAPTERKEY = ICSSStyle.class;
+
+ private static CSSStyleAdapterFactory _instance = new CSSStyleAdapterFactory();
+
+ private CSSStyleAdapterFactory() {
+ super(ADAPTERKEY, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @seeorg.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory#createAdapter(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier)
+ */
+ protected INodeAdapter createAdapter(INodeNotifier target) {
+ if (target instanceof Element) {
+ return new AbstractStyle((Element) target);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return
+ */
+ public static CSSStyleAdapterFactory getInstance() {
+ return _instance = new CSSStyleAdapterFactory();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/DocumentEditPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/DocumentEditPart.java
new file mode 100644
index 000000000..691825c22
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/DocumentEditPart.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowPage;
+import org.eclipse.wst.css.core.internal.event.ICSSStyleListener;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSSelector;
+import org.eclipse.wst.html.core.internal.htmlcss.StyleListener;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ */
+public class DocumentEditPart extends NodeEditPart implements StyleListener,
+ ICSSStyleListener {
+ boolean _refreshing = false;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
+ */
+ protected List getModelChildren() {
+ List list = new ArrayList();
+ Node model = (Node) getModel();
+ if (model == null) {
+ return list;
+ }
+
+ NodeList children = model.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node node = children.item(i);
+ if (node.getNodeType() != Node.TEXT_NODE
+ && node.getNodeType() != Node.ELEMENT_NODE) {
+ continue;
+ }
+ list.add(node);
+ }
+ return list;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
+ */
+ protected IFigure createFigure() {
+ FlowPage f = new FlowPage();
+ return f;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ refresh();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#refresh()
+ */
+ public void refresh() {
+ if (_refreshing) {
+ return;
+ }
+ _refreshing = true;
+ try {
+ super.refresh();
+ } finally {
+ _refreshing = false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractEditPart#refreshChildren()
+ */
+ protected void refreshChildren() {
+ super.refreshChildren();
+ List children = getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ ((EditPart) children.get(i)).refresh();
+ }
+ }
+
+ // protected void removeChildVisual(EditPart childEditPart)
+ // {
+ // if (childEditPart instanceof SubNodeEditPart)
+ // {
+ // Node node = ((SubNodeEditPart) childEditPart).getNodeForFigure();
+ // if (node != null)
+ // {
+ // getDestDocumentForDesign().removeChild(node);
+ // }
+ // }
+ // super.removeChildVisual(childEditPart);
+ // }
+ //
+ // protected void addChildVisual(EditPart childEditPart, int index)
+ // {
+ // if (childEditPart instanceof SubNodeEditPart)
+ // {
+ // Node node = ((SubNodeEditPart) childEditPart).getNodeForFigure();
+ // if (node != null)
+ // {
+ // NodeList nodeList = getDestDocumentForDesign().getChildNodes();
+ // if (nodeList.getLength() > index)
+ // {
+ // getDestDocumentForDesign().insertBefore(node, nodeList.item(index));
+ // }
+ // else
+ // {
+ // getDestDocumentForDesign().appendChild(node);
+ // }
+ // }
+ // }
+ // super.addChildVisual(childEditPart, index);
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.html.core.internal.htmlcss.StyleListener#styleChanged()
+ */
+ public void styleChanged() {
+ // refresh the whole document when style change (<style> or <link>)
+ this.refreshStyle();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.css.core.internal.event.ICSSStyleListener#styleChanged(org.eclipse.wst.css.core.internal.provisional.document.ICSSModel,
+ * org.eclipse.wst.css.core.document.ICSSSelector[],
+ * org.eclipse.wst.css.core.document.ICSSSelector[], java.lang.String)
+ */
+ public void styleChanged(ICSSModel srcModel, ICSSSelector[] removed,
+ ICSSSelector[] added, String media) {
+ if ((removed != null && removed.length > 0) || added != null
+ && added.length > 0) {
+ this.refreshStyle();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.css.core.internal.event.ICSSStyleListener#styleUpdate(org.eclipse.wst.css.core.internal.provisional.document.ICSSModel)
+ */
+ public void styleUpdate(ICSSModel srcModel) {
+ this.refreshStyle();
+ }
+
+ /**
+ *
+ */
+ private void refreshStyle() {
+ List childParts = this.getChildren();
+ for (Iterator iter = childParts.iterator(); iter.hasNext();) {
+ EditPart part = (EditPart) iter.next();
+ if (part instanceof ElementEditPart) {
+ IDOMNode node = (IDOMNode) ((ElementEditPart) part)
+ .getNodeForFigure();
+ if (node != null) {
+ refreshChildStyles(node);
+ }
+ }
+ }
+ getFigure().revalidate();
+ // getFigure().repaint();
+ }
+
+ /**
+ * @param node
+ */
+ private void refreshChildStyles(IDOMNode node) {
+ NodeList childNodes = node.getChildNodes();
+ for (int i = 0, size = childNodes.getLength(); i < size; i++) {
+ refreshChildStyles((IDOMNode) childNodes.item(i));
+ }
+ if (node instanceof IDOMElement) {
+ // only refresh style on element.
+ ICSSStyle a = (ICSSStyle) node.getAdapterFor(ICSSStyle.class);
+ if (a != null) {
+ a.reset();
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/EditProxyAdapter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/EditProxyAdapter.java
new file mode 100644
index 000000000..55381c611
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/EditProxyAdapter.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.jst.pagedesigner.css2.style.IRangeSelectionProxy;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+
+/**
+ * EditProxyAdapter is used to provide additional information to the underlying
+ * figures. As when we doing the "convert", we are creating new nodes and
+ * generate figure using those new nodes. This class is used to adapt to those
+ * new nodes, and providing additional information to them.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class EditProxyAdapter implements INodeAdapter, IRangeSelectionProxy {
+ ElementEditPart _part;
+
+ /**
+ *
+ */
+ public EditProxyAdapter(ElementEditPart part) {
+ _part = part;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ if (type == IRangeSelectionProxy.class) {
+ return true;
+ } else if (type == EditProxyAdapter.class) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.style.IRangeSelectionProxy#isRangeSelected()
+ */
+ public boolean isRangeSelected() {
+ return _part.isRangeSelected();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/ElementEditPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/ElementEditPart.java
new file mode 100644
index 000000000..73cf55446
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/ElementEditPart.java
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.tools.DragEditPartsTracker;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
+import org.eclipse.jst.pagedesigner.converter.ConverterFactoryRegistry;
+import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
+import org.eclipse.jst.pagedesigner.converter.ITagConverter;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSWidgetLayout;
+import org.eclipse.jst.pagedesigner.css2.style.AbstractStyle;
+import org.eclipse.jst.pagedesigner.css2.widget.HiddenProvider;
+import org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy;
+import org.eclipse.jst.pagedesigner.elementedit.ElementEditFactoryRegistry;
+import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
+import org.eclipse.jst.pagedesigner.figurehandler.FigureFactory;
+import org.eclipse.jst.pagedesigner.figurehandler.IFigureHandler;
+import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.tools.ObjectModeDragTracker;
+import org.eclipse.jst.pagedesigner.tools.RangeDragTracker;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ElementEditPart extends SubNodeEditPart {
+ private static Logger _log = PDPlugin.getLogger(ElementEditPart.class);
+
+ private Element _elementNode;
+
+ private ITagConverter _tagConverter;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.EditPart#setModel(java.lang.Object)
+ */
+ public void setModel(Object model) {
+ super.setModel(model);
+ _elementNode = (Element) model;
+ _tagConverter = getTagConverter(_elementNode);
+ _tagConverter.convertRefresh(null);
+ adaptEditProxy();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#getDragTracker(org.eclipse.gef.Request)
+ */
+ public DragTracker getDragTracker(Request request) {
+ EditPolicy policy = this
+ .getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);
+ if (policy instanceof ElementResizableEditPolicy) {
+ if (((ElementResizableEditPolicy) policy)
+ .shouldUseObjectMode(request)) {
+ return new ObjectModeDragTracker(this);
+ } else {
+ return new RangeDragTracker(this);
+ }
+ } else {
+ // should not happen
+ return new DragEditPartsTracker(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#createEditPolicies()
+ */
+ protected void createEditPolicies() {
+ super.createEditPolicies();
+ IElementEdit support = getElementEdit();
+ if (support != null) {
+ support.createEditPolicies(this);
+ }
+
+ // if ElementEdit didn't install special SELECTION_FEEDBACK_ROLE policy,
+ // then default
+ if (this.getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE) == null) {
+ this.installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE,
+ new ElementResizableEditPolicy());
+ }
+ }
+
+ /**
+ * @param node
+ * @return
+ */
+ public IElementEdit getElementEdit() {
+ // XXX: should we cache it?
+ return ElementEditFactoryRegistry.getInstance().createElementEdit(
+ _elementNode);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#addNotify()
+ */
+ public void addNotify() {
+ if (_tagConverter == null) {
+ _tagConverter = getTagConverter(_elementNode);
+ _tagConverter.convertRefresh(null);
+ adaptEditProxy();
+ }
+ super.addNotify();
+ }
+
+ /**
+ * @param node
+ * @return
+ */
+ private ITagConverter getTagConverter(Element node) {
+ return ConverterFactoryRegistry.getInstance().createTagConverter(node,
+ IConverterFactory.MODE_DESIGNER,
+ this.getDestDocumentForDesign());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeNotify()
+ */
+ public void removeNotify() {
+ super.removeNotify();
+ // if (_tagConverter != null)
+ // {
+ // _tagConverter.dispose();
+ // _tagConverter = null;
+ // }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
+ */
+ protected List getModelChildren() {
+ return _tagConverter.getChildModeList();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
+ */
+ protected IFigure createFigure() {
+ // if (_tagConverter.isVisualByHTML())
+ // {
+ // Element result = _tagConverter.getResultElement();
+ // return FigureFactory.createFigure(result,
+ // true);//_tagConverter.isMultiLevel());
+ // }
+ // else
+ // {
+ // CSSWidgetFigure figure = new CSSWidgetFigure(this._elementNode,
+ // createHiddenProvider());
+ // return figure;
+ // }
+ return new CSSFigure();
+ }
+
+ /**
+ * @return
+ */
+ private HiddenProvider createHiddenProvider() {
+ Element result = _tagConverter.getHostElement();
+ String localName = result.getLocalName();
+ String appendString = localName;
+ if (localName.equalsIgnoreCase(IJSPCoreConstants.TAG_DIRECTIVE_TAGLIB)) {
+ appendString = ((IDOMElement) result)
+ .getAttribute(IJSPCoreConstants.ATTR_URI);
+ if (appendString == null) {
+ appendString = "";
+ }
+ }
+ Image image = _tagConverter.getVisualImage();
+ HiddenProvider provider = new HiddenProvider(image, this);
+ ((CSSFigure) getFigure()).setCSSStyle(provider.getCSSStyle());
+ provider.setLabel(appendString);
+ return provider;
+ }
+
+ /**
+ * called by the
+ *
+ */
+ public void refreshModelChange(boolean recursive) {
+ IElementEdit support = getElementEdit();
+ if (support == null
+ || !support.handleModelChange(_elementNode, this, recursive)) {
+ this.refresh(recursive);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#refresh()
+ */
+ public void refresh() {
+ refresh(false);
+ }
+
+ public void refresh(boolean recursive) {
+ if (!_tagConverter.isVisualByHTML()) {
+ _tagConverter.convertRefresh(null);
+ ((CSSFigure) getFigure())
+ .setFixedLayoutManager(new CSSWidgetLayout(
+ (CSSFigure) getFigure(), createHiddenProvider()));
+ // nothing to refresh
+ // ((CSSWidgetFigure)
+ // getFigure()).setProvider(createHiddenProvider());
+ return;
+ }
+ EditPart editPart;
+ Object model;
+
+ Map modelToEditPart = new HashMap();
+ List children = getChildren();
+
+ for (int i = 0, n = children.size(); i < n; i++) {
+ editPart = (EditPart) children.get(i);
+ modelToEditPart.put(editPart.getModel(), editPart);
+ // remove child visual, since we may reconstruct the figure
+ // structure of this edit part
+ removeChildVisual(editPart);
+ }
+
+ Element oldEle = _tagConverter.getResultElement();
+
+ // link parent node.
+ Node parent = oldEle.getParentNode();
+ _tagConverter.convertRefresh(null);
+ if (parent != null) {
+ // a new element is generated. replace the old one.
+ parent.replaceChild(_tagConverter.getResultElement(), oldEle);
+ }
+
+ adaptEditProxy();
+
+ // XXX: comment out the if-else for always deep update.
+ // this is for the case when a empty container generate child
+ // text node, and then when user input data into the container,
+ // the node change from "multiLevel" state to "non-multilevel"
+ // state. We don't handle this very well yet, so always to deep
+ // update for now. (lium)
+ // if (_tagConverter.isMultiLevel())
+ // {
+ FigureFactory.updateDeepFigure(_tagConverter.getResultElement(),
+ oldEle, (CSSFigure) this.getFigure());
+ // }
+ // else
+ // {
+ // FigureFactory.updateNonDeepFigure(_tagConverter.getResultElement(),
+ // this.getFigure());
+ // }
+
+ List modelObjects = getModelChildren();
+ if (!recursive) {
+ for (int i = 0, n = modelObjects.size(); i < n; i++) {
+ model = modelObjects.get(i);
+
+ // Look to see if the EditPart is already around but in the
+ // wrong location
+ editPart = (EditPart) modelToEditPart.remove(model);
+
+ if (editPart != null) {
+ addChildVisual(editPart, i);
+ } else {
+ // An editpart for this model doesn't exist yet. Create and
+ // insert one.
+ editPart = createChild(model);
+ addChild(editPart, i);
+ }
+ }
+ for (Iterator iter = modelToEditPart.values().iterator(); iter
+ .hasNext();) {
+ EditPart part = (EditPart) iter.next();
+ removeChild(part);
+ }
+ } else {
+ // remove all child, and recreate them.
+ for (Iterator iter = modelToEditPart.values().iterator(); iter
+ .hasNext();) {
+ EditPart part = (EditPart) iter.next();
+ removeChild(part);
+ }
+ for (int i = 0, n = modelObjects.size(); i < n; i++) {
+ model = modelObjects.get(i);
+
+ // Look to see if the EditPart is already around but in the
+ // wrong location
+ // An editpart for this model doesn't exist yet. Create and
+ // insert one.
+ editPart = createChild(model);
+ addChild(editPart, i);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private void adaptEditProxy() {
+ Element resultEle = _tagConverter.getResultElement();
+ if (resultEle instanceof IDOMElement) {
+ INodeAdapter adapter = ((IDOMElement) resultEle)
+ .getAdapterFor(EditProxyAdapter.class);
+ if (adapter != null) {
+ ((IDOMElement) resultEle).removeAdapter(adapter);
+ }
+ ((IDOMElement) resultEle).addAdapter(new EditProxyAdapter(this));
+ }
+ }
+
+ /**
+ * @return
+ */
+ public boolean isRangeSelected() {
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) this.getViewer();
+ if (viewer == null || !viewer.isInRangeMode()) {
+ return false;
+ }
+ DesignRange range = viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ return false;
+ }
+ return RangeUtil.intersect(range, this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#isWidget()
+ */
+ public boolean isWidget() {
+ return _tagConverter.isWidget();
+ }
+
+ /**
+ * @return
+ */
+ public boolean canHaveDirectTextChild() {
+ return CMUtil.canHaveDirectTextChild(this._elementNode);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#isResizable()
+ */
+ public boolean isResizable() {
+ if (!_tagConverter.isVisualByHTML()) {
+ return false;
+ }
+ IElementEdit edit = this.getElementEdit();
+ if (edit != null) {
+ return edit.isResizable(this._elementNode);
+ } else {
+ CMElementDeclaration decl = CMUtil
+ .getElementDeclaration(this._elementNode);
+ if (decl != null) {
+ // XXX: default implementation, if this element support "style"
+ // attribute,
+ // then we think it support resize.
+ return decl.getAttributes().getNamedItem("style") != null;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * @param parent
+ * @return
+ */
+ private IFigure getFigure(Node parent) {
+ if (parent instanceof INodeNotifier) {
+ IFigureHandler handler = (IFigureHandler) ((INodeNotifier) parent)
+ .getAdapterFor(IFigureHandler.class);
+ if (handler != null) {
+ return handler.getFigure();
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#addChildVisual(org.eclipse.gef.EditPart,
+ * int)
+ */
+ protected void addChildVisual(EditPart childEditPart, int index) {
+ boolean figureAdded = false;
+ Node childNode = (Node) childEditPart.getModel();
+ IFigure childFigure = ((GraphicalEditPart) childEditPart).getFigure();
+ ConvertPosition position = _tagConverter
+ .getChildVisualPosition(childNode);
+ if (position != null) {
+ Node parent = position.getParentNode();
+ // link up figure.
+ IFigure parentFigure = getFigure(parent);
+ if (parentFigure != null) {
+ parentFigure.add(childFigure, position.getIndex());
+ figureAdded = true;
+ }
+ // link up style
+ if (parent instanceof INodeNotifier) {
+ ICSSStyle parentStyle = (ICSSStyle) ((INodeNotifier) parent)
+ .getAdapterFor(ICSSStyle.class);
+ if (parentStyle != null) {
+ ICSSStyle childStyle = (ICSSStyle) ((INodeNotifier) childNode)
+ .getAdapterFor(ICSSStyle.class);
+ if (childStyle instanceof AbstractStyle) {
+ ((AbstractStyle) childStyle)
+ .setParentStyle(parentStyle);
+ }
+ }
+ }
+ // link up the nodeForFigure
+ if (childEditPart instanceof SubNodeEditPart) {
+ Node nodeForFigure = ((SubNodeEditPart) childEditPart)
+ .getNodeForFigure();
+ if (nodeForFigure != null /*
+ * && !(nodeForFigure instanceof
+ * PseudoElement)
+ */) {
+ parent.appendChild(nodeForFigure);
+ }
+ }
+ } else {
+ _log.error("getChildVisualPosition() return null");
+ }
+
+ if (!figureAdded) {
+ super.addChildVisual(childEditPart, index);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeChildVisual(org.eclipse.gef.EditPart)
+ */
+ protected void removeChildVisual(EditPart childEditPart) {
+ // remove figure
+ IFigure childFigure = ((GraphicalEditPart) childEditPart).getFigure();
+ IFigure parent = childFigure.getParent();
+ if (parent != null) {
+ parent.remove(childFigure);
+ }
+ // de-link style
+ Node childNode = (Node) childEditPart.getModel();
+ ICSSStyle childStyle = (ICSSStyle) ((INodeNotifier) childNode)
+ .getAdapterFor(ICSSStyle.class);
+ if (childStyle instanceof AbstractStyle) {
+ ((AbstractStyle) childStyle).setParentStyle(null);
+ }
+ // de-link nodeForFigure
+ if (childEditPart instanceof SubNodeEditPart) {
+ Node nodeForFigure = ((SubNodeEditPart) childEditPart)
+ .getNodeForFigure();
+ if (nodeForFigure != null && nodeForFigure.getParentNode() != null) {
+ nodeForFigure.getParentNode().removeChild(nodeForFigure);
+ }
+ }
+ }
+
+ /**
+ * @return
+ */
+ public ITagConverter getTagConvert() {
+ return _tagConverter;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ refresh();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.SubNodeEditPart#getNodeForFigure()
+ */
+ public Node getNodeForFigure() {
+ return _tagConverter.getResultElement();
+ }
+
+ /**
+ * @return
+ */
+ public boolean haveNonWhitespaceTextChild() {
+ List children = this.getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ if (children.get(i) instanceof TextEditPart) {
+ IDOMText xmltext = (IDOMText) ((TextEditPart) children.get(i))
+ .getIDOMNode();
+ if (!xmltext.isElementContentWhitespace()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/HTMLEditPartsFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/HTMLEditPartsFactory.java
new file mode 100644
index 000000000..e286d5ea1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/HTMLEditPartsFactory.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartFactory;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.w3c.dom.Node;
+
+/**
+ * The model here can only be Document/Element/Text.
+ *
+ * @author mengbo
+ */
+public class HTMLEditPartsFactory implements EditPartFactory {
+ private IDOMDocument _destDocument;
+
+ public HTMLEditPartsFactory(IDOMDocument destDoc) {
+ this._destDocument = destDoc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.EditPartFactory#createEditPart(org.eclipse.gef.EditPart,
+ * java.lang.Object)
+ */
+ public EditPart createEditPart(EditPart context, Object model) {
+ Node node = (Node) model;
+ NodeEditPart part = null;
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ part = new DocumentEditPart();
+ } else if (node.getNodeType() == Node.ELEMENT_NODE) {
+ // String tag = ((Element)node).getTagName();
+ // if ("TABLE".equalsIgnoreCase(tag))
+ // part = new HTMLTableEditPart();
+ // else
+ part = new ElementEditPart();
+ } else if (node.getNodeType() == Node.TEXT_NODE
+ || node.getNodeType() == Node.CDATA_SECTION_NODE) {
+ part = new TextEditPart();
+ }
+ if (part != null) {
+ part.setDestDocumentForDesign(this._destDocument);
+ part.setModel(model);
+ }
+ return part;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/NodeEditPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/NodeEditPart.java
new file mode 100644
index 000000000..8174eca69
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/NodeEditPart.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.RequestConstants;
+import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
+import org.eclipse.gef.requests.LocationRequest;
+import org.eclipse.jst.pagedesigner.dnd.LocalDropRequest;
+import org.eclipse.jst.pagedesigner.dnd.internal.LocalDropEditPolicy;
+import org.eclipse.jst.pagedesigner.editpolicies.DragMoveEditPolicy;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemCreationEditPolicy;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemCreationRequest;
+import org.eclipse.jst.pagedesigner.tools.RangeDragTracker;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @author mengbo
+ */
+public abstract class NodeEditPart extends AbstractGraphicalEditPart implements
+ INodeAdapter {
+
+ private IDOMDocument _destDocument;
+
+ /**
+ * this method is called from the HTMLEditPartsFactory directly after the
+ * part's creation.
+ *
+ * @param doc
+ */
+ public void setDestDocumentForDesign(IDOMDocument doc) {
+ this._destDocument = doc;
+ }
+
+ public IDOMDocument getDestDocumentForDesign() {
+ if (this._destDocument == null) {
+ return (IDOMDocument) this.getIDOMNode().getOwnerDocument();
+ } else {
+ return this._destDocument;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
+ */
+ protected void createEditPolicies() {
+ installEditPolicy(EditPolicy.NODE_ROLE, null);
+ installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, null);
+ installEditPolicy(LocalDropRequest.REQ_LOCAL_DROP,
+ new LocalDropEditPolicy());
+ installEditPolicy(ItemCreationRequest.REQ_ITEM_CREATION,
+ new ItemCreationEditPolicy());
+ installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE,
+ new DragMoveEditPolicy());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.sse.model.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ return type == EditPart.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#addNotify()
+ */
+ public void addNotify() {
+ Object obj = getModel();
+ if (obj instanceof INodeNotifier) {
+ ((INodeNotifier) obj).addAdapter(this);
+ }
+ super.addNotify();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeNotify()
+ */
+ public void removeNotify() {
+ super.removeNotify();
+ Object obj = getModel();
+ if (obj instanceof INodeNotifier) {
+ ((INodeNotifier) obj).removeAdapter(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.EditPart#deactivate()
+ */
+ public void deactivate() {
+ LocationRequest hoverRequest = new LocationRequest();
+ hoverRequest.setType(RequestConstants.REQ_SELECTION_HOVER);
+ this.eraseTargetFeedback(hoverRequest);
+ super.deactivate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class key) {
+ Object obj = getModel();
+ if (key == IPropertySource.class) {
+ if (obj instanceof INodeNotifier) {
+ return (IPropertySource) ((INodeNotifier) obj)
+ .getAdapterFor(IPropertySource.class);
+ }
+ }
+
+ if (obj instanceof IAdaptable) {
+ Object ret = ((IAdaptable) obj).getAdapter(key);
+ if (ret != null)
+ return ret;
+ }
+ return super.getAdapter(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getDragTracker(org.eclipse.gef.Request)
+ */
+ public DragTracker getDragTracker(Request request) {
+ return new RangeDragTracker(this);
+ }
+
+ /**
+ * @return
+ */
+ public IDOMNode getIDOMNode() {
+ return ((IDOMNode) getModel());
+ }
+
+ /**
+ * if a EditPart don't support caret inside it, and don't can't have child
+ * edit part, then we call it as a widget.
+ *
+ * @return
+ */
+ public boolean isWidget() {
+ return false; // child class must override.
+ }
+
+ /**
+ * whether this EditPart allow the selection range to have one edge in the
+ * edit part and one edge outside the edit part.
+ *
+ * @return
+ */
+ public boolean allowSelectionRangeAcross() {
+ return true;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isResizable() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/Refresher.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/Refresher.java
new file mode 100644
index 000000000..3f6f12087
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/Refresher.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class Refresher implements INodeAdapter {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#isAdapterForType(java.lang.Object)
+ */
+ public boolean isAdapterForType(Object type) {
+ return (type == Refresher.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ if (eventType == INodeNotifier.ADD || eventType == INodeNotifier.REMOVE) {
+ // for ADD and REMOVE, system will fire CHANGE event, so we ignore
+ // the ADD/REMOVE
+ // event here.
+ return;
+ }
+ if (notifier instanceof IDOMNode) {
+ IDOMNode node = (IDOMNode) notifier;
+ // we need to refresh all CSS style adapter of node and its
+ // children.
+ EditPart part = (EditPart) node.getAdapterFor(EditPart.class);
+ if (part instanceof SubNodeEditPart) {
+ Node nodeForFigure = ((SubNodeEditPart) part)
+ .getNodeForFigure();
+ if (nodeForFigure instanceof IDOMNode) {
+ refreshChildStyles((IDOMNode) nodeForFigure);
+ }
+ }
+
+ // we need also find the nearest parent node that has editpart, and
+ // refresh it.
+ refreshContainingPart(node,
+ eventType == INodeNotifier.STRUCTURE_CHANGED);
+
+ part = (EditPart) node.getAdapterFor(EditPart.class);
+ if (part != null) {
+ ((HTMLGraphicalViewer) part.getViewer()).clearSelectionRange();
+ }
+ }
+ }
+
+ /**
+ * @param node
+ */
+ private void refreshContainingPart(IDOMNode node, boolean recursive) {
+ if (node.getOwnerDocument() == node) {
+ EditPart part = (EditPart) node.getAdapterFor(EditPart.class);
+ if (part != null) {
+ part.refresh();
+ }
+ } else {
+ while (node != null) {
+ EditPart part = (EditPart) node.getAdapterFor(EditPart.class);
+ if (part != null) {
+ if (part instanceof ElementEditPart) {
+ ((ElementEditPart) part).refreshModelChange(recursive);
+ } else {
+ part.refresh();
+ }
+ return;
+ }
+ node = (IDOMNode) node.getParentNode();
+ }
+ }
+ }
+
+ /**
+ * @param node
+ */
+ private void refreshChildStyles(IDOMNode node) {
+ NodeList childNodes = node.getChildNodes();
+ for (int i = 0, size = childNodes.getLength(); i < size; i++) {
+ refreshChildStyles((IDOMNode) childNodes.item(i));
+ }
+ if (node instanceof IDOMElement) {
+ // only refresh style on element.
+ ICSSStyle a = (ICSSStyle) node.getAdapterFor(ICSSStyle.class);
+ if (a != null) {
+ a.reset();
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/RefresherFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/RefresherFactory.java
new file mode 100644
index 000000000..04aa76e20
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/RefresherFactory.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RefresherFactory extends AbstractAdapterFactory {
+ Refresher refresher = new Refresher();
+
+ RefresherFactory() {
+ super(Refresher.class, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @seeorg.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory#createAdapter(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier)
+ */
+ protected INodeAdapter createAdapter(INodeNotifier target) {
+ return refresher;
+ }
+
+ static RefresherFactory _instance = new RefresherFactory();
+
+ public static RefresherFactory getInstance() {
+ return _instance;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/SubNodeEditPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/SubNodeEditPart.java
new file mode 100644
index 000000000..8056dd9d7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/SubNodeEditPart.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class SubNodeEditPart extends NodeEditPart {
+ /**
+ *
+ * @return could be null
+ */
+ public abstract Node getNodeForFigure();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/TextEditPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/TextEditPart.java
new file mode 100644
index 000000000..84eba10fa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/parts/TextEditPart.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.parts;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSTextFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider;
+import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
+import org.eclipse.jst.pagedesigner.editpolicies.LinkEditPolicy;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class TextEditPart extends SubNodeEditPart implements ICSSTextProvider {
+ private String _cachedData;
+
+ private Text _textNode;
+
+ private Text _textNodeForFigure;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.EditPart#setModel(java.lang.Object)
+ */
+ public void setModel(Object model) {
+ super.setModel(model);
+ _textNode = (Text) model;
+ _cachedData = _textNode.getData();
+ _textNodeForFigure = getDestDocumentForDesign().createTextNode(
+ _cachedData);
+ }
+
+ protected IFigure createFigure() {
+ // XXX: currently creating of CSSTextFigure is distributed both here
+ // and FigureFactory. We may want to unify them later.
+ CSSTextFigure figure = new CSSTextFigure(this);
+ return figure;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
+ */
+ protected void createEditPolicies() {
+ super.createEditPolicies();
+ this.installEditPolicy("link editpolicy", new LinkEditPolicy());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.SubNodeEditPart#getNodeForFigure()
+ */
+ public Node getNodeForFigure() {
+ return _textNodeForFigure;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ibm.sse.model.INodeAdapter#notifyChanged(com.ibm.sse.model.INodeNotifier,
+ * int, java.lang.Object, java.lang.Object, java.lang.Object, int)
+ */
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ _cachedData = _textNode.getData();
+ _textNodeForFigure.setData(_cachedData);
+ if (eventType == INodeNotifier.CHANGE) {
+ getFigure().revalidate();
+ } else {
+ // XXX: been removed? parent EditPart should have handled it.
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.css2.provider.ICSSTextProvider#getCSSStyle()
+ */
+ public ICSSStyle getCSSStyle() {
+ IFigure figure = this.getFigure();
+ if (figure instanceof ICSSFigure) {
+ ICSSStyle style = ((ICSSFigure) figure).getCSSStyle();
+ if (style != null) {
+ return style;
+ }
+ }
+ return DefaultStyle.getInstance();
+ }
+
+ /**
+ * As when text are displayed in HTML, they are "normalized". For example,
+ * leading whitespace may be removed dure to previous node as trailing
+ * whitespace. Entity reference may have be resolved. Sequence whitespace
+ * been merged.
+ *
+ * It is also possible that the text node is in "PRE" mode, in that case the
+ * above things are not done.
+ *
+ * This method return the really value that is going to be presented to
+ * user. EditPartPosition's offset is referencing this value.
+ *
+ * @return
+ * @see org.eclipse.jst.pagedesigner.viewer.DesignPosition
+ */
+ public String getTextData() {
+ ICSSStyle style = getCSSStyle();
+ String data = _cachedData;
+ if (style.getStyleProperty(ICSSPropertyID.ATTR_WHITESPACE) != ICSSPropertyID.VAL_PRE) {
+ return HTMLUtil.compactWhitespaces(_textNode, data);
+ } else {
+ return data;
+ }
+ }
+
+ /**
+ * check what part of this text node is in the range selection.
+ *
+ * @return
+ */
+ public int[] getSelectedRange() {
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) this.getViewer();
+ if (viewer == null || !viewer.isInRangeMode()) {
+ return null;
+ }
+ DesignRange range = viewer.getRangeSelection();
+ if (range == null || !range.isValid()) {
+ return null;
+ }
+ if (!RangeUtil.intersect(range, this)) {
+ return null;
+ }
+ // ok, we intersect with the range.
+ range = RangeUtil.normalize(range);
+ EditPart startContainer = range.getStartPosition().getContainerPart();
+ EditPart endContainer = range.getEndPosition().getContainerPart();
+ int[] ret = new int[2];
+ if (startContainer != this) {
+ ret[0] = 0;
+ } else {
+ ret[0] = range.getStartPosition().getOffset();
+ }
+ if (endContainer != this) {
+ ret[1] = this.getTextData().length();
+ } else {
+ {
+ ret[1] = range.getEndPosition().getOffset();
+ }
+ }
+ return ret;
+ }
+
+ public boolean isSelectable() {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PageExpressionContext.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PageExpressionContext.java
new file mode 100644
index 000000000..220b72f7e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PageExpressionContext.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.preview;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.FunctionMapper;
+import javax.servlet.jsp.el.VariableResolver;
+
+import org.apache.commons.el.ExpressionEvaluatorImpl;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.jsp.core.el.JSFELParserHelper;
+import org.eclipse.jst.pagedesigner.jsp.core.el.LoadBundleUtil;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.IPageVariablesProvider;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.IVariableInfo;
+
+/**
+ * This is a static class. But it has "session" concept in it. To make it static
+ * is only to simplify its use.
+ *
+ * This class currently is only used by TagConverter, when calculating the
+ * displayed string for resource bundle items.
+ *
+ * XXX: in the future, if we want to this to be non-static, we may incorportate
+ * it into the context of the tag converter.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+// TODO: we may consider support cache the properties.
+public class PageExpressionContext {
+ private static final Logger _log = PDPlugin
+ .getLogger(PageExpressionContext.class);
+
+ static PageExpressionContext _current;
+
+ List _pageVarProviders = new ArrayList();
+
+ VariableResolver resolver = new SimpleVariableResolver();
+
+ private IProject _prj;
+
+ /**
+ * @param prj
+ */
+ public PageExpressionContext(IProject prj) {
+ _prj = prj;
+ }
+
+ public static void reset() {
+ _current = null;
+ }
+
+ public static void initialize(IProject prj) {
+ _current = new PageExpressionContext(prj);
+ }
+
+ public static PageExpressionContext getCurrent() {
+ return _current;
+ }
+
+ public void pushPageVarProvider(IPageVariablesProvider provider) {
+ _pageVarProviders.add(provider);
+ }
+
+ public void popPageVarProvider(IPageVariablesProvider provider) {
+ try {
+ _pageVarProviders.remove(_pageVarProviders.size() - 1);
+ } catch (Exception ex) {
+ // "Error"
+ _log.info("PageExpressionContext.Info.0", ex); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * this method is for design time expression evaluation. Currently it only
+ * handles
+ *
+ * @param expression
+ * @param pageVars
+ * @param jspFile
+ * @param options
+ * XXX: not used today. In the future, we may support things like
+ * locale in options
+ * @return
+ */
+ public Object evaluateExpression(String expression, Class expectedClass,
+ Map options) throws ELException {
+ expression = JSFELParserHelper.toJspElExpression(expression);
+ ExpressionEvaluatorImpl evaluator = new ExpressionEvaluatorImpl();
+ FunctionMapper mapper = new EmptyFunctionMapper();
+
+ return evaluator.evaluate(expression, expectedClass, resolver, mapper);
+ }
+
+ class SimpleVariableResolver implements VariableResolver {
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.jsp.el.VariableResolver#resolveVariable(java.lang.String)
+ */
+ public Object resolveVariable(String varName) throws ELException {
+ // reverse order.
+ for (int k = _pageVarProviders.size() - 1; k >= 0; k--) {
+ IPageVariablesProvider _pageVars = (IPageVariablesProvider) _pageVarProviders
+ .get(k);
+ if (_pageVars != null) {
+ IVariableInfo[] vars = _pageVars.getBeanInfos();
+ if (vars != null) {
+ for (int i = 0; i < vars.length; i++) {
+ if (varName.equals(vars[i].getName())) {
+ // ok we found.
+ if (vars[i].getMode() == IVariableInfo.RESOURCEBUNDLE) {
+ String resourceName = vars[i]
+ .getTypeInfoString();
+ IStorage s = null;
+ try {
+ s = LoadBundleUtil
+ .getLoadBundleResource(_prj,
+ resourceName);
+ } catch (CoreException ex) {
+ // "Error"
+ _log
+ .info(
+ "PageExpressionContext.Info.0", ex); //$NON-NLS-1$
+ }
+ if (s == null) {
+ throw new ELException();
+ }
+ InputStream input = null;
+ try {
+ input = new BufferedInputStream(s
+ .getContents());
+ Properties p = new Properties();
+ p.load(input);
+ return p;
+ } catch (CoreException e) {
+ throw new ELException(e);
+ } catch (IOException e) {
+ throw new ELException(e);
+ } finally {
+ ResourceUtils.ensureClosed(input);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ throw new ELException("Can't find: " + varName); //$NON-NLS-1$
+ }
+
+ }
+
+ static class EmptyFunctionMapper implements FunctionMapper {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.jsp.el.FunctionMapper#resolveFunction(java.lang.String,
+ * java.lang.String)
+ */
+ public Method resolveFunction(String arg0, String arg1) {
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewConvertContext.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewConvertContext.java
new file mode 100644
index 000000000..69c0016b8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewConvertContext.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.preview;
+
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
+import org.eclipse.jst.pagedesigner.converter.ConverterFactoryRegistry;
+import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
+import org.eclipse.jst.pagedesigner.converter.ITagConverter;
+import org.eclipse.wst.xml.core.internal.document.InvalidCharacterException;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PreviewConvertContext {
+ private Logger _log = PDPlugin.getLogger(PreviewConvertContext.class);
+
+ private IDOMDocument _destDocument;
+
+ /**
+ *
+ */
+ public PreviewConvertContext(IDOMDocument destDocument) {
+ this._destDocument = destDocument;
+ }
+
+ /**
+ * @param ele
+ * @return
+ */
+ public Node previewConvert(Node ele) {
+ if (ele instanceof Element) {
+ return previewConvertElement((Element) ele);
+ } else if (ele instanceof Text) {
+ return createText((Text) ele);
+ } else {
+ // XXX: we'll support other node like doctype etc in the future.
+ // so they should also be rendered into preview.
+
+ return null;
+ }
+ }
+
+ /**
+ * @param text
+ * @return
+ */
+ private Node createText(Text text) {
+ Text previewText = this._destDocument.createTextNode(text.getData());
+ try {
+ ((IDOMText) previewText).setSource(((IDOMText) text).getSource());
+ } catch (InvalidCharacterException e) {
+ // "Error"
+ _log.info("PreviewConvertContext.Error.0", e); //$NON-NLS-1$
+ }
+ return previewText;
+ }
+
+ protected Node previewConvertElement(Element ele) {
+ ITagConverter converter = createTagConverter(ele);
+ if (!converter.isVisualByHTML()) {
+ return null;
+ }
+ converter.convertRefresh(null);
+ Element result = converter.getResultElement();
+ List children = converter.getChildModeList();
+ if (children != null) {
+ for (int i = 0, size = children.size(); i < size; i++) {
+ Node child = (Node) children.get(i);
+ if (child != null) {
+ Node childPreview = previewConvert(child);
+ if (childPreview != null) {
+ ConvertPosition position = converter
+ .getChildVisualPosition(child);
+ if (position != null) {
+ // FIXME: not using index here, need fix.
+ position.getParentNode().appendChild(childPreview);
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param ele
+ * @return
+ */
+ private ITagConverter createTagConverter(Element ele) {
+ return ConverterFactoryRegistry.getInstance().createTagConverter(ele,
+ IConverterFactory.MODE_PREVIEW, _destDocument);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewHandlerNew.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewHandlerNew.java
new file mode 100644
index 000000000..84a9c4fc7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewHandlerNew.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.preview;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.IPageVariablesProvider;
+import org.eclipse.jst.pagedesigner.jsp.core.pagevar.adapter.IDocumentPageVariableAdapter;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.utils.PreviewUtil;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeIdForHTML;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+import org.eclipse.wst.xml.core.internal.document.XMLGeneratorImpl;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PreviewHandlerNew {
+ private static Logger _log = PDPlugin.getLogger(PreviewHandlerNew.class);
+
+ public static void generatePreview(DocumentEditPart part,
+ StringBuffer result) throws IOException {
+ try {
+ IProject prj = StructuredModelUtil.getProjectFor(part.getIDOMNode()
+ .getModel());
+ PageExpressionContext.initialize(prj);
+
+ IDOMDocument doc = (IDOMDocument) part.getIDOMNode();
+ Object obj = doc.getAdapterFor(IDocumentPageVariableAdapter.class);
+ if (obj instanceof IPageVariablesProvider) {
+ ((IPageVariablesProvider) obj).refresh();
+ PageExpressionContext.getCurrent().pushPageVarProvider(
+ (IPageVariablesProvider) obj);
+ } else {
+ PageExpressionContext.getCurrent().pushPageVarProvider(null);
+ }
+
+ // IDOMModel previewModel =
+ // (IDOMModel)StructuredModelManager.getModelManager().createNewInstance(doc.getModel());
+ // IDOMDocument previewDoc = previewModel.getDocument();
+
+ // CR400625: creating XML model here instead of HTML model. Since
+ // for HTML model, there are checking enforced
+ // by WTP to make sure the HTML content model is not invalidated.
+ // And sometimes, the converted HTML may not fully
+ // comply with HTML content model.
+ // Use XML instead to workaround the content model validation.
+
+ // CR403449: But if we use XML, then system can't recogonize special
+ // tag such as "script", "style", they
+ // support <!-- --> in them.
+ // So we are still using HTML model, but in TagConverter, we are
+ // always caling DOMUtil.cloneNodeDeepIgnoreError
+ // to try to skip the errors.
+ // Hopefully in later version of SSE, the famous "br" problem is
+ // fixed, and we won't met error when doing
+ // deep clone.
+ // IStructuredModel sModel =
+ // StructuredModelManager.getModelManager().createUnManagedStructuredModelFor(IContentTypeIdentifier.ContentTypeID_XML);
+ // FIXME: if is not jsp, should use original contentType, if is jsp,
+ // should use the corresponding
+ // content type
+ IStructuredModel sModel = StructuredModelManager.getModelManager()
+ .createUnManagedStructuredModelFor(
+ ContentTypeIdForHTML.ContentTypeID_HTML);
+
+ IDOMDocument previewDoc = ((IDOMModel) sModel).getDocument();
+ PreviewConvertContext context = new PreviewConvertContext(
+ previewDoc);
+
+ ISourceGenerator generator = XMLGeneratorImpl.getInstance();
+ List subeditparts = part.getChildren();
+ for (int i = 0, size = subeditparts.size(); i < size; i++) {
+ NodeEditPart subpart = (NodeEditPart) subeditparts.get(i);
+ Node node = context.previewConvert(subpart.getIDOMNode());
+
+ PreviewUtil.previewNode(node);
+
+ if (node != null) {
+ result.append(generator.generateSource(node));
+ }
+
+ }
+ // XXX: seemed in WTP0.7, releaseFromEdit for a unmanaged model may
+ // fail
+ try {
+ sModel.releaseFromEdit();
+ } catch (Throwable th) {
+ // "Error in model release:"
+ // _log.info("PreviewHandlerNew.Error.0", th); //$NON-NLS-1$
+ }
+ return;
+ } finally {
+ PageExpressionContext.reset();
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.java
new file mode 100644
index 000000000..2ff76671d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.preview;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+
+/**
+ * @author mengbo
+ */
+public class PreviewResources extends ResourceUtils {
+ /** Create the logger for this class */
+ private static Logger _log = PDPlugin.getLogger(PreviewResources.class);
+
+ private static PreviewResources _resource; // singleton
+
+ private static final String BUNDLE = "org.eclipse.jst.pagedesigner.preview.PreviewResources";
+
+ /**
+ * Empty Constructor.
+ *
+ * @return WizardsResources
+ */
+
+ public static PreviewResources getInstance() {
+ if (_resource == null) {
+ _resource = new PreviewResources();
+ }
+ return _resource;
+ }
+
+ /**
+ * The constructor create a resource bundle
+ */
+ protected PreviewResources() {
+ try {
+ _resources = ResourceBundle.getBundle(BUNDLE);
+ // NOTE: this throws a runtime "MissingResourceException".
+ } catch (MissingResourceException ee) {
+ _log
+ .error(
+ "Log.Error.PreviewResources.ResouceNotFound", BUNDLE, ee); //$NON-NLS-1$
+ }
+ setBundle(_resources, BUNDLE);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.properties
new file mode 100644
index 000000000..34dca06fd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/PreviewResources.properties
@@ -0,0 +1,6 @@
+####################################################
+# Resource message for RenderingTraverser
+####################################################
+RenderingTraverser.Error.FileNotFound = File not found.
+RenderingTraverser.Error.UnsupportedEncoding = Unsupport encoding.
+RenderingTraverser.Error.IO = IO exception.
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/WindowsIEBrowser.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/WindowsIEBrowser.java
new file mode 100644
index 000000000..b03ed75e2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/preview/WindowsIEBrowser.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.preview;
+
+import java.io.File;
+
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.widgets.Composite;
+
+public class WindowsIEBrowser implements ProgressListener {
+ private Browser _browser;
+
+ private File _file;
+
+ public void create(Composite composite, int i) {
+ _browser = new Browser(composite, i);
+ _browser.addProgressListener(this);
+ }
+
+ public synchronized void loadFile(File file) {
+ if (_browser == null) {
+ return;
+ } else {
+ _file = file;
+ String s = "file:" + file.getAbsolutePath();
+ _browser.setUrl(s);
+ return;
+ }
+ }
+
+ public void dispose() {
+ if (_browser == null) {
+ return;
+ } else {
+ _browser.dispose();
+ _browser = null;
+ return;
+ }
+ }
+
+ public void changed(ProgressEvent progressevent) {
+ }
+
+ public synchronized void completed(ProgressEvent progressevent) {
+ if (_file != null) {
+ // XXX: don't delete, for debug purpose.
+ // _file.delete();
+ // _file = null;
+ }
+ }
+
+ /**
+ *
+ */
+ public Browser getBrowser() {
+ return _browser;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AllPropertySection.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AllPropertySection.java
new file mode 100644
index 000000000..f69e35e4a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AllPropertySection.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.properties.IPropertySourceProvider;
+import org.eclipse.wst.common.ui.properties.internal.provisional.AbstractPropertySection;
+import org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetPage;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * mainly copied from AdvancedPropertySection. But extend it to allow setting
+ * PropertySourceProvider.
+ *
+ * @author mengbo
+ */
+public class AllPropertySection extends AbstractPropertySection {
+ // FIXME: workaround the eclipse properties view limitation of sorting
+ // category.
+ private MyPropertySheetPage page;
+
+ protected IPropertySourceProvider _provider;
+
+ protected IDOMElement _element;
+
+ protected INodeAdapter _adapter = new INodeAdapter() {
+ public boolean isAdapterForType(Object type) {
+ return false;
+ }
+
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ refresh();
+ }
+ };
+
+ /**
+ *
+ */
+ public AllPropertySection() {
+ this.setPropertySourceProvider(new AttributePropertySourceProvider());
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent,
+ TabbedPropertySheetPage tabbedPropertySheetPage) {
+ super.createControls(parent, tabbedPropertySheetPage);
+ Composite composite = getWidgetFactory()
+ .createFlatFormComposite(parent);
+ page = new MyPropertySheetPage();
+ page.init(tabbedPropertySheetPage.getSite());
+
+ if (_provider != null) {
+ page.setPropertySourceProvider(_provider);
+ }
+
+ page.createControl(composite);
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, 0);
+ data.bottom = new FormAttachment(100, 0);
+ data.height = 100;
+ data.width = 100;
+ page.getControl().setLayoutData(data);
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.internal.provisional.ISection#setInput(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void setInput(IWorkbenchPart part, ISelection selection) {
+ super.setInput(part, selection);
+ page.selectionChanged(part, selection);
+
+ IDOMElement newEle = (IDOMElement) DesignerPropertyTool.getElement(
+ part, selection);
+ if (_element != newEle) {
+ if (_element != null) {
+ _element.removeAdapter(_adapter);
+ }
+ _element = newEle;
+ if (_element != null) {
+ _element.addAdapter(_adapter);
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.view.ISection#dispose()
+ */
+ public void dispose() {
+ super.dispose();
+
+ if (_element != null) {
+ _element.removeAdapter(_adapter);
+ }
+ if (page != null) {
+ page.dispose();
+ page = null;
+ }
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.view.ISection#refresh()
+ */
+ public void refresh() {
+ page.refresh();
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.view.ISection#shouldUseExtraSpace()
+ */
+ public boolean shouldUseExtraSpace() {
+ return true;
+ }
+
+ public void setPropertySourceProvider(IPropertySourceProvider provider) {
+ _provider = provider;
+ if (page != null)
+ page.setPropertySourceProvider(_provider);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertyDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertyDescriptor.java
new file mode 100644
index 000000000..6cf5837e9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertyDescriptor.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jst.pagedesigner.meta.EditorCreator;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+
+/**
+ * This is the PropertyDescriptor for an attribute. Getting information from a
+ * IAttributeDescriptor and an IPropertyDescriptor.
+ *
+ * @author mengbo
+ */
+public class AttributePropertyDescriptor implements IPropertyDescriptor {
+ private IAttributeDescriptor _attr;
+
+ private IPropertyDescriptor _inner; // this could be null
+
+ private Element _element;
+
+ /**
+ * @param element
+ * the owner of the attribute.
+ * @param descriptor
+ * can't be null
+ * @param desc
+ * could be null
+ */
+ public AttributePropertyDescriptor(Element element,
+ IAttributeDescriptor descriptor, IPropertyDescriptor desc) {
+ _element = element;
+ _attr = descriptor;
+ _inner = desc;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor(org.eclipse.swt.widgets.Composite)
+ */
+ public CellEditor createPropertyEditor(Composite parent) {
+ CellEditor editor;
+ editor = EditorCreator.getInstance().createCellEditorWithWrapper(
+ parent, _attr, (IDOMElement) _element, null);
+
+ if (editor != null) {
+ return editor;
+ } else {
+ EditorCreator.CellEditorHolder holder = new EditorCreator.CellEditorHolder() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator.CellEditorHolder#createCellEditor(org.eclipse.swt.widgets.Composite)
+ */
+ public CellEditor createCellEditor(Composite parent) {
+ if (_inner != null) {
+ return _inner.createPropertyEditor(parent);
+ } else {
+ return new TextCellEditor(parent);
+ }
+ }
+ };
+ return EditorCreator.getInstance().createCellEditorWithWrapper(
+ parent, _attr, holder, (IDOMElement) _element, null);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getCategory()
+ */
+ public String getCategory() {
+ String cat = _attr.getCategory();
+ if (cat != null) {
+ return cat;
+ } else {
+ return ITabbedPropertiesConstants.OTHER_CATEGORY;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getDescription()
+ */
+ public String getDescription() {
+ String s = _attr.getDescription();
+ if (s == null && _inner != null) {
+ return _inner.getDescription();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getDisplayName()
+ */
+ public String getDisplayName() {
+ return _attr.getAttributeName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getFilterFlags()
+ */
+ public String[] getFilterFlags() {
+ if (_inner != null) {
+ return _inner.getFilterFlags();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getHelpContextIds()
+ */
+ public Object getHelpContextIds() {
+ if (_inner != null) {
+ return _inner.getHelpContextIds();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getId()
+ */
+ public Object getId() {
+ return _attr.getAttributeName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getLabelProvider()
+ */
+ public ILabelProvider getLabelProvider() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#isCompatibleWith(org.eclipse.ui.views.properties.IPropertyDescriptor)
+ */
+ public boolean isCompatibleWith(IPropertyDescriptor anotherProperty) {
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySource.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySource.java
new file mode 100644
index 000000000..fadeede71
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySource.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeAttributeCommand;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.ICMRegistry;
+import org.eclipse.jst.pagedesigner.meta.IElementDescriptor;
+import org.eclipse.jst.pagedesigner.meta.internal.CMRegistry;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Element;
+
+/**
+ *
+ * @author mengbo
+ */
+public class AttributePropertySource implements IPropertySource {
+ private IDOMElement _element;
+
+ private IPropertySource _innerSource;
+
+ public AttributePropertySource(Element ele, IPropertySource source) {
+ _element = (IDOMElement) ele;
+ _innerSource = source;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
+ */
+ public Object getEditableValue() {
+ return _innerSource.getEditableValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
+ */
+ public Object getPropertyValue(Object id) {
+ // CR377844: when the attribute in source is "a&gt;b", we would like to
+ // display
+ // "a>b" in cell editor. But _innerSource.getPropertyValue(id) will
+ // return the source
+ // of the attribute, so can't use that here.
+ // read QTS log for detail.
+ // return _innerSource.getPropertyValue(id);
+ if (id == null) {
+ return null;
+ }
+ String name = id.toString();
+ String value = _element.getAttribute(name);
+ if (value == null) {
+ value = ""; //$NON-NLS-1$
+ }
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
+ */
+ public boolean isPropertySet(Object id) {
+ return _innerSource.isPropertySet(id);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
+ */
+ public void resetPropertyValue(Object id) {
+ _innerSource.resetPropertyValue(id);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object,
+ * java.lang.Object)
+ */
+ public void setPropertyValue(final Object id, final Object value) {
+ Object oldValue = getPropertyValue(id);
+ if (oldValue == value || (oldValue != null && oldValue.equals(value))) {
+ return;
+ }
+ Command c = new ChangeAttributeCommand(
+ PDPlugin
+ .getResourceString("AttributePropertySource.CommandLabel.ChangeAttribute"), (IDOMElement) _element, (String) id, (String) value); //$NON-NLS-1$
+ c.execute();
+ }
+
+ /**
+ * the major job of this wrapper is to provide
+ */
+ public IPropertyDescriptor[] getPropertyDescriptors() {
+ IElementDescriptor elementDescriptor = getElementDescriptor();
+ List result = new ArrayList();
+
+ if (elementDescriptor == null) {
+ IPropertyDescriptor[] original = _innerSource
+ .getPropertyDescriptors();
+ for (int i = 0; i < original.length; i++) {
+ result
+ .add(new PropertyDescriptorWrapper(_element,
+ original[i]));
+ }
+ } else {
+ // put the inner property descriptors into a map.
+ Map map = new HashMap();
+ IPropertyDescriptor[] descs = _innerSource.getPropertyDescriptors();
+ if (descs != null) {
+ for (int i = 0; i < descs.length; i++) {
+ map.put(descs[i].getId(), descs[i]);
+ }
+ }
+
+ IAttributeDescriptor[] attrs = elementDescriptor
+ .getAttributeDescriptors();
+ if (attrs != null) {
+ for (int i = 0; i < attrs.length; i++) {
+ IPropertyDescriptor desc = (IPropertyDescriptor) map
+ .remove(attrs[i].getAttributeName());
+ result.add(new AttributePropertyDescriptor(_element,
+ attrs[i], desc));
+ }
+ }
+ // ok, we have handled all attributes declared in ElementDescriptor,
+ // let's see the remaining
+ for (Iterator iter = map.values().iterator(); iter.hasNext();) {
+ IPropertyDescriptor desc = (IPropertyDescriptor) iter.next();
+ IAttributeDescriptor attr = findReferencedAttribute(
+ elementDescriptor, desc);
+ if (attr != null) {
+ result.add(new AttributePropertyDescriptor(_element, attr,
+ desc));
+ } else {
+ result.add(new PropertyDescriptorWrapper(
+ (IDOMElement) _element, desc));
+ }
+ }
+ }
+ IPropertyDescriptor[] ret = new IPropertyDescriptor[result.size()];
+ result.toArray(ret);
+ return ret;
+ }
+
+ private IAttributeDescriptor findReferencedAttribute(
+ IElementDescriptor elementDescriptor, IPropertyDescriptor desc) {
+ return null;
+ }
+
+ private IElementDescriptor getElementDescriptor() {
+ ICMRegistry registry = CMRegistry.getInstance();
+ String uri = CMUtil.getElementNamespaceURI(_element);
+ return registry.getElementDescriptor(uri, _element.getLocalName());
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySourceProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySourceProvider.java
new file mode 100644
index 000000000..b944edfa0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/AttributePropertySourceProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.IPropertySourceProvider;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySource;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class AttributePropertySourceProvider implements IPropertySourceProvider {
+ public AttributePropertySourceProvider() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertySourceProvider#getPropertySource(java.lang.Object)
+ */
+ public IPropertySource getPropertySource(Object object) {
+ Element model = null;
+ IPropertySource source = null;
+
+ if ((model = DesignerPropertyTool.getElementNode(object)) != null) {
+ source = (IPropertySource) ((INodeNotifier) (model))
+ .getAdapterFor(IPropertySource.class);
+ if (source == null) {
+ source = new XMLPropertySource((INodeNotifier) model);
+ }
+ }
+ if (source != null) {
+ return new AttributePropertySource(model, source);
+ }
+ return source;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/BaseCustomSection.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/BaseCustomSection.java
new file mode 100644
index 000000000..054cb2af8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/BaseCustomSection.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.dialogfield.StatusUtil;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.wst.common.ui.properties.internal.provisional.AbstractPropertySection;
+import org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetPage;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public abstract class BaseCustomSection extends AbstractPropertySection {
+
+ public static final Status OKSTATUS = new Status(IStatus.OK, PDPlugin
+ .getPluginId(), 0, "", null);
+
+ private DesignerTabbedPropertySheetPage _propertySheetPage;
+
+ private boolean _visible = false;
+
+ protected IDOMElement _element;
+
+ protected INodeAdapter _adapter = new INodeAdapter() {
+ public boolean isAdapterForType(Object type) {
+ return false;
+ }
+
+ public void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ BaseCustomSection.this.notifyChanged(notifier, eventType,
+ changedFeature, oldValue, newValue, pos);
+ }
+ };
+
+ public void setInput(IWorkbenchPart part, ISelection selection) {
+ super.setInput(part, selection);
+ IDOMElement newEle = (IDOMElement) DesignerPropertyTool.getElement(
+ part, selection);
+ if (_element != newEle) {
+ if (_element != null) {
+ _element.removeAdapter(_adapter);
+ }
+ _element = newEle;
+ if (_element != null) {
+ _element.addAdapter(_adapter);
+ }
+ }
+ }
+
+ protected abstract void notifyChanged(INodeNotifier notifier,
+ int eventType, Object changedFeature, Object oldValue,
+ Object newValue, int pos);
+
+ public void createControls(Composite parent,
+ TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ _propertySheetPage = (DesignerTabbedPropertySheetPage) aTabbedPropertySheetPage;
+ }
+
+ /**
+ * for certain action performed in the section, may result big change in the
+ * model. e.g: change tag name will result in editpart recreate. In this
+ * case, we need do a total refresh.
+ *
+ */
+ public void refreshPropertySheetPage() {
+ if (_propertySheetPage != null) {
+ IWorkbenchPart part = getPart();
+ if (part != null) {
+ ISelection sel = part.getSite().getSelectionProvider()
+ .getSelection();
+ _propertySheetPage.selectionChanged(part, sel);
+ } else {
+ // XXX: will else happen?
+ System.out.println("AbstractCustomSection --> What to do?");
+ }
+ }
+ }
+
+ public void gotoNode(Node node) {
+ _propertySheetPage.internalChangeSelection(node, node);
+ }
+
+ public IStatusLineManager getStatusLineManager() {
+ if (_propertySheetPage != null) {
+ IActionBars bar = _propertySheetPage.getSite().getActionBars();
+ if (bar != null) {
+ return bar.getStatusLineManager();
+ }
+ }
+ return null;
+ }
+
+ public void applyStatus(IStatus[] status) {
+ if (!_visible) {
+ return;
+ }
+
+ IStatusLineManager statusLine = getStatusLineManager();
+ if (statusLine == null) {
+ return;
+ }
+
+ IStatus s;
+ if (status == null || status.length == 0) {
+ s = null;
+ } else {
+ s = StatusUtil.getMostSevere(status);
+ }
+
+ if (s == null || s.getSeverity() != IStatus.ERROR) {
+ statusLine.setErrorMessage(null);
+ } else {
+ statusLine.setErrorMessage(s.getMessage());
+ }
+ }
+
+ public void setErrorMessage(String message) {
+ IStatusLineManager s = getStatusLineManager();
+ if (s != null) {
+ s.setErrorMessage(message);
+ }
+ }
+
+ public Status createErrorStatus(String message) {
+ return new Status(IStatus.ERROR, PDPlugin.getPluginId(), 0, message,
+ null);
+ }
+
+ public void aboutToBeHidden() {
+ applyStatus(null);
+ _visible = false;
+ super.aboutToBeHidden();
+ }
+
+ public void aboutToBeShown() {
+ super.aboutToBeShown();
+ _visible = true;
+ }
+
+ public IProject getProject() {
+ if (_propertySheetPage != null) {
+ IEditorInput input = _propertySheetPage.getEditor()
+ .getEditorInput();
+ if (input instanceof IFileEditorInput) {
+ return ((IFileEditorInput) input).getFile().getProject();
+ }
+ }
+ return null;
+ }
+
+ public void dispose() {
+ super.dispose();
+ if (_element != null) {
+ _element.removeAdapter(_adapter);
+ }
+ }
+
+ public IFile getFile() {
+ if (_propertySheetPage != null) {
+ IEditorInput input = _propertySheetPage.getEditor()
+ .getEditorInput();
+ if (input instanceof IFileEditorInput) {
+ return ((IFileEditorInput) input).getFile();
+ }
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerPropertyTool.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerPropertyTool.java
new file mode 100644
index 000000000..2373c5ea8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerPropertyTool.java
@@ -0,0 +1,411 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.gef.editparts.AbstractEditPart;
+import org.eclipse.gef.ui.parts.GraphicalEditor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.jst.pagedesigner.utils.SelectionHelper;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
+import org.eclipse.wst.xml.core.internal.document.ElementImpl;
+import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * This is util class most used by Property related operation.
+ *
+ * @author mengbo
+ */
+public class DesignerPropertyTool {
+ public static String getAttributeValue(Element fNode, CMNode attributeDesc) {
+ if (attributeDesc == null) {
+ return ""; //$NON-NLS-1$
+ }
+ String returnedValue = ""; //$NON-NLS-1$
+ NamedNodeMap attrMap = fNode.getAttributes();
+ if (attrMap != null) {
+ Node attribute = attrMap.getNamedItem(attributeDesc.getNodeName());
+ if (attribute != null) {
+ if (attribute instanceof IDOMNode) {
+ returnedValue = ((IDOMNode) attribute).getValueSource();
+ } else {
+ returnedValue = attribute.getNodeValue();
+ }
+ }
+ }
+ return returnedValue;
+ }
+
+ public static Object[] getElementReferedAttributes(Element fNode,
+ String[] filter) {
+ List result = new ArrayList();
+ CMNamedNodeMap cmnnm = getElementDeclaredAttributes(fNode);
+ for (int i = 0, n = cmnnm.getLength(); i < n; i++) {
+ String name = cmnnm.item(i).getNodeName();
+ if (Arrays.asList(filter).contains(name)) {
+ result.add(cmnnm.item(i));
+ }
+ }
+ return result.toArray(new CMNode[result.size()]);
+ }
+
+ public static CMNamedNodeMap getElementDeclaredAttributes(Node fNode) {
+ IStructuredModel structModel = null;
+ if (fNode instanceof IDOMNode) {
+ structModel = ((IDOMNode) fNode).getModel();
+ }
+ if (null == structModel) {
+ return null;
+ }
+ CMElementDeclaration cmde = null;
+ CMNamedNodeMap cmnnm = null;
+ if (fNode == null || fNode.getNodeType() != Node.ELEMENT_NODE) {
+ cmde = null;
+ }
+ ModelQuery modelQuery = ModelQueryUtil.getModelQuery(fNode
+ .getOwnerDocument());
+ if (modelQuery != null) {
+ cmde = modelQuery.getCMElementDeclaration((Element) fNode);
+ }
+ if (cmde != null) {
+ cmnnm = cmde.getAttributes();
+ }
+ return cmnnm;
+ }
+
+ /**
+ * the selection could be different kinds of selection, including: 1.
+ * ITextSelection 2. IStructuredSelection (Node) 3. IStructuredSelection
+ * (EditPart) 4. DesignRange we want to normalize it to only #2. If the node
+ * is ATTR or TEXT/CDATA_SECTION, will use it's parent node.
+ *
+ * @param part
+ * @param selection
+ * @return null if can't normalize.
+ */
+ public static Node normalizeSelectionToElement(
+ IWorkbenchPart selectingPart, ISelection selection,
+ HTMLEditor _htmlEditor) {
+ Node node = null;
+ if (selectingPart instanceof HTMLEditor) {
+ IEditorPart part = ((HTMLEditor) selectingPart).getActiveEditor();
+ if (part instanceof TextEditor) {
+ if (selection instanceof ITextSelection) {
+ IStructuredModel model = ((HTMLEditor) selectingPart)
+ .getModel();
+ node = SelectionHelper.toNode(model,
+ (ITextSelection) selection);
+ }
+ } else if (part instanceof GraphicalEditor) {
+ if (selection instanceof IStructuredSelection) {
+ node = SelectionHelper
+ .toNode((IStructuredSelection) selection);
+ } else if (selection instanceof DesignRange) {
+ node = SelectionHelper.toNode((DesignRange) selection);
+ }
+ }
+ if (node instanceof Attr) {
+ node = ((Attr) node).getOwnerElement();
+ } else if (node instanceof Text || node instanceof CDATASection) {
+ node = node.getParentNode();
+ }
+ } else if (selectingPart instanceof ContentOutline) {
+ if (selection instanceof IStructuredSelection
+ && ((ContentOutline) selectingPart).getCurrentPage() != null
+ && ((ContentOutline) selectingPart).getCurrentPage()
+ .getControl().isFocusControl()) {
+ node = SelectionHelper.toNode((IStructuredSelection) selection);
+ if (node == null) {
+ node = _htmlEditor.getDOMDocument();
+ }
+ }
+ }
+
+ return node;
+ }
+
+ // /**
+ // * the selection could be different kinds of selection, including:
+ // * 1. ITextSelection
+ // * 2. IStructuredSelection (Node)
+ // * 3. IStructuredSelection (EditPart)
+ // * 4. DesignRange
+ // * we want to normalize it to only #2 and #4.
+ // *
+ // * @param part
+ // * @param selection
+ // * @return null if can't normalize.
+ // */
+ // public static ISelection normalizeSelection(IWorkbenchPart selectingPart,
+ // ISelection selection)
+ // {
+ // // On Attr nodes, select the owner Element. On Text nodes, select the
+ // parent Element.
+ // ISelection preferredSelection = null;
+ // if (selection instanceof ITextSelection)
+ // {
+ // // FIXME: currently always normalize to a single node. should also
+ // consider change into DesignRange
+ // // on text selection, find the appropriate Node
+ // ITextSelection textSel = (ITextSelection) selection;
+ // IStructuredModel model = null;
+ // if (selectingPart instanceof HTMLEditor)
+ // {
+ // model = ((HTMLEditor) selectingPart).getModel();
+ //
+ // Object inode = model.getIndexedRegion(textSel.getOffset());
+ // if (inode instanceof Node)
+ // {
+ // Node node = (Node) inode;
+ // // replace Attribute Node with its owner
+ // if (node.getNodeType() == Node.ATTRIBUTE_NODE)
+ // inode = ((Attr) node).getOwnerElement();
+ // // replace Text Node with its parent
+ // else if ((node.getNodeType() == Node.TEXT_NODE || (node.getNodeType() ==
+ // Node.CDATA_SECTION_NODE)) && node.getParentNode() != null)
+ // {
+ // inode = node.getParentNode();
+ // }
+ // }
+ // if (inode != null)
+ // {
+ // return new StructuredSelection(inode);
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+ // else if (selection instanceof IStructuredSelection)
+ // {
+ // if (((IStructuredSelection) selection).isEmpty())
+ // {
+ // return null;
+ // }
+ //
+ // IStructuredSelection structuredSel = (IStructuredSelection) selection;
+ // List inputList = new ArrayList(structuredSel.size());
+ // for (Iterator iter = structuredSel.iterator(); iter.hasNext();)
+ // {
+ // Object inode = iter.next();
+ // if (inode instanceof NodeEditPart)
+ // {
+ // inode = ((NodeEditPart) inode).getModel();
+ // }
+ //
+ // if (inode instanceof Node)
+ // {
+ // inputList.add(inode);
+ // }
+ // }
+ // if (inputList.isEmpty())
+ // {
+ // return null;
+ // }
+ // else
+ // {
+ // return new StructuredSelection(inputList);
+ // }
+ // }
+ // else if (selection instanceof DesignRange)
+ // {
+ // return selection;
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+
+ public static Element getElementNode(Object node) {
+ Object model;
+ Element element = null;
+ if (node == null) {
+ return null;
+ }
+
+ if (node instanceof Element) {
+ element = (Element) node;
+ } else if (node instanceof AbstractEditPart) {
+ model = ((AbstractEditPart) node).getModel();
+ if (model instanceof Element) {
+ element = (Element) model;
+ }
+ } else if (node instanceof ISelection) {
+ element = getElement(null, (ISelection) node);
+ }
+ return element;
+ }
+
+ public static List getNameList(Element element, String[] filter) {
+ List result = new ArrayList();
+ CMNamedNodeMap attributes = getElementDeclaredAttributes(element);
+ if (attributes != null) {
+ for (int i = 0, n = attributes.getLength(); i < n; i++) {
+ String name = attributes.item(i).getNodeName();
+ if (Arrays.asList(filter).contains(name))
+ result.add(name);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param selection
+ * should be a normalized selection
+ * @return
+ */
+ public static Node getCommonParent(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) selection).getFirstElement();
+ return (Node) obj;
+ } else if (selection instanceof DesignRange) {
+ DesignRange range = (DesignRange) selection;
+ Node node1 = range.getStartPosition().getContainerNode();
+ Node node2 = range.getEndPosition().getContainerNode();
+ return DOMUtil.findCommonAncester(node1, node2);
+ } else {
+ // should not happen
+ return null;
+ }
+ }
+
+ /**
+ * The passed in selection should be normalized selection.
+ *
+ * @param selectingPart
+ * @param selection
+ * @return
+ */
+ public static Element getElement(IWorkbenchPart selectingPart,
+ ISelection selection) {
+ Node node = getCommonParent(selection);
+ if (node instanceof Element) {
+ return (Element) node;
+ } else if (node != null) {
+ node = node.getParentNode();
+ if (node instanceof Element) {
+ return (Element) node;
+ }
+ }
+ return null;
+ }
+
+ // reserved for future native use.
+ // public static void dumpChildren(Element element)
+ // {
+ // // In this function we are using logger to dump message out.
+ // Logger logger = PDPlugin.getLogger(DesignerPropertyTool.class);
+ // if (element == null || !DEBUG)
+ // return;
+ // NodeList nl = element.getChildNodes();
+ // // It's our pattern for dumping message
+ // logger.debug("\n----------------------------"); //$NON-NLS-1$
+ // logger.debug("Element:" + element.getNodeName()); //$NON-NLS-1$
+ // for (int i = 0; i < nl.getLength(); i++)
+ // {
+ // Node node = nl.item(i);
+ // logger.debug("child[" + i + "]:" + node.getNodeName()); //$NON-NLS-1$
+ // //$NON-NLS-2$
+ // }
+ // logger.debug("----------------------------\n"); //$NON-NLS-1$
+ // }
+
+ public static boolean isMultiSelection(Element element) {
+ if (element.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_OPTION)) {
+ return element.getAttribute(ICSSPropertyID.ATTR_MULTIPLE) != null;
+ }
+ return false;
+ }
+
+ public static String getElementTextSource(Element element) {
+ if (element == null) {
+ return null;
+ }
+ if (element instanceof ElementImpl) {
+ return ((ElementImpl) element).getSource();
+ }
+ return null;
+ }
+
+ public static IJavaProject getJavaProject(Object project) {
+ if (project == null) {
+ return null;
+ }
+ if (project instanceof IJavaProject) {
+ return (IJavaProject) project;
+ } else if (project instanceof IProject) {
+ try {
+ IProjectNature nature = ((IProject) project)
+ .getNature(JavaCore.NATURE_ID);
+ if (nature == null) {
+ return null;
+ } else {
+ return (IJavaProject) nature;
+ }
+ } catch (Exception e) {
+ // Error.DesignerPropertyTool.NatureQuerying = Error in project
+ // java nature querying
+ PDPlugin.getLogger(DesignerPropertyTool.class).error(
+ "Error.DesignerPropertyTool.NatureQuerying", e); //$NON-NLS-1$
+ // Should be error tolerable?
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public static IProject getProject(Object project) {
+ if (project instanceof IProject) {
+ return (IProject) project;
+ } else if (project instanceof IJavaProject) {
+ return ((IJavaProject) project).getProject();
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerTabbedPropertySheetPage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerTabbedPropertySheetPage.java
new file mode 100644
index 000000000..063a0ec09
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/DesignerTabbedPropertySheetPage.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySheetPageContributor;
+import org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetPage;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @author mengbo
+ */
+public class DesignerTabbedPropertySheetPage extends TabbedPropertySheetPage {
+ // TODO: when we want to extend this page, HTMLEditor would not be the sole
+ // type of editor part.
+ private HTMLEditor _htmlEditor;
+
+ private NavigationHiearchyAction _hiearchAction = new NavigationHiearchyAction(
+ this);
+
+ /**
+ * @param tabbedPropertySheetPageContributor
+ */
+ public DesignerTabbedPropertySheetPage(
+ ITabbedPropertySheetPageContributor tabbedPropertySheetPageContributor,
+ HTMLEditor editor) {
+ super(tabbedPropertySheetPageContributor);
+ _htmlEditor = editor;
+ }
+
+ protected IStructuredModel getModel() {
+ return _htmlEditor.getModel();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ if (part == null) {
+ part = _htmlEditor;
+ }
+ if (part instanceof HTMLEditor || part instanceof ContentOutline) {
+ Node node = DesignerPropertyTool.normalizeSelectionToElement(part,
+ selection, _htmlEditor);
+ if (node != null) {
+ try {
+ _hiearchAction.refresh(node, node);
+ this.getSite().getActionBars().getToolBarManager().update(
+ true);
+ super.selectionChanged(part, new StructuredSelection(node));
+ } catch (Exception e) {
+ // Some synchronization would cause this, it does not damage
+ // the data.
+ }
+ }
+ }
+ }
+
+ /**
+ * This method should be called from internal of the property page. Normally
+ * means user did some action inside the property sheet to change current
+ * selection.
+ *
+ * @param selectedNode
+ * @param node
+ */
+ public void internalChangeSelection(Node selectedNode, Node innerNode) {
+ getEditor().setFocus();
+ _hiearchAction.refresh(selectedNode, innerNode);
+ this.getSite().getActionBars().getToolBarManager().update(true);
+ super.selectionChanged(null, new StructuredSelection(selectedNode));
+ }
+
+ public EditorPart getEditor() {
+ return this._htmlEditor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.Page#init(org.eclipse.ui.part.IPageSite)
+ */
+ public void init(IPageSite pageSite) {
+ super.init(pageSite);
+ setSelectionProvider();
+ setSelectionListener();
+ IToolBarManager toolbar = pageSite.getActionBars().getToolBarManager();
+ toolbar.add(_hiearchAction);
+ _hiearchAction.refresh(null, null);
+ }
+
+ private void setSelectionListener() {
+ this.getSite().getWorkbenchWindow().getSelectionService()
+ .addPostSelectionListener(new ISelectionListener() {
+ public void selectionChanged(IWorkbenchPart part,
+ ISelection selection) {
+ DesignerTabbedPropertySheetPage.this.selectionChanged(
+ part, selection);
+ }
+ });
+ }
+
+ private void setSelectionProvider() {
+ this.getSite().setSelectionProvider(new ISelectionProvider() {
+ private ISelection _selection;
+
+ public void addSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ ;
+ }
+
+ /**
+ * Returns the current selection for this provider.
+ *
+ * @return the current selection
+ */
+ public ISelection getSelection() {
+ return _selection;
+ }
+
+ /**
+ * Removes the given selection change listener from this selection
+ * provider. Has no affect if an identical listener is not
+ * registered.
+ *
+ * @param listener
+ * a selection changed listener
+ */
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ ;
+ }
+
+ /**
+ * Sets the current selection for this selection provider.
+ *
+ * @param selection
+ * the new selection
+ */
+ public void setSelection(ISelection selection) {
+ _selection = selection;
+ }
+ });
+
+ }
+
+ public void createControl(Composite parent) {
+ super.createControl(parent);
+ PlatformUI
+ .getWorkbench()
+ .getHelpSystem()
+ .setHelp(
+ getControl(),
+ PDPlugin
+ .getResourceString("DesignerTabbedPropertySheetPage.help.id"));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ISectionFilter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ISectionFilter.java
new file mode 100644
index 000000000..3294ba424
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ISectionFilter.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ISectionFilter {
+
+ /**
+ * @param node
+ * @return
+ */
+ boolean appliesTo(Element node);
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ITabbedPropertiesConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ITabbedPropertiesConstants.java
new file mode 100644
index 000000000..ab11aa245
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/ITabbedPropertiesConstants.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface ITabbedPropertiesConstants {
+ static final String GENERAL_TAB_ID = "org.eclipse.jst.pagedesigner.tabQuickEdit";
+
+ static final String ALL_TAB_ID = "org.eclipse.jst.pagedesigner.tabAttributes";
+
+ static final String DEBUG_TAB_ID = "org.eclipse.jst.pagedesigner.pageDesignerTabDebug";
+
+ public String ACCCESSIBILITY_SECTION_ID = "section.accessibility";
+
+ public String ALL_PROPERTY_SECTION_ID = "section.allproperty";
+
+ /** jsf core tags */
+ public String JSF_CORE_ActionListener = "section.jsf_core_actionListener";
+
+ public String JSF_CORE_Attribute = "section.jsf_core_attribute";
+
+ public String JSF_CORE_ConvertDateTime = "section.jsf_core_convertDateTime";
+
+ public String JSF_CORE_Converter = "section.jsf_core_converter";
+
+ public String JSF_CORE_ConvertNumber = "section.jsf_core_convertNumber";
+
+ public String JSF_CORE_Facet = "section.jsf_core_facet";
+
+ public String JSF_CORE_LoadBundle = "section.jsf_core_loadBundle";
+
+ public String JSF_CORE_Param = "section.jsf_core_param";
+
+ public String JSF_CORE_SelectItem = "section.jsf_core_selectItem";
+
+ public String JSF_CORE_SelectItems = "section.jsf_core_selectItems";
+
+ public String JSF_CORE_Subview = "section.jsf_core_subview";
+
+ public String JSF_CORE_ValidateDoubleRange = "section.jsf_core_validateDoubleRange";
+
+ public String JSF_CORE_ValidateLength = "section.jsf_core_validateLength";
+
+ public String JSF_CORE_ValidateLongRange = "section.jsf_core_validateLongRange";
+
+ public String JSF_CORE_Validator = "section.jsf_core_validator";
+
+ public String JSF_CORE_ValueChangeListener = "section.jsf_core_valueChangeListener";
+
+ public String JSF_CORE_Verbatim = "section.jsf_core_verbatim";
+
+ public String JSF_CORE_View = "section.jsf_core_view";
+
+ /** jsf html tags */
+ public String JSF_HTML_Column = "section.jsf_html_column";
+
+ public String JSF_HTML_CommandButton = "section.jsf_html_commandButton";
+
+ public String JSF_HTML_CommandLink = "section.jsf_html_commandLink";
+
+ public String JSF_HTML_DataTable = "section.jsf_html_dataTable";
+
+ public String JSF_HTML_Form = "section.jsf_html_form";
+
+ public String JSF_HTML_GraphicImage = "section.jsf_html_graphicImage";
+
+ public String JSF_HTML_InputHidden = "section.jsf_html_inputHidden";
+
+ public String JSF_HTML_InputSecret = "section.jsf_html_inputSecret";
+
+ public String JSF_HTML_InputText = "section.jsf_html_inputText";
+
+ public String JSF_HTML_InputTextarea = "section.jsf_html_inputTextarea";
+
+ public String JSF_HTML_Message = "section.jsf_html_message";
+
+ public String JSF_HTML_Messages = "section.jsf_html_messages";
+
+ public String JSF_HTML_OutputFormat = "section.jsf_html_outputFormat";
+
+ public String JSF_HTML_OutputLabel = "section.jsf_html_outputLabel";
+
+ public String JSF_HTML_OutputLink = "section.jsf_html_outputLink";
+
+ public String JSF_HTML_OutputText = "section.jsf_html_outputText";
+
+ public String JSF_HTML_PanelGrid = "section.jsf_html_panelGrid";
+
+ public String JSF_HTML_PanelGroup = "section.jsf_html_panelGroup";
+
+ public String JSF_HTML_SelectBooleanCheckbox = "section.jsf_html_selectBooleanCheckbox";
+
+ public String JSF_HTML_SelectManyCheckbox = "section.jsf_html_selectManyCheckbox";
+
+ public String JSF_HTML_SelectManyListbox = "section.jsf_html_selectManyListbox";
+
+ public String JSF_HTML_SelectManyMenu = "section.jsf_html_selectManyMenu";
+
+ public String JSF_HTML_SelectOneListbox = "section.jsf_html_selectOneListbox";
+
+ public String JSF_HTML_SelectOneMenu = "section.jsf_html_selectOneMenu";
+
+ public String JSF_HTML_SelectOneRadio = "section.jsf_html_selectOneRadio";
+
+ /** sybase datawindow */
+ public String DW_DataWindow = "section.dw_dataWindow";
+
+ public String DW_Objectlink = "section.dw_objectlink";
+
+ // FIXME: when return null, will in fact using "Misc". This may not garantee
+ // it be the
+ // last category, since is sorted by string order.
+ static final String OTHER_CATEGORY = "Other";
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/MyPropertySheetPage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/MyPropertySheetPage.java
new file mode 100644
index 000000000..439cb4bdd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/MyPropertySheetPage.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.meta.internal.CategoryNameComparator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.views.properties.PropertySheetPage;
+import org.eclipse.ui.views.properties.PropertySheetSorter;
+
+/**
+ * In PropertySheetPage, the <code>setSorter</code> is protected. Creating
+ * this class to make setSorter accessible to us.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class MyPropertySheetPage extends PropertySheetPage {
+ /**
+ * Use my sorter to sort the category name. Only override the
+ * compareCategories method.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+ private static class MySorter extends PropertySheetSorter {
+ public int compareCategories(String categoryA, String categoryB) {
+ return CategoryNameComparator.getInstance().compare(categoryA,
+ categoryB);
+ }
+ }
+
+ public MyPropertySheetPage() {
+ super();
+ setSorter(new MySorter());
+ }
+
+ public void createControl(Composite parent) {
+ super.createControl(parent);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+ PDPlugin.getResourceString("MyPropertySheetPage.help.id"));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/NavigationHiearchyAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/NavigationHiearchyAction.java
new file mode 100644
index 000000000..cca5ca566
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/NavigationHiearchyAction.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class NavigationHiearchyAction extends Action {
+ private Menu _hiearchyMenu;
+
+ private Node _startNode;
+
+ private Node _currentNode;
+
+ private DesignerTabbedPropertySheetPage _propertyPage;
+
+ private class MenuCreator implements IMenuCreator {
+ public void dispose() {
+ if (_hiearchyMenu != null) {
+ for (int i = 0, n = _hiearchyMenu.getItemCount(); i < n; i++) {
+ MenuItem menuItem = _hiearchyMenu.getItem(i);
+ menuItem.setData(null);
+ }
+ _hiearchyMenu.dispose();
+ _hiearchyMenu = null;
+ }
+ }
+
+ public Menu getMenu(Menu parent) {
+ return null;
+ }
+
+ public Menu getMenu(Control parent) {
+ dispose();
+ _hiearchyMenu = new Menu(parent);
+
+ // next we need to add the list of parents node into the menu.
+ Node node = _startNode;
+ List list = new ArrayList();
+ while (node != null && !(node instanceof Document)
+ && !(node instanceof DocumentFragment)) {
+ list.add(node);
+ node = node.getParentNode();
+ }
+
+ // adding ancesters reverse order.
+ for (int i = list.size() - 1; i >= 0; i--) {
+ Node thenode = (Node) list.get(i);
+ MenuItem item = new MenuItem(_hiearchyMenu, SWT.CHECK);
+ item.setSelection(thenode == _currentNode ? true : false);
+ String text = thenode.getNodeName();
+ item.setText(text);
+ item.setData(thenode);
+ item.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ Node selectedNode = (Node) e.widget.getData();
+ _propertyPage.internalChangeSelection(selectedNode,
+ _startNode);
+ }
+ });
+ }
+
+ return _hiearchyMenu;
+ }
+ }
+
+ public NavigationHiearchyAction(DesignerTabbedPropertySheetPage propertyPage) {
+ super("");
+ setEnabled(true);
+ setMenuCreator(new MenuCreator());
+ this._propertyPage = propertyPage;
+ }
+
+ protected void changeSelection(Node selectedNode, Node startNode) {
+ this._propertyPage.internalChangeSelection(selectedNode, startNode);
+ this._currentNode = selectedNode;
+ this._startNode = startNode;
+ this.setText(this._currentNode.getNodeName());
+ }
+
+ protected void refresh(Node currentNode, Node startNode) {
+ this._currentNode = currentNode;
+ this._startNode = startNode;
+ if (!(_currentNode instanceof Text)
+ && !(_currentNode instanceof Element)) {
+ this.setText("---");
+ this.setEnabled(false);
+ } else {
+ this.setText(_currentNode.getNodeName());
+ this.setEnabled(true);
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IAction.
+ */
+ public void run() {
+ this._propertyPage.internalChangeSelection(_currentNode, _startNode);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/PropertyDescriptorWrapper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/PropertyDescriptorWrapper.java
new file mode 100644
index 000000000..6642ba169
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/PropertyDescriptorWrapper.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jst.pagedesigner.meta.EditorCreator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * This is a simple PropertyDescriptor wrapper. It simply changed the category
+ * name. This is because the default category name is "Attributes", which will
+ * make them appear before other things, and that is not what we want.
+ *
+ * @author mengbo
+ */
+public class PropertyDescriptorWrapper implements IPropertyDescriptor {
+
+ private IPropertyDescriptor _inner;
+
+ private IDOMElement _element;
+
+ /**
+ *
+ */
+ public PropertyDescriptorWrapper(IDOMElement element,
+ IPropertyDescriptor innerDescriptor) {
+ this._element = element;
+ this._inner = innerDescriptor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor(org.eclipse.swt.widgets.Composite)
+ */
+ public CellEditor createPropertyEditor(Composite parent) {
+ EditorCreator.CellEditorHolder holder = new EditorCreator.CellEditorHolder() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.EditorCreator.CellEditorHolder#createCellEditor(org.eclipse.swt.widgets.Composite)
+ */
+ public CellEditor createCellEditor(Composite parent) {
+ if (_inner != null) {
+ return _inner.createPropertyEditor(parent);
+ } else {
+ return new TextCellEditor(parent);
+ }
+ }
+ };
+ return EditorCreator.getInstance().createCellEditorWithWrapper(parent,
+ null, holder, (IDOMElement) _element, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getCategory()
+ */
+ public String getCategory() {
+ return ITabbedPropertiesConstants.OTHER_CATEGORY;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getDescription()
+ */
+ public String getDescription() {
+ return _inner.getDescription();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getDisplayName()
+ */
+ public String getDisplayName() {
+ return _inner.getDisplayName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getFilterFlags()
+ */
+ public String[] getFilterFlags() {
+ return _inner.getFilterFlags();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getHelpContextIds()
+ */
+ public Object getHelpContextIds() {
+ return _inner.getHelpContextIds();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getId()
+ */
+ public Object getId() {
+ return _inner.getId();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#getLabelProvider()
+ */
+ public ILabelProvider getLabelProvider() {
+ return _inner.getLabelProvider();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.views.properties.IPropertyDescriptor#isCompatibleWith(org.eclipse.ui.views.properties.IPropertyDescriptor)
+ */
+ public boolean isCompatibleWith(IPropertyDescriptor anotherProperty) {
+ if (anotherProperty instanceof PropertyDescriptorWrapper) {
+ return _inner
+ .isCompatibleWith(((PropertyDescriptorWrapper) anotherProperty)
+ .getInner());
+ }
+ return _inner.isCompatibleWith(anotherProperty);
+ }
+
+ public IPropertyDescriptor getInner() {
+ return _inner;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroup.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroup.java
new file mode 100644
index 000000000..c7296b44a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroup.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.attrgroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogFieldGroup;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldChangeListener;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue;
+import org.eclipse.jst.pagedesigner.meta.AttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.EditorCreator;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IElementDescriptor;
+import org.eclipse.jst.pagedesigner.meta.internal.CMRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class AttributeGroup extends DialogFieldGroup {
+ private static final Object KEY_ATTR = "KEY_ATTR"; //$NON-NLS-1$
+
+ private String _uri;
+
+ private String _tagName;
+
+ private IAttributeDescriptor[] _attrs;
+
+ private String _helpContextId;
+
+ private List _dialogFields = null;
+
+ private IDOMElement _ownerElement;
+
+ /**
+ * @param pageName
+ * @param title
+ * @param titleImage
+ */
+ public AttributeGroup(String uri, String tagName, String[] attrNames) {
+ this._uri = uri;
+ this._tagName = tagName;
+ this._attrs = prepareAttributeDescriptors(uri, tagName, attrNames);
+ }
+
+ public String getTagName() {
+ return this._tagName;
+ }
+
+ /**
+ * @return
+ */
+ public String getURI() {
+ return this._uri;
+ }
+
+ /**
+ * @param uri
+ * @param tagName
+ * @param attrNames
+ */
+ private IAttributeDescriptor[] prepareAttributeDescriptors(String uri,
+ String tagName, String[] attrNames) {
+ IAttributeDescriptor[] attrs;
+ IElementDescriptor eleDesc = CMRegistry.getInstance()
+ .getElementDescriptor(uri, tagName);
+ if (eleDesc != null) {
+ _helpContextId = eleDesc.getHelpContextID();
+ if (attrNames == null) {
+ attrs = eleDesc.getAttributeDescriptors();
+ } else {
+ attrs = new IAttributeDescriptor[attrNames.length];
+ for (int i = 0; i < attrs.length; i++) {
+ attrs[i] = eleDesc.getAttributeDescriptor(attrNames[i]);
+ if (attrs[i] == null) {
+ attrs[i] = new AttributeDescriptor(attrNames[i]);
+ }
+ }
+ }
+ } else {
+ if (attrNames == null) {
+ attrs = new IAttributeDescriptor[0];
+ } else {
+ attrs = new IAttributeDescriptor[attrNames.length];
+ for (int i = 0; i < attrs.length; i++) {
+ attrs[i] = new AttributeDescriptor(attrNames[i]);
+ }
+ }
+ }
+ return attrs;
+ }
+
+ public IAttributeDescriptor getAttributeDescriptor(DialogField field) {
+ Object obj = field.getAttachedData(KEY_ATTR);
+ if (obj instanceof IAttributeDescriptor) {
+ return (IAttributeDescriptor) obj;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Child class could override this method to create customized dialogField.
+ * Otherwise, system will use meta data to create default dailog field.
+ *
+ * @param uri
+ * @param tag
+ * @param attr
+ * @return if null, system will create default dialog field.
+ */
+ protected DialogField createDialogField(String uri, String tag,
+ IAttributeDescriptor attr) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogFieldGroup#initialize()
+ */
+ public void initialize() {
+ if (_dialogFields == null) {
+ _dialogFields = new ArrayList();
+
+ IAttributeDescriptor[] descriptors = _attrs;
+
+ for (int i = 0; i < descriptors.length; i++) {
+ DialogField field;
+ field = createDialogField(this._uri, this._tagName,
+ descriptors[i]);
+ if (field == null) {
+ EditorCreator creator = EditorCreator.getInstance();
+ field = creator.createDialogFieldWithWrapper(this._uri,
+ this._tagName, descriptors[i], null);
+ }
+
+ field.putAttachedData(KEY_ATTR, descriptors[i]);
+
+ IDialogFieldApplyListener applyListener = getDialogFieldApplyListener(
+ this._uri, this._tagName, descriptors[i]);
+ if (applyListener == null) {
+ applyListener = getDefaultApplyListener();
+ }
+ field.setDialogFieldApplyListener(applyListener);
+
+ IDialogFieldChangeListener changeListener = getDialogFieldChangeListener(
+ this._uri, this._tagName, descriptors[i]);
+ if (changeListener == null) {
+ changeListener = getDefaultChangeListener();
+ }
+ field.setDialogFieldChangeListener(changeListener);
+ _dialogFields.add(field);
+ }
+ }
+ }
+
+ /**
+ * Child class can override the method to provide listener implementation
+ *
+ * @param uri
+ * @param tag
+ * @param attr
+ * @return
+ */
+ public IDialogFieldApplyListener getDialogFieldApplyListener(String uri,
+ String tag, IAttributeDescriptor attr) {
+ return null;
+ }
+
+ /**
+ * Child class can override the method to provide listener implementation
+ *
+ * @param uri
+ * @param tag
+ * @param attr
+ * @return
+ */
+ public IDialogFieldChangeListener getDialogFieldChangeListener(String uri,
+ String tag, IAttributeDescriptor attr) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogFieldGroup#refreshData()
+ */
+ public void refreshData() {
+ if (_ownerElement == null) {
+ return;
+ }
+ initialize();
+ for (int i = 0, size = _dialogFields.size(); i < size; i++) {
+ DialogField field = (DialogField) _dialogFields.get(i);
+
+ ISupportTextValue textValue = (ISupportTextValue) field;
+ IAttributeDescriptor attr = (IAttributeDescriptor) field
+ .getAttachedData(KEY_ATTR);
+ String attrName = attr.getAttributeName();
+ String attrValue = _ownerElement.getAttribute(attrName);
+ textValue.setTextWithoutUpdate(attrValue);
+ }
+ }
+
+ public IDOMElement getElement() {
+ return _ownerElement;
+ }
+
+ public void setElementContext(IDOMNode context, IDOMElement owner) {
+ initialize();
+ this._ownerElement = owner;
+ if (context != null) {
+ for (int i = 0, size = _dialogFields.size(); i < size; i++) {
+ DialogField field = (DialogField) _dialogFields.get(i);
+ if (field instanceof IElementContextable) {
+ ((IElementContextable) field).setElementContext(context,
+ owner);
+ }
+ }
+ }
+ refreshData();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogFieldGroup#layoutDialogFields(org.eclipse.ui.forms.widgets.FormToolkit,
+ * org.eclipse.swt.widgets.Composite)
+ */
+ public void layoutDialogFields(FormToolkit toolkit, Composite parent) {
+ Composite top;
+ if (toolkit == null) {
+ top = new Composite(parent, SWT.NONE);
+ } else {
+ top = toolkit.createComposite(parent);
+ }
+ FillLayout fillLayout = new FillLayout(SWT.VERTICAL);
+ parent.setLayout(fillLayout);
+
+ if (this._helpContextId != null && this._helpContextId.length() > 0) {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(top,
+ _helpContextId);
+ }
+
+ GridLayout layout = new GridLayout();
+ int numColumns = getNumColumns();
+ layout.numColumns = numColumns;
+ top.setLayout(layout);
+
+ initialize();
+ for (int i = 0, size = _dialogFields.size(); i < size; i++) {
+ DialogField field = (DialogField) _dialogFields.get(i);
+ field.doFillIntoGrid(toolkit, top, numColumns);
+ }
+
+ DialogField maxColumnField = null;
+ int maxColumn = 0;
+ for (int i = 0, size = _dialogFields.size(); i < size; i++) {
+ DialogField field = (DialogField) _dialogFields.get(i);
+ int c = field.getNumberOfControls();
+ if (c > maxColumn) {
+ maxColumn = c;
+ maxColumnField = field;
+ }
+ }
+ if (maxColumnField != null) {
+ maxColumnField.handleGrabHorizontal();
+ }
+ }
+
+ /**
+ * @return
+ */
+ public int getNumColumns() {
+ int columns = 1;
+ initialize();
+ for (int i = 0, size = _dialogFields.size(); i < size; i++) {
+ DialogField field = (DialogField) _dialogFields.get(i);
+ columns = Math.max(columns, field.getNumberOfControls());
+ }
+ return columns;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogFieldGroup#validateDialogFields()
+ */
+ public IStatus[] validateDialogFields() {
+ return null;
+ }
+
+ /**
+ * @return
+ */
+ public DialogField[] getDialogFields() {
+ initialize();
+ DialogField[] ret = new DialogField[_dialogFields.size()];
+ _dialogFields.toArray(ret);
+ return ret;
+ }
+
+ /**
+ * get the dialogfield for the corresponding attribute.
+ *
+ * @param attrName
+ * case sensitive attribute name.
+ * @return null if fail to find.
+ */
+ public DialogField getDialogField(String attrName) {
+ initialize();
+ for (int i = 0, size = _dialogFields.size(); i < size; i++) {
+ DialogField field = (DialogField) _dialogFields.get(i);
+ IAttributeDescriptor attr = this.getAttributeDescriptor(field);
+ if (attr != null && attr.getAttributeName().equals(attrName)) {
+ return field;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupMessages.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupMessages.java
new file mode 100644
index 000000000..761d4a7de
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupMessages.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.attrgroup;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class AttributeGroupMessages {
+ private static final String BUNDLE_NAME = "org.eclipse.jst.pagedesigner.properties.attrgroup.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private AttributeGroupMessages() {
+ }
+
+ public static String getString(String key) {
+ // TODO Auto-generated method stub
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Build a formated string from the resource bundle.
+ *
+ * @param key
+ * the key into the resource bundle that has the formated string.
+ * @param arg0
+ * the first argument.
+ * @return the formated string with the argument inline.
+ */
+ public static String getString(String key, Object arg0) {
+ Object[] args = new Object[1];
+ args[0] = arg0;
+
+ MessageFormat formatter = new MessageFormat(getString(key));
+ return formatter.format(args);
+ }
+
+ /**
+ * Build a formated string from the resource bundle.
+ *
+ * @param key
+ * the key into the resource bundle that has the formated string.
+ * @param arg0
+ * the first argument.
+ * @param arg1
+ * the second argument.
+ * @return the formated string with the argument inline.
+ */
+ public static String getString(String key, Object arg0, Object arg1) {
+ Object[] args = new Object[2];
+ args[0] = arg0;
+ args[1] = arg1;
+
+ MessageFormat formatter = new MessageFormat(getString(key));
+ return formatter.format(args);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupSection.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupSection.java
new file mode 100644
index 000000000..6e3dd8ee4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/AttributeGroupSection.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.attrgroup;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeAttributeCommand;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.properties.BaseCustomSection;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetPage;
+import org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetWidgetFactory;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+
+/**
+ * This is a section for a list of attribute dialog fields.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class AttributeGroupSection extends BaseCustomSection {
+ private static final Object KEY_ATTR = "KEY_ATTR"; //$NON-NLS-1$
+
+ private IDialogFieldApplyListener _fieldApplyListener = new IDialogFieldApplyListener() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener#dialogFieldApplied(org.eclipse.jst.pagedesigner.common.dialogfield.DialogField)
+ */
+ public void dialogFieldApplied(DialogField field) {
+ Object attr = field.getAttachedData(KEY_ATTR);
+ if (attr instanceof IAttributeDescriptor && _element != null) {
+ ISupportTextValue textValue = (ISupportTextValue) field;
+ ChangeAttributeCommand c = new ChangeAttributeCommand(
+ AttributeGroupMessages
+ .getString("AttributeGroupSection.changeAttribute"), _element, ((IAttributeDescriptor) attr).getAttributeName(), textValue.getText()); //$NON-NLS-1$
+ c.execute();
+ }
+ }
+ };
+
+ protected AttributeGroup _group;
+
+ /**
+ * create the section with a default AttributeGroup. In default
+ * AttributeGroup, there is no relationship between fields.
+ *
+ * @param uri
+ * @param tagName
+ * @param attrNames
+ */
+ public AttributeGroupSection(String uri, String tagName, String[] attrNames) {
+ this(new AttributeGroup(uri, tagName, attrNames));
+ }
+
+ /**
+ * In case the group is not a default group (e.g. you may add some
+ * customized relationship between the fields).
+ *
+ * @param group
+ */
+ public AttributeGroupSection(AttributeGroup group) {
+ _group = group;
+ _group.setDefaultApplyListener(_fieldApplyListener);
+ _group.initialize();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.common.ui.properties.internal.provisional.AbstractPropertySection#setInput(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void setInput(IWorkbenchPart part, ISelection selection) {
+ super.setInput(part, selection);
+ _group.setElementContext(_element, _element);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.integration.properties.section.AbstractCustomSection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent,
+ TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ TabbedPropertySheetWidgetFactory factory = aTabbedPropertySheetPage
+ .getWidgetFactory();
+ _group.layoutDialogFields(factory, parent);
+ }
+
+ protected void notifyChanged(INodeNotifier notifier, int eventType,
+ Object changedFeature, Object oldValue, Object newValue, int pos) {
+ if (_group != null) {
+ _group.refreshData();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/DialogUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/DialogUtil.java
new file mode 100644
index 000000000..bf583569e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/DialogUtil.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.attrgroup;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.single.AddSubNodeCommand;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogFieldGroupPage;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue;
+import org.eclipse.jst.pagedesigner.common.dialogs.CommonWizardDialog;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DialogUtil {
+ /**
+ * Utility method, this method will popup a dialog for user to input
+ * attributes for initialize a sub element. In this method will create a
+ * command and execute it.
+ *
+ * @param shell
+ * parent shell for dialog
+ * @param parent
+ * the parent element
+ * @param group
+ * the AttributeGroup
+ * @return true if success, false if user canceled.
+ */
+ public static boolean createSubElement(Shell shell,
+ final IDOMElement parent, final AttributeGroup group) {
+ group.setElementContext(parent, null);
+ final DialogFieldGroupPage page = new DialogFieldGroupPage("", group); //$NON-NLS-1$
+ page.setTitle(AttributeGroupMessages.getString(
+ "DialogUtil.createTitle", group.getTagName())); //$NON-NLS-1$
+ page
+ .setDescription(AttributeGroupMessages
+ .getString(
+ "DialogUtil.createDescription", group.getTagName(), parent.getTagName())); //$NON-NLS-1$
+
+ Wizard wizard = new Wizard() {
+ public void addPages() {
+ super.addPage(page);
+ }
+
+ public boolean performFinish() {
+ DialogField[] fields = group.getDialogFields();
+ Map map = new HashMap();
+ for (int i = 0; i < fields.length; i++) {
+ IAttributeDescriptor desc = group
+ .getAttributeDescriptor(fields[i]);
+ if (desc != null && fields[i] instanceof ISupportTextValue) {
+ String value = ((ISupportTextValue) fields[i])
+ .getText();
+ if (value != null && value.length() > 0) {
+ map.put(desc.getAttributeName(), value);
+ }
+ }
+ }
+ AddSubNodeCommand addSubCommand = new AddSubNodeCommand(
+ AttributeGroupMessages
+ .getString(
+ "DialogUtil.createCommandLabel", group.getTagName()), parent, group.getTagName(), group.getURI(), map); //$NON-NLS-1$
+ addSubCommand.execute();
+ return true;
+ }
+ };
+ wizard.setWindowTitle(AttributeGroupMessages.getString(
+ "DialogUtil.createTitle", group.getTagName())); //$NON-NLS-1$
+ wizard.setDefaultPageImageDescriptor(PDPlugin.getDefault()
+ .getImageDescriptor("newsuade_wiz.gif")); //$NON-NLS-1$
+ CommonWizardDialog dialog = new CommonWizardDialog(shell, wizard);
+
+ return dialog.open() == Window.OK;
+ }
+
+ /**
+ * Utility method, this method will popup a dialog for user to input
+ * attributes for initialize a sub element. In this method will create a
+ * command and execute it.
+ *
+ * @param shell
+ * parent shell for dialog
+ * @param parent
+ * parent element
+ * @param uri
+ * new ele's uri
+ * @param tagName
+ * new ele's tag name
+ * @param attributes
+ * an array of attribute names. The dialog will create a
+ * dialogfield for each of them to allow user to input initial
+ * value. If null, the system will try to use all attribute of
+ * the element.
+ * @return true if success, false if user canceled.
+ */
+ public static boolean createSubElement(Shell shell,
+ final IDOMElement parent, final String uri, final String tagName,
+ final String[] attributes) {
+ final AttributeGroup group = new AttributeGroup(uri, tagName,
+ attributes);
+ return createSubElement(shell, parent, group);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/IElementContextable.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/IElementContextable.java
new file mode 100644
index 000000000..bb90d8033
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/IElementContextable.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.attrgroup;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * This is a special interface for those special dialog field that need context
+ * information.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IElementContextable {
+ /**
+ *
+ * @param ancester
+ * an non null element, could be the element being edited, or an
+ * ancester element when we are creating new element.
+ * @param element
+ * if not null, then is the element being edited, could be used
+ * to retrive initial data.
+ *
+ */
+ public void setElementContext(IDOMNode ancester, IDOMElement element);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/messages.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/messages.properties
new file mode 100644
index 000000000..af94f3351
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/attrgroup/messages.properties
@@ -0,0 +1,4 @@
+DialogUtil.createTitle=Create {0}
+DialogUtil.createDescription=Create subelement "{0}" under "{1}"
+DialogUtil.createCommandLabel=Create {0}
+AttributeGroupSection.changeAttribute=Change Attribute
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CSSDialogCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CSSDialogCellEditor.java
new file mode 100644
index 000000000..5a35af0f9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CSSDialogCellEditor.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeStyleCommand;
+import org.eclipse.jst.pagedesigner.ui.dialogs.StyleDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclaration;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.w3c.dom.css.ElementCSSInlineStyle;
+
+public class CSSDialogCellEditor extends EditableDialogCellEditor {
+ private IDOMElement _element;
+
+ /**
+ * @param parent
+ */
+ public CSSDialogCellEditor(Composite parent, IDOMElement element) {
+ super(parent);
+ _element = element;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(org.eclipse.swt.widgets.Control)
+ */
+ protected Object openDialogBox(Control cellEditorWindow) {
+ ICSSStyleDeclaration styleDeclaration = (ICSSStyleDeclaration) ((ElementCSSInlineStyle) _element)
+ .getStyle();
+
+ PreferenceManager manager = new PreferenceManager();
+ Shell shell = cellEditorWindow.getShell();
+
+ CSSPropertyContext context = new CSSPropertyContext(styleDeclaration);
+ StyleDialog dialog = new StyleDialog(shell, manager, _element, context);
+ if (dialog.open() == Window.OK) {
+ if (context.isModified()) {
+ ChangeStyleCommand c = new ChangeStyleCommand(_element, context);
+ c.execute();
+ }
+ }
+
+ String style = (_element == null ? null : _element
+ .getAttribute(IJSFConstants.ATTR_STYLE));
+ return style == null ? "" : style;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorFactory.java
new file mode 100644
index 000000000..6ac004d78
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorFactory.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.TreeMap;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ComboDialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.StyleComboDialogField;
+import org.eclipse.jst.pagedesigner.css2.CSSUtil;
+import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
+import org.eclipse.jst.pagedesigner.meta.IAttributeCellEditorFactory;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IValueType;
+import org.eclipse.jst.pagedesigner.ui.dialogfields.ContextableClasspathResourceButtonDialogField;
+import org.eclipse.jst.pagedesigner.ui.dialogfields.ContextableResourceButtonDialogField;
+import org.eclipse.jst.pagedesigner.ui.dialogfields.StyleButtonDialogField;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+
+/**
+ *
+ * @author mengbo
+ */
+public class CellEditorFactory implements IAttributeCellEditorFactory {
+ private static String[] CURRENCYCODES = { "AED", // United Arab Emirates,
+ // Dirhams //$NON-NLS-1$
+ "AFA", // Afghanistan, Afghanis //$NON-NLS-1$
+ "ALL", // Albania, Leke //$NON-NLS-1$
+ "AMD", // Armenia, Drams //$NON-NLS-1$
+ "ANG", // Netherlands Antilles, Guilders (also called Florins)
+ // //$NON-NLS-1$
+ "AOA", // Angola, Kwanza //$NON-NLS-1$
+ "ARS", // Argentina, Pesos //$NON-NLS-1$
+ "AUD", // Australia, Dollars //$NON-NLS-1$
+ "AWG", // Aruba, Guilders (also called Florins) //$NON-NLS-1$
+ "AZM", // Azerbaijan, Manats //$NON-NLS-1$
+ "BAM", // Bosnia and Herzegovina, Convertible Marka //$NON-NLS-1$
+ "BBD", // Barbados, Dollars //$NON-NLS-1$
+ "BDT", // Bangladesh, Taka //$NON-NLS-1$
+ "BGN", // Bulgaria, Leva //$NON-NLS-1$
+ "BHD", // Bahrain, Dinars //$NON-NLS-1$
+ "BIF", // Burundi, Francs //$NON-NLS-1$
+ "BMD", // Bermuda, Dollars //$NON-NLS-1$
+ "BND", // Brunei Darussalam, Dollars //$NON-NLS-1$
+ "BOB", // Bolivia, Bolivianos //$NON-NLS-1$
+ "BRL", // Brazil, Brazil Real //$NON-NLS-1$
+ "BSD", // Bahamas, Dollars //$NON-NLS-1$
+ "BTN", // Bhutan, Ngultrum //$NON-NLS-1$
+ "BWP", // Botswana, Pulas //$NON-NLS-1$
+ "BYR", // Belarus, Rubles //$NON-NLS-1$
+ "BZD", // Belize, Dollars //$NON-NLS-1$
+ "CAD", // Canada, Dollars //$NON-NLS-1$
+ "CDF", // Congo/Kinshasa, Congolese Francs //$NON-NLS-1$
+ "CHF", // Switzerland, Francs //$NON-NLS-1$
+ "CLP", // Chile, Pesos //$NON-NLS-1$
+ "CNY", // China, Yuan Renminbi //$NON-NLS-1$
+ "COP", // Colombia, Pesos //$NON-NLS-1$
+ "CRC", // Costa Rica, Colones //$NON-NLS-1$
+ "CSD", // Serbia, Dinars //$NON-NLS-1$
+ "CUP", // Cuba, Pesos //$NON-NLS-1$
+ "CVE", // Cape Verde, Escudos //$NON-NLS-1$
+ "CYP", // Cyprus, Pounds //$NON-NLS-1$
+ "CZK", // Czech Republic, Koruny //$NON-NLS-1$
+ "DJF", // Djibouti, Francs //$NON-NLS-1$
+ "DKK", // Denmark, Kroner //$NON-NLS-1$
+ "DOP", // Dominican Republic, Pesos //$NON-NLS-1$
+ "DZD", // Algeria, Algeria Dinars //$NON-NLS-1$
+ "EEK", // Estonia, Krooni //$NON-NLS-1$
+ "EGP", // Egypt, Pounds //$NON-NLS-1$
+ "ERN", // Eritrea, Nakfa //$NON-NLS-1$
+ "ETB", // Ethiopia, Birr //$NON-NLS-1$
+ "EUR", // Euro Member Countries, Euro //$NON-NLS-1$
+ "FJD", // Fiji, Dollars //$NON-NLS-1$
+ "FKP", // Falkland Islands (Malvinas), Pounds //$NON-NLS-1$
+ "GBP", // United Kingdom, Pounds //$NON-NLS-1$
+ "GEL", // Georgia, Lari //$NON-NLS-1$
+ "GGP", // Guernsey, Pounds //$NON-NLS-1$
+ "GHC", // Ghana, Cedis //$NON-NLS-1$
+ "GIP", // Gibraltar, Pounds //$NON-NLS-1$
+ "GMD", // Gambia, Dalasi //$NON-NLS-1$
+ "GNF", // Guinea, Francs //$NON-NLS-1$
+ "GTQ", // Guatemala, Quetzales //$NON-NLS-1$
+ "GYD", // Guyana, Dollars //$NON-NLS-1$
+ "HKD", // Hong Kong, Dollars //$NON-NLS-1$
+ "HNL", // Honduras, Lempiras //$NON-NLS-1$
+ "HRK", // Croatia, Kuna //$NON-NLS-1$
+ "HTG", // Haiti, Gourdes //$NON-NLS-1$
+ "HUF", // Hungary, Forint //$NON-NLS-1$
+ "IDR", // Indonesia, Rupiahs //$NON-NLS-1$
+ "ILS", // Israel, New Shekels //$NON-NLS-1$
+ "IMP", // Isle of Man, Pounds //$NON-NLS-1$
+ "INR", // India, Rupees //$NON-NLS-1$
+ "IQD", // Iraq, Dinars //$NON-NLS-1$
+ "IRR", // Iran, Rials //$NON-NLS-1$
+ "ISK", // Iceland, Kronur //$NON-NLS-1$
+ "JEP", // Jersey, Pounds //$NON-NLS-1$
+ "JMD", // Jamaica, Dollars //$NON-NLS-1$
+ "JOD", // Jordan, Dinars //$NON-NLS-1$
+ "JPY", // Japan, Yen //$NON-NLS-1$
+ "KES", // Kenya, Shillings //$NON-NLS-1$
+ "KGS", // Kyrgyzstan, Soms //$NON-NLS-1$
+ "KHR", // Cambodia, Riels //$NON-NLS-1$
+ "KMF", // Comoros, Francs //$NON-NLS-1$
+ "KPW", // Korea (North), Won //$NON-NLS-1$
+ "KRW", // Korea (South), Won //$NON-NLS-1$
+ "KWD", // Kuwait, Dinars //$NON-NLS-1$
+ "KYD", // Cayman Islands, Dollars //$NON-NLS-1$
+ "KZT", // Kazakhstan, Tenge //$NON-NLS-1$
+ "LAK", // Laos, Kips //$NON-NLS-1$
+ "LBP", // Lebanon, Pounds //$NON-NLS-1$
+ "LKR", // Sri Lanka, Rupees //$NON-NLS-1$
+ "LRD", // Liberia, Dollars //$NON-NLS-1$
+ "LSL", // Lesotho, Maloti //$NON-NLS-1$
+ "LTL", // Lithuania, Litai //$NON-NLS-1$
+ "LVL", // Latvia, Lati //$NON-NLS-1$
+ "LYD", // Libya, Dinars //$NON-NLS-1$
+ "MAD", // Morocco, Dirhams //$NON-NLS-1$
+ "MDL", // Moldova, Lei //$NON-NLS-1$
+ "MGA", // Madagascar, Ariary //$NON-NLS-1$
+ "MKD", // Macedonia, Denars //$NON-NLS-1$
+ "MMK", // Myanmar (Burma), Kyats //$NON-NLS-1$
+ "MNT", // Mongolia, Tugriks //$NON-NLS-1$
+ "MOP", // Macau, Patacas //$NON-NLS-1$
+ "MRO", // Mauritania, Ouguiyas //$NON-NLS-1$
+ "MTL", // Malta, Liri //$NON-NLS-1$
+ "MUR", // Mauritius, Rupees //$NON-NLS-1$
+ "MVR", // Maldives (Maldive Islands), Rufiyaa //$NON-NLS-1$
+ "MWK", // Malawi, Kwachas //$NON-NLS-1$
+ "MXN", // Mexico, Pesos //$NON-NLS-1$
+ "MYR", // Malaysia, Ringgits //$NON-NLS-1$
+ "MZM", // Mozambique, Meticais //$NON-NLS-1$
+ "NAD", // Namibia, Dollars //$NON-NLS-1$
+ "NGN", // Nigeria, Nairas //$NON-NLS-1$
+ "NIO", // Nicaragua, Cordobas //$NON-NLS-1$
+ "NOK", // Norway, Krone //$NON-NLS-1$
+ "NPR", // Nepal, Nepal Rupees //$NON-NLS-1$
+ "NZD", // New Zealand, Dollars //$NON-NLS-1$
+ "OMR", // Oman, Rials //$NON-NLS-1$
+ "PAB", // Panama, Balboa //$NON-NLS-1$
+ "PEN", // Peru, Nuevos Soles //$NON-NLS-1$
+ "PGK", // Papua New Guinea, Kina //$NON-NLS-1$
+ "PHP", // Philippines, Pesos //$NON-NLS-1$
+ "PKR", // Pakistan, Rupees //$NON-NLS-1$
+ "PLN", // Poland, Zlotych //$NON-NLS-1$
+ "PYG", // Paraguay, Guarani //$NON-NLS-1$
+ "QAR", // Qatar, Rials //$NON-NLS-1$
+ "ROL", // Romania, Lei //$NON-NLS-1$
+ "RUB", // Russia, Rubles //$NON-NLS-1$
+ "RWF", // Rwanda, Rwanda Francs //$NON-NLS-1$
+ "SAR", // Saudi Arabia, Riyals //$NON-NLS-1$
+ "SBD", // Solomon Islands, Dollars //$NON-NLS-1$
+ "SCR", // Seychelles, Rupees //$NON-NLS-1$
+ "SDD", // Sudan, Dinars //$NON-NLS-1$
+ "SEK", // Sweden, Kronor //$NON-NLS-1$
+ "SGD", // Singapore, Dollars //$NON-NLS-1$
+ "SHP", // Saint Helena, Pounds //$NON-NLS-1$
+ "SIT", // Slovenia, Tolars //$NON-NLS-1$
+ "SKK", // Slovakia, Koruny //$NON-NLS-1$
+ "SLL", // Sierra Leone, Leones //$NON-NLS-1$
+ "SOS", // Somalia, Shillings //$NON-NLS-1$
+ "SPL", // Seborga, Luigini //$NON-NLS-1$
+ "SRD", // Suriname, Dollars //$NON-NLS-1$
+ "STD", // S?o Tome and Principe, Dobras //$NON-NLS-1$
+ "SVC", // El Salvador, Colones //$NON-NLS-1$
+ "SYP", // Syria, Pounds //$NON-NLS-1$
+ "SZL", // Swaziland, Emalangeni //$NON-NLS-1$
+ "THB", // Thailand, Baht //$NON-NLS-1$
+ "TJS", // Tajikistan, Somoni //$NON-NLS-1$
+ "TMM", // Turkmenistan, Manats //$NON-NLS-1$
+ "TND", // Tunisia, Dinars //$NON-NLS-1$
+ "TOP", // Tonga, Pa'anga //$NON-NLS-1$
+ "TRL", // Turkey, Liras [being phased out] //$NON-NLS-1$
+ "TRY", // Turkey, New Lira //$NON-NLS-1$
+ "TTD", // Trinidad and Tobago, Dollars //$NON-NLS-1$
+ "TVD", // Tuvalu, Tuvalu Dollars //$NON-NLS-1$
+ "TWD", // Taiwan, New Dollars //$NON-NLS-1$
+ "TZS", // Tanzania, Shillings //$NON-NLS-1$
+ "UAH", // Ukraine, Hryvnia //$NON-NLS-1$
+ "UGX", // Uganda, Shillings //$NON-NLS-1$
+ "USD", // United States of America, Dollars //$NON-NLS-1$
+ "UYU", // Uruguay, Pesos //$NON-NLS-1$
+ "UZS", // Uzbekistan, Sums //$NON-NLS-1$
+ "VEB", // Venezuela, Bolivares //$NON-NLS-1$
+ "VND", // Viet Nam, Dong //$NON-NLS-1$
+ "VUV", // Vanuatu, Vatu //$NON-NLS-1$
+ "WST", // Samoa, Tala //$NON-NLS-1$
+ "XAF", // Communaut�� Financi��re Africaine BEAC, Francs
+ // //$NON-NLS-1$
+ "XAG", // Silver, Ounces //$NON-NLS-1$
+ "XAU", // Gold, Ounces //$NON-NLS-1$
+ "XCD", // East Caribbean Dollars //$NON-NLS-1$
+ "XDR", // International Monetary Fund (IMF) Special Drawing Rights
+ // //$NON-NLS-1$
+ "XOF", // Communaut�� Financi��re Africaine BCEAO, Francs
+ // //$NON-NLS-1$
+ "XPD", // Palladium Ounces //$NON-NLS-1$
+ "XPF", // Comptoirs Fran?ais du Pacifique Francs //$NON-NLS-1$
+ "XPT", // Platinum, Ounces //$NON-NLS-1$
+ "YER", // Yemen, Rials //$NON-NLS-1$
+ "ZAR", // South Africa, Rand //$NON-NLS-1$
+ "ZMK", // Zambia, Kwacha //$NON-NLS-1$
+ "ZWD" // Zimbabwe, Zimbabwe Dollars //$NON-NLS-1$
+ };
+
+ public CellEditor createCellEditor(Composite parent,
+ IAttributeDescriptor attr, Element element) {
+ String type = attr.getValueType();
+
+ if (IValueType.ENUMERATED.equalsIgnoreCase(type)) {
+ Map map = new HashMap(attr.getOptions());
+ String defaultValue = attr.getDefaultValue();
+ if (defaultValue == null) {
+ return LabeledComboBoxCellEditor.newInstance(parent, map,
+ SWT.NONE);
+ } else {
+ return LabeledStyleComboCellEditor.newInstance(parent, map,
+ defaultValue, SWT.NONE);
+ }
+ } else if (IValueType.LOCALE.equalsIgnoreCase(type)) {
+ Map map = new HashMap();
+ Locale[] locales = Locale.getAvailableLocales();
+ for (int i = 0, size = locales.length; i < size; i++) {
+ map.put(locales[i].toString(), locales[i].toString());
+ }
+ return LabeledComboBoxCellEditor.newInstance(parent, map, SWT.NONE);
+ } else if (IValueType.TIMEZONE.equalsIgnoreCase(type)) {
+ Map map = new HashMap();
+ String[] ids = TimeZone.getAvailableIDs();
+ for (int i = 0, size = ids.length; i < size; i++) {
+ map.put(ids[i], ids[i]);
+ }
+ return LabeledComboBoxCellEditor.newInstance(parent, map, SWT.NONE);
+ } else if (IValueType.RELATIVEPATH.equalsIgnoreCase(type)
+ || IValueType.WEBPATH.equalsIgnoreCase(type)) {
+ IProject project = getProject(element);
+ if (project != null) {
+ ResourceDialogCellEditor cellEditor = new ResourceDialogCellEditor(
+ parent);
+ cellEditor.setSuffixs(attr.getParameterByName(
+ IAttributeDescriptor.PARAMETER_SUFFIX).split(";"));
+ cellEditor
+ .setSeparator(attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_SEPARATOR));
+ cellEditor.setProject(project);
+ cellEditor.setReferredFile(getFile(element));
+ if ("".equalsIgnoreCase(cellEditor.getSeparator())) {
+ cellEditor.setResourceDescription(ResourceBoundle
+ .getString("FileCellEditor.Msg"));
+ } else {
+ cellEditor.setResourceDescription(ResourceBoundle
+ .getString("FileCellEditor.Msg1"));
+ }
+ if (IValueType.WEBPATH.equalsIgnoreCase(type)) {
+ cellEditor.setWebPath(true);
+ }
+
+ if (IJSPCoreConstants.TAG_DIRECTIVE_INCLUDE.equals(element
+ .getLocalName())
+ || IJSPCoreConstants.TAG_INCLUDE.equals(element
+ .getLocalName())) {
+ cellEditor.setTransformJSPURL(false);
+ }
+ return cellEditor;
+ }
+ } else if (IValueType.CLASSPATH_RESOURCE.equalsIgnoreCase(type)) {
+ return new LoadbundleSelectionCellEditor(parent,
+ getProject(element));
+ } else if (IValueType.CSSID.equalsIgnoreCase(type)) {
+
+ } else if (IValueType.CSSCLASS.equalsIgnoreCase(type)) {
+ String cssclasses[] = CSSUtil.getCSSClasses(element
+ .getOwnerDocument());
+ Map map = new HashMap();
+ if (cssclasses != null) {
+ for (int i = 0; i < cssclasses.length; i++) {
+ map.put(cssclasses[i], cssclasses[i]);
+ }
+ }
+ return LabeledComboBoxCellEditor.newInstance(parent, map, SWT.NONE);
+ } else if (IValueType.BOOLEAN.equalsIgnoreCase(type)) {
+ String defaultValue = attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_DEFAULT);
+ Map booleanMap = new HashMap();
+ booleanMap.put(Boolean.TRUE.toString(), Boolean.TRUE.toString());
+ booleanMap.put(Boolean.FALSE.toString(), Boolean.FALSE.toString());
+ if (defaultValue == null) {
+ return LabeledComboBoxCellEditor.newInstance(parent,
+ booleanMap, SWT.NONE);
+ } else {
+ return LabeledStyleComboCellEditor.newInstance(parent,
+ booleanMap, defaultValue, SWT.NONE);
+ }
+ } else if (IValueType.CSSSTYLE.equalsIgnoreCase(type)) {
+ String param = attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_STYLE);
+ if (!param.equalsIgnoreCase("STYLE")) {
+ return null;
+ }
+ CSSDialogCellEditor cellEditor = new CSSDialogCellEditor(parent,
+ (IDOMElement) element);
+ return cellEditor;
+ } else if (IValueType.NAMED_BOOLEAN.equalsIgnoreCase(type)) {
+ return NamedBooleanCellEditor.newInstance(parent, SWT.NONE,
+ (IDOMElement) element, attr);
+ } else if (IValueType.CURRENCYCODE.equalsIgnoreCase(type)) {
+ Map map = new HashMap();
+ for (int i = 0, n = CURRENCYCODES.length; i < n; i++) {
+ map.put(CURRENCYCODES[i], CURRENCYCODES[i]);
+ }
+
+ return LabeledComboBoxCellEditor.newInstance(parent, map, SWT.NONE);
+ }
+
+ // if there is no type or type unknonw, then we just return null. and
+ // system will
+ // create default (text cell editor).
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.meta.IAttributeCellEditorFactory#createDialogField(org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor,
+ * org.w3c.dom.Element, org.w3c.dom.Element)
+ */
+ public DialogField createDialogField(IAttributeDescriptor attr) {
+ String type = attr.getValueType();
+
+ if (IValueType.ENUMERATED.equalsIgnoreCase(type)
+ || IValueType.LOCALE.equalsIgnoreCase(type)
+ || IValueType.TIMEZONE.equalsIgnoreCase(type)) {
+ Map map = new HashMap();
+ if (IValueType.ENUMERATED.equalsIgnoreCase(type)) {
+ map = attr.getOptions();
+ } else if (IValueType.LOCALE.equalsIgnoreCase(type)) {
+ Locale[] locales = Locale.getAvailableLocales();
+ for (int i = 0, size = locales.length; i < size; i++) {
+ map.put(locales[i].toString(), locales[i].toString());
+ }
+ } else {
+ String[] ids = TimeZone.getAvailableIDs();
+ for (int i = 0, size = ids.length; i < size; i++) {
+ map.put(ids[i], ids[i]);
+ }
+ }
+ if (map != null && !map.isEmpty()) {
+ String defaultValue = attr.getDefaultValue();
+ if (defaultValue == null || "".equals(defaultValue)) {
+ attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_DEFAULT);
+ }
+ StyleComboDialogField field = new StyleComboDialogField(
+ SWT.NONE);
+ field.setDefaultValue(defaultValue);
+ field.setLabelText(attr.getLabelString());
+ field.setEntryMap(new TreeMap(map));
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ }
+ // eles the config is incorrect. fall through, will return null.
+ } else if (IValueType.RELATIVEPATH.equalsIgnoreCase(type)) {
+ String param = attr.getTypeParameter();
+ ContextableResourceButtonDialogField field = new ContextableResourceButtonDialogField();
+ field.setLabelText(attr.getLabelString());
+ if (param != null) {
+ field.setSuffixs(attr.getParameterByName(
+ IAttributeDescriptor.PARAMETER_SUFFIX).split(";"));
+ }
+ field.setResourceDescription(ResourceBoundle
+ .getString("FileCellEditor.Msg"));
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ } else if (IValueType.WEBPATH.equalsIgnoreCase(type)) {
+ String param = attr.getTypeParameter();
+ ContextableResourceButtonDialogField field = new ContextableResourceButtonDialogField();
+ field.setLabelText(attr.getLabelString());
+ if (param != null) {
+ field.setSuffixs(attr.getParameterByName(
+ IAttributeDescriptor.PARAMETER_SUFFIX).split(";"));
+ field
+ .setSeparator(attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_SEPARATOR));
+ }
+ if ("".equalsIgnoreCase(field.getSeparator())) {
+ field.setResourceDescription(ResourceBoundle
+ .getString("FileCellEditor.Msg"));
+ } else {
+ field.setResourceDescription(ResourceBoundle
+ .getString("FileCellEditor.Msg1"));
+ }
+ field.setWebPath(true);
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ } else if (IValueType.CLASSPATH_RESOURCE.equals(type)) {
+ ContextableClasspathResourceButtonDialogField field = new ContextableClasspathResourceButtonDialogField();
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ } else if (IValueType.BOOLEAN.equalsIgnoreCase(type)) {
+ String defaultValue = attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_DEFAULT);
+ StyleComboDialogField field = new StyleComboDialogField(SWT.NONE);
+ TreeMap map = new TreeMap();
+ map.put("", "");
+ map.put(Boolean.FALSE.toString(), Boolean.FALSE.toString());
+ map.put(Boolean.TRUE.toString(), Boolean.TRUE.toString());
+ field.setEntryMap(map);
+ field.setDefaultValue(defaultValue);
+ field.setLabelText(attr.getLabelString());
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ } else if (IValueType.CSSSTYLE.equalsIgnoreCase(type)) {
+ String param = attr
+ .getParameterByName(IAttributeDescriptor.PARAMETER_STYLE);
+ if (!"STYLE".equalsIgnoreCase(param)) {
+ return null;
+ }
+ StyleButtonDialogField field = new StyleButtonDialogField();
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ } else if (IValueType.CURRENCYCODE.equalsIgnoreCase(type)) {
+ ComboDialogField field = new ComboDialogField(SWT.NONE);
+ field.setLabelText(attr.getLabelString());
+ field.setItems(CURRENCYCODES);
+ field.setRequired(attr.isRequired());
+ field.setToolTip(attr.getDescription());
+ return field;
+ }
+
+ // if there is no type or type unknonw, then we just return null. and
+ // system will
+ // create default (text cell editor).
+ return null;
+ }
+
+ private IProject getProject(Element element) {
+ if (element instanceof IDOMElement) {
+ IDOMModel model = ((IDOMElement) element).getModel();
+ IFile file = StructuredModelUtil.getFileFor(model);
+ if (file != null) {
+ return file.getProject();
+ }
+ }
+ return null;
+ }
+
+ public String[] getSupportedValueTypes() {
+ return null;
+ }
+
+ private IFile getFile(Element element) {
+ if (element instanceof IDOMElement) {
+ IDOMModel model = ((IDOMElement) element).getModel();
+ IFile file = StructuredModelUtil.getFileFor(model);
+ return file;
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorWrapper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorWrapper.java
new file mode 100644
index 000000000..65ba99814
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/CellEditorWrapper.java
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ICellEditorListener;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * CellEditorWrapper is a special cell editor, that wraps an existing cell
+ * editor by adding a small clickable button to end of it.
+ *
+ * Due to limitation of the CellEditor framework, this wrapping technology may
+ * resulting in some small inconvenience when change focus from the "wrapped"
+ * cell editor to the "added" button.
+ *
+ * This is an abstract class. Child class need override some methods.
+ *
+ * @author mengbo
+ */
+public abstract class CellEditorWrapper extends CellEditor {
+ /**
+ * The editor control.
+ */
+ private Composite _editor;
+
+ /**
+ * the wrapped cell editor
+ */
+ private CellEditor _wrapped;
+
+ /**
+ * The button.
+ */
+ private Button _button;
+
+ /**
+ * Internal class for laying out the dialog.
+ */
+ private class DialogCellLayout extends Layout {
+ public void layout(Composite editor, boolean force) {
+ Rectangle bounds = editor.getClientArea();
+ Point size = _button.computeSize(SWT.DEFAULT, SWT.DEFAULT, force);
+ // if (_wrapped != null)
+ _wrapped.getControl().setBounds(0, 0, bounds.width - size.x,
+ bounds.height);
+ _button.setBounds(bounds.width - size.x, 0, size.x, bounds.height);
+ }
+
+ public Point computeSize(Composite editor, int wHint, int hHint,
+ boolean force) {
+ if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
+ return new Point(wHint, hHint);
+ Point contentsSize = _wrapped.getControl().computeSize(SWT.DEFAULT,
+ SWT.DEFAULT, force);
+ Point buttonSize = _button.computeSize(SWT.DEFAULT, SWT.DEFAULT,
+ force);
+ // Just return the button width to ensure the button is not clipped
+ // if the label is long.
+ // The label will just use whatever extra width there is
+ Point result = new Point(buttonSize.x, Math.max(contentsSize.y,
+ buttonSize.y));
+ return result;
+ }
+ }
+
+ /**
+ * Default DialogCellEditor style
+ */
+ private static final int defaultStyle = SWT.NONE;
+
+ /**
+ * Creates a new dialog cell editor with no control
+ *
+ * @since 2.1
+ */
+ public CellEditorWrapper() {
+ setStyle(defaultStyle);
+ }
+
+ /**
+ * Creates a new dialog cell editor parented under the given control. The
+ * cell editor value is <code>null</code> initially, and has no validator.
+ *
+ * @param parent
+ * the parent control
+ */
+ protected CellEditorWrapper(Composite parent) {
+ this(parent, defaultStyle);
+ }
+
+ /**
+ * Creates a new dialog cell editor parented under the given control. The
+ * cell editor value is <code>null</code> initially, and has no validator.
+ *
+ * @param parent
+ * the parent control
+ * @param style
+ * the style bits
+ * @since 2.1
+ */
+ protected CellEditorWrapper(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ /**
+ * Creates the button for this cell editor under the given parent control.
+ * <p>
+ * The default implementation of this framework method creates the button
+ * display on the right hand side of the dialog cell editor. Subclasses may
+ * extend or reimplement.
+ * </p>
+ *
+ * @param parent
+ * the parent control
+ * @return the new button control
+ */
+ protected Button createButton(Composite parent) {
+ Button result = new Button(parent, SWT.DOWN);
+ result.setImage(getBindingImage());
+ // result.setText("..."); //$NON-NLS-1$
+ return result;
+ }
+
+ /**
+ * Since createButton is called from constructor, so we could only let child
+ * class override this method to provide image. Rather than setting as
+ * property.
+ *
+ * @return
+ */
+ protected abstract Image getBindingImage();
+
+ /**
+ * Creates the controls used to show the value of this cell editor.
+ * <p>
+ * The default implementation of this framework method creates a label
+ * widget, using the same font and background color as the parent control.
+ * </p>
+ * <p>
+ * Subclasses may reimplement. If you reimplement this method, you should
+ * also reimplement <code>updateContents</code>.
+ * </p>
+ *
+ * @param cell
+ * the control for this cell editor
+ */
+ protected Control createContents(Composite cell) {
+ _wrapped = createWrappedCellEditor(cell);
+ if (_wrapped == null) {
+ _wrapped = new TextCellEditor(cell);
+ }
+ _wrapped.addListener(new ICellEditorListener() {
+ public void applyEditorValue() {
+ fireApplyEditorValue();
+ }
+
+ public void cancelEditor() {
+ fireCancelEditor();
+ }
+
+ public void editorValueChanged(boolean oldValidState,
+ boolean newValidState) {
+ fireEditorValueChanged(oldValidState, newValidState);
+ }
+ });
+ _wrapped.addPropertyChangeListener(new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ // FIXME:
+ }
+ });
+
+ _wrapped.getControl().setVisible(true);
+ _wrapped.getControl().addListener(SWT.Hide, new Listener() {
+ public void handleEvent(Event event) {
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ if (_wrapped != null && _wrapped.getControl() != null
+ && !_wrapped.getControl().isDisposed()) {
+ _wrapped.getControl().setVisible(true);
+ } else {
+ deactivate();
+ }
+ }
+ });
+
+ }
+ });
+ return _wrapped.getControl();
+ }
+
+ /**
+ * @param cell
+ * @return
+ */
+ protected abstract CellEditor createWrappedCellEditor(Composite cell);
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected Control createControl(Composite parent) {
+ Font font = parent.getFont();
+ Color bg = parent.getBackground();
+
+ _editor = new Composite(parent, getStyle());
+ _editor.setFont(font);
+ _editor.setBackground(bg);
+ _editor.setLayout(new DialogCellLayout());
+
+ createContents(_editor);
+ // updateContents(value);
+
+ _button = createButton(_editor);
+ _button.setFont(font);
+
+ _button.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ if (e.character == '\u001b') { // Escape
+ fireCancelEditor();
+ }
+ }
+ });
+
+ _button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ Object newValue = openDialogBox(_editor);
+ if (newValue != null) {
+ boolean newValidState = isCorrect(newValue);
+ if (newValidState) {
+ markDirty();
+ doSetValue(newValue);
+ } else {
+ // try to insert the current value into the error
+ // message.
+ setErrorMessage(MessageFormat.format(getErrorMessage(),
+ new Object[] { newValue.toString() }));
+ }
+ fireApplyEditorValue();
+ }
+ }
+ });
+
+ setValueValid(true);
+
+ return _editor;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor. The focus is set to the cell
+ * editor's button.
+ */
+ protected void doSetFocus() {
+ if (_wrapped != null && _wrapped.getControl() != null
+ && !_wrapped.getControl().isDisposed()) {
+ _wrapped.setFocus();
+ } else {
+ _button.setFocus();
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected Object doGetValue() {
+ return _wrapped.getValue();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected void doSetValue(Object value) {
+ if (_wrapped != null) {
+ _wrapped.setValue(value);
+ }
+ }
+
+ /**
+ * Opens a dialog box under the given parent control and returns the
+ * dialog's value when it closes, or <code>null</code> if the dialog was
+ * cancelled or no selection was made in the dialog.
+ * <p>
+ * This framework method must be implemented by concrete subclasses. It is
+ * called when the user has pressed the button and the dialog box must pop
+ * up.
+ * </p>
+ *
+ * @param cellEditorWindow
+ * the parent control cell editor's window so that a subclass can
+ * adjust the dialog box accordingly
+ * @return the selected value, or <code>null</code> if the dialog was
+ * cancelled or no selection was made in the dialog
+ */
+ protected abstract Object openDialogBox(Control cellEditorWindow);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#activate()
+ */
+ public void activate() {
+ super.activate();
+ _wrapped.activate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#deactivate()
+ */
+ public void deactivate() {
+ super.deactivate();
+ // if (_wrapped != null)
+ // {
+ // _wrapped.deactivate();
+ // }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#dispose()
+ */
+ public void dispose() {
+ _wrapped.dispose();
+ super.dispose();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/EditableDialogCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/EditableDialogCellEditor.java
new file mode 100644
index 000000000..9a9c38599
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/EditableDialogCellEditor.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jface.viewers.DialogCellEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author mengbo
+ */
+public abstract class EditableDialogCellEditor extends DialogCellEditor {
+ private Text _text;
+
+ /**
+ *
+ */
+ public EditableDialogCellEditor() {
+ super();
+ }
+
+ /**
+ * @param parent
+ */
+ public EditableDialogCellEditor(Composite parent) {
+ super(parent);
+ }
+
+ /**
+ * @param parent
+ * @param style
+ */
+ public EditableDialogCellEditor(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.DialogCellEditor#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createContents(Composite cell) {
+ _text = new Text(cell, SWT.LEFT);
+ _text.setFont(cell.getFont());
+ _text.setBackground(cell.getBackground());
+ _text.addKeyListener(new KeyAdapter() {
+ // hook key pressed - see PR 14201
+ public void keyPressed(KeyEvent e) {
+ keyReleaseOccured(e);
+ // disposed this cell editor
+ if ((getControl() == null) || getControl().isDisposed()) {
+ return;
+ }
+ }
+ });
+ // when the text control has focus, the cellEditor will deactive even
+ // when you press the button.
+ // Add the follow codes enable switch to the button control.
+ _text.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent e) {
+ boolean newValidState = isCorrect(_text.getText());
+ if (newValidState) {
+ markDirty();
+ doSetValue(_text.getText());
+ } else {
+ // try to insert the current value into the error message.
+ setErrorMessage(MessageFormat.format(getErrorMessage(),
+ new Object[] { _text.getText().toString() }));
+ }
+ }
+ });
+
+ return _text;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#doSetFocus()
+ */
+ protected void doSetFocus() {
+ _text.setFocus();
+ _text.selectAll();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.DialogCellEditor#updateContents(java.lang.Object)
+ */
+ protected void updateContents(Object value) {
+ if (_text == null || _text.isDisposed()) {
+ return;
+ }
+
+ String text = "";//$NON-NLS-1$
+ if (value != null) {
+ text = value.toString();
+ }
+ _text.setText(text);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#keyReleaseOccured(org.eclipse.swt.events.KeyEvent)
+ */
+ protected void keyReleaseOccured(KeyEvent keyEvent) {
+ if (keyEvent.character == '\r') {
+ boolean newValidState = isCorrect(_text.getText());
+ if (newValidState) {
+ markDirty();
+ doSetValue(_text.getText());
+ } else {
+ // try to insert the current value into the error message.
+ setErrorMessage(MessageFormat.format(getErrorMessage(),
+ new Object[] { _text.getText().toString() }));
+ }
+ fireApplyEditorValue();
+ }
+ super.keyReleaseOccured(keyEvent);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledComboBoxCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledComboBoxCellEditor.java
new file mode 100644
index 000000000..989c3bb93
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledComboBoxCellEditor.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.sse.ui.internal.Logger;
+
+/**
+ * A simple ComboBoxCellEditor, which allow value and display string to be
+ * different.
+ *
+ * @author mengbo
+ */
+public class LabeledComboBoxCellEditor extends ComboBoxCellEditor {
+ private boolean _fSettingValue = false;
+
+ private Object[] _values;
+
+ public static LabeledComboBoxCellEditor newInstance(Composite parent,
+ Map valueLabelMap, int style) {
+ // we'll sort according to label. since that is what being show to user.
+ List list = new ArrayList();
+ for (Iterator iter = valueLabelMap.keySet().iterator(); iter.hasNext();) {
+ Object key = (Object) iter.next();
+ String label = (String) valueLabelMap.get(key);
+ list.add(new Object[] { key, label });
+ }
+ // sort by label
+ Collections.sort(list, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ String label1 = (String) ((Object[]) o1)[1];
+ String label2 = (String) ((Object[]) o2)[1];
+ return label1.compareTo(label2);
+ }
+ });
+ Object[] values = new Object[list.size()];
+ String[] labels = new String[list.size()];
+ for (int i = 0, n = list.size(); i < n; i++) {
+ values[i] = ((Object[]) list.get(i))[0];
+ labels[i] = (String) ((Object[]) list.get(i))[1];
+ }
+ return new LabeledComboBoxCellEditor(parent, values, labels, style);
+ }
+
+ /**
+ * @param parent
+ * @param items
+ */
+ public LabeledComboBoxCellEditor(Composite parent, Object[] values,
+ String[] labels) {
+ this(parent, values, labels, SWT.NONE);
+ }
+
+ /**
+ * @param parent
+ * @param items
+ * @param style
+ */
+ public LabeledComboBoxCellEditor(Composite parent, Object[] values,
+ String[] labels, int style) {
+ super(parent, labels, style);
+ _values = values;
+ }
+
+ protected Object doGetValue() {
+ // otherwise limits to set of valid values
+ Object index = super.doGetValue();
+ int selection = -1;
+ if (index instanceof Integer) {
+ selection = ((Integer) index).intValue();
+ }
+ if (selection >= 0) {
+ return _values[selection];
+ } else if (getControl() instanceof CCombo) {
+ // retrieve the actual text as the list of valid items doesn't
+ // contain the value
+ return ((CCombo) getControl()).getText();
+ }
+ return null;
+ }
+
+ protected void doSetValue(Object value) {
+ if (_fSettingValue) {
+ return;
+ }
+ _fSettingValue = true;
+ if (value instanceof Integer) {
+ super.doSetValue(value);
+ } else {
+ String stringValue = value.toString();
+ int selection = -1;
+ for (int i = 0; i < _values.length; i++) {
+ if (_values[i].equals(stringValue)) {
+ selection = i;
+ }
+ }
+ if (selection >= 0) {
+ super.doSetValue(new Integer(selection));
+ } else {
+ super.doSetValue(new Integer(-1));
+ if (getControl() instanceof CCombo
+ && !stringValue.equals(((CCombo) getControl())
+ .getText())) {
+ // update the Text widget
+ ((CCombo) getControl()).setText(stringValue);
+ }
+ }
+ }
+ _fSettingValue = false;
+ }
+
+ public void setItems(String[] newItems) {
+ if (getControl() == null || getControl().isDisposed()) {
+ Logger.log(Logger.ERROR,
+ "Attempted to update item list for disposed cell editor"); //$NON-NLS-1$
+ return;
+ }
+
+ // keep selection if possible
+ Object previousSelectedValue = getValue();
+ super.setItems(newItems);
+ if (previousSelectedValue != null && getControl() instanceof CCombo) {
+ for (int i = 0; i < newItems.length; i++) {
+ if (newItems[i].equals(previousSelectedValue)) {
+ setValue(previousSelectedValue);
+ }
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledStyleComboCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledStyleComboCellEditor.java
new file mode 100644
index 000000000..f1b2cd80c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LabeledStyleComboCellEditor.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jst.pagedesigner.common.widget.StyleCombo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.sse.ui.internal.Logger;
+
+public class LabeledStyleComboCellEditor extends StyleComboCellEditor {
+ private boolean _fSettingValue = false;
+
+ private Object[] _values;
+
+ public static LabeledStyleComboCellEditor newInstance(Composite parent,
+ Map valueLabelMap, String defaultValue, int style) {
+ // we'll sort according to label. since that is what being show to user.
+ List list = new ArrayList();
+ for (Iterator iter = valueLabelMap.keySet().iterator(); iter.hasNext();) {
+ Object key = (Object) iter.next();
+ String label = (String) valueLabelMap.get(key);
+ list.add(new Object[] { key, label });
+ }
+ // sort by label
+ Collections.sort(list, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ String label1 = (String) ((Object[]) o1)[1];
+ String label2 = (String) ((Object[]) o2)[1];
+ return label1.compareTo(label2);
+ }
+ });
+ Object[] values = new Object[list.size()];
+ String[] labels = new String[list.size()];
+ for (int i = 0, n = list.size(); i < n; i++) {
+ values[i] = ((Object[]) list.get(i))[0];
+ labels[i] = (String) ((Object[]) list.get(i))[1];
+ }
+ return new LabeledStyleComboCellEditor(parent, values, labels,
+ defaultValue, style);
+ }
+
+ /**
+ * @param parent
+ * @param items
+ * @param style
+ */
+ public LabeledStyleComboCellEditor(Composite parent, Object[] values,
+ String[] labels, String defaultValue, int style) {
+ super(parent, labels, style);
+ StyleCombo combo = (StyleCombo) getControl();
+ combo.setDefaultValue(defaultValue);
+ _values = values;
+ }
+
+ protected Object doGetValue() {
+ // otherwise limits to set of valid values
+ Object index = super.doGetValue();
+ int selection = -1;
+ if (index instanceof Integer) {
+ selection = ((Integer) index).intValue();
+ }
+ if (selection >= 0) {
+ return _values[selection];
+ } else if (getControl() instanceof StyleCombo) {
+ // retrieve the actual text as the list of valid items doesn't
+ // contain the value
+ return ((StyleCombo) getControl()).getText();
+ }
+ return null;
+ }
+
+ protected void doSetValue(Object value) {
+ if (_fSettingValue) {
+ return;
+ }
+ _fSettingValue = true;
+ if (value instanceof Integer) {
+ super.doSetValue(value);
+ } else {
+ String stringValue = value.toString();
+ int selection = -1;
+ for (int i = 0; i < _values.length; i++) {
+ if (_values[i].equals(stringValue)) {
+ selection = i;
+ }
+ }
+ if (selection >= 0) {
+ super.doSetValue(new Integer(selection));
+ } else {
+ super.doSetValue(new Integer(-1));
+ if (getControl() instanceof StyleCombo
+ && !stringValue.equals(((StyleCombo) getControl())
+ .getText())) {
+ // update the Text widget
+ ((StyleCombo) getControl()).setText(stringValue);
+ }
+ }
+ }
+ _fSettingValue = false;
+ }
+
+ public void setItems(String[] newItems) {
+ if (getControl() == null || getControl().isDisposed()) {
+ Logger.log(Logger.ERROR,
+ "Attempted to update item list for disposed cell editor"); //$NON-NLS-1$
+ return;
+ }
+
+ // keep selection if possible
+ Object previousSelectedValue = getValue();
+ super.setItems(newItems);
+ if (previousSelectedValue != null && getControl() instanceof StyleCombo) {
+ for (int i = 0; i < newItems.length; i++) {
+ if (newItems[i].equals(previousSelectedValue)) {
+ setValue(previousSelectedValue);
+ }
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LoadbundleSelectionCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LoadbundleSelectionCellEditor.java
new file mode 100644
index 000000000..50a0f977e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/LoadbundleSelectionCellEditor.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.jst.pagedesigner.common.dialogs.ResourceOnClasspathDialog;
+import org.eclipse.jst.pagedesigner.properties.DesignerPropertyTool;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @author mengbo
+ */
+public class LoadbundleSelectionCellEditor extends EditableDialogCellEditor {
+ private static final String[] PROPERTIES_FILES_SUFFIXS = new String[] { IFileFolderConstants.EXT_PROPERTIES };
+
+ private String _value;
+
+ private IProject _project;
+
+ /**
+ * @param parent
+ */
+ public LoadbundleSelectionCellEditor(Composite parent, IProject project) {
+ super(parent);
+ _project = project;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(org.eclipse.swt.widgets.Control)
+ */
+ protected Object openDialogBox(Control cellEditorWindow) {
+ ResourceOnClasspathDialog dialog = new ResourceOnClasspathDialog(
+ cellEditorWindow.getShell(), DesignerPropertyTool
+ .getJavaProject(_project));
+ dialog.setTitle(ResourceBoundle.getString("FileCellEditor.Title"));
+ dialog.setSuffixs(PROPERTIES_FILES_SUFFIXS);
+ dialog.open();
+ if (dialog.getResult() != null) {
+ _value = (String) dialog.getResult()[0];
+ }
+ return _value;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/NamedBooleanCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/NamedBooleanCellEditor.java
new file mode 100644
index 000000000..159e3ec13
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/NamedBooleanCellEditor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class NamedBooleanCellEditor extends LabeledComboBoxCellEditor {
+ /**
+ * @param parent
+ * @param items
+ * @param style
+ */
+ private NamedBooleanCellEditor(Composite parent, Object[] values,
+ String[] labels, int style) {
+ super(parent, values, labels, style);
+ }
+
+ public static NamedBooleanCellEditor newInstance(Composite parent,
+ int style, IDOMElement element, IAttributeDescriptor attribute) {
+ String[] values = new String[] { "", attribute.getAttributeName() };
+ return new NamedBooleanCellEditor(parent, values, values, style);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceBoundle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceBoundle.java
new file mode 100644
index 000000000..a68d2fe47
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceBoundle.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ResourceBoundle {
+ private static final String BUNDLE_NAME = "org.eclipse.jst.pagedesigner.properties.celleditors.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private ResourceBoundle() {
+ }
+
+ public static String getString(String key) {
+ // TODO Auto-generated method stub
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceDialogCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceDialogCellEditor.java
new file mode 100644
index 000000000..fdb1a4e15
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/ResourceDialogCellEditor.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jst.pagedesigner.common.dialogs.CommonResourceDialog;
+import org.eclipse.jst.pagedesigner.common.utils.PathUtil;
+import org.eclipse.jst.pagedesigner.common.utils.WebrootUtil;
+import org.eclipse.jst.pagedesigner.utils.WebAppUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author mengbo
+ */
+public class ResourceDialogCellEditor extends EditableDialogCellEditor {
+ private IProject _project;
+
+ private String[] _suffixs;
+
+ private String _resourceDescription;
+
+ private IFile _referredFile;
+
+ private boolean _isWebPath = false;
+
+ private boolean _needTransformJSPURL = true;
+
+ private String _separator = "";
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see DialogCellEditor#DialogCellEditor()
+ */
+ public ResourceDialogCellEditor() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see DialogCellEditor#DialogCellEditor(Composite parent)
+ */
+ public ResourceDialogCellEditor(Composite parent) {
+ super(parent);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see DialogCellEditor#DialogCellEditor(Composite parent, int style)
+ */
+ public ResourceDialogCellEditor(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(org.eclipse.swt.widgets.Control)
+ */
+ protected Object openDialogBox(Control cellEditorWindow) {
+ Shell shell = cellEditorWindow.getShell();
+ int style = "".equals(_separator) ? SWT.NONE : SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL;
+ CommonResourceDialog dialog = new CommonResourceDialog(shell, _project,
+ style);
+ dialog.setTitle(ResourceBoundle.getString("FileCellEditor.Title"));
+ dialog.setSuffixs(_suffixs);
+ dialog.setResourceDescription(_resourceDescription);
+ if (dialog.open() == Window.OK) {
+ Object[] result = dialog.getResult();
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < result.length; i++) {
+ IPath path = ((IFile) result[i]).getLocation();
+
+ IPath referredPath = null;
+ if (_referredFile != null) {
+ referredPath = _referredFile.getLocation();
+ } else {
+ referredPath = _project.getLocation();
+ }
+
+ String newValue = null;
+ if (this._isWebPath) {
+ IFile selectedFile = ((IFile) result[i]);
+ newValue = WebrootUtil.getWebPath(selectedFile
+ .getFullPath());
+ } else {
+ newValue = PathUtil.convertToRelativePath(path.toString(),
+ referredPath.toString());
+ }
+ if (this._needTransformJSPURL) {
+ newValue = WebAppUtil.transformJSPURL(newValue,
+ this._referredFile);
+ }
+ buffer.append(newValue);
+ buffer.append(_separator);
+ }
+ if (buffer.length() > 0) {
+ return buffer.substring(0, buffer.length()
+ - _separator.length());
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param project
+ */
+ public void setProject(IProject project) {
+ this._project = project;
+ }
+
+ /**
+ * @return Returns the project.
+ */
+ public IProject getProject() {
+ return _project;
+ }
+
+ /**
+ * @return Returns the referredFile.
+ */
+ public IFile getReferredFile() {
+ return _referredFile;
+ }
+
+ /**
+ * @param referredFile
+ * The referredFile to set.
+ */
+ public void setReferredFile(IFile referredFile) {
+ this._referredFile = referredFile;
+ }
+
+ /**
+ * @return Returns the resourceDescription.
+ */
+ public String getResourceDescription() {
+ return _resourceDescription;
+ }
+
+ /**
+ * @param resourceDescription
+ * The resourceDescription to set.
+ */
+ public void setResourceDescription(String resourceDescription) {
+ this._resourceDescription = resourceDescription;
+ }
+
+ /**
+ * @return Returns the suffixs.
+ */
+ public String[] getSuffixs() {
+ return _suffixs;
+ }
+
+ /**
+ * @param suffixs
+ * The suffixs to set.
+ */
+ public void setSuffixs(String[] suffixs) {
+ this._suffixs = suffixs;
+ }
+
+ /**
+ * set some special path to web path instead of relative path
+ *
+ * @param isWebPath
+ */
+ public void setWebPath(boolean isWebPath) {
+ this._isWebPath = isWebPath;
+ }
+
+ public void setTransformJSPURL(boolean needTransform) {
+ this._needTransformJSPURL = needTransform;
+ }
+
+ public String getSeparator() {
+ return _separator;
+ }
+
+ public void setSeparator(String separator) {
+ this._separator = separator;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/StyleComboCellEditor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/StyleComboCellEditor.java
new file mode 100644
index 000000000..c6e414aa8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/StyleComboCellEditor.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.celleditors;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jst.pagedesigner.common.widget.StyleCombo;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public class StyleComboCellEditor extends CellEditor {
+ /**
+ * The list of items to present in the combo box.
+ */
+ private String[] items;
+
+ /**
+ * The zero-based index of the selected item.
+ */
+ int selection;
+
+ /**
+ * The custom combo box control.
+ */
+ StyleCombo comboBox;
+
+ /**
+ * Default ComboBoxCellEditor style
+ */
+ private static final int defaultStyle = SWT.NONE;
+
+ public StyleComboCellEditor() {
+ setStyle(defaultStyle);
+ }
+
+ public StyleComboCellEditor(Composite parent, String[] items) {
+ this(parent, items, defaultStyle);
+ }
+
+ public StyleComboCellEditor(Composite parent, String[] items, int style) {
+ super(parent, style);
+ setItems(items);
+ }
+
+ /**
+ * Returns the list of choices for the combo box
+ *
+ * @return the list of choices for the combo box
+ */
+ public String[] getItems() {
+ return this.items;
+ }
+
+ /**
+ * Sets the list of choices for the combo box
+ *
+ * @param items
+ * the list of choices for the combo box
+ */
+ public void setItems(String[] items) {
+ Assert.isNotNull(items);
+ this.items = items;
+ populateComboBoxItems();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected Control createControl(Composite parent) {
+
+ comboBox = new StyleCombo(parent, getStyle());
+ comboBox.setFont(parent.getFont());
+
+ comboBox.addKeyListener(new KeyAdapter() {
+ // hook key pressed - see PR 14201
+ public void keyPressed(KeyEvent e) {
+ keyReleaseOccured(e);
+ }
+ });
+
+ comboBox.addSelectionListener(new SelectionAdapter() {
+ public void widgetDefaultSelected(SelectionEvent event) {
+ applyEditorValueAndDeactivate();
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ selection = comboBox.getSelectionIndex();
+ }
+ });
+
+ comboBox.addTraverseListener(new TraverseListener() {
+ public void keyTraversed(TraverseEvent e) {
+ if (e.detail == SWT.TRAVERSE_ESCAPE
+ || e.detail == SWT.TRAVERSE_RETURN) {
+ e.doit = false;
+ }
+ }
+ });
+
+ comboBox.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent e) {
+ StyleComboCellEditor.this.focusLost();
+ }
+ });
+ return comboBox;
+ }
+
+ /**
+ * The <code>ComboBoxCellEditor</code> implementation of this
+ * <code>CellEditor</code> framework method returns the zero-based index
+ * of the current selection.
+ *
+ * @return the zero-based index of the current selection wrapped as an
+ * <code>Integer</code>
+ */
+ protected Object doGetValue() {
+ return new Integer(selection);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected void doSetFocus() {
+ comboBox.setFocus();
+ }
+
+ /**
+ * The <code>ComboBoxCellEditor</code> implementation of this
+ * <code>CellEditor</code> framework method sets the minimum width of the
+ * cell. The minimum width is 10 characters if <code>comboBox</code> is
+ * not <code>null</code> or <code>disposed</code> eles it is 60 pixels
+ * to make sure the arrow button and some text is visible. The list of
+ * CCombo will be wide enough to show its longest item.
+ */
+ public LayoutData getLayoutData() {
+ LayoutData layoutData = super.getLayoutData();
+ if ((comboBox == null) || comboBox.isDisposed())
+ layoutData.minimumWidth = 60;
+ else {
+ // make the comboBox 10 characters wide
+ GC gc = new GC(comboBox);
+ layoutData.minimumWidth = (gc.getFontMetrics()
+ .getAverageCharWidth() * 10) + 10;
+ gc.dispose();
+ }
+ return layoutData;
+ }
+
+ /**
+ * The <code>ComboBoxCellEditor</code> implementation of this
+ * <code>CellEditor</code> framework method accepts a zero-based index of
+ * a selection.
+ *
+ * @param value
+ * the zero-based index of the selection wrapped as an
+ * <code>Integer</code>
+ */
+ protected void doSetValue(Object value) {
+ Assert.isTrue(comboBox != null && (value instanceof Integer));
+ selection = ((Integer) value).intValue();
+ comboBox.select(selection);
+ }
+
+ /**
+ * Updates the list of choices for the combo box for the current control.
+ */
+ private void populateComboBoxItems() {
+ if (comboBox != null && items != null) {
+ comboBox.removeAll();
+ for (int i = 0; i < items.length; i++)
+ comboBox.add(items[i], i);
+
+ setValueValid(true);
+ selection = 0;
+ }
+ }
+
+ /**
+ * Applies the currently selected value and deactiavates the cell editor
+ */
+ void applyEditorValueAndDeactivate() {
+ // must set the selection before getting value
+ selection = comboBox.getSelectionIndex();
+ Object newValue = doGetValue();
+ markDirty();
+ boolean isValid = isCorrect(newValue);
+ setValueValid(isValid);
+ if (!isValid) {
+ // try to insert the current value into the error message.
+ setErrorMessage(MessageFormat.format(getErrorMessage(),
+ new Object[] { items[selection] }));
+ }
+ fireApplyEditorValue();
+ deactivate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#focusLost()
+ */
+ protected void focusLost() {
+ if (isActivated()) {
+ applyEditorValueAndDeactivate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.CellEditor#keyReleaseOccured(org.eclipse.swt.events.KeyEvent)
+ */
+ protected void keyReleaseOccured(KeyEvent keyEvent) {
+ if (keyEvent.character == '\u001b') { // Escape character
+ fireCancelEditor();
+ } else if (keyEvent.character == '\t') { // tab key
+ applyEditorValueAndDeactivate();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/messages.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/messages.properties
new file mode 100644
index 000000000..c27d05da4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/celleditors/messages.properties
@@ -0,0 +1,3 @@
+FileCellEditor.Title=Select File
+FileCellEditor.Msg=Select a file
+FileCellEditor.Msg1=Select one or more files
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerSectionDescriptor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerSectionDescriptor.java
new file mode 100644
index 000000000..a9eed5044
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerSectionDescriptor.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.utils.StringUtil;
+import org.eclipse.jst.pagedesigner.properties.DesignerPropertyTool;
+import org.eclipse.jst.pagedesigner.properties.ISectionFilter;
+import org.eclipse.jst.pagedesigner.properties.attrgroup.AttributeGroup;
+import org.eclipse.jst.pagedesigner.properties.attrgroup.AttributeGroupSection;
+import org.eclipse.jst.pagedesigner.utils.CMUtil;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ISection;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ISectionDescriptor;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ITypeMapper;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DesignerSectionDescriptor implements ISectionDescriptor {
+ private static final String ATT_ID = "id"; //$NON-NLS-1$
+
+ private static final String ATT_TARGET_TAB = "tab"; //$NON-NLS-1$
+
+ private static final String ATT_AFTER_SECTION = "afterSection"; //$NON-NLS-1$
+
+ private static final String ATT_CLASS = "class"; //$NON-NLS-1$
+
+ private static final String ATT_FILTER = "filter"; //$NON-NLS-1$
+
+ private static final String TOP = "top"; //$NON-NLS-1$
+
+ private static final String TAGFILTER = "tagFilter";
+
+ private static final String CASESENSITIVE = "caseSensitive";
+
+ private static final String TAGNAME = "tagName";
+
+ private static final String URI = "uri";
+
+ private String _id;
+
+ private String _targetTab;
+
+ private String _afterSection;
+
+ private ISectionFilter _sectionFilter;
+
+ private IConfigurationElement _configurationElement;
+
+ private TagFilter[] _tagFilters;
+
+ private static class TagFilter {
+ public String uri;
+
+ public String tag;
+
+ public boolean caseSensitive = false;
+ }
+
+ /**
+ * Constructor for the section descriptor.
+ *
+ * @param configurationElement
+ * the configuration element for the section descriptor.
+ */
+ public DesignerSectionDescriptor(IConfigurationElement configurationElement) {
+ _configurationElement = configurationElement;
+
+ _id = getConfigurationElement().getAttribute(ATT_ID);
+ _targetTab = getConfigurationElement().getAttribute(ATT_TARGET_TAB);
+ _afterSection = getConfigurationElement().getAttribute(
+ ATT_AFTER_SECTION);
+
+ if (_id == null || _targetTab == null) {
+ // the section id and tab are mandatory - log error
+ handleSectionError(null);
+ }
+ if (getAfterSection() == null) {
+ _afterSection = TOP;
+ }
+
+ String filterClass = getConfigurationElement().getAttribute(ATT_FILTER);
+ if (filterClass != null) {
+ try {
+ Object obj = getConfigurationElement()
+ .createExecutableExtension(ATT_FILTER);
+ if (obj instanceof ISectionFilter) {
+ _sectionFilter = (ISectionFilter) obj;
+ }
+ } catch (CoreException ex) {
+ handleSectionError(ex);
+ }
+ }
+
+ IConfigurationElement[] elements = getConfigurationElement()
+ .getChildren(TAGFILTER);
+ if (elements != null && elements.length > 0) {
+ _tagFilters = new TagFilter[elements.length];
+ for (int i = 0; i < _tagFilters.length; i++) {
+ _tagFilters[i] = new TagFilter();
+ _tagFilters[i].uri = elements[i].getAttribute(URI);
+ _tagFilters[i].tag = elements[i].getAttribute(TAGNAME);
+ _tagFilters[i].caseSensitive = Boolean.TRUE.toString()
+ .equalsIgnoreCase(
+ elements[i].getAttribute(CASESENSITIVE));
+ }
+ }
+ }
+
+ /**
+ * Handle the section error when an issue is found loading from the
+ * configuration element.
+ *
+ * @param _configurationElement
+ * the configuration element
+ * @param exception
+ * an optional CoreException
+ */
+ private void handleSectionError(CoreException exception) {
+ PDPlugin.getLogger(DesignerSectionDescriptor.class).error("error",
+ exception);
+ exception.printStackTrace();
+ // String pluginId = PDPlugin.getPluginId();
+ // String message = MessageFormat.format(SECTION_ERROR, new Object[] {
+ // pluginId});
+ // IStatus status = new Status(IStatus.ERROR, pluginId,
+ // CommonUIPropertiesStatusCodes.GENERAL_UI_FAILURE, message,
+ // exception);
+ // CommonUIPropertiesPlugin.getPlugin().getLog().log(status);
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySectionDescriptor#getId()
+ */
+ public String getId() {
+ return _id;
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySectionDescriptor#getTargetTab()
+ */
+ public String getTargetTab() {
+ return _targetTab;
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.internal.provisional.ISectionDescriptor#appliesTo(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean appliesTo(IWorkbenchPart part, ISelection selection) {
+ Element node = DesignerPropertyTool.getElement(part, selection);
+ if (node == null) {
+ return false;
+ }
+ if (_tagFilters != null) {
+ String uri = CMUtil.getElementNamespaceURI(node);
+ String tag = node.getLocalName();
+ for (int i = 0; i < _tagFilters.length; i++) {
+ if (!match(uri, tag, _tagFilters[i])) {
+ return false;
+ }
+ }
+ }
+ if (_sectionFilter != null) {
+ if (!_sectionFilter.appliesTo(node)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param uri2
+ * @param tag
+ * @param filter
+ * @return
+ */
+ private boolean match(String uri, String tag, TagFilter filter) {
+ if (!StringUtil.isSameString(uri, filter.uri)) {
+ return false;
+ }
+ if (uri != null && filter.uri != null && !uri.equals(filter.uri)) {
+ return false;
+ }
+ if (filter.caseSensitive) {
+ return tag.equals(filter.tag);
+ } else {
+ return tag.equalsIgnoreCase(filter.tag);
+ }
+ }
+
+ /**
+ * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySectionDescriptor#getAfterSection()
+ */
+ public String getAfterSection() {
+ return _afterSection;
+ }
+
+ /**
+ * Creates an instance of a section described by this descriptor
+ *
+ * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySectionDescriptor#getSectionClass()
+ */
+ public ISection getSectionClass() {
+ ISection section = null;
+ try {
+ Object secOrGroup = getConfigurationElement()
+ .createExecutableExtension(ATT_CLASS);
+ if (secOrGroup instanceof ISection) {
+ section = (ISection) secOrGroup;
+ } else if (secOrGroup instanceof AttributeGroup) {
+ section = new AttributeGroupSection((AttributeGroup) secOrGroup);
+ }
+ } catch (CoreException exception) {
+ handleSectionError(exception);
+ }
+
+ return section;
+ }
+
+ /**
+ * Gets the input types that are valid for this section.
+ *
+ * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySectionDescriptor#getInputTypes()
+ */
+ public List getInputTypes() {
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return getId();
+ }
+
+ /**
+ * @return Returns the configurationElement.
+ */
+ private IConfigurationElement getConfigurationElement() {
+ return _configurationElement;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.common.ui.properties.internal.provisional.ISectionDescriptor#getFilter()
+ */
+ public ITypeMapper getFilter() {
+ return null;
+ }
+
+ public int getEnablesFor() {
+ return 1;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerTabPropertySectionDescriptorProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerTabPropertySectionDescriptorProvider.java
new file mode 100644
index 000000000..81276e829
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/properties/internal/DesignerTabPropertySectionDescriptorProvider.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.properties.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ISectionDescriptor;
+import org.eclipse.wst.common.ui.properties.internal.provisional.ISectionDescriptorProvider;
+
+/**
+ * The DesignerTagPropertySectionDescriptorProvider will provide the section
+ * descriptiors. Now section descriptor come from two sources.
+ *
+ * One is reading from the "org.eclipse.jst.pagedesigner.propertyContributor"
+ * extension point. This extension point will contribute additional section
+ * providers, which provides a set of sections.
+ *
+ * One is reading from the "org.eclipse.jst.pagedesigner.propertySections"
+ * extension point. This extension provide a single section.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class DesignerTabPropertySectionDescriptorProvider implements
+ ISectionDescriptorProvider {
+ private static final String EXTPT_SECTIONS = "propertySections"; //$NON-NLS-1$
+
+ private static final String ELEMENT_SECTION = "propertySection"; //$NON-NLS-1$
+
+ private static final String EXTPT_SECTIONDESCRIPTORPROVIDER = "propertyContributor";
+
+ private static final String ELEMENT_PROPERTYCONTRIBUTOR = "propertyContributor";
+
+ private static final String ATTR_SECTIONDESCRIPTORPROVIDER = "sectionDescriptorProvider";
+
+ ISectionDescriptor[] _descriptors = null;
+
+ /**
+ *
+ */
+ public DesignerTabPropertySectionDescriptorProvider() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.common.ui.properties.internal.provisional.ISectionDescriptorProvider#getSectionDescriptors()
+ */
+ public ISectionDescriptor[] getSectionDescriptors() {
+ if (_descriptors == null) {
+ List result = new ArrayList();
+ List contributedSections = readSectionDescriptors();
+ result.addAll(contributedSections);
+
+ List providers = readAdditionalSectionDescriptorProviders();
+ for (int i = 0, size = providers.size(); i < size; i++) {
+ try {
+ ISectionDescriptorProvider provider = (ISectionDescriptorProvider) providers
+ .get(i);
+ ISectionDescriptor[] sections = provider
+ .getSectionDescriptors();
+ if (sections != null) {
+ result.addAll(Arrays.asList(sections));
+ }
+ } catch (Exception ex) {
+ // ignore
+ ex.printStackTrace();
+ }
+ }
+ _descriptors = new ISectionDescriptor[result.size()];
+ result.toArray(_descriptors);
+ }
+ return _descriptors;
+ }
+
+ protected List readAdditionalSectionDescriptorProviders() {
+ List result = new ArrayList();
+ IConfigurationElement[] extensions = getConfigurationElements(EXTPT_SECTIONDESCRIPTORPROVIDER);
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement extension = extensions[i];
+ if (ELEMENT_PROPERTYCONTRIBUTOR.equals(extension.getName())) {
+ IConfigurationElement contributor = extension;
+ try {
+ Object obj = contributor
+ .createExecutableExtension(ATTR_SECTIONDESCRIPTORPROVIDER);
+ if (obj instanceof ISectionDescriptorProvider) {
+ result.add(obj);
+ }
+ } catch (CoreException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ return result;
+ }
+
+ protected List readSectionDescriptors() {
+ List result = new ArrayList();
+ IConfigurationElement[] extensions = getConfigurationElements(EXTPT_SECTIONS);
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement extension = extensions[i];
+ IConfigurationElement[] sections = extension
+ .getChildren(ELEMENT_SECTION);
+ for (int j = 0; j < sections.length; j++) {
+ IConfigurationElement section = sections[j];
+ ISectionDescriptor descriptor = new DesignerSectionDescriptor(
+ section);
+ result.add(descriptor);
+ }
+ }
+ return result;
+ }
+
+ public static IConfigurationElement[] getConfigurationElements(
+ String extensionPointId) {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PDPlugin.getPluginId(), extensionPointId);
+
+ if (extensionPoint == null) {
+ return null;
+ }
+ return extensionPoint.getConfigurationElements();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/range/RangeUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/range/RangeUtil.java
new file mode 100644
index 000000000..bce86c272
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/range/RangeUtil.java
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.range;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.TextPosition;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class RangeUtil {
+ /**
+ * append the child after the reference node as next sibling.
+ *
+ * @param child
+ * can't be null
+ * @param reference
+ * can't be null
+ */
+ public static Node appendAfter(Node child, Node reference) {
+ Node next = reference.getNextSibling();
+ if (next == null)
+ return reference.getParentNode().appendChild(child);
+ else
+ return reference.getParentNode().insertBefore(child, next);
+ }
+
+ public static Node insertBefore(Node child, Node reference) {
+ return reference.getParentNode().insertBefore(child, reference);
+ }
+
+ /**
+ * Insert a node into the specified position. The node can be an element or
+ * DocumentFragment.
+ *
+ * @param node
+ * @param position
+ */
+ public static Node insertElement(DesignPosition position, Element node) {
+ EditPart containerEditPart = position.getContainerPart();
+ int offset = position.getOffset();
+
+ if (containerEditPart instanceof TextEditPart) {
+ TextEditPart textPart = (TextEditPart) containerEditPart;
+ String textData = textPart.getTextData();
+ Node textNode = (Node) textPart.getModel();
+ if (offset == 0)
+ return insertBefore(node, textNode);
+ else if (offset == textData.length())
+ return appendAfter(node, textNode);
+ else {
+ // inserting the element in the middle of text.
+ String before = textData.substring(0, offset);
+ String after = textData.substring(offset);
+
+ // XXX: don't know whether setNodeValue() will do all those
+ // escape or not.
+ textNode.setNodeValue(after);
+ Node newnode = insertBefore(node, textNode);
+
+ // XXX: don't know whether createTextNode() will do all those
+ // escape or not
+ Text t = textNode.getOwnerDocument().createTextNode(before);
+
+ insertBefore(t, newnode);
+ return newnode;
+ }
+ } else {
+ return insertIntoEditPart(containerEditPart, node, offset);
+ }
+ }
+
+ /**
+ * @param containerEditPart
+ * @param node
+ * @param offset
+ * @return
+ */
+ private static Node insertIntoEditPart(EditPart containerEditPart,
+ Node node, int offset) {
+ Node parent = (Node) containerEditPart.getModel();
+ List childParts = containerEditPart.getChildren();
+ if (offset >= childParts.size()) {
+ // to the end of parent
+ return parent.appendChild(node);
+ } else {
+ Node child = (Node) ((EditPart) childParts.get(offset)).getModel();
+ return insertBefore(node, child);
+ }
+ }
+
+ public static TextPosition insertText(DesignPosition position, String data) {
+ EditPart containerEditPart = position.getContainerPart();
+
+ position = moveIntoText(position);
+ int offset = position.getOffset();
+
+ if (position.getContainerPart() instanceof TextEditPart) {
+ // it is guaranteeed that now the containing edit part is text node.
+ TextEditPart textPart = (TextEditPart) position.getContainerPart();
+ String textData = textPart.getTextData();
+ String before = textData.substring(0, offset);
+ String after = textData.substring(offset);
+ if (data.startsWith(" ") && before.endsWith(" ")) {
+ before = before.substring(0, before.length() - 1) + "&nbsp;";
+ }
+ if (after.startsWith(" ") && data.endsWith(" ")) {
+ data = data.substring(0, data.length() - 1) + (char) 160;
+ }
+ String nextData = before + data + after;
+ IDOMText text = (IDOMText) textPart.getModel();
+ text.setData(nextData);
+ return new TextPosition(text, offset + data.length());
+ } else {
+ // can't merge into a neighboring text node. So create a text node
+ // of it's own
+ EditPart part = position.getContainerPart();
+ Node parent = (Node) part.getModel();
+ Text text = parent.getOwnerDocument().createTextNode(data);
+ insertIntoEditPart(part, text, offset);
+ return new TextPosition((IDOMText) text, offset);
+ }
+ }
+
+ /**
+ * Try to make the position move into a text node.
+ *
+ * @param position
+ * @return
+ */
+ public static DesignPosition moveIntoText(DesignPosition position) {
+ EditPart container = position.getContainerPart();
+ if (container instanceof TextEditPart)
+ return position;
+ if (position.getOffset() > 0) {
+ EditPart pre = (EditPart) container.getChildren().get(
+ position.getOffset() - 1);
+ if (pre instanceof TextEditPart) {
+ return new DesignPosition(pre, ((TextEditPart) pre)
+ .getTextData().length());
+ }
+ }
+ if (position.getOffset() < container.getChildren().size()) {
+ EditPart next = (EditPart) container.getChildren().get(
+ position.getOffset());
+ if (next instanceof TextEditPart) {
+ return new DesignPosition(next, 0);
+ }
+ }
+ return position;
+ }
+
+ /**
+ * try to move the position up to not inside a text. if the position is at 0
+ * index or last index of a text node, then try to move it up.
+ *
+ * @param position
+ * @return
+ */
+ public static DesignPosition moveOutFromText(DesignPosition position) {
+ EditPart container = position.getContainerPart();
+ if (container instanceof TextEditPart) {
+ int offset = position.getOffset();
+ String text = ((TextEditPart) container).getTextData();
+ if (offset == 0) {
+ return new DesignPosition(container.getParent(), container
+ .getParent().getChildren().indexOf(container));
+ } else if (offset == text.length()) {
+ return new DesignPosition(container.getParent(), container
+ .getParent().getChildren().indexOf(container) + 1);
+ }
+ }
+ return position;
+ }
+
+ public static void insertDocumentFragment(DesignPosition position,
+ DocumentFragment fragment) {
+ // FIXME: NOT DONE.
+ }
+
+ /**
+ * Test whether the range intersect with the part.
+ *
+ * @param range
+ * @param part
+ */
+ public static boolean intersect(DesignRange range, EditPart part) {
+ if (range == null || !range.isValid())
+ return false;
+ range = normalize(range);
+ if (part instanceof DocumentEditPart)
+ return true;
+ EditPart parent = part.getParent();
+ int index = parent.getChildren().indexOf(part);
+ DesignPosition left = new DesignPosition(parent, index);
+ DesignPosition right = new DesignPosition(parent, index + 1);
+ int compare = compareDesignPosition(left, range.getEndPosition());
+ if (compare == 1 || compare == 0 || compare == Integer.MIN_VALUE)
+ return false;
+
+ compare = compareDesignPosition(right, range.getStartPosition());
+ if (compare == -1 || compare == 0 || compare == Integer.MIN_VALUE)
+ return false;
+
+ return true;
+ }
+
+ /**
+ * make sure the start position is before end position. If the original
+ * range is already normalized, then the original range will be returned
+ * without constructing a new one.
+ *
+ * @param range
+ * @return
+ */
+ public static DesignRange normalize(DesignRange range) {
+ if (range == null || !range.isValid()) {
+ return range;
+ }
+ int result = compareDesignPosition(range.getStartPosition(), range
+ .getEndPosition());
+ if (result == 1)
+ return new DesignRange(range.getEndPosition(), range
+ .getStartPosition());
+ else
+ return range;
+ }
+
+ /**
+ *
+ * @param p1
+ * @param p2
+ * @return 0 means equal. 1 Means p1 is after p2. -1 means p1 is before p2.
+ * Integer.MIN_VALUE means some error and can't compare.
+ */
+ public static int compareDesignPosition(DesignPosition p1, DesignPosition p2) {
+ if (!p1.isValid() || !p2.isValid())
+ return Integer.MIN_VALUE;
+ if (p1.equals(p2))
+ return 0;
+ int offset1 = p1.getOffset();
+ int offset2 = p2.getOffset();
+ List a1 = getAncesters(p1.getContainerPart());
+ List a2 = getAncesters(p2.getContainerPart());
+ if (a1 == null || a2 == null)
+ return Integer.MIN_VALUE;
+ if (a1.get(0) != a2.get(0))
+ return Integer.MIN_VALUE; // not same DocumentEditPart
+ for (int i = 1;; i++) {
+ EditPart p1a = (EditPart) a1.get(i);
+ EditPart p2a = (EditPart) a2.get(i);
+ if (p1a == p2a) {
+ if (p1a != null)
+ continue; // same ancester
+ else {
+ // both are null. just compare the offset.
+ return offset1 < offset2 ? -1
+ : (offset1 == offset2 ? 0 : 1);
+ }
+ }
+ // p1a != p2a. now we can just compare p1a and p2a to decide the
+ // order.
+ if (p1a != null)
+ offset1 = p1a.getParent().getChildren().indexOf(p1a);
+ if (p2a != null)
+ offset2 = p2a.getParent().getChildren().indexOf(p2a);
+ if ((p1a == null && p2a == null) || (p1a != null && p2a != null)) {
+ return offset1 < offset2 ? -1 : (offset1 == offset2 ? 0 : 1);
+ } else if (p1a == null) {
+ return offset1 <= offset2 ? -1 : 1;
+ } else {
+ return offset1 >= offset2 ? 1 : -1;
+ }
+ }
+ }
+
+ /**
+ * Get a list of ancester nodes starting from the DocumentEditPart till the
+ * node.
+ *
+ * @param part
+ * @return
+ */
+ private static List getAncesters(EditPart part) {
+ List list = new ArrayList();
+ while (part != null) {
+ list.add(part);
+ if (part instanceof DocumentEditPart)
+ break;
+ else
+ part = part.getParent();
+ }
+ if (part == null) {
+ // if part ==null, means we didn't find a DocumentEditPart,
+ // something must be wrong.
+ return null;
+ }
+ // reverse to make it starting from the docuemnteditpart node.
+ Collections.reverse(list);
+ list.add(null); // add an null terminator.
+ return list;
+ }
+
+ /**
+ * find the smallest common ancester of two edit part.
+ *
+ * @param part1
+ * @param part2
+ * @return
+ */
+ public static EditPart findCommonAncester(EditPart part1, EditPart part2) {
+ if (part1 == part2) {
+ return part1;
+ }
+ List list1 = getAncesters(part1);
+ if (list1 == null)
+ return null;
+ List list2 = getAncesters(part2);
+ if (list2 == null)
+ return null;
+ if (list1.get(0) != list2.get(0))
+ return null;
+ EditPart common = (EditPart) list1.get(0);
+ for (int i = 1;; i++) {
+ EditPart p1 = (EditPart) list1.get(i);
+ EditPart p2 = (EditPart) list2.get(i);
+ if (p1 == null || p2 == null)
+ return common;
+ if (p1 != p2)
+ return common;
+ common = p1;
+ }
+
+ }
+
+ public static EditPart findCommonAncestor(DesignRange range) {
+ if (!range.isValid()) {
+ return null;
+ }
+ DesignPosition startPosition = range.getStartPosition();
+ DesignPosition endPosition = range.getEndPosition();
+ return findCommonAncester(startPosition.getContainerPart(), endPosition
+ .getContainerPart());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/LocationModifierRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/LocationModifierRequest.java
new file mode 100644
index 000000000..49cc4a617
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/LocationModifierRequest.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.requests;
+
+import org.eclipse.gef.requests.LocationRequest;
+
+/**
+ * This is a LocationRequest plus keyboard modified support.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class LocationModifierRequest extends LocationRequest {
+
+ private int _statemask;
+
+ private boolean _controlKeyDown;
+
+ /**
+ *
+ */
+ public LocationModifierRequest() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param type
+ */
+ public LocationModifierRequest(Object type) {
+ super(type);
+ }
+
+ public boolean isControlKeyPressed() {
+ return _controlKeyDown;
+ }
+
+ public void setControlKeyPressed(boolean b) {
+ this._controlKeyDown = b;
+ }
+ // /**
+ // * Returns <code>true</code> if the ALT key is currently pressed.
+ // * @return whether the ALT key is pressed
+ // */
+ // public boolean isAltKeyPressed() {
+ // return ((_statemask & MouseEvent.ALT) != 0);
+ // }
+ //
+ // /**
+ // * Returns <code>true</code> if any mouse button is currently pressed.
+ // * @return whether any mouse button is pressed
+ // */
+ // public boolean isAnyMouseButtonPressed() {
+ // return ((_statemask & MouseEvent.ANY_BUTTON) != 0);
+ // }
+ //
+ // /**
+ // * Returns <code>true</code> if the CTRL key is currently pressed.
+ // * @return whether the CTRL key is pressed
+ // */
+ // public boolean isControlKeyPressed() {
+ // return ((_statemask & MouseEvent.CONTROL) != 0);
+ // }
+ //
+ // /**
+ // * Returns <code>true</code> if the left mouse button is pressed.
+ // * @return whether the left mouse button is pressed
+ // */
+ // public boolean isLeftMouseButtonPressed() {
+ // return ((_statemask & MouseEvent.BUTTON1) != 0);
+ // }
+ //
+ // /**
+ // * Returns <code>true</code> if the right mouse button is pressed.
+ // * @return whether the right mouse button is pressed
+ // */
+ // public boolean isRightMouseButtonPressed() {
+ // return ((_statemask & MouseEvent.BUTTON3) != 0);
+ // }
+ //
+ // /**
+ // * Returns <code>true</code> if the SHIFT key is currently pressed.
+ // * @return whether the SHIFT key is pressed
+ // */
+ // public boolean isShiftKeyPressed() {
+ // return ((_statemask & MouseEvent.SHIFT) != 0);
+ // }
+ //
+ // /**
+ // * Sets the statemask for this request.
+ // * @param mask the statemask
+ // */
+ // public void setModifiers(int mask) {
+ // this._statemask = mask;
+ // }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/NodeCreationFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/NodeCreationFactory.java
new file mode 100644
index 000000000..e8cd1e18e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/requests/NodeCreationFactory.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.requests;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.gef.requests.CreationFactory;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.editors.HTMLEditor;
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ */
+public class NodeCreationFactory implements CreationFactory {
+ String _tagName;
+
+ String _uri;
+
+ String _suggestedPrefix;
+
+ Map _attributes;
+
+ public NodeCreationFactory(String uri, String tagname,
+ String suggestedPrefix, Map attributes) {
+ _tagName = tagname;
+ _uri = uri;
+ _suggestedPrefix = suggestedPrefix;
+ _attributes = attributes;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.requests.CreationFactory#getNewObject()
+ */
+ public Object getNewObject() {
+ Document ownerdoc = getOwnerDocument();
+ if (ownerdoc == null)
+ return null;
+
+ Element ele = ownerdoc.createElement(_tagName);
+ if (ele instanceof IDOMNode) {
+ String prefix = getPrefix(_uri, ((IDOMDocument) ownerdoc)
+ .getModel(), _suggestedPrefix);
+ if (prefix != null) {
+ ele.setPrefix(prefix);
+ }
+ }
+ if (_attributes != null) {
+ for (Iterator iter = _attributes.keySet().iterator(); iter
+ .hasNext();) {
+ String key = (String) iter.next();
+ String value = (String) _attributes.get(key);
+ ele.setAttribute(key, value);
+ }
+ }
+ return ele;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.requests.CreationFactory#getObjectType()
+ */
+ public Object getObjectType() {
+ return _tagName;
+ }
+
+ /**
+ * XXX: need some better way for owner document. Maybe pass in from
+ * constructor
+ *
+ * @return
+ */
+ protected Document getOwnerDocument() {
+ IWorkbenchWindow active = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow();
+ if (active == null)
+ return null;
+ IWorkbenchPage page = active.getActivePage();
+ if (page == null)
+ return null;
+ IEditorPart editor = page.getActiveEditor();
+ if (editor instanceof HTMLEditor) {
+ return ((HTMLEditor) editor).getDOMDocument();
+ } else
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.requests.NodeCreationFactory#getPrefix(int)
+ */
+ public String getPrefix(String uri, IDOMModel model, String suggested) {
+ if (IJMTConstants.URI_HTML.equals(uri)
+ || IJMTConstants.URI_JSP.equals(uri))
+ return null;
+
+ // now handles custom tag lib
+ return JSPUtil.getOrCreatePrefix(model, uri, suggested);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnHandle.java
new file mode 100644
index 000000000..85c6e5cb4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnHandle.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.GraphicalEditPart;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ColumnHandle extends TableSideItemHandle {
+
+ /**
+ * @param owner
+ * @param isRow
+ * @param index
+ */
+ public ColumnHandle(GraphicalEditPart owner, int index) {
+ super(owner, false, index);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnResizeHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnResizeHandle.java
new file mode 100644
index 000000000..92496e141
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/ColumnResizeHandle.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.GraphicalEditPart;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ColumnResizeHandle extends TableSideResizeHandle {
+ // 0 means before first column
+ int _columnIndex;
+
+ /**
+ *
+ */
+ public ColumnResizeHandle(GraphicalEditPart owner, int index) {
+ super(owner, false, index);
+ _columnIndex = index;
+ }
+
+ public int getColumnIndex() {
+ return _columnIndex;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterAction.java
new file mode 100644
index 000000000..7ce481afd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterAction.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DeleteHeaderFooterAction extends Action {
+ private Command _command;
+
+ /**
+ * @param text
+ */
+ public DeleteHeaderFooterAction(String text, EditPart editPart,
+ boolean isHeader) {
+ super(text);
+ DeleteHeaderFooterRequest req = new DeleteHeaderFooterRequest(text,
+ isHeader);
+ this._command = editPart.getCommand(req);
+ this.setEnabled(this._command != null && this._command.canExecute());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ _command.execute();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterRequest.java
new file mode 100644
index 000000000..3a48173aa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteHeaderFooterRequest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.Request;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DeleteHeaderFooterRequest extends Request {
+ private boolean _isHeader;
+
+ public DeleteHeaderFooterRequest(String type, boolean isHeader) {
+ super(type);
+ this._isHeader = isHeader;
+ }
+
+ /**
+ * @return Returns the _isHeader.
+ */
+ public boolean isHeader() {
+ return _isHeader;
+ }
+
+ /**
+ * @param header
+ * The _isHeader to set.
+ */
+ public void setHeader(boolean header) {
+ _isHeader = header;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteRowColumnAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteRowColumnAction.java
new file mode 100644
index 000000000..e56fe3fe4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/DeleteRowColumnAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DeleteRowColumnAction extends Action {
+ private Command _command;
+
+ /**
+ * @param text
+ */
+ public DeleteRowColumnAction(String text, EditPart tablePart, int index,
+ boolean isrow) {
+ super(text);
+
+ TableRowColumnDeleteRequest req = new TableRowColumnDeleteRequest(
+ isrow, index);
+ this._command = tablePart.getCommand(req);
+ this.setEnabled(this._command != null && this._command.canExecute());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ _command.execute();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/EmptyLocator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/EmptyLocator.java
new file mode 100644
index 000000000..9c6e2f78e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/EmptyLocator.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Locator;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class EmptyLocator implements Locator {
+ /**
+ *
+ */
+ public EmptyLocator() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure)
+ */
+ public void relocate(IFigure target) {
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterAction.java
new file mode 100644
index 000000000..4d0000e90
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterAction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class InsertHeaderFooterAction extends Action {
+ private Command _command;
+
+ /**
+ * @param text
+ */
+ public InsertHeaderFooterAction(String text, EditPart editPart,
+ boolean isHeader) {
+ super(text);
+
+ InsertHeaderFooterRequest req = new InsertHeaderFooterRequest(text,
+ isHeader);
+ this._command = editPart.getCommand(req);
+ this.setEnabled(this._command != null && this._command.canExecute());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ _command.execute();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterRequest.java
new file mode 100644
index 000000000..2f86799dd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertHeaderFooterRequest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.Request;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class InsertHeaderFooterRequest extends Request {
+ private boolean _isHeader;
+
+ public InsertHeaderFooterRequest(String type, boolean isHeader) {
+ super(type);
+ this._isHeader = isHeader;
+ }
+
+ /**
+ * @return Returns the _isHeader.
+ */
+ public boolean isHeader() {
+ return _isHeader;
+ }
+
+ /**
+ * @param header
+ * The _isHeader to set.
+ */
+ public void setHeader(boolean header) {
+ _isHeader = header;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertRowColumnAction.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertRowColumnAction.java
new file mode 100644
index 000000000..ebd835d65
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/InsertRowColumnAction.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.jface.action.Action;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class InsertRowColumnAction extends Action {
+ private Command _command;
+
+ /**
+ * @param text
+ */
+ public InsertRowColumnAction(String text, EditPart tablePart, int index,
+ boolean isrow, boolean isbefore) {
+ super(text);
+
+ TableInsertRequest req = new TableInsertRequest(isrow, index, isbefore);
+ this._command = tablePart.getCommand(req);
+ this.setEnabled(this._command != null && this._command.canExecute());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ _command.execute();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/MarqueeRectangleFigure.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/MarqueeRectangleFigure.java
new file mode 100644
index 000000000..8c4afbbb2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/MarqueeRectangleFigure.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This class is copied from MarqueeSelectionTool, since it is private there.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+class MarqueeRectangleFigure extends Figure {
+
+ private int offset = 0;
+
+ private boolean schedulePaint = true;
+
+ private static final int DELAY = 110; // animation delay in millisecond
+
+ /**
+ * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintFigure(Graphics graphics) {
+ Rectangle bounds = getBounds().getCopy();
+ graphics.translate(getLocation());
+
+ graphics.setXORMode(true);
+ graphics.setForegroundColor(ColorConstants.white);
+ graphics.setBackgroundColor(ColorConstants.black);
+
+ graphics.setLineStyle(Graphics.LINE_DOT);
+
+ int[] points = new int[6];
+
+ points[0] = 0 + offset;
+ points[1] = 0;
+ points[2] = bounds.width - 1;
+ points[3] = 0;
+ points[4] = bounds.width - 1;
+ points[5] = bounds.height - 1;
+
+ graphics.drawPolyline(points);
+
+ points[0] = 0;
+ points[1] = 0 + offset;
+ points[2] = 0;
+ points[3] = bounds.height - 1;
+ points[4] = bounds.width - 1;
+ points[5] = bounds.height - 1;
+
+ graphics.drawPolyline(points);
+
+ graphics.translate(getLocation().getNegated());
+
+ if (schedulePaint) {
+ Display.getCurrent().timerExec(DELAY, new Runnable() {
+ public void run() {
+ offset++;
+ if (offset > 5)
+ offset = 0;
+
+ schedulePaint = true;
+ repaint();
+ }
+ });
+ }
+
+ schedulePaint = false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowHandle.java
new file mode 100644
index 000000000..8cd08d2fb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowHandle.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.GraphicalEditPart;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RowHandle extends TableSideItemHandle {
+
+ /**
+ * @param owner
+ * @param isRow
+ * @param index
+ */
+ public RowHandle(GraphicalEditPart owner, int index) {
+ super(owner, true, index);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowResizeHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowResizeHandle.java
new file mode 100644
index 000000000..10682ff4f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/RowResizeHandle.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.GraphicalEditPart;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class RowResizeHandle extends TableSideResizeHandle {
+ // 0 means before first row
+ int _rowIndex;
+
+ /**
+ *
+ */
+ public RowResizeHandle(GraphicalEditPart owner, int index) {
+ super(owner, true, index);
+
+ _rowIndex = index;
+ }
+
+ public int getRowIndex() {
+ return _rowIndex;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandle.java
new file mode 100644
index 000000000..466159bfc
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandle.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableColumnHandle extends TableSideHandle {
+ /**
+ * @param tableHost
+ */
+ public TableColumnHandle(GraphicalEditPart tableHost) {
+ super(tableHost, new TableColumnHandleLocator(tableHost));
+ }
+
+ /**
+ *
+ *
+ */
+ public void setupColumns() {
+ ITableEditAdapter tableAdapter = getTableEditAdapter();
+ if (tableAdapter == null) {
+ return;
+ }
+ int numColumns = tableAdapter.getColumnCount();
+ for (int i = 0; i < numColumns; i++) {
+ ColumnHandle columnHandle = createColumnHandle(i);
+ add(columnHandle);
+ ColumnResizeHandle columnResizeHandle = createColumnResizeHandle(i);
+ add(columnResizeHandle);
+ }
+ ColumnResizeHandle lastResize = createColumnResizeHandle(numColumns);
+ add(lastResize);
+ }
+
+ /**
+ * @param numColumns
+ * @return
+ */
+ private ColumnResizeHandle createColumnResizeHandle(int numColumns) {
+ return new ColumnResizeHandle(getOwner(), numColumns);
+ }
+
+ /**
+ * @param i
+ * @return
+ */
+ private ColumnHandle createColumnHandle(int i) {
+ return new ColumnHandle(getOwner(), i);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandleLocator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandleLocator.java
new file mode 100644
index 000000000..9816f9327
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableColumnHandleLocator.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.handles.HandleBounds;
+import org.eclipse.gef.handles.MoveHandleLocator;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableColumnHandleLocator extends MoveHandleLocator {
+
+ GraphicalEditPart _tablePart;
+
+ /**
+ * @param ref
+ */
+ public TableColumnHandleLocator(GraphicalEditPart tablePart) {
+ super(tablePart.getFigure());
+ _tablePart = tablePart;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.MoveHandleLocator#relocate(org.eclipse.draw2d.IFigure)
+ */
+ public void relocate(IFigure target) {
+ Rectangle bounds;
+ if (getReference() instanceof HandleBounds) {
+ bounds = ((HandleBounds) getReference()).getHandleBounds();
+ } else {
+ bounds = getReference().getBounds();
+ }
+ Insets referenceInsets = getReference().getInsets();
+
+ Rectangle r = new Rectangle(bounds.x + referenceInsets.left, bounds.y
+ + bounds.height, bounds.width - referenceInsets.getWidth(),
+ TableEditConst.HEIGHT);
+
+ getReference().translateToAbsolute(r);
+ target.translateToRelative(r);
+
+ target.setBounds(r);
+ relocateChildren(target, getReference());
+ }
+
+ /**
+ * @param target
+ * @param reference
+ */
+ private void relocateChildren(IFigure target, IFigure reference) {
+ // As user may removed columns/rows, so need to recalculate columns.
+ TableColumnHandle tableColumnHandle = (TableColumnHandle) target;
+ tableColumnHandle.removeAll();
+ tableColumnHandle.setupColumns();
+
+ // ---------------------------
+ List children = target.getChildren();
+
+ ITableEditAdapter tableAdapter = TableEditHelper
+ .getTableEditAdapter(this._tablePart);
+ if (tableAdapter == null) {
+ // XXX: what should we do if we found it is no longer table?
+ // here just skip
+ return;
+ }
+ for (int i = 0, size = children.size(); i < size; i++) {
+ Rectangle rect = null;
+ IFigure child = (IFigure) children.get(i);
+ if (child instanceof ColumnHandle) {
+ ColumnHandle columnHandle = (ColumnHandle) child;
+ int columnIndex = columnHandle.getIndex();
+ rect = new Rectangle(tableAdapter.getColumnStart(columnIndex),
+ 0, tableAdapter.getColumnWidth(columnIndex),
+ TableEditConst.HEIGHT);
+ } else if (child instanceof ColumnResizeHandle) {
+ ColumnResizeHandle resizeHandle = (ColumnResizeHandle) child;
+ int columnIndex = resizeHandle.getColumnIndex();
+ rect = new Rectangle(tableAdapter
+ .getColumnResizeStart(columnIndex), 0, tableAdapter
+ .getColumnResizeWidth(), TableEditConst.HEIGHT);
+ } else {
+ // should not happen.
+ }
+ if (rect != null) {
+ child.setBounds(rect);
+ }
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditAdapter.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditAdapter.java
new file mode 100644
index 000000000..1c820965e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditAdapter.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableLayout2;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableEditAdapter implements ITableEditAdapter {
+ CSSTableLayout2 _tableLayout;
+
+ /**
+ * @param layout2
+ */
+ public TableEditAdapter(CSSTableLayout2 layout2) {
+ this._tableLayout = layout2;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getColumnCount()
+ */
+ public int getColumnCount() {
+ return _tableLayout.getColumnWidths().length;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getRowCount()
+ */
+ public int getRowCount() {
+ return _tableLayout.getRowHeights().length;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#insertColumn(int)
+ */
+ public void insertColumn(int atPosition) {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#insertRow(int)
+ */
+ public void insertRow(int rowPosition) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getResizeStart(int)
+ */
+ public int getColumnResizeStart(int columnIndex) {
+ int w = 0;
+ int[] columnWidths = _tableLayout.getColumnWidths();
+ for (int i = 0; i < columnIndex; i++) {
+ w += columnWidths[i];
+ }
+ w += columnIndex * _tableLayout.getHSpacing();
+ return w;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getResizeWidth()
+ */
+ public int getColumnResizeWidth() {
+ return _tableLayout.getHSpacing();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getColumnStart(int)
+ */
+ public int getColumnStart(int columnIndex) {
+ return getColumnResizeStart(columnIndex) + _tableLayout.getHSpacing();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getColumnWidth(int)
+ */
+ public int getColumnWidth(int columnIndex) {
+ return _tableLayout.getColumnWidths()[columnIndex];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getRowStart(int)
+ */
+ public int getRowStart(int rowIndex) {
+ int start = getRowResizeStart(rowIndex) + _tableLayout.getVSpacing();
+ if (_tableLayout.getCaptionInfo() != null
+ && "top".equalsIgnoreCase(_tableLayout.getCaptionInfo().getAlign())) //$NON-NLS-1$
+ {
+ start += _tableLayout.getCaptionSize().height;
+ }
+ return start;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getRowHeight(int)
+ */
+ public int getRowHeight(int rowIndex) {
+ return _tableLayout.getRowHeights()[rowIndex];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getRowResizeStart(int)
+ */
+ public int getRowResizeStart(int rowIndex) {
+ int w = 0;
+ int[] rowHeights = _tableLayout.getRowHeights();
+ for (int i = 0; i < rowIndex; i++) {
+ w += rowHeights[i];
+ }
+ w += rowIndex * _tableLayout.getHSpacing();
+ return w;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter#getRowResizeWidth()
+ */
+ public int getRowResizeWidth() {
+ return _tableLayout.getVSpacing();
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditConst.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditConst.java
new file mode 100644
index 000000000..54b714ac7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditConst.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface TableEditConst {
+ public static final int HEIGHT = 10;
+
+ public static final int WIDTH = 10;
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditHelper.java
new file mode 100644
index 000000000..f1b4a85ff
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableEditHelper.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.LayoutManager;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.css2.layout.table.CSSTableLayout2;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableEditHelper {
+ /**
+ * This method will return null if the editpart is not a table.
+ *
+ * @param tablePart
+ * @return
+ */
+ public static ITableEditAdapter getTableEditAdapter(
+ GraphicalEditPart tablePart) {
+ IFigure figure = tablePart.getFigure();
+ LayoutManager layout = figure.getLayoutManager();
+ if (layout instanceof CSSTableLayout2) {
+ return new TableEditAdapter((CSSTableLayout2) layout);
+ }
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableHandleKit.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableHandleKit.java
new file mode 100644
index 000000000..c8082e517
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableHandleKit.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import java.util.List;
+
+import org.eclipse.gef.GraphicalEditPart;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableHandleKit {
+
+ /**
+ * @param tableHost
+ * @param handles
+ */
+ public static void addHandles(GraphicalEditPart tableHost, List handles) {
+ addColumnHandles(tableHost, handles);
+ addRowHandles(tableHost, handles);
+ }
+
+ /**
+ * @param tableHost
+ * @param handles
+ */
+ private static void addColumnHandles(GraphicalEditPart tableHost,
+ List handles) {
+ TableColumnHandle handle = new TableColumnHandle(tableHost);
+ handles.add(handle);
+
+ }
+
+ /**
+ * @param tableHost
+ * @param handles
+ */
+ private static void addRowHandles(GraphicalEditPart tableHost, List handles) {
+ TableRowHandle handle = new TableRowHandle(tableHost);
+ handles.add(handle);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableInsertRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableInsertRequest.java
new file mode 100644
index 000000000..d7c9fae21
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableInsertRequest.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableInsertRequest extends TableRowColumnRequest {
+ public static final String TABLE_INSERT_REQUEST = "Table Insert";
+
+ boolean _before;
+
+ /**
+ *
+ */
+ public TableInsertRequest(boolean row, int index, boolean before) {
+ super(TABLE_INSERT_REQUEST, row, index);
+ this._before = before;
+ }
+
+ public boolean isBefore() {
+ return _before;
+ }
+
+ public void setBefore(boolean before) {
+ this._before = before;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizableEditPolicy.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizableEditPolicy.java
new file mode 100644
index 000000000..87619c24f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizableEditPolicy.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import java.util.List;
+
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableResizableEditPolicy extends ElementResizableEditPolicy {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#createSelectionHandles()
+ */
+ protected List createSelectionHandles() {
+ List list = super.createSelectionHandles();
+
+ // CR402770-1. Add a check whether it is table. If is not, will not
+ // create the handles. Thus, the handles could assume
+ // TableEditHelper.getTableEditAdatper()
+ // will always return non null.
+ ITableEditAdapter adapter = TableEditHelper
+ .getTableEditAdapter((GraphicalEditPart) getHost());
+ if (adapter != null) {
+ TableHandleKit.addHandles((GraphicalEditPart) getHost(), list);
+ }
+ return list;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizeRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizeRequest.java
new file mode 100644
index 000000000..b4dbef73c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableResizeRequest.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.Request;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableResizeRequest extends Request {
+ public static final String TABLE_RESIZE_REQ = "Table Resize";
+
+ private boolean _row;
+
+ private int _index;
+
+ private int _delta;
+
+ /**
+ *
+ */
+ public TableResizeRequest(boolean isrow, int index) {
+ super(TABLE_RESIZE_REQ);
+ this._row = isrow;
+ this._index = index;
+ }
+
+ public int getIndex() {
+ return _index;
+ }
+
+ public void setIndex(int index) {
+ this._index = index;
+ }
+
+ public boolean isRow() {
+ return _row;
+ }
+
+ public void setRow(boolean row) {
+ this._row = row;
+ }
+
+ public int getDelta() {
+ return _delta;
+ }
+
+ public void setDelta(int delta) {
+ this._delta = delta;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnDeleteRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnDeleteRequest.java
new file mode 100644
index 000000000..aa860524e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnDeleteRequest.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableRowColumnDeleteRequest extends TableRowColumnRequest {
+ public static final String TABLE_ROWCOLUMN_DELETE = "Table RowColumn Delete";
+
+ /**
+ * @param type
+ * @param row
+ * @param index
+ */
+ public TableRowColumnDeleteRequest(boolean row, int index) {
+ super(TABLE_ROWCOLUMN_DELETE, row, index);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnRequest.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnRequest.java
new file mode 100644
index 000000000..0a5b33a04
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowColumnRequest.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.Request;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableRowColumnRequest extends Request {
+ int _index;
+
+ boolean _row;
+
+ /**
+ * @param type
+ */
+ public TableRowColumnRequest(Object type, boolean row, int index) {
+ super(type);
+ this._row = row;
+ this._index = index;
+ }
+
+ public int getIndex() {
+ return _index;
+ }
+
+ public void setIndex(int index) {
+ this._index = index;
+ }
+
+ public boolean isRow() {
+ return _row;
+ }
+
+ public void setRow(boolean row) {
+ this._row = row;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandle.java
new file mode 100644
index 000000000..daca6e405
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandle.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableRowHandle extends TableSideHandle {
+ /**
+ * @param tableHost
+ */
+ public TableRowHandle(GraphicalEditPart tableHost) {
+ super(tableHost, new TableRowHandleLocator(tableHost));
+ // setupRows();
+ }
+
+ /**
+ *
+ *
+ */
+ public void setupRows() {
+ ITableEditAdapter tableAdapter = getTableEditAdapter();
+ if (tableAdapter == null) {
+ return;
+ }
+ int numRows = tableAdapter.getRowCount();
+ for (int i = 0; i < numRows; i++) {
+ RowHandle rowHandle = createRowHandle(i);
+ add(rowHandle);
+ RowResizeHandle rowResizeHandle = createRowResizeHandle(i);
+ add(rowResizeHandle);
+ }
+ RowResizeHandle lastResize = createRowResizeHandle(numRows);
+ add(lastResize);
+ }
+
+ /**
+ * @param rowIndex
+ * @return
+ */
+ private RowResizeHandle createRowResizeHandle(int rowIndex) {
+ return new RowResizeHandle(getOwner(), rowIndex);
+ }
+
+ /**
+ * @param rowIndex
+ * @return
+ */
+ private RowHandle createRowHandle(int rowIndex) {
+ return new RowHandle(getOwner(), rowIndex);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandleLocator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandleLocator.java
new file mode 100644
index 000000000..d1c2a9eca
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableRowHandleLocator.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.handles.HandleBounds;
+import org.eclipse.gef.handles.MoveHandleLocator;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableRowHandleLocator extends MoveHandleLocator {
+
+ GraphicalEditPart _tablePart;
+
+ /**
+ * @param ref
+ */
+ public TableRowHandleLocator(GraphicalEditPart tablePart) {
+ super(tablePart.getFigure());
+ _tablePart = tablePart;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.MoveHandleLocator#relocate(org.eclipse.draw2d.IFigure)
+ */
+ public void relocate(IFigure target) {
+ Rectangle bounds;
+ if (getReference() instanceof HandleBounds) {
+ bounds = ((HandleBounds) getReference()).getHandleBounds();
+ } else {
+ bounds = getReference().getBounds();
+ }
+ // bounds = new PrecisionRectangle(bounds.getResized(-1, -1));
+ Insets referenceInsets = getReference().getInsets();
+
+ Rectangle r = new Rectangle(bounds.x + bounds.width, bounds.y
+ + referenceInsets.top, TableEditConst.WIDTH, bounds.height
+ - referenceInsets.getHeight());
+ bounds = new PrecisionRectangle(r);
+
+ getReference().translateToAbsolute(bounds);
+ target.translateToRelative(bounds);
+
+ target.setBounds(bounds);
+ relocateChildren(target, getReference());
+ }
+
+ /**
+ * @param target
+ * @param reference
+ */
+ private void relocateChildren(IFigure target, IFigure reference) {
+ // As user may removed columns/rows, so need to recalculate columns.
+ TableRowHandle tableRowHandle = (TableRowHandle) target;
+ tableRowHandle.removeAll();
+ tableRowHandle.setupRows();
+ List children = target.getChildren();
+
+ ITableEditAdapter tableAdapter = TableEditHelper
+ .getTableEditAdapter(this._tablePart);
+ if (tableAdapter == null) {
+ return;
+ }
+ for (int i = 0, size = children.size(); i < size; i++) {
+ Rectangle rect = null;
+ IFigure child = (IFigure) children.get(i);
+ if (child instanceof RowHandle) {
+ RowHandle rowHandle = (RowHandle) child;
+ int rowIndex = rowHandle.getIndex();
+ rect = new Rectangle(0, tableAdapter.getRowStart(rowIndex),
+ TableEditConst.WIDTH, tableAdapter
+ .getRowHeight(rowIndex));
+ } else if (child instanceof RowResizeHandle) {
+ RowResizeHandle resizeHandle = (RowResizeHandle) child;
+ int rowIndex = resizeHandle.getRowIndex();
+ rect = new Rectangle(0, tableAdapter
+ .getRowResizeStart(rowIndex), TableEditConst.WIDTH,
+ tableAdapter.getRowResizeWidth());
+ } else {
+ // should not happen.
+ }
+ if (rect != null) {
+ child.setBounds(rect);
+ }
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideHandle.java
new file mode 100644
index 000000000..ab53c8745
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideHandle.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.Locator;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.handles.AbstractHandle;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableSideHandle extends AbstractHandle {
+ /**
+ * @param owner
+ * @param loc
+ */
+ public TableSideHandle(GraphicalEditPart owner, Locator loc) {
+ super(owner, loc);
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.AbstractHandle#createDragTracker()
+ */
+ protected DragTracker createDragTracker() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public GraphicalEditPart getTableEditPart() {
+ return this.getOwner();
+ }
+
+ public ITableEditAdapter getTableEditAdapter() {
+ return TableEditHelper.getTableEditAdapter(getOwner());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#useLocalCoordinates()
+ */
+ protected boolean useLocalCoordinates() {
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemDragTracker.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemDragTracker.java
new file mode 100644
index 000000000..c3d068e0d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemDragTracker.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.tools.DragEditPartsTracker;
+
+/**
+ * This is the tracker for the TableSideItem. It will be responsible to track
+ * the right mouse down event and popup a menu.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableSideItemDragTracker extends DragEditPartsTracker {
+ private boolean _isRow;
+
+ private int _index;
+
+ /**
+ *
+ * @param sourceEditPart
+ * @param isrow
+ * @param index
+ */
+ public TableSideItemDragTracker(EditPart sourceEditPart, boolean isrow,
+ int index) {
+ super(sourceEditPart);
+ this._isRow = isrow;
+ this._index = index;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.DragEditPartsTracker#handleButtonUp(int)
+ */
+ protected boolean handleButtonUp(int button) {
+ boolean result = super.handleButtonUp(button);
+ //
+ // if (button == 3)
+ // {
+ // MenuManager m = new MenuManager();
+ // if (_isRow)
+ // {
+ // m.add(new InsertRowColumnAction("Insert row before",
+ // getSourceEditPart(), _index, _isRow, true));
+ // m.add(new InsertRowColumnAction("Insert row after",
+ // getSourceEditPart(), _index, _isRow, false));
+ // m.add(new DeleteRowColumnAction("Delete row", getSourceEditPart(),
+ // _index, _isRow));
+ // }
+ // else
+ // {
+ // m.add(new InsertRowColumnAction("Insert column before",
+ // getSourceEditPart(), _index, _isRow, true));
+ // m.add(new InsertRowColumnAction("Insert column after",
+ // getSourceEditPart(), _index, _isRow, false));
+ // m.add(new DeleteRowColumnAction("Delete column", getSourceEditPart(),
+ // _index, _isRow));
+ // }
+ // m.createContextMenu(this.getCurrentViewer().getControl()).setVisible(true);
+ // }
+ return result;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemHandle.java
new file mode 100644
index 000000000..854f465fa
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideItemHandle.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Cursors;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.handles.AbstractHandle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class TableSideItemHandle extends AbstractHandle {
+ private boolean _isRow;
+
+ private int _index;
+
+ /**
+ *
+ */
+ public TableSideItemHandle(GraphicalEditPart owner, boolean isRow, int index) {
+ super(owner, new EmptyLocator());
+ this._isRow = isRow;
+ this._index = index;
+ initialize();
+ }
+
+ /**
+ *
+ */
+ private void initialize() {
+ this.setOpaque(false);
+ LineBorder border = new LineBorder(ColorConstants.green, 1);
+ this.setBorder(border);
+ this.setCursor(Cursors.ARROW);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics)
+ */
+ protected void paintFigure(Graphics graphics) {
+ graphics.setXORMode(true);
+ graphics.setBackgroundColor(ColorConstants.darkGray);
+ graphics.fillRectangle(getBounds());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.AbstractHandle#createDragTracker()
+ */
+ protected DragTracker createDragTracker() {
+ return new TableSideItemDragTracker(getOwner(), _isRow, _index);
+ }
+
+ public int getIndex() {
+ return _index;
+ }
+
+ public boolean isRow() {
+ return _isRow;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeDragTracker.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeDragTracker.java
new file mode 100644
index 000000000..abfe87827
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeDragTracker.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.tools.DragEditPartsTracker;
+import org.eclipse.jst.pagedesigner.editpolicies.ITableEditAdapter;
+
+/**
+ * This is the drag tracker for the small resize item on the
+ * TableSideResizeHandle. used to adjust a single column/row size.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableSideResizeDragTracker extends DragEditPartsTracker {
+ private boolean _isrow;
+
+ private int _index;
+
+ private MarqueeRectangleFigure _marqueeFigure;
+
+ /**
+ * @param sourceEditPart
+ */
+ public TableSideResizeDragTracker(EditPart sourceEditPart, boolean isrow,
+ int index) {
+ super(sourceEditPart);
+ this._isrow = isrow;
+ this._index = index;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.DragEditPartsTracker#showSourceFeedback()
+ */
+ protected void showSourceFeedback() {
+ Rectangle rect = getFeedbackRect();
+ if (rect != null) {
+ rect = rect.getCopy();
+ getMarqueeRectangleFigure().setBounds(rect);
+ } else {
+ // ignore.
+ }
+ }
+
+ private int calculateDelta() {
+ int delta;
+ // FIXME: TODO: XXX: when delta is too small (<0) to make previous
+ // column/row
+ // to have negative size, then we need adjust delta.
+ if (_isrow) {
+ delta = getLocation().y - getStartLocation().y;
+ } else {
+ delta = getLocation().x - getStartLocation().x;
+ }
+ return delta;
+ }
+
+ /**
+ * @return null if this is not a table.
+ */
+ private Rectangle getFeedbackRect() {
+ ITableEditAdapter adapter = getTableEditAdapter();
+ if (adapter == null) {
+ return null;
+ }
+
+ IFigure figure = ((GraphicalEditPart) this.getSourceEditPart())
+ .getFigure();
+ Rectangle bounds = figure.getBounds();
+ Insets insets = figure.getInsets();
+ Rectangle rect;
+ if (_isrow) {
+ int delta = calculateDelta();
+ rect = new Rectangle(0, adapter.getRowResizeStart(_index) + delta,
+ bounds.width - insets.getWidth(), adapter
+ .getRowResizeWidth());
+ } else {
+ int delta = calculateDelta();
+ rect = new Rectangle(adapter.getColumnResizeStart(_index) + delta,
+ 0, adapter.getColumnResizeWidth(), bounds.height
+ - insets.getHeight());
+ }
+ rect.translate(bounds.x + insets.left, bounds.y + insets.top);
+
+ figure.translateToAbsolute(rect);
+ getMarqueeRectangleFigure().translateToRelative(rect);
+ return rect;
+ }
+
+ /**
+ *
+ * @return null if this is not a table.
+ */
+ private ITableEditAdapter getTableEditAdapter() {
+ return TableEditHelper.getTableEditAdapter((GraphicalEditPart) this
+ .getSourceEditPart());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.DragEditPartsTracker#eraseSourceFeedback()
+ */
+ protected void eraseSourceFeedback() {
+ super.eraseSourceFeedback();
+ if (_marqueeFigure != null) {
+ removeFeedback(_marqueeFigure);
+ _marqueeFigure = null;
+ }
+ }
+
+ protected MarqueeRectangleFigure getMarqueeRectangleFigure() {
+ if (this._marqueeFigure == null) {
+ this._marqueeFigure = new MarqueeRectangleFigure();
+ addFeedback(this._marqueeFigure);
+ }
+ return this._marqueeFigure;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.DragEditPartsTracker#createTargetRequest()
+ */
+ protected Request createTargetRequest() {
+ return new TableResizeRequest(this._isrow, this._index);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.DragEditPartsTracker#updateTargetRequest()
+ */
+ protected void updateTargetRequest() {
+ TableResizeRequest req = (TableResizeRequest) getTargetRequest();
+ req.setDelta(calculateDelta());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.SelectEditPartTracker#handleButtonDown(int)
+ */
+ protected boolean handleButtonDown(int button) {
+ lockTargetEditPart(getSourceEditPart());
+ return super.handleButtonDown(button);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.DragEditPartsTracker#getCommand()
+ */
+ protected Command getCommand() {
+ return getTargetEditPart().getCommand(getTargetRequest());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeHandle.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeHandle.java
new file mode 100644
index 000000000..af5d8ecf4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tableedit/TableSideResizeHandle.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tableedit;
+
+import org.eclipse.draw2d.Cursors;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.handles.AbstractHandle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TableSideResizeHandle extends AbstractHandle {
+ private boolean _isRow;
+
+ private int _index;
+
+ /**
+ *
+ */
+ public TableSideResizeHandle(GraphicalEditPart owner, boolean isrow,
+ int index) {
+ super(owner, new EmptyLocator());
+ this._isRow = isrow;
+ this._index = index;
+
+ this.setCursor(isrow ? Cursors.SIZEN : Cursors.SIZEE);
+ // this.setBackgroundColor(ColorConstants.green);
+ this.setOpaque(false);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.handles.AbstractHandle#createDragTracker()
+ */
+ protected DragTracker createDragTracker() {
+ return new TableSideResizeDragTracker(getOwner(), _isRow, _index);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ExposeHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ExposeHelper.java
new file mode 100644
index 000000000..cb82d513c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ExposeHelper.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tools;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.editpolicies.AbstractEditPolicy;
+import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Node;
+
+/**
+ * This helper class expose an rectangle in design view, currentlly it is used
+ * to help expose caret.
+ *
+ * @author mengbo
+ */
+public class ExposeHelper {
+ private static final int DEFAULT_OFFSET = 100;
+
+ private static final int SCROLL_OFFSET = 8;
+
+ IHTMLGraphicalViewer _viewer;
+
+ /**
+ * @param owner
+ */
+ public ExposeHelper(IHTMLGraphicalViewer viewer) {
+ _viewer = viewer;
+ }
+
+ /**
+ * Expose rectangle. (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ExposeHelper#exposeDescendant(org.eclipse.gef.EditPart)
+ */
+ public void exposeArea(Rectangle rect) {
+ if (_viewer == null) {
+ return;
+ }
+ FigureCanvas canvas = (FigureCanvas) _viewer.getControl();
+ Viewport port = _viewer.getViewport();
+
+ if (port == null) {
+ return;
+ }
+ Rectangle exposeRegion = rect.getCopy();
+ Rectangle portBounds = port.getBounds().getCopy();
+ Point viewLocation = port.getViewLocation();
+ Dimension diff = calculateDiff(portBounds, exposeRegion);
+ if (diff != null) {
+ viewLocation.x -= diff.width;
+ viewLocation.y -= diff.height;
+ canvas.scrollSmoothTo(viewLocation.x, viewLocation.y);
+ }
+ }
+
+ private void exposeVertical(int offset) {
+ if (_viewer == null) {
+ return;
+ }
+ FigureCanvas canvas = (FigureCanvas) _viewer.getControl();
+ Viewport port = _viewer.getViewport();
+
+ if (port == null) {
+ return;
+ }
+ Point viewLocation = port.getViewLocation();
+ viewLocation.y += offset;
+ canvas.scrollSmoothTo(viewLocation.x, viewLocation.y);
+ }
+
+ private void exposeHorizontal(int offset) {
+ if (_viewer == null) {
+ return;
+ }
+ FigureCanvas canvas = (FigureCanvas) _viewer.getControl();
+ Viewport port = _viewer.getViewport();
+
+ if (port == null) {
+ return;
+ }
+ Point viewLocation = port.getViewLocation();
+ viewLocation.x += offset;
+ canvas.scrollSmoothTo(viewLocation.x, viewLocation.y);
+ }
+
+ private int calculateX(Rectangle portBounds, Rectangle caretRect) {
+ int result = 0;
+ if (portBounds.x > caretRect.getRight().x) {
+ result = portBounds.getLeft().getDifference(caretRect.getRight()).width;
+ if (portBounds.width >= caretRect.width) {
+ result = portBounds.getLeft()
+ .getDifference(caretRect.getLeft()).width;
+ }
+ } else if (portBounds.getRight().x < caretRect.getLeft().x) {
+ result = portBounds.getRight().getDifference(caretRect.getLeft()).width;
+ if (portBounds.width >= caretRect.width) {
+ result = portBounds.getRight().getDifference(
+ caretRect.getRight()).width;
+ }
+ }
+ return result;
+ }
+
+ private int calculateY(Rectangle portBounds, Rectangle caretRect) {
+ int result = 0;
+ if (portBounds.y > caretRect.getBottom().y) {
+ result = portBounds.getTop().getDifference(caretRect.getBottom()).height;
+ if (portBounds.height >= caretRect.height) {
+ result = portBounds.getTop().getDifference(caretRect.getTop()).height;
+ }
+ } else if (portBounds.getBottom().y < caretRect.getTop().y) {
+ result = portBounds.getBottom().getDifference(caretRect.getTop()).height;
+ if (portBounds.height >= caretRect.height) {
+ result = portBounds.getBottom().getDifference(
+ caretRect.getBottom()).height;
+ }
+ } else if (portBounds.getBottom().y < caretRect.getBottom().y) {
+ if (portBounds.height >= caretRect.height) {
+ result = portBounds.getBottom().getDifference(
+ caretRect.getBottom()).height;
+ }
+ } else if (portBounds.getTop().y > caretRect.getTop().y) {
+ if (portBounds.height >= caretRect.height) {
+ result = portBounds.getTop().getDifference(caretRect.getTop()).height;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Calculate caretPoint's offset to posrBounds at both x coordinate and y
+ * coordinate.
+ *
+ * @param portBounds
+ * @param exposeRegion
+ * @param canvas
+ * @param caretPoint
+ */
+ private Dimension calculateDiff(Rectangle portBounds, Rectangle caretRect) {
+ Dimension diff = new Dimension(0, 0);
+ diff.width = calculateX(portBounds, caretRect);
+ diff.height = calculateY(portBounds, caretRect);
+ return diff;
+ }
+
+ // /**
+ // * Calculate caretPoint's offset to posrBounds at both x coordinate and y
+ // coordinate.
+ // *
+ // * @param portBounds
+ // * @param exposeRegion
+ // * @param canvas
+ // * @param caretPoint
+ // */
+ // private Dimension calculateDiff(Rectangle portBounds, Point caretPoint)
+ // {
+ // int position = portBounds.getPosition(caretPoint);
+ // Dimension diff = null;
+ // Point containerPos = null;
+ // switch (position)
+ // {
+ // case PositionConstants.EAST:
+ // containerPos = new Point(portBounds.getRight().x, caretPoint.y);
+ // diff = containerPos.getDifference(caretPoint);
+ // break;
+ // case PositionConstants.NORTH_EAST:
+ // diff = portBounds.getTopRight().getDifference(caretPoint);
+ // break;
+ // case PositionConstants.WEST:
+ // containerPos = new Point(portBounds.getLeft().x, caretPoint.y);
+ // diff = containerPos.getDifference(caretPoint);
+ // break;
+ // case PositionConstants.NORTH_WEST:
+ // diff = portBounds.getTopLeft().getDifference(caretPoint);
+ // break;
+ // case PositionConstants.SOUTH_WEST:
+ // diff = portBounds.getBottomLeft().getDifference(caretPoint);
+ // break;
+ // case PositionConstants.SOUTH_EAST:
+ // diff = portBounds.getBottomRight().getDifference(caretPoint);
+ // break;
+ // case PositionConstants.NORTH:
+ // containerPos = new Point(caretPoint.x, portBounds.getTop().y);
+ // diff = containerPos.getDifference(caretPoint);
+ // break;
+ // case PositionConstants.SOUTH:
+ // containerPos = new Point(caretPoint.x, portBounds.getBottom().y);
+ // diff = containerPos.getDifference(caretPoint);
+ // break;
+ // }
+ // return diff;
+ // }
+ //
+ private static void expose(EditPart part, ScrollingGraphicalViewer viewer) {
+ if (part != null && part.getModel() instanceof Node) {
+ viewer.reveal(part);
+ }
+ }
+
+ private static void expose(Node element, ScrollingGraphicalViewer viewer) {
+ if (element instanceof INodeNotifier) {
+ EditPart editPart = (EditPart) ((INodeNotifier) element)
+ .getAdapterFor(EditPart.class);
+ expose(editPart, viewer);
+ }
+ }
+
+ public static void expose(ISelection selection,
+ ScrollingGraphicalViewer viewer) {
+ if (selection instanceof IStructuredSelection) {
+ Object element = ((IStructuredSelection) selection)
+ .getFirstElement();
+ if (element instanceof Node) {
+ expose((Node) element, viewer);
+ } else if (element instanceof EditPart) {
+ expose((EditPart) element, viewer);
+ }
+ }
+ }
+
+ public void adjustVertical(Point p) {
+ int offset = 0;
+ if ((offset = getVerticalBoundsOffset(p, false)) < SCROLL_OFFSET) {
+ exposeVertical(SCROLL_OFFSET - offset);
+ } else if ((offset = getVerticalBoundsOffset(p, true)) < SCROLL_OFFSET) {
+ exposeVertical(offset - SCROLL_OFFSET);
+ }
+ if ((offset = getHorizontalBoundsOffset(p, true)) < SCROLL_OFFSET) {
+ exposeHorizontal(SCROLL_OFFSET - offset);
+ } else if ((offset = getHorizontalBoundsOffset(p, false)) < SCROLL_OFFSET) {
+ exposeHorizontal(offset - SCROLL_OFFSET);
+ }
+ }
+
+ public Point getViewpostLocation() {
+ if (_viewer != null) {
+ Viewport port = _viewer.getViewport();
+
+ if (port != null) {
+ return port.getViewLocation();
+ }
+ }
+ return null;
+ }
+
+ public Point translateToViewport(IFigure figure, Point p) {
+ Point vp = getViewpostLocation();
+ return new Point(p.x - vp.x, p.y - vp.y);
+ }
+
+ private int getHorizontalBoundsOffset(Point p, boolean forward) {
+ if (_viewer == null) {
+ return DEFAULT_OFFSET;
+ }
+ Viewport port = _viewer.getViewport();
+
+ if (port == null) {
+ return DEFAULT_OFFSET;
+ }
+ if (forward) {
+ Rectangle portBounds = port.getBounds().getCopy();
+ return portBounds.getRight().x - p.x;
+ } else {
+ return p.x;
+ }
+ }
+
+ private int getVerticalBoundsOffset(Point p, boolean up) {
+ if (_viewer == null) {
+ return DEFAULT_OFFSET;
+ }
+ Viewport port = _viewer.getViewport();
+
+ if (port == null) {
+ return DEFAULT_OFFSET;
+ }
+ if (!up) {
+ Rectangle portBounds = port.getBounds().getCopy();
+ return portBounds.getBottom().y - p.y;
+ } else {
+ return p.y;
+ }
+ }
+
+ public void exposeBorder(Rectangle rect, AbstractEditPolicy policy) {
+ Point p = rect.getTopLeft();
+ p = translateToViewport(((GraphicalEditPart) policy.getHost())
+ .getFigure(), p);
+ adjustVertical(p);
+ p = rect.getBottomRight();
+ p = translateToViewport(((GraphicalEditPart) policy.getHost())
+ .getFigure(), p);
+ adjustVertical(p);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ObjectModeDragTracker.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ObjectModeDragTracker.java
new file mode 100644
index 000000000..15519bcf3
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/ObjectModeDragTracker.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tools;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.tools.DragEditPartsTracker;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+
+/**
+ * When user press right mouse to do selection, if the selected node is inside
+ * current range selection, then don't change selection. This is for better
+ * context menu support.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class ObjectModeDragTracker extends DragEditPartsTracker {
+ /**
+ * @param sourceEditPart
+ */
+ public ObjectModeDragTracker(EditPart sourceEditPart) {
+ super(sourceEditPart);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.SelectEditPartTracker#handleButtonDown(int)
+ */
+ protected boolean handleButtonDown(int button) {
+ if (button == 3 && isInState(STATE_INITIAL)) {
+ EditPart sourcePart = this.getSourceEditPart();
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) sourcePart
+ .getViewer();
+ if (viewer != null && viewer.isInRangeMode()) {
+ DesignRange range = viewer.getRangeSelection();
+ if (range != null && range.isValid()) {
+ if (RangeUtil.intersect(range, sourcePart)) {
+ return true;
+ }
+ }
+ }
+ }
+ return super.handleButtonDown(button);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeDragTracker.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeDragTracker.java
new file mode 100644
index 000000000..18ba9e6bd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeDragTracker.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tools;
+
+import java.util.Collections;
+
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.RequestConstants;
+import org.eclipse.gef.requests.SelectionRequest;
+import org.eclipse.gef.tools.TargetingTool;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.range.RangeUtil;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingPositionMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.graphics.Cursor;
+
+/**
+ * @author mengbo
+ */
+public class RangeDragTracker extends TargetingTool implements DragTracker {
+ /** Flag to indicate selection has been performed. */
+ protected static final int FLAG_SELECTION_PERFORMED = TargetingTool.MAX_FLAG << 1;
+
+ /** Max flag */
+ protected static final int MAX_FLAG = FLAG_SELECTION_PERFORMED;
+
+ private EditPart editpart;
+
+ /**
+ * Constructs a new SelectEditPartTracker with the given edit part as the
+ * source.
+ *
+ * @param owner
+ * the source edit part
+ */
+ public RangeDragTracker(EditPart owner) {
+ setSourceEditPart(owner);
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#calculateCursor()
+ */
+ protected Cursor calculateCursor() {
+ if (isInState(STATE_INITIAL | STATE_DRAG | STATE_ACCESSIBLE_DRAG)) {
+ return getDefaultCursor();
+ }
+ return super.calculateCursor();
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#getCommandName()
+ */
+ protected String getCommandName() {
+ return "Range Drag Tracker";//$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#getDebugName()
+ */
+ protected String getDebugName() {
+ return "Range Drag Tracker";//$NON-NLS-1$
+ }
+
+ /**
+ * Returns the source edit part.
+ *
+ * @return the source edit part
+ */
+ protected EditPart getSourceEditPart() {
+ return editpart;
+ }
+
+ /**
+ * Performs a conditional selection if needed (if right or left mouse button
+ * have been pressed) and goes into the drag state. If any other button has
+ * been pressed, the tool goes into the invalid state.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)
+ */
+ protected boolean handleButtonDown(int button) {
+ if (button == 3 && isInState(STATE_INITIAL)) {
+ EditPart sourcePart = this.getSourceEditPart();
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) sourcePart
+ .getViewer();
+ if (viewer != null && viewer.isInRangeMode()) {
+ DesignRange range = viewer.getRangeSelection();
+ if (range != null && range.isValid()) {
+ if (RangeUtil.intersect(range, sourcePart)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ if ((button == 1 || button == 3) && isInState(STATE_INITIAL)) {
+ peroformSelectionBegin();
+ }
+
+ if (button != 1) {
+ setState(STATE_INVALID);
+ if (button == 3)
+ setState(STATE_TERMINAL);
+ handleInvalidInput();
+ } else {
+ stateTransition(STATE_INITIAL, STATE_DRAG);
+ }
+ return true;
+ }
+
+ /**
+ * Calls {@link #performSelection()}if the source is not selected. If the
+ * source is selected and there are no modifier keys pressed (i.e. the user
+ * isn't selecting multiple edit parts or deselecting edit parts), sets the
+ * direct edit flag so that when the mouse is released, a direct edit will
+ * be performed.
+ */
+ protected void peroformSelectionBegin() {
+ // if (getCurrentInput().isControlKeyDown())
+ // {
+ // // when control key is down, switch to object selection mode.
+ // getHTMLGraphicalViewer().ensureObjectSelectionMode();
+ // setFlag(FLAG_SELECTION_PERFORMED, true);
+ // EditPartViewer viewer = getCurrentViewer();
+ // List selectedObjects = viewer.getSelectedEditParts();
+ //
+ // if (selectedObjects.contains(getSourceEditPart()))
+ // viewer.deselect(getSourceEditPart());
+ // else
+ // viewer.appendSelection(getSourceEditPart());
+ // }
+ // else
+ if (getCurrentInput().isShiftKeyDown()) {
+ getHTMLGraphicalViewer().ensureRangeSelectionMode();
+ rangeSelection(true);
+ } else {
+ if (shouldStartRangeSelection()) {
+ rangeSelection(false);
+ } else {
+ getCurrentViewer().select(getSourceEditPart());
+ }
+ }
+ }
+
+ /**
+ * If in the drag state, the tool selects the source edit part. If the edit
+ * part was already selected, {@link #performDirectEdit()}is called. If the
+ * edit part is newly selected and not completely visible,
+ * {@link EditPartViewer#reveal(EditPart)}is called to show the selected
+ * edit part.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
+ */
+ protected boolean handleButtonUp(int button) {
+ if (isInState(STATE_DRAG)) {
+ // XXX: commented the following two line (lium)
+ // performSelection();
+ // if (button == 1 && getSourceEditPart().getSelected() !=
+ // EditPart.SELECTED_NONE)
+ // getCurrentViewer().reveal(getSourceEditPart());
+ setState(STATE_TERMINAL);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Calls {@link #performOpen()}if the double click was with mouse button 1.
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleDoubleClick(int)
+ */
+ protected boolean handleDoubleClick(int button) {
+ if (button == 1) {
+ performOpen();
+ }
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()
+ */
+ protected boolean handleDragStarted() {
+ return stateTransition(STATE_DRAG, STATE_DRAG_IN_PROGRESS);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress()
+ */
+ protected boolean handleDragInProgress() {
+ if (getHTMLGraphicalViewer().isInRangeMode()) {
+ rangeSelection(true);
+ return true;
+ } else {
+ return super.handleDragInProgress();
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if selection has already occured.
+ *
+ * @return <code>true</code> if selection has occured
+ */
+ protected boolean hasSelectionOccurred() {
+ return getFlag(FLAG_SELECTION_PERFORMED);
+ }
+
+ /**
+ * Creates a {@link SelectionRequest}and sends it to the source edit part
+ * via {@link EditPart#performRequest(Request)}. Possible uses are to open
+ * the selected item in another editor or replace the current editor's
+ * contents based on the selected item.
+ */
+ protected void performOpen() {
+ SelectionRequest request = new SelectionRequest();
+ request.setLocation(getLocation());
+ request.setType(RequestConstants.REQ_OPEN);
+ getSourceEditPart().performRequest(request);
+ }
+
+ /**
+ * @see org.eclipse.gef.tools.AbstractTool#resetFlags()
+ */
+ protected void resetFlags() {
+ super.resetFlags();
+ setFlag(FLAG_SELECTION_PERFORMED, false);
+ }
+
+ /**
+ * Sets the source edit part.
+ *
+ * @param part
+ * the source edit part
+ */
+ protected void setSourceEditPart(EditPart part) {
+ this.editpart = part;
+ }
+
+ public IHTMLGraphicalViewer getHTMLGraphicalViewer() {
+ return (IHTMLGraphicalViewer) getCurrentViewer();
+ }
+
+ /**
+ * @return
+ */
+ private boolean shouldStartRangeSelection() {
+ IPositionMediator positionMediator = new InlineEditingPositionMediator(
+ new ActionData(ActionData.INLINE_EDIT, null));
+ if (positionMediator.isEditable(new Target(getSourceEditPart()))) {
+ return getSourceEditPart() instanceof TextEditPart
+ || !(((NodeEditPart) getSourceEditPart()).isWidget());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param b
+ * true means remain the old range start position.
+ */
+ private void rangeSelection(boolean b) {
+ // XXX: not using updateTargetEditPartUnderMouse. Maybe should. Don't
+ // want to
+ // go through the request mechanism, so simple implementation for now.
+ EditPart editPart = getCurrentViewer().findObjectAtExcluding(
+ getLocation(), Collections.EMPTY_LIST);
+ IPositionMediator positionMediator = new InlineEditingPositionMediator(
+ new ActionData(ActionData.INLINE_EDIT, null));
+ ExposeHelper exposeHelper = new ExposeHelper(getHTMLGraphicalViewer());
+ exposeHelper.adjustVertical(getCurrentInput().getMouseLocation());
+ DesignPosition position = EditPartPositionHelper.findEditPartPosition(
+ editPart, getCurrentInput().getMouseLocation(),
+ positionMediator);
+ if (b) {
+ getHTMLGraphicalViewer().setRangeEndPosition(position);
+ } else {
+ getHTMLGraphicalViewer().setRange(position, position);
+ }
+ if (getHTMLGraphicalViewer() instanceof HTMLGraphicalViewer) {
+ ((HTMLGraphicalViewer) getHTMLGraphicalViewer())
+ .updateHorizontalPos();
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeSelectionTool.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeSelectionTool.java
new file mode 100644
index 000000000..ead3d23c1
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/tools/RangeSelectionTool.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.tools;
+
+import org.eclipse.gef.Request;
+import org.eclipse.gef.RequestConstants;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.requests.LocationRequest;
+import org.eclipse.gef.tools.SelectionTool;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.commands.DeleteNodeCommand;
+import org.eclipse.jst.pagedesigner.commands.SwitchSelectionCommand;
+import org.eclipse.jst.pagedesigner.commands.nav.HorizontalMoveCommand;
+import org.eclipse.jst.pagedesigner.commands.nav.ICaretPositionMover;
+import org.eclipse.jst.pagedesigner.commands.nav.VerticalMoveCommand;
+import org.eclipse.jst.pagedesigner.commands.range.ContentCommand;
+import org.eclipse.jst.pagedesigner.commands.range.CopyCommand;
+import org.eclipse.jst.pagedesigner.commands.range.CutCommand;
+import org.eclipse.jst.pagedesigner.commands.range.DeleteCommand;
+import org.eclipse.jst.pagedesigner.commands.range.InsertCommand;
+import org.eclipse.jst.pagedesigner.commands.range.KeyboardData;
+import org.eclipse.jst.pagedesigner.commands.range.PasteCommand;
+import org.eclipse.jst.pagedesigner.commands.range.SelectAllCommand;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.requests.LocationModifierRequest;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+
+/**
+ * @author mengbo
+ */
+public class RangeSelectionTool extends SelectionTool {
+ static final private Logger _log = PDPlugin
+ .getLogger(RangeSelectionTool.class);
+
+ private LocationRequest _hoverRequest;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.SelectionTool#handleKeyDown(org.eclipse.swt.events.KeyEvent)
+ */
+ protected boolean handleKeyDown(KeyEvent e) {
+ // resetHover() is not visible.
+ if (isHoverActive()) {
+ handleHoverStop();
+ }
+ setHoverActive(false);
+
+ if ((e.stateMask & SWT.ALT) != 0) {
+ return false;
+ }
+ Command command = null;
+ KeyboardData keyCode = null;
+ switch (e.keyCode) {
+ case SWT.F2:
+ command = new SwitchSelectionCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer());
+
+ break;
+ case SWT.ARROW_UP:
+ command = new VerticalMoveCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer(), true, (e.stateMask & SWT.SHIFT) != 0);
+ break;
+ case SWT.ARROW_DOWN:
+ command = new VerticalMoveCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer(), false, (e.stateMask & SWT.SHIFT) != 0);
+ break;
+ case SWT.ARROW_LEFT:
+ command = new HorizontalMoveCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer(), false, (e.stateMask & SWT.SHIFT) != 0);
+ break;
+ case SWT.ARROW_RIGHT:
+ command = new HorizontalMoveCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer(), true, (e.stateMask & SWT.SHIFT) != 0);
+ break;
+ case SWT.DEL:
+ if ((e.stateMask & SWT.SHIFT) == 0) {
+ if (getCurrentViewer().getSelection() != null) {
+ ISelection selection = getCurrentViewer().getSelection();
+ if (selection instanceof StructuredSelection) {
+ Object object = ((StructuredSelection) selection)
+ .getFirstElement();
+ if (!(object instanceof DocumentEditPart)) {
+ // "delete node"
+ command = new DeleteNodeCommand(
+ (IHTMLGraphicalViewer) getCurrentViewer());
+ }
+ }
+ }
+ if (command == null) {
+ // "delete"
+ command = new DeleteCommand(true,
+ (IHTMLGraphicalViewer) this.getCurrentViewer()); //$NON-NLS-1$
+ }
+ } else {
+ // "cut"
+ command = new CutCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer()); //$NON-NLS-1$
+ e.doit = false;
+ }
+ break;
+ case SWT.BS:
+ // "delete"
+ command = new DeleteCommand(false, (IHTMLGraphicalViewer) this
+ .getCurrentViewer()); //$NON-NLS-1$
+ e.doit = false;
+ break;
+ case SWT.INSERT:
+ if ((e.stateMask & SWT.SHIFT) != 0) {
+ // "paste"
+ command = new PasteCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer()); //$NON-NLS-1$
+ e.doit = false;
+ break;
+ } else if ((e.stateMask & SWT.CONTROL) != 0) {
+ // "copy"
+ command = new CopyCommand((IHTMLGraphicalViewer) this
+ .getCurrentViewer()); //$NON-NLS-1$
+ e.doit = false;
+ break;
+ }
+ break;
+ case SWT.LF:
+ case SWT.CR:
+ // "insert"
+ keyCode = new KeyboardData(e.character, e.stateMask,
+ (IHTMLGraphicalViewer) getCurrentViewer());
+ command = new InsertCommand(
+ PageDesignerResources.getInstance().getString(
+ "RangeSelectionTool.CommandLabel.Insert"), (IHTMLGraphicalViewer) this.getCurrentViewer(), keyCode); //$NON-NLS-1$
+ e.doit = false;
+ break;
+ default:
+ if (e.keyCode == 'a' && (e.stateMask & SWT.CTRL) != 0) {
+ command = new SelectAllCommand("selectAll",
+ (IHTMLGraphicalViewer) this.getCurrentViewer());
+ e.doit = false;
+ } else {
+ if (getCurrentViewer() instanceof HTMLGraphicalViewer
+ && ((HTMLGraphicalViewer) getCurrentViewer())
+ .isInRangeMode()
+ && (!Character.isIdentifierIgnorable(e.character) && !Character
+ .isISOControl(e.character))
+ || (e.character == '\r')) {
+ keyCode = new KeyboardData(e.character, e.stateMask,
+ (IHTMLGraphicalViewer) getCurrentViewer());
+ // "insert"
+ command = new InsertCommand(
+ PageDesignerResources.getInstance().getString(
+ "RangeSelectionTool.CommandLabel.Insert"), (IHTMLGraphicalViewer) this.getCurrentViewer(), keyCode); //$NON-NLS-1$
+ e.doit = false;
+ break;
+ } else {
+ return super.handleKeyDown(e);
+ }
+ }
+ }
+ if (command != null) {
+ command.execute();
+ e.doit = false;
+ if (command instanceof ICaretPositionMover) {
+ if (getCurrentViewer() instanceof HTMLGraphicalViewer) {
+ ((HTMLGraphicalViewer) getCurrentViewer())
+ .updateHorizontalPos();
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param e
+ * @return
+ */
+ protected boolean handleObjectModeKeyDown(KeyEvent e) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ // /**
+ // * @param e
+ // * @return
+ // */
+ // protected boolean handleRangeModeKeyDown(KeyEvent e)
+ // {
+ // if (e.keyCode == SWT.SHIFT || e.keyCode == SWT.CONTROL || e.keyCode ==
+ // SWT.ALT)
+ // {
+ // return false;
+ // }
+ //
+ // dumpKey(e);
+ // Command command = null;
+ // switch (e.keyCode)
+ // {
+ // case SWT.ARROW_LEFT:
+ // command = new HorizontalMoveCommand((IHTMLGraphicalViewer)
+ // this.getCurrentViewer(), false,
+ // (e.stateMask & SWT.SHIFT) != 0);
+ // break;
+ // case SWT.ARROW_RIGHT:
+ // command = new HorizontalMoveCommand((IHTMLGraphicalViewer)
+ // this.getCurrentViewer(), true,
+ // (e.stateMask & SWT.SHIFT) != 0);
+ // break;
+ //
+ // }
+ // if (command != null)
+ // {
+ // command.execute();
+ // return true;
+ // }
+ //
+ // char content = e.character;
+ //
+ // // when reach here, should be standard content keys.
+ // return handleRangeModeContentChar(content);
+ // }
+
+ /**
+ * For inner debuging.
+ *
+ * @param e
+ */
+ private void dumpKey(KeyEvent e) {
+ String message = "code:" + Integer.toBinaryString(e.keyCode) + "char:" + e.character + "key:" + Integer.toBinaryString(e.stateMask); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ _log.info(message);
+ }
+
+ /**
+ * @param content
+ */
+ private boolean handleRangeModeContentChar(char content) {
+ IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) this
+ .getCurrentViewer();
+ ContentCommand c = new ContentCommand(viewer, content);
+ c.execute();
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.SelectionTool#createHoverRequest()
+ */
+ protected void createHoverRequest() {
+ this._hoverRequest = new LocationModifierRequest();
+ _hoverRequest.setType(RequestConstants.REQ_SELECTION_HOVER);
+ }
+
+ protected Request getTargetHoverRequest() {
+ if (_hoverRequest == null) {
+ createHoverRequest();
+ }
+ return _hoverRequest;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.tools.SelectionTool#updateHoverRequest()
+ */
+ protected void updateHoverRequest() {
+ LocationModifierRequest request = (LocationModifierRequest) getTargetHoverRequest();
+ request.setLocation(getLocation());
+ request.setControlKeyPressed(getCurrentInput().isControlKeyDown());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/CommonResourceDialog.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/CommonResourceDialog.java
new file mode 100644
index 000000000..970f38088
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/CommonResourceDialog.java
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.WebrootUtil;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+/**
+ * This dialog shows IFile type resources within a IProject domain for
+ * selection. The client can prvide the suffixs of files to filter when
+ * candidates are shown on the tree,
+ *
+ * @author mengbo
+ */
+public class CommonResourceDialog extends TreeViewerSelectionDialog {
+ private static final int WEBROOT_FOLDER_DEPTH = 2;
+
+ // CommonResourceDialog.statusMessage = Please select an image file
+ private static final String STATUS_MESSAGE = PageDesignerResources
+ .getInstance().getString("CommonResourceDialog.statusMessage"); //$NON-NLS-1$
+
+ private String _suffixs[] = null;
+
+ private CommonResourceFilter _filter;
+
+ /** Create the logger for this class */
+ private static Logger _log = PDPlugin.getLogger(CommonResourceDialog.class);
+
+ // The content provider
+ class ProjectFileDialogContentProvider implements ITreeContentProvider {
+ /**
+ * The visual part that is using this content provider is about to be
+ * disposed. Deallocate all allocated SWT resources.
+ */
+ public void dispose() {
+ }
+
+ /**
+ * @see ITreeContentProvider#getChildren
+ */
+ public Object[] getChildren(Object element) {
+ if (element instanceof IWorkspace) {
+ IWorkspaceRoot root = ((IWorkspace) element).getRoot();
+ IProject[] projects = root.getProjects();
+ return projects;
+ } else if (element instanceof IContainer) {
+ if (element instanceof IProject) {
+ IContainer container = (IContainer) element;
+ if (container.isAccessible()) {
+ try {
+ IResource[] members = container.members();
+ return members;
+ } catch (CoreException e) {
+ // "Error.CommonResourceDialog.0.1" = "Error in
+ // project memeber querying"
+ // "Error.CommonResourceDialog.0.2" = "Please refer
+ // to the log for details"
+ PDPlugin
+ .getAlerts()
+ .error(
+ "Error.CommonResourceDialog.0.1", "Error.CommonResourceDialog.0.2"); //$NON-NLS-1$ //$NON-NLS-2$
+ // Error.ProjectFileDialogContentProvider.0 = Core
+ // error, you may need to restart the application
+ _log
+ .error(
+ "Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
+ }
+ }
+ } else if (element instanceof IFolder) {
+ // Process the folder container
+ IContainer container = (IContainer) element;
+ if (container.isAccessible()) {
+ try {
+ // Filter all the files under the project and only
+ // show
+ // the folder in the container selection dialog
+ List children = new ArrayList();
+ IResource[] members = container.members();
+ for (int i = 0; i < members.length; i++) {
+ if (!members[i].getName().equals(
+ IFileFolderConstants.FOLDER_WEBINF)
+ && !members[i]
+ .getName()
+ .equals(
+ IFileFolderConstants.FOLDER_METAINF)) {
+ children.add(members[i]);
+ }
+ }
+ return children.toArray();
+ } catch (CoreException e) {
+ // "Error.CommonResourceDialog.0.1" = "Error in
+ // project memeber querying"
+ // "Error.CommonResourceDialog.0.2" = "Please refer
+ // to the log for details"
+ PDPlugin
+ .getAlerts()
+ .error(
+ "Error.CommonResourceDialog.0.1", "Error.CommonResourceDialog.0.2"); //$NON-NLS-1$ //$NON-NLS-2$
+ // Error.ProjectFileDialogContentProvider.0 = core
+ // error, you may need to restart the application
+ _log
+ .error(
+ "Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return new Object[0];
+ }
+
+ /**
+ * @see ITreeContentProvider#getElements
+ */
+ public Object[] getElements(Object element) {
+ return getChildren(element);
+ }
+
+ /**
+ * @see ITreeContentProvider#getParent
+ */
+ public Object getParent(Object element) {
+ if (element instanceof IResource) {
+ return ((IResource) element).getParent();
+ }
+ return null;
+ }
+
+ /**
+ * @see ITreeContentProvider#hasChildren
+ */
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ /**
+ * @see IContentProvider#inputChanged
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+ // The default resource filter
+ class CommonResourceFilter extends ViewerFilter {
+ private String _suffixs[] = { IFileFolderConstants.EXT_PROPERTIES };
+
+ Logger _log = PDPlugin.getLogger(CommonResourceFilter.class);
+
+ private IProject _project;
+
+ /**
+ * @return Returns the _suffixs.
+ */
+ public String[] getSuffixs() {
+ return _suffixs;
+ }
+
+ /**
+ * @param _suffixs
+ * The _suffixs to set.
+ */
+ public void setSuffixs(String[] _suffixs) {
+ this._suffixs = _suffixs;
+ }
+
+ public CommonResourceFilter(IProject project) {
+ _project = project;
+ }
+
+ /**
+ * @param _project
+ * The _project to set.
+ */
+ public void setProject(IProject project) {
+ this._project = project;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer,
+ * java.lang.Object, java.lang.Object)
+ */
+ public boolean select(Viewer viewer, Object parentElement,
+ Object element) {
+ // TODO: This logic can be improved by add caching mechanism
+ if (element instanceof IWorkspace) {
+ return true;
+ } else if (element instanceof IFile) {
+ if (Arrays.asList(_suffixs).contains(
+ ((IFile) element).getFileExtension())) {
+ return true;
+ }
+ } else if (element instanceof IContainer) {
+ if (!((IContainer) element).isAccessible()) {
+ return false;
+ }
+ if (element instanceof IProject) {
+ IProject container = (IProject) element;
+ if (isWebAppProject(container)
+ && this.isSameProject(container, _project)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else if (element instanceof IFolder) {
+ IContainer container = (IContainer) element;
+ try {
+ if (container.getName().equals(
+ IFileFolderConstants.FOLDER_WEBINF)
+ || container.getName().equals(
+ IFileFolderConstants.FOLDER_METAINF)) {
+ return false;
+ }
+ IResource[] members = container.members();
+ for (int i = 0; i < members.length; i++) {
+ {
+ if (select(viewer, members[i].getParent(),
+ members[i])) {
+ return true;
+ }
+ }
+ }
+ } catch (CoreException e) {
+ // "Error.ImgFileFilter.0" = "Error in filtering the
+ // tree", "Error.ImgFileFilter.2 = ""CoreException is
+ // thrown, please refer to error log for details"
+ // "Error.ProjectFileDialogContentProvider.0" = core
+ // error, show alert dialog to user.
+ PDPlugin
+ .getAlerts()
+ .detailError(
+ "Error.ImgFileFilter.0", "Error.ImgFileFilter.2"); //$NON-NLS-2$
+ _log.error(
+ "Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
+ return false;
+ }
+ }
+ }
+ // we don't select any other types of resources.
+ return false;
+ }
+
+ /**
+ * Determines if a project is a Web Application project by the presence
+ * of an associated Web Application Nature.
+ *
+ * @return boolean - True, when project is a Web Application project
+ */
+ private boolean isWebAppProject(IProject project) {
+ return WebrootUtil.isValidWebProject(project);
+ }
+
+ private boolean isSameProject(IProject orig, IProject dst) {
+ String currentProjectName = ((IProject) orig).getFullPath()
+ .toString().trim();
+ String projectName = dst.getFullPath().toString().trim();
+ return projectName.equalsIgnoreCase(currentProjectName);
+ }
+ }
+
+ /**
+ * This is a dialog for common resource selection, the resouce supported
+ * include IFolder, IProject, IFile, user can provide
+ *
+ * @param parentShell
+ * @param project
+ */
+ public CommonResourceDialog(Shell parentShell, IProject project) {
+ super(parentShell, STATUS_MESSAGE);
+ setContentProvider(new ProjectFileDialogContentProvider());
+ setLabelProvider(WorkbenchLabelProvider
+ .getDecoratingWorkbenchLabelProvider());
+ _filter = new CommonResourceFilter(project);
+ setFilter(_filter);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#findInputElement()
+ */
+ protected Object findInputElement() {
+ return ResourcesPlugin.getWorkspace();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#isValidSelection(java.lang.Object)
+ */
+ protected boolean isValidSelection(Object selection) {
+ if (getContainerFullPath(selection) == null) {
+ return false;
+ } else {
+ int depth = getContainerFullPath(selection).segmentCount();
+ // The location is within WEBROOT PATH?
+ if ((selection instanceof IFile) && depth >= WEBROOT_FOLDER_DEPTH) {
+ // Null means no filter is set
+ if (_suffixs == null) {
+ return true;
+ }
+ // The extension is supported?
+ else if (_suffixs != null
+ && Arrays.asList(_suffixs).contains(
+ ((IFile) selection).getFileExtension())) {
+ return true;
+ }
+ }
+ // None of above conditions, invalid.
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.dialogs.SelectionDialog#getResult()
+ */
+ public Object[] getResult() {
+ Object[] objects = super.getResult();
+ if (objects == null || objects.length == 0) {
+ return null;
+ }
+ // Only one element is set by us.
+ IPath returnValue = getWebRelatedPath(objects[0]);
+ if (returnValue != null) {
+ if (!(returnValue.toString().startsWith(
+ IFileFolderConstants.PATH_SEPARATOR) || returnValue
+ .toString().startsWith("\\"))) {
+ Path tempPath = new Path(IFileFolderConstants.PATH_SEPARATOR
+ + returnValue.toString());
+ returnValue = tempPath;
+ }
+ }
+ return new Object[] { returnValue };
+ }
+
+ public IPath getContainerFullPath(Object _selectedElement) {
+ if (_selectedElement == null) {
+ return null;
+ } else if (_selectedElement instanceof IContainer) {
+ return ((IContainer) _selectedElement).getFullPath();
+ } else if (_selectedElement instanceof IFile) {
+ return ((IFile) _selectedElement).getFullPath();
+ }
+ return null;
+ }
+
+ public IPath getWebRelatedPath(Object _selectedElement) {
+ IPath result = null;
+ if (_selectedElement == null) {
+ return null;
+ } else if (_selectedElement instanceof IContainer) {
+ result = ((IContainer) _selectedElement).getFullPath();
+ } else if (_selectedElement instanceof IFile) {
+ result = ((IFile) _selectedElement).getFullPath();
+ }
+ if (result != null) {
+ if (result.segmentCount() > 2) {
+ result = result.removeFirstSegments(2);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param _suffixs
+ * The _suffixs to set.
+ */
+ public void setSuffixs(String[] suffixs) {
+ this._suffixs = suffixs;
+ _filter.setSuffixs(suffixs);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/PartActivationHandler.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/PartActivationHandler.java
new file mode 100644
index 000000000..e5e16907e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/PartActivationHandler.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common;
+
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * @author mengbo
+ */
+public abstract class PartActivationHandler extends ShellAdapter implements
+ IPartListener {
+ private IWorkbenchPart _activePart;
+
+ private boolean _isHandlingActivation = false;
+
+ private IWorkbenchPart _trace;
+
+ public PartActivationHandler(IWorkbenchPart part) {
+ _trace = part;
+ }
+
+ /**
+ * this method is called when the specified part is activated.
+ */
+ public abstract void handleActivation();
+
+ private void internalHandleActivation() {
+
+ if (_isHandlingActivation)
+ return;
+
+ if (_activePart == _trace) {
+ _isHandlingActivation = true;
+ try {
+ handleActivation();
+ } finally {
+ _isHandlingActivation = false;
+ }
+ }
+ }
+
+ /**
+ * @see IPartListener#partActivated(IWorkbenchPart)
+ */
+ public void partActivated(IWorkbenchPart part) {
+ _activePart = part;
+ internalHandleActivation();
+ }
+
+ /**
+ * @see IPartListener#partBroughtToTop(IWorkbenchPart)
+ */
+ public void partBroughtToTop(IWorkbenchPart part) {
+ }
+
+ /**
+ * @see IPartListener#partClosed(IWorkbenchPart)
+ */
+ public void partClosed(IWorkbenchPart part) {
+ }
+
+ /**
+ * @see IPartListener#partDeactivated(IWorkbenchPart)
+ */
+ public void partDeactivated(IWorkbenchPart part) {
+ _activePart = null;
+ }
+
+ /**
+ * @see IPartListener#partOpened(IWorkbenchPart)
+ */
+ public void partOpened(IWorkbenchPart part) {
+ }
+
+ /*
+ * @see ShellListener#shellActivated(ShellEvent)
+ */
+ public void shellActivated(ShellEvent e) {
+ internalHandleActivation();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/ResourceOnClasspathDialog.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/ResourceOnClasspathDialog.java
new file mode 100644
index 000000000..95f9fbcc9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/ResourceOnClasspathDialog.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common;
+
+import java.io.File;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.JarEntryFile;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.jst.pagedesigner.utils.JavaUtil;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog will let client to select resources that located on a
+ * IJavaProject classpath, the client can provide a list of files suffixs to
+ * filter.
+ *
+ * @author mengbo
+ */
+// TODO: Since many jar files might do nothing to do with client's selection, we
+// may need to provides more filter choice
+// to clients to exclude unnecessary jar files, such as that are located in JDK
+// dir.
+public class ResourceOnClasspathDialog extends TreeViewerSelectionDialog {
+ // ResourcesOnClasspathDialog.statusMessage = Please select a property file
+ private static final String STATUS_MESSAGE = PageDesignerResources
+ .getInstance()
+ .getString("ResourcesOnClasspathDialog.statusMessage"); //$NON-NLS-1$
+
+ private IJavaProject _javaProject;
+
+ // the suffixs of files that can be selected
+ private String _suffixs[]; // =
+
+ // IJMTConstants.DEFAULT_SUFFIX;
+
+ private ResourceOnClasspathFilter _filter;
+
+ // Client doesn't need to know it.
+ class ResourceOnClasspathFilter extends ViewerFilter {
+ StandardJavaElementContentProvider _javaContentProvider;
+
+ public ResourceOnClasspathFilter(
+ StandardJavaElementContentProvider contentProvider) {
+ _javaContentProvider = contentProvider;
+ }
+
+ /**
+ * Set the suffixs of files need to be selected.
+ *
+ * @param suffixs
+ */
+ public void setSuffixs(String suffixs[]) {
+ _suffixs = suffixs;
+ }
+
+ /**
+ * @param contentProvider
+ * The _javaContentProvider to set.
+ */
+ public void setJavaContentProvider(
+ StandardJavaElementContentProvider contentProvider) {
+ _javaContentProvider = contentProvider;
+ }
+
+ /**
+ * @param project
+ * The _javaProject to set.
+ */
+ public void setJavaProject(IJavaProject project) {
+ _javaProject = project;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer,
+ * java.lang.Object, java.lang.Object)
+ */
+ public boolean select(Viewer viewer, Object parentElement,
+ Object element) {
+ // TODO: This logic can be improved by add caching mechanism
+ if (element instanceof IJavaProject) {
+ String currentProjectName = ((IJavaProject) element)
+ .getProject().getFullPath().toString().trim();
+ String projectName = _javaProject.getProject().getFullPath()
+ .toString().trim();
+ if (projectName.equalsIgnoreCase(currentProjectName)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else if (element instanceof IResource) {
+ if (((_javaProject != null) && !_javaProject
+ .isOnClasspath((IResource) element))) {
+ return false;
+ }
+ if (element instanceof IFile) {
+ if (Arrays.asList(_suffixs).contains(
+ ((IFile) element).getFileExtension())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // XXX: JarEntryFile is for internal use.
+ if (element instanceof JarEntryFile) {
+ String ext = ((JarEntryFile) element).getFullPath()
+ .getFileExtension();
+ if (ext != null && Arrays.asList(_suffixs).contains(ext)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (!(element instanceof IJavaElement)) {
+ return false;
+ }
+ if (((_javaProject != null) && !_javaProject
+ .isOnClasspath((IJavaElement) element))) {
+ return false;
+ }
+ IJavaElement javaElement = (IJavaElement) element;
+ Object[] children = null;
+ switch (javaElement.getElementType()) {
+ case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+ children = _javaContentProvider.getChildren(javaElement);
+ break;
+ case IJavaElement.IMPORT_CONTAINER:
+ return true;
+ case IJavaElement.PACKAGE_FRAGMENT:
+ children = _javaContentProvider.getChildren(javaElement);
+ break;
+ case IJavaElement.CLASS_FILE:
+ if (Arrays.asList(_suffixs).contains(
+ IFileFolderConstants.EXT_CLASS)) {
+ return true;
+ } else {
+ return false;
+ }
+ case IJavaElement.COMPILATION_UNIT:
+ String ext = javaElement.getPath().getFileExtension();
+ if (ext != null && Arrays.asList(_suffixs).contains(ext)) {
+ return true;
+ } else {
+ return false;
+ }
+ default:
+ return false;
+ }
+
+ for (int i = 0; i < children.length; i++) {
+ if (select(viewer, javaElement, children[i])) {
+ return true;
+ }
+ }
+ // Either the resouce or its children are not for displaying.
+ return false;
+ }
+ }
+
+ /**
+ * Set the suffixs of files need to be selected.
+ *
+ * @param suffixs
+ */
+ public void setSuffixs(String suffixs[]) {
+ _suffixs = suffixs;
+ _filter.setSuffixs(suffixs);
+ }
+
+ /**
+ * @param parentShell
+ * @param project
+ */
+ public ResourceOnClasspathDialog(Shell parentShell, IJavaProject project) {
+ super(parentShell, STATUS_MESSAGE);
+ // set provider and filter
+ StandardJavaElementContentProvider contentProvider = new StandardJavaElementContentProvider();
+ setContentProvider(contentProvider);
+ setLabelProvider(new JavaElementLabelProvider());
+ _filter = new ResourceOnClasspathFilter(contentProvider);
+ setFilter(_filter);
+ // store the project
+ _javaProject = project;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.dialogs.SelectionDialog#getResult()
+ */
+ public Object[] getResult() {
+ Object[] objects = super.getResult();
+ if (objects == null || objects.length == 0) {
+ return null;
+ }
+ IPath path = JavaUtil.getPathOnClasspath(_javaProject, objects[0]);
+ String result = null;
+ if (path.segmentCount() == 0) {
+ return new Object[] { "" };
+ }
+ path = path.removeFileExtension();
+ result = path.toOSString();
+ result = result.replace(File.separatorChar, '.');
+ return new Object[] { result };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#isValidSelection()
+ */
+ protected boolean isValidSelection(Object selection) {
+ String extension = JavaUtil.getPathOnClasspath(_javaProject, selection)
+ .getFileExtension();
+ return (extension != null && Arrays.asList(_suffixs)
+ .contains(extension));
+ }
+
+ protected Object findInputElement() {
+ Object input = ResourcesPlugin.getWorkspace();
+ if (input instanceof IWorkspace) {
+ return JavaCore.create(((IWorkspace) input).getRoot());
+ } else if (input instanceof IContainer) {
+ IJavaElement element = JavaCore.create((IContainer) input);
+ if (element != null && element.exists())
+ return element;
+ return input;
+ }
+ return JavaCore.create(JavaPlugin.getWorkspace().getRoot());
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/TreeViewerSelectionDialog.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/TreeViewerSelectionDialog.java
new file mode 100644
index 000000000..f21b840ee
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/TreeViewerSelectionDialog.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jst.pagedesigner.common.guiutils.SWTUtils;
+import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.part.DrillDownComposite;
+
+/**
+ * This is a base dialog that uses TreeViewer to show selections, subclass needs
+ * to provide IContentProvider, ILabelProvider and ViewerFilter for the
+ * TreeViewer. Subclass needs to implement isValidSelection(), which valids the
+ * selection, and findInputElement() which provides the root element of the
+ * tree. Besides, subclass might need to implement getResult() to return a
+ * customized result.
+ *
+ * @author mengbo
+ */
+public abstract class TreeViewerSelectionDialog extends SelectionDialog {
+ // = "Select a file"
+ private static final String DEFAULT_TITLE = PageDesignerResources
+ .getInstance().getString("TreeViewerSelectionDialog.Title"); //$NON-NLS-1$
+
+ /** Used to tag the image type */
+ public static final int STYLE_NONE = 0;
+
+ public static final int STYLE_INFORMATION = 1;
+
+ public static final int STYLE_ERROR = 2;
+
+ public static final int STYLE_WARNING = 3;
+
+ /** Sizi of the TreeViewer composite */
+ private static final int SIZING_SELECTION_PANE_HEIGHT = 300;
+
+ private static final int SIZING_SELECTION_PANE_WIDTH = 320;
+
+ private String _title = DEFAULT_TITLE;
+
+ // the seleciton on the treeviewer.
+ private static Object _selection;
+
+ // providers
+ private ITreeContentProvider _contentProvider;
+
+ private ILabelProvider _labelProvider;
+
+ private ViewerFilter _filter;
+
+ /** The validation image */
+ private Label _statusImage;
+
+ /** The validation message */
+ private Label _statusLabel;
+
+ private String _statusMessage;
+
+ // private IJavaProject _project;
+ /** The selection tree */
+ private TreeViewer _treeViewer;
+
+ /**
+ * @param parentShell
+ */
+ public TreeViewerSelectionDialog(Shell parentShell, String statusMessage) {
+ super(parentShell);
+ _statusMessage = statusMessage;
+ // ? need SWT.RESIZE
+ setShellStyle(getShellStyle());
+ }
+
+ /**
+ * Returns a new drill down viewer for this dialog.
+ *
+ * @param heightHint -
+ * height hint for the drill down composite
+ */
+ protected void createTreeViewer(Composite parent) {
+ // Create drill down
+ DrillDownComposite drillDown = new DrillDownComposite(parent,
+ SWT.BORDER);
+ GridData spec = new GridData(GridData.VERTICAL_ALIGN_FILL
+ | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
+ | GridData.GRAB_VERTICAL);
+ spec.widthHint = SIZING_SELECTION_PANE_WIDTH;
+ spec.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+ drillDown.setLayoutData(spec);
+ _treeViewer = new TreeViewer(drillDown, SWT.NONE);
+ drillDown.setChildTree(_treeViewer);
+ }
+
+ private void setTreeViewerProviders() {
+ _treeViewer.setContentProvider(_contentProvider);
+ _treeViewer.setLabelProvider(_labelProvider);
+ _treeViewer.setSorter(new ViewerSorter());
+ _treeViewer
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ _selection = getSelectedElement((IStructuredSelection) event
+ .getSelection());
+ updateStatus();
+ };
+ });
+ _treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ ISelection selection = event.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Object item = ((IStructuredSelection) selection)
+ .getFirstElement();
+ if (_treeViewer.getExpandedState(item)) {
+ _treeViewer.collapseToLevel(item, 1);
+ } else {
+ _treeViewer.expandToLevel(item, 1);
+ }
+ }
+ }
+ });
+ _treeViewer.setInput(findInputElement());
+
+ if (_filter != null) {
+ // Assert.isLegal(_contentProvider instanceof
+ // StandardJavaElementContentProvider);
+ _treeViewer.addFilter(_filter);
+ }
+
+ }
+
+ /**
+ * Creates the contents of the composite.
+ */
+ public void createTreeViewerComposite(Composite parent) {
+ Composite treeViewerComposite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ treeViewerComposite.setLayout(layout);
+ GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+ gridData.horizontalSpan = 2;
+ treeViewerComposite.setLayoutData(gridData);
+ Label label = new Label(treeViewerComposite, SWT.WRAP);
+ label.setText(_title);
+ label.setFont(treeViewerComposite.getFont());
+ createTreeViewer(treeViewerComposite);
+ Dialog.applyDialogFont(treeViewerComposite);
+ }
+
+ /**
+ * Sets the selected existing container.
+ *
+ * @param container -
+ * the current selected container.
+ */
+ public void setSelectedElement(Object selection) {
+ // Expand to and select the specified container
+ if (_selection != null) {
+ _treeViewer.expandToLevel(_selection, 1);
+ }
+ List itemsToExpand = new ArrayList();
+ Object parent = _contentProvider.getParent(selection);
+ if (parent == null) {
+ return;
+ }
+ while (parent != null) {
+ itemsToExpand.add(0, parent);
+ parent = _contentProvider.getParent(parent);
+ }
+ _treeViewer.setExpandedElements(itemsToExpand.toArray());
+ _treeViewer.setSelection(new StructuredSelection(selection), true);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite parent) {
+ Composite area = (Composite) super.createDialogArea(parent);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ area.setLayout(gridLayout);
+
+ // Container treeviewer composite
+ createTreeViewerComposite(area);
+
+ _statusImage = SWTUtils.createLabelImage(area,
+ getMessageImage(STYLE_ERROR), 1, null);
+ _statusLabel = SWTUtils.createLabel(area, "", 1);
+ // Link to model
+ setTreeViewerProviders();
+
+ return dialogArea;
+ }
+
+ private Object getSelectedElement(IStructuredSelection selection) {
+ return ((IStructuredSelection) selection).getFirstElement();
+ }
+
+ /**
+ * @param provider
+ * The _contentProvider to set.
+ */
+ public void setContentProvider(ITreeContentProvider provider) {
+ _contentProvider = provider;
+ }
+
+ /**
+ * @param provider
+ * The _labelProvider to set.
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ _labelProvider = provider;
+ }
+
+ /**
+ * @param filter
+ * The _filter to set.
+ */
+ public void setFilter(ViewerFilter filter) {
+ this._filter = filter;
+ }
+
+ public void setStatusMessage(String message) {
+ _statusMessage = message;
+ }
+
+ /**
+ * Update the status message
+ */
+ private void updateStatus() {
+ if (isValidSelection(_selection)) {
+ _statusImage.setImage(getMessageImage(STYLE_NONE));
+ _statusLabel.setText("");
+ getOkButton().setEnabled(true);
+ } else {
+ _statusImage.setImage(getMessageImage(STYLE_ERROR));
+ _statusLabel.setText(_statusMessage);
+ getOkButton().setEnabled(false);
+ }
+ }
+
+ /**
+ * Get the different message according the message type.
+ *
+ * @return Image - the message image
+ */
+ protected Image getMessageImage(int imageType) {
+ switch (imageType) {
+ case STYLE_ERROR:
+ return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR);
+ case STYLE_WARNING:
+ return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING);
+ case STYLE_INFORMATION:
+ return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * The <code>ContainerSelectionDialog</code> implementation of this
+ * <code>Dialog</code> method builds a list of the selected resource
+ * containers for later retrieval by the client and closes this dialog.
+ */
+ protected void okPressed() {
+ List chosenContainerPathList = new ArrayList();
+ if (_selection != null) {
+ chosenContainerPathList.add(_selection);
+ }
+ setResult(chosenContainerPathList);
+ super.okPressed();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createContents(Composite parent) {
+ Control control = super.createContents(parent);
+ if (_selection != null) {
+ this.setSelectedElement(_selection);
+ }
+ return control;
+ }
+
+ protected abstract boolean isValidSelection(Object selection);
+
+ protected abstract Object findInputElement();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/NestedEditorActionBarContributor.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/NestedEditorActionBarContributor.java
new file mode 100644
index 000000000..2e0a2c0e0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/NestedEditorActionBarContributor.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common.sash;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
+
+/**
+ * This contributor should be used when a SashEditor is inside a multipage
+ * editor.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public abstract class NestedEditorActionBarContributor extends
+ MultiPageEditorActionBarContributor {
+ /**
+ * Child class should not override this method.
+ */
+ public final void setActivePage(IEditorPart activeEditor) {
+ if (activeEditor instanceof SashEditorPart) {
+ activeEditor = ((SashEditorPart) activeEditor).getActiveEditor();
+ }
+
+ setInnerActivePage(activeEditor);
+ }
+
+ /**
+ * Child class should override this method
+ *
+ * @param activeEditor
+ */
+ public abstract void setInnerActivePage(IEditorPart activeEditor);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorPart.java
new file mode 100644
index 000000000..1ae97b878
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorPart.java
@@ -0,0 +1,524 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common.sash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.common.guiutils.SWTUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
+import org.eclipse.ui.part.MultiPageEditorPart;
+import org.eclipse.ui.part.MultiPageEditorSite;
+
+/**
+ * This class emulates the MultiPageEditorPart. But instead of using multipage,
+ * it use SashForm to separate the editors.
+ *
+ * @author mengbo
+ */
+public abstract class SashEditorPart extends EditorPart {
+ private int _orientation = SWT.VERTICAL;
+
+ private SashForm _sashForm;
+
+ /**
+ * List of nested editors. Element type: IEditorPart. Need to hang onto them
+ * here, in addition to using get/setData on the items, because dispose()
+ * needs to access them, but widgetry has already been disposed at that
+ * point.
+ */
+ private ArrayList _nestedEditors = new ArrayList(3);
+
+ private Map _editorToComposite = new HashMap();
+
+ private IEditorPart _activeEditor = null;
+
+ /**
+ * Creates and adds a new page containing the given editor to this
+ * multi-page editor. The page is added at the given index. This also hooks
+ * a property change listener on the nested editor.
+ *
+ * @param index
+ * the index at which to add the page (0-based)
+ * @param editor
+ * the nested editor
+ * @param input
+ * the input for the nested editor
+ * @exception PartInitException
+ * if a new page could not be created
+ * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+ * property change events from the nested editor
+ */
+ public void addPage(final IEditorPart editor, IEditorInput input)
+ throws PartInitException {
+ IEditorSite site = createSite(editor);
+ // call init first so that if an exception is thrown, we have created no
+ // new widgets
+ editor.init(site, input);
+ final Composite parent1 = new Composite(getContainer(), SWT.NONE);
+ FillLayout fillLayout = new FillLayout();
+ fillLayout.marginWidth = fillLayout.marginHeight = 1;
+ parent1.setLayout(fillLayout);
+
+ parent1.addListener(SWT.Activate, new Listener() {
+ public void handleEvent(Event event) {
+ if (event.type == SWT.Activate) {
+ activeEditorChanged(editor);
+ parent1.setBackground(ColorConstants.green);
+ }
+ }
+ });
+ parent1.addListener(SWT.Deactivate, new Listener() {
+ public void handleEvent(Event event) {
+ parent1.setBackground(ColorConstants.titleInactiveBackground);
+ }
+ });
+ SWTUtils.workaroundResize(parent1);
+ editor.createPartControl(parent1);
+ editor.addPropertyListener(new IPropertyListener() {
+ public void propertyChanged(Object source, int propertyId) {
+ SashEditorPart.this.handlePropertyChange(propertyId);
+ }
+ });
+
+ _nestedEditors.add(editor);
+ _editorToComposite.put(editor, parent1);
+
+ connectPage(editor);
+ }
+
+ protected void connectPage(IEditorPart editor) {
+ ISelectionProvider editSelectionProvider = editor.getSite()
+ .getSelectionProvider();
+ if (editSelectionProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) editSelectionProvider)
+ .addPostSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ ((SashEditorSelectionProvider) getSite()
+ .getSelectionProvider())
+ .firePostSelectionChanged(event);
+ }
+ });
+ } else {
+ editSelectionProvider
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+
+ public void selectionChanged(SelectionChangedEvent event) {
+ ((SashEditorSelectionProvider) getSite()
+ .getSelectionProvider())
+ .fireSelectionChanged(event);
+ }
+ });
+ }
+ }
+
+ /**
+ * Creates an empty container. Creates a CTabFolder with no style bits set,
+ * and hooks a selection listener which calls <code>pageChange()</code>
+ * whenever the selected tab changes.
+ *
+ * @param parent
+ * The composite in which the container tab folder should be
+ * created; must not be <code>null</code>.
+ * @return a new container
+ */
+ private SashForm createContainer(Composite parent) {
+ // use SWT.FLAT style so that an extra 1 pixel border is not reserved
+ // inside the folder
+ SashForm newContainer = new SashForm(parent, SWT.NONE);
+ SWTUtils.workaroundResize(newContainer);
+ newContainer.setOrientation(_orientation);
+ return newContainer;
+ }
+
+ abstract protected void createPages() throws PartInitException;
+
+ /**
+ * The <code>MultiPageEditor</code> implementation of this
+ * <code>IWorkbenchPart</code> method creates the control for the
+ * multi-page editor by calling <code>createContainer</code>, then
+ * <code>createPages</code>. Subclasses should implement
+ * <code>createPages</code> rather than overriding this method.
+ *
+ * @param parent
+ * The parent in which the editor should be created; must not be
+ * <code>null</code>.
+ */
+ public final void createPartControl(Composite parent) {
+ this._sashForm = createContainer(parent);
+
+ try {
+ createPages();
+ } catch (PartInitException ex) {
+ ex.printStackTrace();
+ }
+ // set the active page (page 0 by default), unless it has already been
+ // done
+ if (getActiveEditor() == null) {
+ if (!_nestedEditors.isEmpty()) {
+ setActiveEditor((IEditorPart) _nestedEditors.get(0));
+ }
+ }
+ }
+
+ /**
+ * Creates the site for the given nested editor. The
+ * <code>MultiPageEditorPart</code> implementation of this method creates
+ * an instance of <code>MultiPageEditorSite</code>. Subclasses may
+ * reimplement to create more specialized sites.
+ *
+ * @param editor
+ * the nested editor
+ * @return the editor site
+ */
+ protected IEditorSite createSite(IEditorPart editor) {
+ return new SashEditorSite(this, editor);
+ }
+
+ /**
+ * The <code>MultiPageEditorPart</code> implementation of this
+ * <code>IWorkbenchPart</code> method disposes all nested editors.
+ * Subclasses may extend.
+ */
+ public void dispose() {
+ _activeEditor = null;
+ for (int i = 0; i < _nestedEditors.size(); ++i) {
+ IEditorPart editor = (IEditorPart) _nestedEditors.get(i);
+ disposePart(editor);
+ }
+ _nestedEditors.clear();
+ _editorToComposite.clear();
+ }
+
+ /**
+ * Returns the active nested editor if there is one.
+ * <p>
+ * Subclasses should not override this method
+ * </p>
+ *
+ * @return the active nested editor, or <code>null</code> if none
+ */
+ public IEditorPart getActiveEditor() {
+ return _activeEditor;
+ }
+
+ /**
+ * Returns the composite control containing this multi-page editor's pages.
+ * This should be used as the parent when creating controls for the
+ * individual pages. That is, when calling <code>addPage(Control)</code>,
+ * the passed control should be a child of this container.
+ * <p>
+ * Warning: Clients should not assume that the container is any particular
+ * subclass of Composite. The actual class used may change in order to
+ * improve the look and feel of multi-page editors. Any code making
+ * assumptions on the particular subclass would thus be broken.
+ * </p>
+ * <p>
+ * Subclasses should not override this method
+ * </p>
+ *
+ * @return the composite, or <code>null</code> if
+ * <code>createPartControl</code> has not been called yet
+ */
+ protected Composite getContainer() {
+ return _sashForm;
+ }
+
+ /**
+ * Returns the editor for the given page index. The page index must be
+ * valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the editor for the specified page, or <code>null</code> if the
+ * specified page was not created with
+ * <code>addPage(IEditorPart,IEditorInput)</code>
+ */
+ protected IEditorPart getEditor(int pageIndex) {
+ return (IEditorPart) _nestedEditors.get(pageIndex);
+ }
+
+ /**
+ * Handles a property change notification from a nested editor. The default
+ * implementation simply forwards the change to listeners on this multi-page
+ * editor by calling <code>firePropertyChange</code> with the same
+ * property id. For example, if the dirty state of a nested editor changes
+ * (property id <code>IEditorPart.PROP_DIRTY</code>), this method handles
+ * it by firing a property change event for
+ * <code>IEditorPart.PROP_DIRTY</code> to property listeners on this
+ * multi-page editor.
+ * <p>
+ * Subclasses may extend or reimplement this method.
+ * </p>
+ *
+ * @param propertyId
+ * the id of the property that changed
+ */
+ protected void handlePropertyChange(int propertyId) {
+ firePropertyChange(propertyId);
+ }
+
+ /**
+ * The <code>MultiPageEditorPart</code> implementation of this
+ * <code>IEditorPart</code> method sets its site to the given site, its
+ * input to the given input, and the site's selection provider to a
+ * <code>MultiPageSelectionProvider</code>. Subclasses may extend this
+ * method.
+ *
+ * @param site
+ * The site for which this part is being created; must not be
+ * <code>null</code>.
+ * @param input
+ * The input on which this editor should be created; must not be
+ * <code>null</code>.
+ * @throws PartInitException
+ * If the initialization of the part fails -- currently never.
+ */
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ setSite(site);
+ setInput(input);
+ site.setSelectionProvider(new SashEditorSelectionProvider(this));
+ }
+
+ /**
+ * The <code>MultiPageEditorPart</code> implementation of this
+ * <code>IEditorPart</code> method returns whether the contents of any of
+ * this multi-page editor's nested editors have changed since the last save.
+ * Pages created with <code>addPage(Control)</code> are ignored.
+ * <p>
+ * Subclasses may extend or reimplement this method.
+ * </p>
+ *
+ * @return <code>true</code> if any of the nested editors are dirty;
+ * <code>false</code> otherwise.
+ */
+ public boolean isDirty() {
+ // use nestedEditors to avoid SWT requests; see bug 12996
+ for (Iterator i = _nestedEditors.iterator(); i.hasNext();) {
+ IEditorPart editor = (IEditorPart) i.next();
+ if (editor.isDirty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Notifies this multi-page editor that the page with the given id has been
+ * activated. This method is called when the user selects a different tab.
+ * <p>
+ * The <code>MultiPageEditorPart</code> implementation of this method sets
+ * focus to the new page, and notifies the action bar contributor (if there
+ * is one). This checks whether the action bar contributor is an instance of
+ * <code>MultiPageEditorActionBarContributor</code>, and, if so, calls
+ * <code>setActivePage</code> with the active nested editor. This also
+ * fires a selection change event if required.
+ * </p>
+ * <p>
+ * Subclasses may extend this method.
+ * </p>
+ *
+ * @param newPageIndex
+ * the index of the activated page
+ */
+ protected void activeEditorChanged(IEditorPart activeEditor) {
+ setActiveEditor(activeEditor);
+ setFocus();
+
+ IEditorSite site = getEditorSite();
+ while (site != null) {
+ IEditorActionBarContributor contributor = site
+ .getActionBarContributor();
+ if (contributor != null
+ && contributor instanceof MultiPageEditorActionBarContributor) {
+ ((MultiPageEditorActionBarContributor) contributor)
+ .setActivePage(activeEditor);
+ }
+ if (site instanceof MultiPageEditorSite) {
+ site = (IEditorSite) ((MultiPageEditorSite) site)
+ .getMultiPageEditor().getSite();
+ } else if (site instanceof SashEditorSite) {
+ site = (IEditorSite) ((SashEditorSite) site).getSashEditor()
+ .getSite();
+ } else {
+ site = null;
+ }
+ }
+
+ if (activeEditor != null) {
+ // Workaround for 1GAUS7C: ITPUI:ALL - Editor not activated when
+ // restored from previous session
+ // do not need second if once fixed
+ ISelectionProvider selectionProvider = activeEditor.getSite()
+ .getSelectionProvider();
+ if (selectionProvider != null) {
+ SelectionChangedEvent event = new SelectionChangedEvent(
+ selectionProvider, selectionProvider.getSelection());
+ ((SashEditorSelectionProvider) getSite().getSelectionProvider())
+ .fireSelectionChanged(event);
+ }
+ }
+ }
+
+ /**
+ * Disposes the given part and its site.
+ *
+ * @param part
+ * The part to dispose; must not be <code>null</code>.
+ */
+ private void disposePart(final IWorkbenchPart part) {
+ Platform.run(new SafeRunnable() {
+ public void run() {
+ if (part.getSite() instanceof SashEditorSite) {
+ SashEditorSite partSite = (SashEditorSite) part.getSite();
+ partSite.dispose();
+ }
+ part.dispose();
+ }
+
+ public void handleException(Throwable e) {
+ // Exception has already being logged by Core. Do nothing.
+ }
+ });
+ }
+
+ /**
+ * Sets the currently active page.
+ *
+ * @param pageIndex
+ * the index of the page to be activated; the index must be valid
+ */
+ protected void setActiveEditor(IEditorPart part) {
+ _activeEditor = part;
+ }
+
+ /**
+ * The <code>MultiPageEditor</code> implementation of this
+ * <code>IWorkbenchPart</code> method sets focus on the active nested
+ * editor, if there is one.
+ * <p>
+ * Subclasses may extend or reimplement.
+ * </p>
+ */
+ public void setFocus() {
+ setFocus(getActiveEditor());
+ }
+
+ /**
+ * Sets focus to the control for the given page. If the page has an editor,
+ * this calls its <code>setFocus()</code> method. Otherwise, this calls
+ * <code>setFocus</code> on the control for the page.
+ *
+ * @param pageIndex
+ * the index of the page
+ */
+ private void setFocus(IEditorPart editor) {
+ final IKeyBindingService service = getSite().getKeyBindingService();
+
+ if (editor == null) {
+ // There is no selected page, so deactivate the active service.
+ if (service instanceof INestableKeyBindingService) {
+ final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+ nestableService.activateKeyBindingService(null);
+ } else {
+ WorkbenchPlugin
+ .log("MultiPageEditorPart.setFocus() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return;
+ } else {
+ editor.setFocus();
+ // There is no selected page, so deactivate the active service.
+ if (service instanceof INestableKeyBindingService) {
+ final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+ if (editor != null) {
+ nestableService.activateKeyBindingService(editor
+ .getEditorSite());
+ } else {
+ nestableService.activateKeyBindingService(null);
+ }
+ } else {
+ WorkbenchPlugin
+ .log("MultiPageEditorPart.setFocus() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+
+ public void doSave(IProgressMonitor monitor) {
+ if (_activeEditor != null) {
+ _activeEditor.doSave(monitor);
+ }
+ }
+
+ public void doSaveAs() {
+ if (_activeEditor != null) {
+ _activeEditor.doSaveAs();
+ }
+
+ }
+
+ public boolean isSaveAsAllowed() {
+ if (_activeEditor != null)
+ return _activeEditor.isSaveAsAllowed();
+ else
+ return false;
+ }
+
+ public void setOrientation(int orientation) {
+ this._orientation = orientation;
+ if (_sashForm != null && !_sashForm.isDisposed()) {
+ _sashForm.setMaximizedControl(null);
+ _sashForm.setOrientation(_orientation);
+ }
+ }
+
+ public void setMaximizedEditor(IEditorPart part) {
+ if (part != null) {
+ Composite c = (Composite) _editorToComposite.get(part);
+ if (c != null && _sashForm != null && !_sashForm.isDisposed()) {
+ _sashForm.setMaximizedControl(c);
+ part.setFocus();
+ }
+ } else {
+ if (_sashForm != null && !_sashForm.isDisposed()) {
+ _sashForm.setMaximizedControl(null);
+ }
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSelectionProvider.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSelectionProvider.java
new file mode 100644
index 000000000..4a8cd363c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSelectionProvider.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common.sash;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * @author mengbo
+ */
+public class SashEditorSelectionProvider implements IPostSelectionProvider {
+
+ /**
+ * Registered selection changed listeners (element type:
+ * <code>ISelectionChangedListener</code>).
+ */
+ private ListenerList _listeners = new ListenerList();
+
+ private ListenerList _postSelectionChangedListeners = new ListenerList(1);
+
+ /**
+ * The multi-page editor.
+ */
+ private SashEditorPart _sashEditor;
+
+ /**
+ * Creates a selection provider for the given multi-page editor.
+ *
+ * @param sashEditor
+ * the multi-page editor
+ */
+ public SashEditorSelectionProvider(SashEditorPart sashEditor) {
+ Assert.isNotNull(sashEditor);
+ this._sashEditor = sashEditor;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on <code>ISelectionProvider</code>.
+ */
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ _listeners.add(listener);
+ }
+
+ /**
+ * Notifies all registered selection changed listeners that the editor's
+ * selection has changed. Only listeners registered at the time this method
+ * is called are notified.
+ *
+ * @param event
+ * the selection changed event
+ */
+ public void fireSelectionChanged(final SelectionChangedEvent event) {
+ Object[] listeners = this._listeners.getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
+ Platform.run(new SafeRunnable() {
+ public void run() {
+ l.selectionChanged(event);
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns the sash editor.
+ */
+ public SashEditorPart getSashEditor() {
+ return _sashEditor;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on <code>ISelectionProvider</code>.
+ */
+ public ISelection getSelection() {
+ IEditorPart activeEditor = _sashEditor.getActiveEditor();
+ if (activeEditor != null) {
+ ISelectionProvider selectionProvider = activeEditor.getSite()
+ .getSelectionProvider();
+ if (selectionProvider != null)
+ return selectionProvider.getSelection();
+ }
+ return null;
+ }
+
+ /*
+ * (non-JavaDoc) Method declaed on <code>ISelectionProvider</code>.
+ */
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ _listeners.remove(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on <code>ISelectionProvider</code>.
+ */
+ public void setSelection(ISelection selection) {
+ IEditorPart activeEditor = _sashEditor.getActiveEditor();
+ if (activeEditor != null) {
+ ISelectionProvider selectionProvider = activeEditor.getSite()
+ .getSelectionProvider();
+ if (selectionProvider != null)
+ selectionProvider.setSelection(selection);
+ }
+ }
+
+ public void addPostSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ _postSelectionChangedListeners.add(listener);
+ }
+
+ public void removePostSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ _postSelectionChangedListeners.remove(listener);
+ }
+
+ /**
+ * Notifies any post selection listeners that a post selection event has
+ * been received. Only listeners registered at the time this method is
+ * called are notified.
+ *
+ * @param event
+ * a selection changed event
+ *
+ * @see #addPostSelectionChangedListener(ISelectionChangedListener)
+ */
+ public void firePostSelectionChanged(final SelectionChangedEvent event) {
+ Object[] listeners = _postSelectionChangedListeners.getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
+ SafeRunnable.run(new SafeRunnable() {
+ public void run() {
+ l.selectionChanged(event);
+ }
+ });
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSite.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSite.java
new file mode 100644
index 000000000..cb9ebc8b4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/common/sash/SashEditorSite.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.common.sash;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.internal.PopupMenuExtender;
+
+/**
+ * @author mengbo
+ */
+public class SashEditorSite implements IEditorSite {
+
+ /**
+ * The nested editor.
+ */
+ private IEditorPart _editor;
+
+ /**
+ * The multi-page editor.
+ */
+ private SashEditorPart _sashEditor;
+
+ /**
+ * The selection provider; <code>null</code> if none.
+ *
+ * @see SashEditorSite#setSelectionProvider(ISelectionProvider)
+ */
+ private ISelectionProvider _selectionProvider = null;
+
+ /**
+ * The selection change listener, initialized lazily; <code>null</code> if
+ * not yet created.
+ */
+ private ISelectionChangedListener _selectionChangedListener = null;
+
+ /**
+ * The cached copy of the key binding service specific to this sash editor
+ * site. This value is <code>null</code> if it is not yet initialized.
+ */
+ private IKeyBindingService _service = null;
+
+ /**
+ * The list of popup menu extenders; <code>null</code> if none registered.
+ */
+ private ArrayList _menuExtenders;
+
+ /**
+ * Creates a site for the given editor nested within the given multi-page
+ * editor.
+ *
+ * @param _sashEditor
+ * the multi-page editor
+ * @param _editor
+ * the nested editor
+ */
+ public SashEditorSite(SashEditorPart sashEditor, IEditorPart editor) {
+ Assert.isNotNull(sashEditor);
+ Assert.isNotNull(editor);
+ this._sashEditor = sashEditor;
+ this._editor = editor;
+ }
+
+ /**
+ * Dispose the contributions.
+ */
+ public void dispose() {
+ if (_menuExtenders != null) {
+ for (int i = 0, size = _menuExtenders.size(); i < size; i++) {
+ ((PopupMenuExtender) _menuExtenders.get(i)).dispose();
+ }
+ _menuExtenders = null;
+ }
+
+ // Remove myself from the list of nested key binding services.
+ if (_service != null) {
+ IKeyBindingService parentService = getEditor().getSite()
+ .getKeyBindingService();
+ if (parentService instanceof INestableKeyBindingService) {
+ INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
+ nestableParent.removeKeyBindingService(this);
+ }
+ _service = null;
+ }
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IEditorSite</code> method returns <code>null</code>, since
+ * nested editors do not have their own action bar contributor.
+ *
+ * @return <code>null</code>
+ */
+ public IEditorActionBarContributor getActionBarContributor() {
+ return null;
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IEditorSite</code> method forwards to the multi-page editor to
+ * return the action bars.
+ *
+ * @return The action bars from the parent multi-page editor.
+ */
+ public IActionBars getActionBars() {
+ return _sashEditor.getEditorSite().getActionBars();
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page
+ * editor to return the decorator manager.
+ *
+ * @return The decorator from the workbench window.
+ * @deprecated use IWorkbench.getDecoratorManager()
+ */
+ public ILabelDecorator getDecoratorManager() {
+ return getWorkbenchWindow().getWorkbench().getDecoratorManager()
+ .getLabelDecorator();
+ }
+
+ /**
+ * Returns the nested editor.
+ *
+ * @return the nested editor
+ */
+ public IEditorPart getEditor() {
+ return _editor;
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns an empty string since
+ * the nested editor is not created from the registry.
+ *
+ * @return An empty string.
+ */
+ public String getId() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IEditorSite.
+ */
+ public IKeyBindingService getKeyBindingService() {
+ if (_service == null) {
+ _service = getSashEditor().getEditorSite().getKeyBindingService();
+ if (_service instanceof INestableKeyBindingService) {
+ INestableKeyBindingService nestableService = (INestableKeyBindingService) _service;
+ _service = nestableService.getKeyBindingService(this);
+
+ } else {
+ /*
+ * This is an internal reference, and should not be copied by
+ * client code. If you are thinking of copying this, DON'T DO
+ * IT.
+ */
+ PDPlugin
+ .getLogger(SashEditorSite.class)
+ .info(
+ "MultiPageEditorSite.getKeyBindingService() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + _service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ return _service;
+ }
+
+ /**
+ * Returns the sash editor.
+ *
+ * @return the sash editor
+ */
+ public SashEditorPart getSashEditor() {
+ return _sashEditor;
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page
+ * editor to return the workbench page.
+ *
+ * @return The workbench page in which this editor site resides.
+ */
+ public IWorkbenchPage getPage() {
+ return getSashEditor().getSite().getPage();
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns an empty string since
+ * the nested editor is not created from the registry.
+ *
+ * @return An empty string.
+ */
+ public String getPluginId() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns an empty string since
+ * the nested editor is not created from the registry.
+ *
+ * @return An empty string.
+ */
+ public String getRegisteredName() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the selection changed listener which listens to the nested
+ * editor's selection changes, and calls <code>handleSelectionChanged</code>.
+ *
+ * @return the selection changed listener
+ */
+ private ISelectionChangedListener getSelectionChangedListener() {
+ if (_selectionChangedListener == null) {
+ _selectionChangedListener = new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ SashEditorSite.this.handleSelectionChanged(event);
+ }
+ };
+ }
+ return _selectionChangedListener;
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns the selection provider
+ * set by <code>setSelectionProvider</code>.
+ *
+ * @return The current selection provider.
+ */
+ public ISelectionProvider getSelectionProvider() {
+ return _selectionProvider;
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page
+ * editor to return the shell.
+ *
+ * @return The shell in which this editor site resides.
+ */
+ public Shell getShell() {
+ return getSashEditor().getSite().getShell();
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page
+ * editor to return the workbench window.
+ *
+ * @return The workbench window in which this editor site resides.
+ */
+ public IWorkbenchWindow getWorkbenchWindow() {
+ return getSashEditor().getSite().getWorkbenchWindow();
+ }
+
+ /**
+ * Handles a selection changed event from the nested editor. The default
+ * implementation gets the selection provider from the multi-page editor's
+ * site, and calls <code>fireSelectionChanged</code> on it (only if it is
+ * an instance of <code>SashSelectionProvider</code>), passing a new
+ * event object.
+ * <p>
+ * Subclasses may extend or reimplement this method.
+ * </p>
+ *
+ * @param event
+ * the event
+ */
+ public void handleSelectionChanged(SelectionChangedEvent event) {
+ // we'll only make the parent editor site fire the selection change
+ // event
+ // when we (the sasheditorsite) is the active editor in the parent site.
+ if (getSashEditor().getActiveEditor() == this.getPart()) {
+ ISelectionProvider parentProvider = getSashEditor().getSite()
+ .getSelectionProvider();
+ if (parentProvider instanceof SashEditorSelectionProvider) {
+ SelectionChangedEvent newEvent = new SelectionChangedEvent(
+ parentProvider, event.getSelection());
+ ((SashEditorSelectionProvider) parentProvider)
+ .fireSelectionChanged(newEvent);
+ }
+ }
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page
+ * editor for registration.
+ *
+ * @param menuID
+ * The identifier for the menu.
+ * @param menuMgr
+ * The menu manager
+ * @param selProvider
+ * The selection provider.
+ */
+ public void registerContextMenu(String menuID, MenuManager menuMgr,
+ ISelectionProvider selProvider) {
+ if (_menuExtenders == null) {
+ _menuExtenders = new ArrayList(1);
+ }
+ // cancel the registration of PopupMenuExtender since the
+ // PopupMenuExtender's behavior
+ // is different between eclipse 3.0 and eclipse 3.1,and we always have
+ // one context
+ // menu listener,no need add PopupMenuExtender as the second
+ // listener(workaroud for bug 408295-1)
+ // _menuExtenders.add(new PopupMenuExtender(menuID, menuMgr,
+ // selProvider,
+ // _editor));
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page
+ * editor for registration.
+ *
+ * @param menuManager
+ * The menu manager
+ * @param selProvider
+ * The selection provider.
+ */
+ public void registerContextMenu(MenuManager menuManager,
+ ISelectionProvider selProvider) {
+ getSashEditor().getSite().registerContextMenu(menuManager, selProvider);
+ }
+
+ /**
+ * The <code>SashEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method remembers the selection
+ * provider, and also hooks a listener on it, which calls
+ * <code>handleSelectionChanged</code> when a selection changed event
+ * occurs.
+ *
+ * @param provider
+ * The selection provider.
+ * @see SashEditorSite#handleSelectionChanged(SelectionChangedEvent)
+ */
+ public void setSelectionProvider(ISelectionProvider provider) {
+ ISelectionProvider oldSelectionProvider = _selectionProvider;
+ _selectionProvider = provider;
+ if (oldSelectionProvider != null) {
+ oldSelectionProvider
+ .removeSelectionChangedListener(getSelectionChangedListener());
+ }
+ if (_selectionProvider != null) {
+ _selectionProvider
+ .addSelectionChangedListener(getSelectionChangedListener());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartSite#progressEnd()
+ */
+ public void progressEnd(Job job) {
+ // Do nothing
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartSite#progressStart()
+ */
+ public void progressStart(Job job) {
+ // Do nothing
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
+ */
+ public IWorkbenchPart getPart() {
+ return _editor;
+ }
+
+ public void registerContextMenu(MenuManager menuManager,
+ ISelectionProvider selectionProvider, boolean includeEditorInput) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void registerContextMenu(String menuId, MenuManager menuManager,
+ ISelectionProvider selectionProvider, boolean includeEditorInput) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Object getService(Class api) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean hasService(Class api) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableClasspathResourceButtonDialogField.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableClasspathResourceButtonDialogField.java
new file mode 100644
index 000000000..b1ff6d2ac
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableClasspathResourceButtonDialogField.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogfields;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ClasspathResourceButtonDialogField;
+import org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ContextableClasspathResourceButtonDialogField extends
+ ClasspathResourceButtonDialogField implements IElementContextable {
+ /**
+ * @param project
+ */
+ public ContextableClasspathResourceButtonDialogField() {
+ super(null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.attributegroup.IElementContextable#setElementContext(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)
+ */
+ public void setElementContext(IDOMNode ancester, IDOMElement element) {
+ IProject prj = StructuredModelUtil.getProjectFor(ancester.getModel());
+ this.setProject(prj);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableResourceButtonDialogField.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableResourceButtonDialogField.java
new file mode 100644
index 000000000..8718c5b62
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ContextableResourceButtonDialogField.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogfields;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ResourceButtonDialogField;
+import org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable;
+import org.eclipse.jst.pagedesigner.utils.StructuredModelUtil;
+import org.eclipse.jst.pagedesigner.utils.WebAppUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ContextableResourceButtonDialogField extends
+ ResourceButtonDialogField implements IElementContextable {
+
+ /**
+ * @param project
+ */
+ public ContextableResourceButtonDialogField() {
+ super(null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable#setElementContext(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)
+ */
+ public void setElementContext(IDOMNode ancester, IDOMElement element) {
+ if (ancester == null) {
+ setProject(null);
+ setReferredFile(null);
+ } else {
+ IDOMModel model = ancester.getModel();
+ IFile file = StructuredModelUtil.getFileFor(model);
+ IProject prj = (file == null ? null : file.getProject());
+ setProject(prj);
+ setReferredFile(file);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.ResourceButtonDialogField#browseButtonPressed()
+ */
+ protected String browseButtonPressed() {
+ String url = super.browseButtonPressed();
+ url = WebAppUtil.transformJSPURL(url, this.getReferredFile());
+ return url;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/DialogFieldWrapper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/DialogFieldWrapper.java
new file mode 100644
index 000000000..ce1d961a2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/DialogFieldWrapper.java
@@ -0,0 +1,411 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogfields;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldChangeListener;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IStringButtonAdapter;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue;
+import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
+import org.eclipse.jst.pagedesigner.meta.IBindingHandler;
+import org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.events.IHyperlinkListener;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * This is a wrapper to a dialog field, by adding a small image button at the
+ * end. The caller is responsible to provide the image and the button click
+ * handler.
+ *
+ * @author mengbo
+ * @version 1.5
+ * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper
+ */
+// NOTE: currently this class is dedicated to page designer by using the
+// IElementContextable interface.
+// It should be very easy to make it standard alone and reused in other places.
+public class DialogFieldWrapper implements DialogField, ISupportTextValue,
+ IElementContextable {
+ private DialogField _wrapped;
+
+ private IDOMNode _ancester;
+
+ private IDOMElement _element;
+
+ private Button _databindingButton;
+
+ private boolean _databindingEnabled;
+
+ private Image _image;
+
+ private Image _disabledImage;
+
+ private IStringButtonAdapter _adapter;
+
+ private String _uri;
+
+ private String _tagName;
+
+ private IAttributeDescriptor _attr;
+
+ private IBindingHandler _handler;
+
+ /**
+ *
+ */
+ public DialogFieldWrapper(DialogField field, Image image,
+ Image disabledImage, String uri, String tagName,
+ IAttributeDescriptor attr, IBindingHandler handler) {
+ super();
+ if (!(field instanceof ISupportTextValue)) {
+ throw new IllegalArgumentException(
+ "Field must be ISupportTextValue");
+ }
+ _wrapped = field;
+ this._image = image;
+ this._disabledImage = disabledImage;
+ this._uri = uri;
+ this._tagName = tagName;
+ this._attr = attr;
+ this._handler = handler;
+
+ setDatabindingPressedHandler(new IStringButtonAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IStringButtonAdapter#changeControlPressed(org.eclipse.jst.pagedesigner.common.dialogfield.DialogField)
+ */
+ public void changeControlPressed(DialogField field) {
+ Shell shell = field.getLabelControl(null, null).getShell();
+ DialogFieldWrapper wrapper = (DialogFieldWrapper) field;
+ String result = _handler
+ .handleBinding(shell, wrapper.getAncester(), wrapper
+ .getElement(), wrapper.getText());
+ if (result != null) {
+ wrapper.setText(result);
+ }
+ }
+ });
+ }
+
+ public void setDatabindingPressedHandler(IStringButtonAdapter adapter) {
+ this._adapter = adapter;
+ this.updateDatabindingControl();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue#setTextWithoutUpdate(java.lang.String)
+ */
+ public void setTextWithoutUpdate(String value) {
+ ((ISupportTextValue) _wrapped).setTextWithoutUpdate(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue#getText()
+ */
+ public String getText() {
+ return ((ISupportTextValue) _wrapped).getText();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.ISupportTextValue#setText(java.lang.String)
+ */
+ public void setText(String value) {
+ ((ISupportTextValue) _wrapped).setText(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable#setElementContext(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)
+ */
+ public void setElementContext(IDOMNode ancester, IDOMElement element) {
+ if (_wrapped instanceof IElementContextable) {
+ ((IElementContextable) _wrapped).setElementContext(ancester,
+ element);
+ }
+ this._ancester = ancester;
+ this._element = element;
+
+ boolean bindingEnabled = _handler.isEnabled(_ancester, _element, _uri,
+ _tagName, _attr);
+ this.setDatabindingEnabled(bindingEnabled);
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // wrapped method to add the data binding browse button
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogField#doFillIntoGrid(org.eclipse.ui.forms.widgets.FormToolkit,
+ * org.eclipse.swt.widgets.Composite, int)
+ */
+ public Control[] doFillIntoGrid(FormToolkit toolkit, Composite parent,
+ int nColumns) {
+ Control[] wrappedControls = _wrapped.doFillIntoGrid(toolkit, parent,
+ nColumns - 1);
+ Control[] result = new Control[wrappedControls.length];
+
+ Control button = getDatabingingButton(toolkit, parent);
+ button.setLayoutData(gridDataForDatabindingButton(1));
+ button.setVisible(false);
+
+ System.arraycopy(wrappedControls, 0, result, 0, wrappedControls.length);
+ result[result.length - 1] = _databindingButton;
+ return result;
+ }
+
+ /**
+ * @param span
+ * @return
+ */
+ private GridData gridDataForDatabindingButton(int span) {
+ GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ gd.horizontalSpan = span;
+ gd.widthHint = gd.heightHint = 18;
+ return gd;
+ }
+
+ /**
+ * @param toolkit
+ * @param parent
+ * @return
+ */
+ private Control getDatabingingButton(FormToolkit toolkit, Composite parent) {
+ if (_databindingButton == null) {
+ Assert.isNotNull(parent,
+ "uncreated control requested with composite null"); //$NON-NLS-1$
+ if (toolkit != null) {
+ _databindingButton = toolkit.createButton(parent, "", SWT.PUSH);
+ _databindingButton.setImage(getImage());
+ } else {
+ _databindingButton = new Button(parent, SWT.PUSH);
+ _databindingButton.setImage(getImage());
+ }
+ _databindingButton.addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ if (!_databindingButton.isEnabled()
+ && getDisabledImage() != null) {
+ Rectangle buttonBounds = _databindingButton.getBounds();
+ Rectangle imageBounds = getDisabledImage().getBounds();
+ e.gc.drawImage(getDisabledImage(),
+ (buttonBounds.width - imageBounds.width) / 2,
+ (buttonBounds.height - imageBounds.height) / 2);
+ }
+ }
+ });
+ _databindingButton.setEnabled(isEnabled() && _databindingEnabled);
+ _databindingButton.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ databindingControlPressed();
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ databindingControlPressed();
+ }
+ });
+
+ }
+ return _databindingButton;
+ }
+
+ /**
+ * @return
+ */
+ private Image getImage() {
+ return _image;
+ }
+
+ private Image getDisabledImage() {
+ return _disabledImage;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogField#getLabelControl(org.eclipse.ui.forms.widgets.FormToolkit,
+ * org.eclipse.swt.widgets.Composite)
+ */
+ public Control getLabelControl(FormToolkit _formToolkit, Composite parent) {
+ return _wrapped.getLabelControl(_formToolkit, parent);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#setHyperLink(org.eclipse.ui.forms.events.IHyperlinkListener)
+ */
+ public void setHyperLink(IHyperlinkListener listener) {
+ _wrapped.setHyperLink(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#setLabelText(java.lang.String)
+ */
+ public void setLabelText(String labeltext) {
+ _wrapped.setLabelText(labeltext);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#setDialogFieldChangeListener(org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldChangeListener)
+ */
+ public void setDialogFieldChangeListener(IDialogFieldChangeListener listener) {
+ _wrapped.setDialogFieldChangeListener(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#setDialogFieldApplyListener(org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener)
+ */
+ public void setDialogFieldApplyListener(IDialogFieldApplyListener listener) {
+ _wrapped.setDialogFieldApplyListener(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#setFocus()
+ */
+ public boolean setFocus() {
+ return _wrapped.setFocus();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#getNumberOfControls()
+ */
+ public int getNumberOfControls() {
+ return _wrapped.getNumberOfControls() + 1;
+ }
+
+ public void setDatabindingEnabled(boolean enabled) {
+ this._databindingEnabled = enabled;
+ updateDatabindingControl();
+ }
+
+ public boolean isDatabindingEnabled() {
+ return _databindingEnabled;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#setEnabled(boolean)
+ */
+ public void setEnabled(boolean enabled) {
+ _wrapped.setEnabled(enabled);
+ updateDatabindingControl();
+ }
+
+ /**
+ *
+ */
+ private void updateDatabindingControl() {
+ if (this._databindingButton != null && !_databindingButton.isDisposed()) {
+ this._databindingButton.setEnabled(this.isEnabled()
+ && _databindingEnabled && _adapter != null);
+ _databindingButton.redraw();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#isEnabled()
+ */
+ public boolean isEnabled() {
+ return _wrapped.isEnabled();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#getAttachedData(java.lang.Object)
+ */
+ public Object getAttachedData(Object key) {
+ return _wrapped.getAttachedData(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.IDialogField#putAttachedData(java.lang.Object,
+ * java.lang.Object)
+ */
+ public void putAttachedData(Object key, Object value) {
+ _wrapped.putAttachedData(key, value);
+ }
+
+ protected void databindingControlPressed() {
+ if (_adapter != null) {
+ _adapter.changeControlPressed(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.DialogField#handleGrabHorizontal()
+ */
+ public void handleGrabHorizontal() {
+ _wrapped.handleGrabHorizontal();
+ }
+
+ public IDOMNode getAncester() {
+ return _ancester;
+ }
+
+ public IDOMElement getElement() {
+ return _element;
+ }
+
+ public DialogField getWrappedDialogField() {
+ return _wrapped;
+ }
+
+ public boolean isRequired() {
+ return _wrapped.isRequired();
+ }
+
+ public void setToolTip(String toolTip) {
+ _wrapped.setToolTip(toolTip);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ExtendedResourceButtonDialogField.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ExtendedResourceButtonDialogField.java
new file mode 100644
index 000000000..f87f39750
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/ExtendedResourceButtonDialogField.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogfields;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ResourceButtonDialogField;
+import org.eclipse.jst.pagedesigner.utils.WebAppUtil;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ExtendedResourceButtonDialogField extends
+ ResourceButtonDialogField {
+ public ExtendedResourceButtonDialogField(IProject project) {
+ super(project);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.common.dialogfield.ResourceButtonDialogField#browseButtonPressed()
+ */
+ protected String browseButtonPressed() {
+ String url = super.browseButtonPressed();
+ url = WebAppUtil.transformJSPURL(url, this.getReferredFile());
+ return url;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/StyleButtonDialogField.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/StyleButtonDialogField.java
new file mode 100644
index 000000000..2bbfeb701
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogfields/StyleButtonDialogField.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogfields;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.commands.single.ChangeStyleCommand;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IStringButtonAdapter;
+import org.eclipse.jst.pagedesigner.common.dialogfield.StringButtonDialogField;
+import org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable;
+import org.eclipse.jst.pagedesigner.ui.dialogs.DialogsMessages;
+import org.eclipse.jst.pagedesigner.ui.dialogs.StyleDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclaration;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.css.ElementCSSInlineStyle;
+
+/**
+ * @author mengbo
+ */
+public class StyleButtonDialogField extends StringButtonDialogField implements
+ IElementContextable {
+ private IDOMElement _element;
+
+ public StyleButtonDialogField() {
+ this(null);
+ }
+
+ public StyleButtonDialogField(IDOMElement element) {
+ this(null, element);
+ setStringButtonAdapter(new IStringButtonAdapter() {
+ public void changeControlPressed(DialogField field) {
+ browseButtonPressed();
+ }
+ });
+ setButtonLabel(DialogsMessages.getString("StyleButtonDialogField.Edit"));//$NON-NLS-1$
+ }
+
+ public StyleButtonDialogField(IStringButtonAdapter adapter,
+ IDOMElement element) {
+ super(adapter);
+ _element = element;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable#setElementContext(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
+ * org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)
+ */
+ public void setElementContext(IDOMNode ancester, IDOMElement element) {
+ this._element = element;
+ }
+
+ private void browseButtonPressed() {
+ if (_element instanceof ElementCSSInlineStyle) {
+ ICSSStyleDeclaration styleDeclaration = (ICSSStyleDeclaration) ((ElementCSSInlineStyle) _element)
+ .getStyle();
+
+ PreferenceManager manager = new PreferenceManager();
+ Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+ .getShell();
+
+ CSSPropertyContext context = new CSSPropertyContext(
+ styleDeclaration);
+ StyleDialog dialog = new StyleDialog(shell, manager, _element,
+ context);
+ if (dialog.open() == Dialog.OK) {
+ if (!context.isModified()) {
+ return;
+ }
+ ChangeStyleCommand c = new ChangeStyleCommand(_element, context);
+ c.execute();
+
+ String style = (_element == null ? null : _element
+ .getAttribute(IJSFConstants.ATTR_STYLE));
+ setText(style);
+ }
+ }
+ }
+
+ public void setElement(IDOMElement element) {
+ _element = element;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroudPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroudPreferenceNode.java
new file mode 100644
index 000000000..c4a0f363e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroudPreferenceNode.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BackgroudPreferenceNode implements IPreferenceNode {
+ private BackgroundPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _style;
+
+ public BackgroudPreferenceNode(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new BackgroundPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Background";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("BackgroundPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroundPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroundPreferencePage.java
new file mode 100644
index 000000000..e23a77e78
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BackgroundPreferencePage.java
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ColorButtonDialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BackgroundPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _backgroundImageCombo, _backgroundRepeatCombo,
+ _backgroundAttachmentCombo, _horizontalNumberCombo,
+ _horizontalUnitCombo, _verticalNumberCombo, _verticalUnitCombo;
+
+ private ColorButtonDialogField _backgroundColorField;
+
+ public BackgroundPreferencePage(IDOMElement element,
+ CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("BackgroundPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(3, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ _backgroundColorField = new ColorButtonDialogField(SWT.BORDER);
+ _backgroundColorField.setLabelText(DialogsMessages
+ .getString("BackgroundBoxPreferencePage.BackgroundColor"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ _backgroundColorField.getLabelControl(null, top).setLayoutData(data);
+
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _backgroundColorField.getComboControl(null, top).setLayoutData(data);
+
+ data = new GridData();
+ _backgroundColorField.getChangeControl(null, top).setLayoutData(data);
+ _backgroundColorField
+ .setDialogFieldApplyListener(new IDialogFieldApplyListener() {
+ public void dialogFieldApplied(DialogField field) {
+ String color = _backgroundColorField.getText();
+
+ _style.setBackgroundColor(color);
+ }
+ });
+
+ Label backgroundImageLabel = new Label(top, SWT.NONE);
+ backgroundImageLabel.setText(DialogsMessages
+ .getString("BackgroundBoxPreferencePage.BackgroundImage")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ backgroundImageLabel.setLayoutData(data);
+
+ _backgroundImageCombo = new StyleCombo(top, SWT.NONE);
+ _backgroundImageCombo.setItems(IStyleConstants.NONE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _backgroundImageCombo.setLayoutData(data);
+ _backgroundImageCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String image = _backgroundImageCombo.getText();
+
+ _style.setBackgroundImage(image);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label backgroundRepeatLabel = new Label(top, SWT.NONE);
+ backgroundRepeatLabel
+ .setText(DialogsMessages
+ .getString("BackgroundBoxPreferencePage.BackgroundRepeatLabel")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ backgroundRepeatLabel.setLayoutData(data);
+
+ _backgroundRepeatCombo = new StyleCombo(top, SWT.NONE);
+ _backgroundRepeatCombo.setItems(IStyleConstants.REPEAT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _backgroundRepeatCombo.setLayoutData(data);
+ _backgroundRepeatCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String repeat = _backgroundRepeatCombo.getText();
+
+ _style.setBackgroundRepeat(repeat);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label backgroundAttachmentLabel = new Label(top, SWT.NONE);
+ backgroundAttachmentLabel
+ .setText(DialogsMessages
+ .getString("BackgroundBoxPreferencePage.BackgroundAttachmentLabel")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ backgroundAttachmentLabel.setLayoutData(data);
+
+ _backgroundAttachmentCombo = new StyleCombo(top, SWT.NONE);
+ _backgroundAttachmentCombo.setItems(IStyleConstants.ATTACHMENT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _backgroundAttachmentCombo.setLayoutData(data);
+ _backgroundAttachmentCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String attachment = _backgroundAttachmentCombo.getText();
+
+ _style.setBackgroundAttachment(attachment);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label backgroundHorizontalLabel = new Label(top, SWT.NONE);
+ backgroundHorizontalLabel.setText(DialogsMessages
+ .getString("BackgroundBoxPreferencePage.HorizontalLabel")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ backgroundHorizontalLabel.setLayoutData(data);
+
+ _horizontalNumberCombo = new StyleCombo(top, SWT.NONE);
+ _horizontalNumberCombo.setItems(IStyleConstants.POSITION);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _horizontalNumberCombo.setLayoutData(data);
+ _horizontalNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _horizontalUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_horizontalNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _horizontalUnitCombo.setEnabled(false);
+ }
+
+ String position = _horizontalNumberCombo.getText();
+ if (_horizontalUnitCombo.isEnabled()) {
+ position += _horizontalUnitCombo.getText();
+ }
+
+ _style.setBackgroundPositionX(position);
+ }
+ });
+
+ _horizontalUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _horizontalUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL);
+ _horizontalUnitCombo.setLayoutData(data);
+ _horizontalUnitCombo.select(0);
+ _horizontalUnitCombo.setEnabled(false);
+ _horizontalUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String position = _horizontalNumberCombo.getText();
+ if (_horizontalUnitCombo.isEnabled()) {
+ position += _horizontalUnitCombo.getText();
+ }
+
+ _style.setBackgroundPositionX(position);
+
+ }
+ });
+
+ Label backgroundVerticalLabel = new Label(top, SWT.NONE);
+ backgroundVerticalLabel.setText(DialogsMessages
+ .getString("BackgroundBoxPreferencePage.VerticalLabel")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ backgroundVerticalLabel.setLayoutData(data);
+
+ _verticalNumberCombo = new StyleCombo(top, SWT.NONE);
+ _verticalNumberCombo.setItems(IStyleConstants.POSITION);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _verticalNumberCombo.setLayoutData(data);
+ _verticalNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _verticalUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_verticalNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _verticalUnitCombo.setEnabled(false);
+ }
+
+ String position = _verticalNumberCombo.getText();
+ if (_verticalUnitCombo.isEnabled()) {
+ position += _verticalUnitCombo.getText();
+ }
+
+ _style.setBackgroundPositionY(position);
+ }
+ });
+
+ _verticalUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _verticalUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL);
+ _verticalUnitCombo.setLayoutData(data);
+ _verticalUnitCombo.select(0);
+ _verticalUnitCombo.setEnabled(false);
+ _verticalUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String position = _verticalNumberCombo.getText();
+ if (_verticalUnitCombo.isEnabled()) {
+ position += _verticalUnitCombo.getText();
+ }
+
+ _style.setBackgroundPositionY(position);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // background-color
+ String color = _style.getBackgroundColor();
+ if (!isEmptyString(color)) {
+ _backgroundColorField.setTextWithoutUpdate(color);
+ }
+
+ // background-image
+ String image = _style.getBackgroundImage();
+ if (!isEmptyString(image)) {
+ int index = _backgroundImageCombo.indexOf(image);
+ if (index != -1) {
+ _backgroundImageCombo.select(index);
+ } else {
+ _backgroundImageCombo.setText(image);
+ }
+ }
+
+ // background-repeat
+ String repeat = _style.getBackgroundRepeat();
+ if (!isEmptyString(repeat)) {
+ int index = _backgroundRepeatCombo.indexOf(repeat);
+ if (index != -1) {
+ _backgroundRepeatCombo.select(index);
+ } else {
+ _backgroundRepeatCombo.setText(repeat);
+ }
+ }
+
+ // background-attachment
+ String attachment = _style.getBackgroundAttachment();
+ if (!isEmptyString(attachment)) {
+ int index = _backgroundAttachmentCombo.indexOf(repeat);
+ if (index != -1) {
+ _backgroundAttachmentCombo.select(index);
+ } else {
+ _backgroundAttachmentCombo.setText(attachment);
+ }
+ }
+
+ // background-position
+ String position = _style.getBackgroundPositionX();
+ if (!isEmptyString(position)) {
+ int index = _horizontalNumberCombo.indexOf(position);
+ if (index != -1) {
+ _horizontalNumberCombo.select(index);
+ } else {
+ _horizontalNumberCombo.setText(position);
+ }
+ }
+ position = _style.getBackgroundPositionY();
+ if (!isEmptyString(position)) {
+ int index = _verticalNumberCombo.indexOf(position);
+ if (index != -1) {
+ _verticalNumberCombo.select(index);
+ } else {
+ _verticalNumberCombo.setText(position);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferenceNode.java
new file mode 100644
index 000000000..a03747d70
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferenceNode.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BlockPreferenceNode implements IPreferenceNode {
+ private BlockPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _style;
+
+ public BlockPreferenceNode(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new BlockPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Block";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("BlockPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferencePage.java
new file mode 100644
index 000000000..51006ed51
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BlockPreferencePage.java
@@ -0,0 +1,394 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BlockPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _wordSpacingNumberCombo, _wordSpacingUnitCombo,
+ _letterSpacingNumberCombo, _letterSpacingUnitCombo,
+ _verticalAlignNumberCombo, _verticalAlignUnitCombo,
+ _textAlignCombo, _textIndentUnitCombo, _whiteSpaceCombo,
+ _displayCombo;
+
+ private Text _textIndentText;
+
+ public BlockPreferencePage(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("BlockPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(3, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Label wordSpacingLabel = new Label(top, SWT.NONE);
+ wordSpacingLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.WordSpacing")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ wordSpacingLabel.setLayoutData(data);
+
+ _wordSpacingNumberCombo = new StyleCombo(top, SWT.NONE);
+ _wordSpacingNumberCombo.setItems(IStyleConstants.NORMAL);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _wordSpacingNumberCombo.setLayoutData(data);
+ _wordSpacingNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _wordSpacingUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_wordSpacingNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _wordSpacingUnitCombo.setEnabled(false);
+ }
+
+ String spacing = _wordSpacingNumberCombo.getText();
+ if (_wordSpacingUnitCombo.isEnabled()) {
+ spacing += _wordSpacingUnitCombo.getText();
+ }
+
+ _style.setWordSpacing(spacing);
+ }
+ });
+
+ _wordSpacingUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _wordSpacingUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _wordSpacingUnitCombo.setLayoutData(data);
+ _wordSpacingUnitCombo.select(0);
+ _wordSpacingUnitCombo.setEnabled(false);
+ _wordSpacingUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String spacing = _wordSpacingNumberCombo.getText();
+ if (_wordSpacingUnitCombo.isEnabled()) {
+ spacing += _wordSpacingUnitCombo.getText();
+ }
+
+ _style.setWordSpacing(spacing);
+
+ }
+ });
+
+ Label letterSpacingLabel = new Label(top, SWT.NONE);
+ letterSpacingLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.LetterSpacing")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ letterSpacingLabel.setLayoutData(data);
+
+ _letterSpacingNumberCombo = new StyleCombo(top, SWT.NONE);
+ _letterSpacingNumberCombo.setItems(IStyleConstants.NORMAL);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _letterSpacingNumberCombo.setLayoutData(data);
+ _letterSpacingNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _letterSpacingUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_letterSpacingNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _letterSpacingUnitCombo.setEnabled(false);
+ }
+
+ String spacing = _letterSpacingNumberCombo.getText();
+ if (_letterSpacingUnitCombo.isEnabled()) {
+ spacing += _letterSpacingUnitCombo.getText();
+ }
+
+ _style.setLetterSpacing(spacing);
+ }
+ });
+
+ _letterSpacingUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _letterSpacingUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _letterSpacingUnitCombo.setLayoutData(data);
+ _letterSpacingUnitCombo.select(0);
+ _letterSpacingUnitCombo.setEnabled(false);
+ _letterSpacingUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String spacing = _letterSpacingNumberCombo.getText();
+ if (_letterSpacingUnitCombo.isEnabled()) {
+ spacing += _letterSpacingUnitCombo.getText();
+ }
+
+ _style.setLetterSpacing(spacing);
+ }
+ });
+
+ Label verticalAlignLabel = new Label(top, SWT.NONE);
+ verticalAlignLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.VerticalAlign")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ verticalAlignLabel.setLayoutData(data);
+
+ _verticalAlignNumberCombo = new StyleCombo(top, SWT.NONE);
+ _verticalAlignNumberCombo.setItems(IStyleConstants.VERTICAL_ALIGN);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _verticalAlignNumberCombo.setLayoutData(data);
+ _verticalAlignNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _verticalAlignUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_verticalAlignNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _verticalAlignUnitCombo.setEnabled(false);
+ }
+
+ String align = _verticalAlignNumberCombo.getText();
+ if (_verticalAlignUnitCombo.isEnabled()) {
+ align += _verticalAlignUnitCombo.getText();
+ }
+
+ _style.setVerticalAlign(align);
+ }
+ });
+
+ _verticalAlignUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _verticalAlignUnitCombo.setItems(IStyleConstants.PERCENT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _verticalAlignUnitCombo.setLayoutData(data);
+ _verticalAlignUnitCombo.select(0);
+ _verticalAlignUnitCombo.setEnabled(false);
+ _verticalAlignUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String align = _verticalAlignNumberCombo.getText();
+ if (_verticalAlignUnitCombo.isEnabled()) {
+ align += _verticalAlignUnitCombo.getText();
+ }
+
+ _style.setVerticalAlign(align);
+ }
+ });
+
+ Label textAlignLabel = new Label(top, SWT.NONE);
+ textAlignLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.TextAlign")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ textAlignLabel.setLayoutData(data);
+
+ _textAlignCombo = new StyleCombo(top, SWT.NONE);
+ _textAlignCombo.setItems(IStyleConstants.TEXT_ALIGN);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _textAlignCombo.setLayoutData(data);
+ _textAlignCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String align = _textAlignCombo.getText();
+
+ _style.setTextAlign(align);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label textIndentLabel = new Label(top, SWT.NONE);
+ textIndentLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.TextIndent")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ textIndentLabel.setLayoutData(data);
+
+ _textIndentText = new Text(top, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _textIndentText.setLayoutData(data);
+ _textIndentText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _textIndentUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_textIndentText.getText());
+ } catch (NumberFormatException ex) {
+ _textIndentUnitCombo.setEnabled(false);
+ }
+
+ String indent = _textIndentText.getText();
+ if (_textIndentUnitCombo.isEnabled()) {
+ indent += _textIndentUnitCombo.getText();
+ }
+
+ _style.setTextIndent(indent);
+ }
+ });
+
+ _textIndentUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _textIndentUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _textIndentUnitCombo.setLayoutData(data);
+ _textIndentUnitCombo.select(0);
+ _textIndentUnitCombo.setEnabled(false);
+ _textIndentUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String indent = _textIndentText.getText();
+ if (_textIndentUnitCombo.isEnabled()) {
+ indent += _textIndentUnitCombo.getText();
+ }
+
+ _style.setTextIndent(indent);
+ }
+ });
+
+ Label whiteSpaceLabel = new Label(top, SWT.NONE);
+ whiteSpaceLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.WhiteSpace")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ whiteSpaceLabel.setLayoutData(data);
+
+ _whiteSpaceCombo = new StyleCombo(top, SWT.NONE);
+ _whiteSpaceCombo.setItems(IStyleConstants.WHITE_SPACE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _whiteSpaceCombo.setLayoutData(data);
+ _whiteSpaceCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String space = _whiteSpaceCombo.getText();
+
+ _style.setWhiteSpace(space);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label displayLabel = new Label(top, SWT.NONE);
+ displayLabel.setText(DialogsMessages
+ .getString("BlockPreferencePage.Display")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ displayLabel.setLayoutData(data);
+
+ _displayCombo = new StyleCombo(top, SWT.NONE);
+ _displayCombo.setItems(IStyleConstants.DISPLAY);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _displayCombo.setLayoutData(data);
+ _displayCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String display = _displayCombo.getText();
+
+ _style.setDisplay(display);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // word-spacing
+ String spacing = _style.getWordSpacing();
+ if (!isEmptyString(spacing)) {
+ int index = _wordSpacingNumberCombo.indexOf(spacing);
+ if (index != -1) {
+ _wordSpacingNumberCombo.select(index);
+ } else {
+ _wordSpacingNumberCombo.setText(spacing);
+ }
+ }
+
+ // letter-spacing
+ spacing = _style.getLetterSpacing();
+ if (!isEmptyString(spacing)) {
+ int index = _letterSpacingNumberCombo.indexOf(spacing);
+ if (index != -1) {
+ _letterSpacingNumberCombo.select(index);
+ } else {
+ _letterSpacingNumberCombo.setText(spacing);
+ }
+ }
+
+ // veritcal-align
+ String align = _style.getVerticalAlign();
+ if (!isEmptyString(align)) {
+ int index = _verticalAlignNumberCombo.indexOf(align);
+ if (index != -1) {
+ _verticalAlignNumberCombo.select(index);
+ } else {
+ _verticalAlignNumberCombo.setText(align);
+ }
+ }
+
+ // text-align
+ align = _style.getTextAlign();
+ if (!isEmptyString(align)) {
+ int index = _textAlignCombo.indexOf(align);
+ if (index != -1) {
+ _textAlignCombo.select(index);
+ } else {
+ _textAlignCombo.setText(align);
+ }
+ }
+
+ // text-indent
+ String indent = _style.getTextIndent();
+ if (!isEmptyString(indent)) {
+ _textIndentText.setText(indent);
+ }
+
+ // white-space
+ String space = _style.getWhiteSpace();
+ if (!isEmptyString(space)) {
+ int index = _whiteSpaceCombo.indexOf(space);
+ if (index != -1) {
+ _whiteSpaceCombo.select(index);
+ } else {
+ _whiteSpaceCombo.setText(space);
+ }
+ }
+
+ // display
+ String display = _style.getDisplay();
+ if (!isEmptyString(display)) {
+ int index = _displayCombo.indexOf(display);
+ if (index != -1) {
+ _displayCombo.select(index);
+ } else {
+ _displayCombo.setText(display);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferenceNode.java
new file mode 100644
index 000000000..de068c673
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferenceNode.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BorderPreferenceNode implements IPreferenceNode {
+ private BorderPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _style;
+
+ public BorderPreferenceNode(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new BorderPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Border";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("BorderPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferencePage.java
new file mode 100644
index 000000000..e9ba4d9df
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BorderPreferencePage.java
@@ -0,0 +1,535 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ColorButtonDialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BorderPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _styleTopCombo, _styleRightCombo, _styleBottomCombo,
+ _styleLeftCombo;
+
+ private StyleCombo _widthTopNumberCombo, _widthRightNumberCombo,
+ _widthBottomNumberCombo, _widthLeftNumberCombo;
+
+ private StyleCombo _widthTopUnitCombo, _widthRightUnitCombo,
+ _widthBottomUnitCombo, _widthLeftUnitCombo;
+
+ private ColorButtonDialogField _colorTopField, _colorRightField,
+ _colorBottomField, _colorLeftField;
+
+ public BorderPreferencePage(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("BorderPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(1, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Group styleGroup = new Group(top, SWT.NONE);
+ styleGroup.setText(DialogsMessages
+ .getString("BorderPreferencePage.Style"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ styleGroup.setLayoutData(data);
+ layout = new GridLayout(2, false);
+ styleGroup.setLayout(layout);
+
+ Label styleTopLabel = new Label(styleGroup, SWT.NONE);
+ styleTopLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Top"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ styleTopLabel.setLayoutData(data);
+
+ _styleTopCombo = new StyleCombo(styleGroup, SWT.NONE);
+ _styleTopCombo.setItems(IStyleConstants.BORDER_STYLE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _styleTopCombo.setLayoutData(data);
+ _styleTopCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String style = _styleTopCombo.getText();
+ _style.setBorderTopStyle(style);
+ }
+ });
+
+ Label styleRightLabel = new Label(styleGroup, SWT.NONE);
+ styleRightLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Right"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ styleRightLabel.setLayoutData(data);
+
+ _styleRightCombo = new StyleCombo(styleGroup, SWT.NONE);
+ _styleRightCombo.setItems(IStyleConstants.BORDER_STYLE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _styleRightCombo.setLayoutData(data);
+ _styleRightCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String style = _styleRightCombo.getText();
+ _style.setBorderRightStyle(style);
+ }
+ });
+
+ Label styleBottomLabel = new Label(styleGroup, SWT.NONE);
+ styleBottomLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Bottom"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ styleBottomLabel.setLayoutData(data);
+
+ _styleBottomCombo = new StyleCombo(styleGroup, SWT.NONE);
+ _styleBottomCombo.setItems(IStyleConstants.BORDER_STYLE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _styleBottomCombo.setLayoutData(data);
+ _styleBottomCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String style = _styleBottomCombo.getText();
+ _style.setBorderBottomStyle(style);
+ }
+ });
+
+ Label styleLeftLabel = new Label(styleGroup, SWT.NONE);
+ styleLeftLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Left"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ styleLeftLabel.setLayoutData(data);
+
+ _styleLeftCombo = new StyleCombo(styleGroup, SWT.NONE);
+ _styleLeftCombo.setItems(IStyleConstants.BORDER_STYLE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _styleLeftCombo.setLayoutData(data);
+ _styleLeftCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String style = _styleLeftCombo.getText();
+ _style.setBorderLeftStyle(style);
+ }
+ });
+
+ Group colorGroup = new Group(top, SWT.NONE);
+ colorGroup.setText(DialogsMessages
+ .getString("BorderPreferencePage.Color"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ colorGroup.setLayoutData(data);
+ layout = new GridLayout(3, false);
+ colorGroup.setLayout(layout);
+
+ _colorTopField = new ColorButtonDialogField(SWT.BORDER);
+ _colorTopField.setLabelText(DialogsMessages
+ .getString("BorderPreferencePage.Top"));
+
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ _colorTopField.getLabelControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _colorTopField.getComboControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData();
+ _colorTopField.getChangeControl(null, colorGroup).setLayoutData(data);
+ _colorTopField
+ .setDialogFieldApplyListener(new IDialogFieldApplyListener() {
+ public void dialogFieldApplied(DialogField field) {
+ String color = _colorTopField.getText();
+ _style.setBorderTopColor(color);
+ }
+ });
+
+ _colorRightField = new ColorButtonDialogField(SWT.BORDER);
+ _colorRightField.setLabelText(DialogsMessages
+ .getString("BorderPreferencePage.Right"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ _colorRightField.getLabelControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _colorRightField.getComboControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData();
+ _colorRightField.getChangeControl(null, colorGroup).setLayoutData(data);
+ _colorRightField
+ .setDialogFieldApplyListener(new IDialogFieldApplyListener() {
+ public void dialogFieldApplied(DialogField field) {
+ String color = _colorRightField.getText();
+ _style.setBorderRightColor(color);
+ }
+ });
+
+ _colorBottomField = new ColorButtonDialogField(SWT.BORDER);
+ _colorBottomField.setLabelText(DialogsMessages
+ .getString("BorderPreferencePage.Bottom"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ _colorBottomField.getLabelControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _colorBottomField.getComboControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData();
+ _colorBottomField.getChangeControl(null, colorGroup)
+ .setLayoutData(data);
+ _colorBottomField
+ .setDialogFieldApplyListener(new IDialogFieldApplyListener() {
+ public void dialogFieldApplied(DialogField field) {
+ String color = _colorBottomField.getText();
+ _style.setBorderBottomColor(color);
+ }
+ });
+
+ _colorLeftField = new ColorButtonDialogField(SWT.BORDER);
+ _colorLeftField.setLabelText(DialogsMessages
+ .getString("BorderPreferencePage.Left"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ _colorLeftField.getLabelControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _colorLeftField.getComboControl(null, colorGroup).setLayoutData(data);
+
+ data = new GridData();
+ _colorLeftField.getChangeControl(null, colorGroup).setLayoutData(data);
+ _colorLeftField
+ .setDialogFieldApplyListener(new IDialogFieldApplyListener() {
+ public void dialogFieldApplied(DialogField field) {
+ String color = _colorLeftField.getText();
+ _style.setBorderLeftColor(color);
+ }
+ });
+
+ Group widthGroup = new Group(top, SWT.NONE);
+ widthGroup.setText(DialogsMessages
+ .getString("BorderPreferencePage.Width"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ widthGroup.setLayoutData(data);
+ layout = new GridLayout(3, false);
+ widthGroup.setLayout(layout);
+
+ Label widthTopLabel = new Label(widthGroup, SWT.NONE);
+ widthTopLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Top"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ widthTopLabel.setLayoutData(data);
+
+ _widthTopNumberCombo = new StyleCombo(widthGroup, SWT.NONE);
+ _widthTopNumberCombo.setItems(IStyleConstants.BORDER_WIDTH);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthTopNumberCombo.setLayoutData(data);
+ _widthTopNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _widthTopUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_widthTopNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _widthTopUnitCombo.setEnabled(false);
+ }
+
+ String width = _widthTopNumberCombo.getText();
+ if (_widthTopUnitCombo.isEnabled()) {
+ width += _widthTopUnitCombo.getText();
+ }
+
+ _style.setBorderTopWidth(width);
+ }
+ });
+
+ _widthTopUnitCombo = new StyleCombo(widthGroup, SWT.READ_ONLY);
+ _widthTopUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthTopUnitCombo.setLayoutData(data);
+ _widthTopUnitCombo.select(0);
+ _widthTopUnitCombo.setEnabled(false);
+ _widthTopUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String width = _widthTopNumberCombo.getText();
+ if (_widthTopUnitCombo.isEnabled()) {
+ width += _widthTopUnitCombo.getText();
+ }
+
+ _style.setBorderTopWidth(width);
+ }
+ });
+
+ Label widthRightLabel = new Label(widthGroup, SWT.NONE);
+ widthRightLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Right"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ widthRightLabel.setLayoutData(data);
+
+ _widthRightNumberCombo = new StyleCombo(widthGroup, SWT.NONE);
+ _widthRightNumberCombo.setItems(IStyleConstants.BORDER_WIDTH);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthRightNumberCombo.setLayoutData(data);
+ _widthRightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _widthRightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_widthRightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _widthRightUnitCombo.setEnabled(false);
+ }
+
+ String width = _widthRightNumberCombo.getText();
+ if (_widthRightUnitCombo.isEnabled()) {
+ width += _widthRightUnitCombo.getText();
+ }
+
+ _style.setBorderRightWidth(width);
+ }
+ });
+
+ _widthRightUnitCombo = new StyleCombo(widthGroup, SWT.READ_ONLY);
+ _widthRightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthRightUnitCombo.setLayoutData(data);
+ _widthRightUnitCombo.select(0);
+ _widthRightUnitCombo.setEnabled(false);
+ _widthRightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String width = _widthRightNumberCombo.getText();
+ if (_widthRightUnitCombo.isEnabled()) {
+ width += _widthRightUnitCombo.getText();
+ }
+
+ _style.setBorderRightWidth(width);
+ }
+ });
+
+ Label widthBottomLabel = new Label(widthGroup, SWT.NONE);
+ widthBottomLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Bottom"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ widthBottomLabel.setLayoutData(data);
+
+ _widthBottomNumberCombo = new StyleCombo(widthGroup, SWT.NONE);
+ _widthBottomNumberCombo.setItems(IStyleConstants.BORDER_WIDTH);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthBottomNumberCombo.setLayoutData(data);
+ _widthBottomNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _widthBottomUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_widthBottomNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _widthBottomUnitCombo.setEnabled(false);
+ }
+
+ String width = _widthBottomNumberCombo.getText();
+ if (_widthBottomUnitCombo.isEnabled()) {
+ width += _widthBottomUnitCombo.getText();
+ }
+
+ _style.setBorderBottomWidth(width);
+ }
+ });
+
+ _widthBottomUnitCombo = new StyleCombo(widthGroup, SWT.READ_ONLY);
+ _widthBottomUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthBottomUnitCombo.setLayoutData(data);
+ _widthBottomUnitCombo.select(0);
+ _widthBottomUnitCombo.setEnabled(false);
+ _widthBottomUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String width = _widthBottomNumberCombo.getText();
+ if (_widthBottomUnitCombo.isEnabled()) {
+ width += _widthBottomUnitCombo.getText();
+ }
+
+ _style.setBorderBottomWidth(width);
+ }
+ });
+
+ Label widthLeftLabel = new Label(widthGroup, SWT.NONE);
+ widthLeftLabel.setText(DialogsMessages
+ .getString("BorderPreferencePage.Left"));
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ widthLeftLabel.setLayoutData(data);
+
+ _widthLeftNumberCombo = new StyleCombo(widthGroup, SWT.NONE);
+ _widthLeftNumberCombo.setItems(IStyleConstants.BORDER_WIDTH);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthLeftNumberCombo.setLayoutData(data);
+ _widthLeftNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _widthLeftUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_widthLeftNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _widthLeftUnitCombo.setEnabled(false);
+ }
+
+ String width = _widthLeftNumberCombo.getText();
+ if (_widthLeftUnitCombo.isEnabled()) {
+ width += _widthLeftUnitCombo.getText();
+ }
+
+ _style.setBorderLeftWidth(width);
+ }
+ });
+
+ _widthLeftUnitCombo = new StyleCombo(widthGroup, SWT.READ_ONLY);
+ _widthLeftUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthLeftUnitCombo.setLayoutData(data);
+ _widthLeftUnitCombo.select(0);
+ _widthLeftUnitCombo.setEnabled(false);
+ _widthLeftUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String width = _widthLeftNumberCombo.getText();
+ if (_widthLeftUnitCombo.isEnabled()) {
+ width += _widthLeftUnitCombo.getText();
+ }
+
+ _style.setBorderLeftWidth(width);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // border-style
+ String style = _style.getBorderTopStyle();
+ if (!isEmptyString(style)) {
+ int index = _styleTopCombo.indexOf(style);
+ if (index != -1) {
+ _styleTopCombo.select(index);
+ } else {
+ _styleTopCombo.setText(style);
+ }
+ }
+ style = _style.getBorderRightStyle();
+ if (!isEmptyString(style)) {
+ int index = _styleRightCombo.indexOf(style);
+ if (index != -1) {
+ _styleRightCombo.select(index);
+ } else {
+ _styleRightCombo.setText(style);
+ }
+ }
+ style = _style.getBorderBottomStyle();
+ if (!isEmptyString(style)) {
+ int index = _styleBottomCombo.indexOf(style);
+ if (index != -1) {
+ _styleBottomCombo.select(index);
+ } else {
+ _styleBottomCombo.setText(style);
+ }
+ }
+ style = _style.getBorderLeftStyle();
+ if (!isEmptyString(style)) {
+ int index = _styleLeftCombo.indexOf(style);
+ if (index != -1) {
+ _styleLeftCombo.select(index);
+ } else {
+ _styleLeftCombo.setText(style);
+ }
+ }
+
+ // border-color
+ String color = _style.getBorderTopColor();
+ if (!isEmptyString(color)) {
+ _colorTopField.setTextWithoutUpdate(color);
+ }
+ color = _style.getBorderRightColor();
+ if (!isEmptyString(color)) {
+ _colorRightField.setTextWithoutUpdate(color);
+ }
+ color = _style.getBorderBottomColor();
+ if (!isEmptyString(color)) {
+ _colorBottomField.setTextWithoutUpdate(color);
+ }
+ color = _style.getBorderLeftColor();
+ if (!isEmptyString(color)) {
+ _colorLeftField.setTextWithoutUpdate(color);
+ }
+
+ // border-width
+ String width = _style.getBorderTopWidth();
+ if (!isEmptyString(width)) {
+ int index = _widthTopNumberCombo.indexOf(width);
+ if (index != -1) {
+ _widthTopNumberCombo.select(index);
+ } else {
+ _widthTopNumberCombo.setText(width);
+ }
+ }
+ width = _style.getBorderRightWidth();
+ if (!isEmptyString(width)) {
+ int index = _widthRightNumberCombo.indexOf(width);
+ if (index != -1) {
+ _widthRightNumberCombo.select(index);
+ } else {
+ _widthRightNumberCombo.setText(width);
+ }
+ }
+ width = _style.getBorderBottomWidth();
+ if (!isEmptyString(width)) {
+ int index = _widthBottomNumberCombo.indexOf(width);
+ if (index != -1) {
+ _widthBottomNumberCombo.select(index);
+ } else {
+ _widthBottomNumberCombo.setText(width);
+ }
+ }
+ width = _style.getBorderLeftWidth();
+ if (!isEmptyString(width)) {
+ int index = _widthLeftNumberCombo.indexOf(width);
+ if (index != -1) {
+ _widthLeftNumberCombo.select(index);
+ } else {
+ _widthLeftNumberCombo.setText(width);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferenceNode.java
new file mode 100644
index 000000000..64ac5b91b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferenceNode.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BoxPreferenceNode implements IPreferenceNode {
+ private BoxPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _styles;
+
+ public BoxPreferenceNode(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _element = element;
+ _styles = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new BoxPreferencePage(_element, _styles);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Box";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("BoxPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferencePage.java
new file mode 100644
index 000000000..2a26134ee
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/BoxPreferencePage.java
@@ -0,0 +1,670 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class BoxPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _widthNumberCombo, _widthUnitCombo, _heightNumberCombo,
+ _heightUnitCombo, _clearCombo;
+
+ private Text _paddingTopNumberText, _paddingRightNumberText,
+ _paddingBottomNumberText, _paddingLeftNumberText;
+
+ private StyleCombo _paddingTopUnitCombo, _paddingRightUnitCombo,
+ _paddingBottomUnitCombo, _paddingLeftUnitCombo;
+
+ private StyleCombo _marginTopNumberCombo, _marginRightNumberCombo,
+ _marginBottomNumberCombo, _marginLeftNumberCombo;
+
+ private StyleCombo _marginTopUnitCombo, _marginRightUnitCombo,
+ _marginBottomUnitCombo, _marginLeftUnitCombo;
+
+ public BoxPreferencePage(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("BoxPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(6, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Label widthLabel = new Label(top, SWT.NONE);
+ widthLabel
+ .setText(DialogsMessages.getString("BoxPreferencePage.Width")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ widthLabel.setLayoutData(data);
+
+ _widthNumberCombo = new StyleCombo(top, SWT.NONE);
+ _widthNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthNumberCombo.setLayoutData(data);
+ _widthNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _widthUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_widthNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _widthUnitCombo.setEnabled(false);
+ }
+
+ String width = _widthNumberCombo.getText();
+ if (_widthUnitCombo.isEnabled()) {
+ width += _widthUnitCombo.getText();
+ }
+
+ _style.setWidth(width);
+ }
+ });
+
+ _widthUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _widthUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthUnitCombo.setLayoutData(data);
+ _widthUnitCombo.select(0);
+ _widthUnitCombo.setEnabled(false);
+ _widthUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String width = _widthNumberCombo.getText();
+ if (_widthUnitCombo.isEnabled()) {
+ width += _widthUnitCombo.getText();
+ }
+
+ _style.setWidth(width);
+ }
+ });
+
+ Label clearLabel = new Label(top, SWT.NONE);
+ clearLabel
+ .setText(DialogsMessages.getString("BoxPreferencePage.Clear")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ clearLabel.setLayoutData(data);
+
+ _clearCombo = new StyleCombo(top, SWT.NONE);
+ _clearCombo.setItems(IStyleConstants.CLEAR);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clearCombo.setLayoutData(data);
+ _clearCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String clear = _clearCombo.getText();
+ _style.setClear(clear);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label heightLabel = new Label(top, SWT.NONE);
+ heightLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Height")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ heightLabel.setLayoutData(data);
+
+ _heightNumberCombo = new StyleCombo(top, SWT.NONE);
+ _heightNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _heightNumberCombo.setLayoutData(data);
+ _heightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _heightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_heightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _heightUnitCombo.setEnabled(false);
+ }
+
+ String height = _heightNumberCombo.getText();
+ if (_heightUnitCombo.isEnabled()) {
+ height += _heightUnitCombo.getText();
+ }
+
+ _style.setHeight(height);
+ }
+ });
+
+ _heightUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _heightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _heightUnitCombo.setLayoutData(data);
+ _heightUnitCombo.select(0);
+ _heightUnitCombo.setEnabled(false);
+ _heightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String height = _heightNumberCombo.getText();
+ if (_heightUnitCombo.isEnabled()) {
+ height += _heightNumberCombo.getText();
+ }
+
+ _style.setHeight(height);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+ new Label(top, SWT.NONE);
+ new Label(top, SWT.NONE);
+
+ Group paddingGroup = new Group(top, SWT.NONE);
+ paddingGroup.setText(DialogsMessages
+ .getString("BoxPreferencePage.Padding"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 3;
+ data.verticalSpan = 4;
+ paddingGroup.setLayoutData(data);
+ layout = new GridLayout(3, false);
+ paddingGroup.setLayout(layout);
+
+ Label paddingTopLabel = new Label(paddingGroup, SWT.NONE);
+ paddingTopLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Top")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ paddingTopLabel.setLayoutData(data);
+
+ _paddingTopNumberText = new Text(paddingGroup, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingTopNumberText.setLayoutData(data);
+ _paddingTopNumberText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _paddingTopUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_paddingTopNumberText.getText());
+ } catch (NumberFormatException ex) {
+ _paddingTopUnitCombo.setEnabled(false);
+ }
+
+ String padding = _paddingTopNumberText.getText();
+ if (_paddingTopUnitCombo.isEnabled()) {
+ padding += _paddingTopUnitCombo.getText();
+ }
+
+ _style.setPaddingTop(padding);
+ }
+ });
+
+ _paddingTopUnitCombo = new StyleCombo(paddingGroup, SWT.READ_ONLY);
+ _paddingTopUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingTopUnitCombo.setLayoutData(data);
+ _paddingTopUnitCombo.select(0);
+ _paddingTopUnitCombo.setEnabled(false);
+ _paddingTopUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String padding = _paddingTopNumberText.getText();
+ if (_paddingTopUnitCombo.isEnabled()) {
+ padding += _paddingTopUnitCombo.getText();
+ }
+
+ _style.setPaddingTop(padding);
+ }
+ });
+
+ Label paddingRightLabel = new Label(paddingGroup, SWT.NONE);
+ paddingRightLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Right")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ paddingRightLabel.setLayoutData(data);
+
+ _paddingRightNumberText = new Text(paddingGroup, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingRightNumberText.setLayoutData(data);
+ _paddingRightNumberText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _paddingRightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_paddingRightNumberText.getText());
+ } catch (NumberFormatException ex) {
+ _paddingRightUnitCombo.setEnabled(false);
+ }
+
+ String padding = _paddingRightNumberText.getText();
+ if (_paddingRightUnitCombo.isEnabled()) {
+ padding += _paddingRightUnitCombo.getText();
+ }
+
+ _style.setPaddingRight(padding);
+ }
+ });
+
+ _paddingRightUnitCombo = new StyleCombo(paddingGroup, SWT.READ_ONLY);
+ _paddingRightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingRightUnitCombo.setLayoutData(data);
+ _paddingRightUnitCombo.select(0);
+ _paddingRightUnitCombo.setEnabled(false);
+ _paddingRightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String padding = _paddingRightNumberText.getText();
+ if (_paddingRightUnitCombo.isEnabled()) {
+ padding += _paddingRightUnitCombo.getText();
+ }
+
+ _style.setPaddingRight(padding);
+ }
+ });
+
+ Label paddingBottomLabel = new Label(paddingGroup, SWT.NONE);
+ paddingBottomLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Bottom")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ paddingBottomLabel.setLayoutData(data);
+
+ _paddingBottomNumberText = new Text(paddingGroup, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingBottomNumberText.setLayoutData(data);
+ _paddingBottomNumberText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _paddingBottomUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_paddingBottomNumberText.getText());
+ } catch (NumberFormatException ex) {
+ _paddingBottomUnitCombo.setEnabled(false);
+ }
+
+ String padding = _paddingBottomNumberText.getText();
+ if (_paddingBottomUnitCombo.isEnabled()) {
+ padding += _paddingBottomUnitCombo.getText();
+ }
+
+ _style.setPaddingBottom(padding);
+ }
+ });
+
+ _paddingBottomUnitCombo = new StyleCombo(paddingGroup, SWT.READ_ONLY);
+ _paddingBottomUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingBottomUnitCombo.setLayoutData(data);
+ _paddingBottomUnitCombo.select(0);
+ _paddingBottomUnitCombo.setEnabled(false);
+ _paddingBottomUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String padding = _paddingBottomNumberText.getText();
+ if (_paddingBottomUnitCombo.isEnabled()) {
+ padding += _paddingBottomUnitCombo.getText();
+ }
+
+ _style.setPaddingBottom(padding);
+ }
+ });
+
+ Label paddingLeftLabel = new Label(paddingGroup, SWT.NONE);
+ paddingLeftLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Left")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ paddingLeftLabel.setLayoutData(data);
+
+ _paddingLeftNumberText = new Text(paddingGroup, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingLeftNumberText.setLayoutData(data);
+ _paddingLeftNumberText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _paddingLeftUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_paddingLeftNumberText.getText());
+ } catch (NumberFormatException ex) {
+ _paddingLeftUnitCombo.setEnabled(false);
+ }
+
+ String top = _paddingLeftNumberText.getText();
+ if (_paddingLeftUnitCombo.isEnabled()) {
+ top += _paddingLeftUnitCombo.getText();
+ }
+
+ _style.setPaddingLeft(top);
+ }
+ });
+
+ _paddingLeftUnitCombo = new StyleCombo(paddingGroup, SWT.READ_ONLY);
+ _paddingLeftUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _paddingLeftUnitCombo.setLayoutData(data);
+ _paddingLeftUnitCombo.select(0);
+ _paddingLeftUnitCombo.setEnabled(false);
+ _paddingLeftUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String top = _paddingLeftNumberText.getText();
+ if (_paddingLeftUnitCombo.isEnabled()) {
+ top += _paddingLeftUnitCombo.getText();
+ }
+
+ _style.setPaddingLeft(top);
+ }
+ });
+
+ Group marginGroup = new Group(top, SWT.NONE);
+ marginGroup.setText(DialogsMessages
+ .getString("BoxPreferencePage.Margin"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 3;
+ data.verticalSpan = 4;
+ marginGroup.setLayoutData(data);
+ layout = new GridLayout(3, false);
+ marginGroup.setLayout(layout);
+
+ Label marginTopLabel = new Label(marginGroup, SWT.NONE);
+ marginTopLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Top")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ marginTopLabel.setLayoutData(data);
+
+ _marginTopNumberCombo = new StyleCombo(marginGroup, SWT.NONE);
+ _marginTopNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginTopNumberCombo.setLayoutData(data);
+ _marginTopNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _marginTopUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_marginTopNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _marginTopUnitCombo.setEnabled(false);
+ }
+
+ String margin = _marginTopNumberCombo.getText();
+ if (_marginTopUnitCombo.isEnabled()) {
+ margin += _marginTopUnitCombo.getText();
+ }
+
+ _style.setMarginTop(margin);
+ }
+ });
+
+ _marginTopUnitCombo = new StyleCombo(marginGroup, SWT.READ_ONLY);
+ _marginTopUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginTopUnitCombo.setLayoutData(data);
+ _marginTopUnitCombo.select(0);
+ _marginTopUnitCombo.setEnabled(false);
+ _marginTopUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String margin = _marginTopNumberCombo.getText();
+ if (_marginTopUnitCombo.isEnabled()) {
+ margin += _marginTopUnitCombo.getText();
+ }
+
+ _style.setMarginTop(margin);
+ }
+ });
+
+ Label marginRightLabel = new Label(marginGroup, SWT.NONE);
+ marginRightLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Right")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ marginRightLabel.setLayoutData(data);
+
+ _marginRightNumberCombo = new StyleCombo(marginGroup, SWT.NONE);
+ _marginRightNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginRightNumberCombo.setLayoutData(data);
+ _marginRightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _marginRightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_marginRightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _marginRightUnitCombo.setEnabled(false);
+ }
+
+ String margin = _marginRightNumberCombo.getText();
+ if (_marginRightUnitCombo.isEnabled()) {
+ margin += _marginRightUnitCombo.getText();
+ }
+
+ _style.setMarginRight(margin);
+ }
+ });
+
+ _marginRightUnitCombo = new StyleCombo(marginGroup, SWT.READ_ONLY);
+ _marginRightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginRightUnitCombo.setLayoutData(data);
+ _marginRightUnitCombo.select(0);
+ _marginRightUnitCombo.setEnabled(false);
+ _marginRightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String margin = _marginRightNumberCombo.getText();
+ if (_marginRightUnitCombo.isEnabled()) {
+ margin += _marginRightUnitCombo.getText();
+ }
+
+ _style.setMarginRight(margin);
+ }
+ });
+
+ Label marginBottomLabel = new Label(marginGroup, SWT.NONE);
+ marginBottomLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Bottom")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ marginBottomLabel.setLayoutData(data);
+
+ _marginBottomNumberCombo = new StyleCombo(marginGroup, SWT.NONE);
+ _marginBottomNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginBottomNumberCombo.setLayoutData(data);
+ _marginBottomNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _marginBottomUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_marginBottomNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _marginBottomUnitCombo.setEnabled(false);
+ }
+
+ String margin = _marginBottomNumberCombo.getText();
+ if (_marginBottomUnitCombo.isEnabled()) {
+ margin += _marginBottomUnitCombo.getText();
+ }
+
+ _style.setMarginBottom(margin);
+ }
+ });
+
+ _marginBottomUnitCombo = new StyleCombo(marginGroup, SWT.READ_ONLY);
+ _marginBottomUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginBottomUnitCombo.setLayoutData(data);
+ _marginBottomUnitCombo.select(0);
+ _marginBottomUnitCombo.setEnabled(false);
+ _marginBottomUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String margin = _marginBottomNumberCombo.getText();
+ if (_marginBottomUnitCombo.isEnabled()) {
+ margin += _marginBottomUnitCombo.getText();
+ }
+
+ _style.setMarginBottom(margin);
+ }
+ });
+
+ Label marginLeftLabel = new Label(marginGroup, SWT.NONE);
+ marginLeftLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Left")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ marginLeftLabel.setLayoutData(data);
+
+ _marginLeftNumberCombo = new StyleCombo(marginGroup, SWT.NONE);
+ _marginLeftNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginLeftNumberCombo.setLayoutData(data);
+ _marginLeftNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _marginLeftUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_marginLeftNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _marginLeftUnitCombo.setEnabled(false);
+ }
+
+ String top = _marginLeftNumberCombo.getText();
+ if (_marginLeftUnitCombo.isEnabled()) {
+ top += _marginLeftUnitCombo.getText();
+ }
+
+ _style.setMarginLeft(top);
+ }
+ });
+
+ _marginLeftUnitCombo = new StyleCombo(marginGroup, SWT.READ_ONLY);
+ _marginLeftUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _marginLeftUnitCombo.setLayoutData(data);
+ _marginLeftUnitCombo.select(0);
+ _marginLeftUnitCombo.setEnabled(false);
+ _marginLeftUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String top = _marginLeftNumberCombo.getText();
+ if (_marginLeftUnitCombo.isEnabled()) {
+ top += _marginLeftUnitCombo.getText();
+ }
+
+ _style.setMarginLeft(top);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // width
+ String width = _style.getWidth();
+ if (!isEmptyString(width)) {
+ int index = _widthNumberCombo.indexOf(width);
+ if (index != -1) {
+ _widthNumberCombo.select(index);
+ } else {
+ _widthNumberCombo.setText(width);
+ }
+ }
+
+ // height
+ String height = _style.getHeight();
+ if (!isEmptyString(height)) {
+ int index = _heightNumberCombo.indexOf(height);
+ if (index != -1) {
+ _heightNumberCombo.select(index);
+ } else {
+ _heightNumberCombo.setText(height);
+ }
+ }
+
+ // clear
+ String clear = _style.getClear();
+ if (!isEmptyString(clear)) {
+ int index = _clearCombo.indexOf(clear);
+ if (index != -1) {
+ _clearCombo.select(index);
+ } else {
+ _clearCombo.setText(clear);
+ }
+ }
+
+ // padding
+ String padding = _style.getPaddingTop();
+ if (!isEmptyString(padding)) {
+ _paddingTopNumberText.setText(padding);
+ }
+ padding = _style.getPaddingRight();
+ if (!isEmptyString(padding)) {
+ _paddingRightNumberText.setText(padding);
+ }
+ padding = _style.getPaddingBottom();
+ if (!isEmptyString(padding)) {
+ _paddingBottomNumberText.setText(padding);
+ }
+ padding = _style.getPaddingLeft();
+ if (!isEmptyString(padding)) {
+ _paddingLeftNumberText.setText(padding);
+ }
+
+ // margin
+ String margin = _style.getMarginTop();
+ if (!isEmptyString(margin)) {
+ int index = _marginTopNumberCombo.indexOf(margin);
+ if (index != -1) {
+ _marginTopNumberCombo.select(index);
+ } else {
+ _marginTopNumberCombo.setText(margin);
+ }
+ }
+ margin = _style.getMarginRight();
+ if (!isEmptyString(margin)) {
+ int index = _marginRightNumberCombo.indexOf(margin);
+ if (index != -1) {
+ _marginRightNumberCombo.select(index);
+ } else {
+ _marginRightNumberCombo.setText(margin);
+ }
+ }
+ margin = _style.getMarginBottom();
+ if (!isEmptyString(margin)) {
+ int index = _marginBottomNumberCombo.indexOf(margin);
+ if (index != -1) {
+ _marginBottomNumberCombo.select(index);
+ } else {
+ _marginBottomNumberCombo.setText(margin);
+ }
+ }
+ margin = _style.getMarginLeft();
+ if (!isEmptyString(margin)) {
+ int index = _marginLeftNumberCombo.indexOf(margin);
+ if (index != -1) {
+ _marginLeftNumberCombo.select(index);
+ } else {
+ _marginLeftNumberCombo.setText(margin);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.java
new file mode 100644
index 000000000..d12ee1473
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class DialogsMessages {
+ private static final String BUNDLE_NAME = "org.eclipse.jst.pagedesigner.ui.dialogs.DialogsMessages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private DialogsMessages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.properties
new file mode 100644
index 000000000..72868099a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/DialogsMessages.properties
@@ -0,0 +1,83 @@
+StyleButtonDialogField.Edit=Edit...
+StyleDialog.Title=CSS Style Definition
+
+TextPreferenceNode.LabelText=Text
+TextPreferencePage.Title=Text
+TextPreferencePage.Font=Font:
+TextPreferencePage.Size=Size:
+TextPreferencePage.Weight=Weight:
+TextPreferencePage.Style=Style:
+TextPreferencePage.Variant=Variant:
+TextPreferencePage.LineHeight=Line Height:
+TextPreferencePage.Case=Case:
+TextPreferencePage.Decoration=Decoration:
+TextPreferencePage.Color=Color:
+
+BackgroundPreferenceNode.LabelText=Background
+BackgroundPreferencePage.Title=Background
+BackgroundBoxPreferencePage.BackgroundColor=Background color:
+BackgroundBoxPreferencePage.BackgroundImage=Background image:
+BackgroundBoxPreferencePage.BackgroundRepeatLabel=Repeat:
+BackgroundBoxPreferencePage.BackgroundAttachmentLabel=Attachment:
+BackgroundBoxPreferencePage.HorizontalLabel=Horizontal position:
+BackgroundBoxPreferencePage.VerticalLabel=Vertical position:
+
+BlockPreferenceNode.LabelText=Block
+BlockPreferencePage.Title=Block
+BlockPreferencePage.WordSpacing=Word spacing:
+BlockPreferencePage.LetterSpacing=Letter spacing:
+BlockPreferencePage.VerticalAlign=Vertical align:
+BlockPreferencePage.TextAlign=Text align:
+BlockPreferencePage.TextIndent=Text indent:
+BlockPreferencePage.WhiteSpace=White space:
+BlockPreferencePage.Display=Display:
+
+BoxPreferenceNode.LabelText=Box
+BoxPreferencePage.Title=Box
+BoxPreferencePage.Width=Width:
+BoxPreferencePage.Clear=Clear:
+BoxPreferencePage.Height=Height:
+BoxPreferencePage.Padding=Padding
+BoxPreferencePage.Margin=Margin
+BoxPreferencePage.Top=Top:
+BoxPreferencePage.Right=Right:
+BoxPreferencePage.Bottom=Bottom:
+BoxPreferencePage.Left=Left:
+
+BorderPreferenceNode.LabelText=Border
+BorderPreferencePage.Title=Border
+BorderPreferencePage.Style=Style
+BorderPreferencePage.Width=Width
+BorderPreferencePage.Color=Color
+BorderPreferencePage.Top=Top:
+BorderPreferencePage.Right=Right:
+BorderPreferencePage.Bottom=Bottom:
+BorderPreferencePage.Left=Left:
+
+ListPreferenceNode.LabelText=List
+ListPreferencePage.Title=List
+ListPreferencePage.Type=Type:
+ListPreferencePage.Image=Bullet image:
+ListPreferencePage.Position=Position:
+
+PositioningPreferenceNode.LabelText=Positioning
+PositioningPreferencePage.Title=Positioning
+PositioningPreferencePage.Type=Type:
+PositioningPreferencePage.Visibility=Visibility:
+PositioningPreferencePage.Width=Width:
+PositioningPreferencePage.ZIndex=Z-Index:
+PositioningPreferencePage.Height=Height:
+PositioningPreferencePage.Overflow=Overflow:
+PositioningPreferencePage.Placement=Placement
+PositioningPreferencePage.Clip=Clip
+PositioningPreferencePage.Right=Right:
+PositioningPreferencePage.Bottom=Bottom:
+PositioningPreferencePage.Left=Left:
+
+ExtensionsPreferenceNode.LabelText=Extensions
+ExtensionsPreferencePage.Title=Extensions
+ExtensionsPreferencePage.PageBreak=Page break
+ExtensionsPreferencePage.Before=Before:
+ExtensionsPreferencePage.After=After:
+ExtensionsPreferencePage.VisualEffect=Visual effect
+ExtensionsPreferencePage.Cursor=Cursor:
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferenceNode.java
new file mode 100644
index 000000000..1b3c5509b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferenceNode.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ExtensionsPreferenceNode implements IPreferenceNode {
+ private ExtensionsPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _style;
+
+ public ExtensionsPreferenceNode(IDOMElement element,
+ CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new ExtensionsPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Extensions";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("ExtensionsPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferencePage.java
new file mode 100644
index 000000000..73bf4e4eb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ExtensionsPreferencePage.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ExtensionsPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _beforeCombo, _afterCombo, _cursorCombo;
+
+ public ExtensionsPreferencePage(IDOMElement element,
+ CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("ExtensionsPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(1, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Group pageGroup = new Group(top, SWT.NONE);
+ pageGroup.setText(DialogsMessages
+ .getString("ExtensionsPreferencePage.PageBreak"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ pageGroup.setLayoutData(data);
+ layout = new GridLayout(2, false);
+ pageGroup.setLayout(layout);
+
+ Label beforeLabel = new Label(pageGroup, SWT.NONE);
+ beforeLabel.setText(DialogsMessages
+ .getString("ExtensionsPreferencePage.Before")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ beforeLabel.setLayoutData(data);
+
+ _beforeCombo = new StyleCombo(pageGroup, SWT.NONE);
+ _beforeCombo.setItems(IStyleConstants.PAGE_BREAK);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _beforeCombo.setLayoutData(data);
+ _beforeCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String page = _beforeCombo.getText();
+ _style.setPageBreakBefore(page);
+ }
+ });
+
+ Label afterLabel = new Label(pageGroup, SWT.NONE);
+ afterLabel.setText(DialogsMessages
+ .getString("ExtensionsPreferencePage.After")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ afterLabel.setLayoutData(data);
+
+ _afterCombo = new StyleCombo(pageGroup, SWT.NONE);
+ _afterCombo.setItems(IStyleConstants.PAGE_BREAK);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _afterCombo.setLayoutData(data);
+ _afterCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String page = _afterCombo.getText();
+ _style.setPageBreakAfter(page);
+ }
+ });
+
+ Group visualGroup = new Group(top, SWT.NONE);
+ visualGroup.setText(DialogsMessages
+ .getString("ExtensionsPreferencePage.VisualEffect"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ visualGroup.setLayoutData(data);
+ layout = new GridLayout(2, false);
+ visualGroup.setLayout(layout);
+
+ Label cursorLabel = new Label(visualGroup, SWT.NONE);
+ cursorLabel.setText(DialogsMessages
+ .getString("ExtensionsPreferencePage.Cursor")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ cursorLabel.setLayoutData(data);
+
+ _cursorCombo = new StyleCombo(visualGroup, SWT.NONE);
+ _cursorCombo.setItems(IStyleConstants.CURSOR);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _cursorCombo.setLayoutData(data);
+ _cursorCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String position = _cursorCombo.getText();
+ _style.setListStylePosition(position);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // page-break-before
+ String page = _style.getPageBreakBefore();
+ if (!isEmptyString(page)) {
+ int index = _beforeCombo.indexOf(page);
+ if (index != -1) {
+ _beforeCombo.select(index);
+ } else {
+ _beforeCombo.setText(page);
+ }
+ }
+
+ // page-break-after
+ page = _style.getPageBreakAfter();
+ if (!isEmptyString(page)) {
+ int index = _afterCombo.indexOf(page);
+ if (index != -1) {
+ _afterCombo.select(index);
+ } else {
+ _afterCombo.setText(page);
+ }
+ }
+
+ // cursor
+ String cursor = _style.getCursor();
+ if (!isEmptyString(cursor)) {
+ int index = _cursorCombo.indexOf(cursor);
+ if (index != -1) {
+ _cursorCombo.select(index);
+ } else {
+ _cursorCombo.setText(cursor);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/IStyleConstants.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/IStyleConstants.java
new file mode 100644
index 000000000..9c0952a03
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/IStyleConstants.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public interface IStyleConstants {
+ final public static String[] ATTACHMENT = { "fixed", "scroll" };
+
+ final public static String[] AUTO = { "auto" };
+
+ final public static String[] BORDER_STYLE = { "none", "dotted", "dashed",
+ "solid", "double", "groove", "ridge", "inset", "outset" };
+
+ final public static String[] BORDER_WIDTH = { "thin", "medium", "thick" };
+
+ final public static String[] CLEAR = { "left", "right", "both", "none" };
+
+ final public static String[] COLOR = { "black", "blue", "gray", "green",
+ "orange", "red", "white", "yellow", "aqua", "fuchsia", "lime",
+ "maroon", "navy", "olive", "purple", "silver", "teal" };
+
+ final public static String[] DISPLAY = { "none", "inline", "block",
+ "list-item", "run-in", "compact", "marker", "table",
+ "inline-table", "table-row-group", "table-header-group",
+ "table-footer-group", "table-row", "table-column-group",
+ "table-column", "table-cell", "table-caption" };
+
+ final public static String[] FLOAT = { "left", "right", "none" };
+
+ final public static String[] FONT_FAMILY = { "Verdana, Arial, Sans-Serif",
+ "Tahoma, Verdana, Arial, Sans-Serif", "\"Times New Roman\", Serif",
+ "Georgia, \"Times New Roman\", Serif",
+ "\"Book Antiqua\", \"Times New Roman\", Serif",
+ "\"Comic Sans MS\", Sans-Serif", "\"Courier New\", Courier",
+ "\"Trebuchet MS\", Sans-Serif" };
+
+ final public static String[] FONT_SIZE_NUMBER = { "9", "10", "12", "14",
+ "16", "18", "24", "36", "xx-small", "x-small", "small", "medium",
+ "large", "x-large", "xx-large", "smaller", "larger" };
+
+ final public static String[] FONT_STYLE = { "normal", "italic", "oblique" };
+
+ final public static String[] FONT_TEXTTRANSFORM = { "capitalize",
+ "uppercase", "lowercase", "none" };
+
+ final public static String[] FONT_VARIANT = { "normal", "small-caps" };
+
+ final public static String[] FONT_WEIGHT = { "normal", "bold", "bolder",
+ "lighter", "100", "200", "300", "400", "500", "600", "700", "800",
+ "900" };
+
+ final public static String[] LIST_POSITION = { "inside", "outside" };
+
+ final public static String[] LIST_TYPE = { "disc", "circle", "sqaure",
+ "decimal", "lower-roman", "upper-roman", "lower-alpha",
+ "upper-alpah", "none" };
+
+ final public static String[] NONE = { "none" };
+
+ final public static String[] NORMAL = { "normal" };
+
+ final public static String[] PERCENT = { "%" };
+
+ final public static String[] POSITION = { "left", "center", "right" };
+
+ final public static String[] POSITIONING_TYPE = { "absolute", "relative",
+ "static" };
+
+ final public static String[] REPEAT = { "no-repeat", "repeat", "repeat-x",
+ "repeat-y" };
+
+ final public static String[] SIZE_UNIT = { "px", "pt", "in", "cm", "mm",
+ "pc", "em", "ex", "%" };
+
+ final public static String[] TEXT_ALIGN = { "left", "right", "center",
+ "justify" };
+
+ final public static String[] TEXT_DECORATION = { "underline", "overline",
+ "line-through", "blink", "none" };
+
+ final public static String[] VERTICAL_ALIGN = { "baseline", "sub", "super",
+ "top", "text-top", "middle", "bottom", "text-bottom" };
+
+ final public static String[] WHITE_SPACE = { "normal", "pre", "nowrap" };
+
+ final public static String[] VISIBILITY = { "inherit", "visible", "hidden" };
+
+ final public static String[] OVERFLOW = { "visible", "hidden", "scroll",
+ "auto" };
+
+ final public static String[] PAGE_BREAK = { "auto", "always", "left",
+ "right" };
+
+ final public static String[] CURSOR = { "hand", "crosshair", "text",
+ "wait", "default", "help", "e-resize", "ne-resize", "n-resize",
+ "nw-resize", "w-resize", "sw-resize", "s-resize", "se-resize",
+ "auto" };
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferenceNode.java
new file mode 100644
index 000000000..4b8859fc6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferenceNode.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ListPreferenceNode implements IPreferenceNode {
+ private ListPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _style;
+
+ public ListPreferenceNode(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new ListPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "List";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("ListPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferencePage.java
new file mode 100644
index 000000000..9192e59f4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/ListPreferencePage.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ListPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _typeCombo, _imageCombo, _positionCombo;
+
+ public ListPreferencePage(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("ListPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(2, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Label typeLabel = new Label(top, SWT.NONE);
+ typeLabel.setText(DialogsMessages.getString("ListPreferencePage.Type")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ typeLabel.setLayoutData(data);
+
+ _typeCombo = new StyleCombo(top, SWT.NONE);
+ _typeCombo.setItems(IStyleConstants.LIST_TYPE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _typeCombo.setLayoutData(data);
+ _typeCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String type = _typeCombo.getText();
+ _style.setListStyleType(type);
+ }
+ });
+
+ Label imageLabel = new Label(top, SWT.NONE);
+ imageLabel.setText(DialogsMessages
+ .getString("ListPreferencePage.Image")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ imageLabel.setLayoutData(data);
+
+ _imageCombo = new StyleCombo(top, SWT.NONE);
+ _imageCombo.setItems(IStyleConstants.NONE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _imageCombo.setLayoutData(data);
+ _imageCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String image = _imageCombo.getText();
+ _style.setListStyleImage(image);
+ }
+ });
+
+ Label positionLabel = new Label(top, SWT.NONE);
+ positionLabel.setText(DialogsMessages
+ .getString("ListPreferencePage.Position")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ positionLabel.setLayoutData(data);
+
+ _positionCombo = new StyleCombo(top, SWT.NONE);
+ _positionCombo.setItems(IStyleConstants.LIST_POSITION);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _positionCombo.setLayoutData(data);
+ _positionCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String position = _positionCombo.getText();
+ _style.setListStylePosition(position);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // list-style-tyle
+ String type = _style.getListStyleType();
+ if (!isEmptyString(type)) {
+ int index = _typeCombo.indexOf(type);
+ if (index != -1) {
+ _typeCombo.select(index);
+ } else {
+ _typeCombo.setText(type);
+ }
+ }
+
+ // list-style-image
+ String image = _style.getListStyleImage();
+ if (!isEmptyString(image)) {
+ int index = _imageCombo.indexOf(image);
+ if (index != -1) {
+ _imageCombo.select(index);
+ } else {
+ _imageCombo.setText(image);
+ }
+ }
+
+ // list-style-position
+ String position = _style.getListStylePosition();
+ if (!isEmptyString(position)) {
+ int index = _positionCombo.indexOf(position);
+ if (index != -1) {
+ _positionCombo.select(index);
+ } else {
+ _positionCombo.setText(position);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferenceNode.java
new file mode 100644
index 000000000..d5641831a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferenceNode.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PositioningPreferenceNode implements IPreferenceNode {
+ private PositioningPreferencePage _page;
+
+ private IDOMElement _element;
+
+ private CSSPropertyContext _style;
+
+ public PositioningPreferenceNode(IDOMElement element,
+ CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new PositioningPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Positioning";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("PositioningPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferencePage.java
new file mode 100644
index 000000000..703c25055
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/PositioningPreferencePage.java
@@ -0,0 +1,779 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class PositioningPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private Combo _typeCombo, _visibilityCombo, _widthNumberCombo,
+ _widthUnitCombo, _zIndexCombo, _heightNumberCombo,
+ _heightUnitCombo, _overflowCombo;
+
+ private Combo _placementTopNumberCombo, _placementRightNumberCombo,
+ _placementBottomNumberCombo, _placementLeftNumberCombo;
+
+ private Combo _placementTopUnitCombo, _placementRightUnitCombo,
+ _placementBottomUnitCombo, _placementLeftUnitCombo;
+
+ private Combo _clipTopNumberCombo, _clipRightNumberCombo,
+ _clipBottomNumberCombo, _clipLeftNumberCombo;
+
+ private Combo _clipTopUnitCombo, _clipRightUnitCombo, _clipBottomUnitCombo,
+ _clipLeftUnitCombo;
+
+ public PositioningPreferencePage(IDOMElement element,
+ CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ setTitle(DialogsMessages.getString("PositioningPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(6, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Label typeLabel = new Label(top, SWT.NONE);
+ typeLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Type")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ typeLabel.setLayoutData(data);
+
+ _typeCombo = new Combo(top, SWT.NONE);
+ _typeCombo.setItems(IStyleConstants.POSITIONING_TYPE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 2;
+ _typeCombo.setLayoutData(data);
+ _typeCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String type = _typeCombo.getText();
+ _style.setPosition(type);
+ }
+ });
+
+ Label visibilityLabel = new Label(top, SWT.NONE);
+ visibilityLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Visibility")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ visibilityLabel.setLayoutData(data);
+
+ _visibilityCombo = new Combo(top, SWT.NONE);
+ _visibilityCombo.setItems(IStyleConstants.VISIBILITY);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _visibilityCombo.setLayoutData(data);
+ _visibilityCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String visibility = _visibilityCombo.getText();
+ _style.setVisibility(visibility);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label widthLabel = new Label(top, SWT.NONE);
+ widthLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Width")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ widthLabel.setLayoutData(data);
+
+ _widthNumberCombo = new Combo(top, SWT.NONE);
+ _widthNumberCombo.setItems(IStyleConstants.LIST_POSITION);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthNumberCombo.setLayoutData(data);
+ _widthNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _widthUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_widthNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _widthUnitCombo.setEnabled(false);
+ }
+
+ String width = _widthNumberCombo.getText();
+ if (_widthUnitCombo.isEnabled()) {
+ width += _widthUnitCombo.getText();
+ }
+
+ _style.setWidth(width);
+ }
+ });
+
+ _widthUnitCombo = new Combo(top, SWT.READ_ONLY);
+ _widthUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _widthUnitCombo.setLayoutData(data);
+ _widthUnitCombo.select(0);
+ _widthUnitCombo.setEnabled(false);
+ _widthUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String width = _widthNumberCombo.getText();
+ if (_widthUnitCombo.isEnabled()) {
+ width += _widthUnitCombo.getText();
+ }
+
+ _style.setWidth(width);
+ }
+ });
+
+ Label zIndexLabel = new Label(top, SWT.NONE);
+ zIndexLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.ZIndex")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ zIndexLabel.setLayoutData(data);
+
+ _zIndexCombo = new Combo(top, SWT.NONE);
+ _zIndexCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _zIndexCombo.setLayoutData(data);
+ _zIndexCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String index = _zIndexCombo.getText();
+ _style.setZIndex(index);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label heightLabel = new Label(top, SWT.NONE);
+ heightLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Height")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ heightLabel.setLayoutData(data);
+
+ _heightNumberCombo = new Combo(top, SWT.NONE);
+ _heightNumberCombo.setItems(IStyleConstants.LIST_POSITION);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _heightNumberCombo.setLayoutData(data);
+ _heightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _heightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_heightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _heightUnitCombo.setEnabled(false);
+ }
+
+ String height = _heightNumberCombo.getText();
+ if (_heightUnitCombo.isEnabled()) {
+ height += _heightUnitCombo.getText();
+ }
+
+ _style.setHeight(height);
+ }
+ });
+
+ _heightUnitCombo = new Combo(top, SWT.READ_ONLY);
+ _heightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _heightUnitCombo.setLayoutData(data);
+ _heightUnitCombo.select(0);
+ _heightUnitCombo.setEnabled(false);
+ _heightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String height = _heightNumberCombo.getText();
+ if (_heightUnitCombo.isEnabled()) {
+ height += _heightUnitCombo.getText();
+ }
+
+ _style.setHeight(height);
+ }
+ });
+
+ Label overflowLabel = new Label(top, SWT.NONE);
+ overflowLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Overflow")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ overflowLabel.setLayoutData(data);
+
+ _overflowCombo = new Combo(top, SWT.NONE);
+ _overflowCombo.setItems(IStyleConstants.OVERFLOW);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _overflowCombo.setLayoutData(data);
+ _overflowCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String overflow = _overflowCombo.getText();
+ _style.setOverflow(overflow);
+ }
+ });
+
+ Group placementGroup = new Group(top, SWT.NONE);
+ placementGroup.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Placement"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 3;
+ data.verticalSpan = 4;
+ placementGroup.setLayoutData(data);
+ layout = new GridLayout(3, false);
+ placementGroup.setLayout(layout);
+
+ Label placementTopLabel = new Label(placementGroup, SWT.NONE);
+ placementTopLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Top")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ placementTopLabel.setLayoutData(data);
+
+ _placementTopNumberCombo = new Combo(placementGroup, SWT.NONE);
+ _placementTopNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementTopNumberCombo.setLayoutData(data);
+ _placementTopNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _placementTopUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_placementTopNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _placementTopUnitCombo.setEnabled(false);
+ }
+
+ String placement = _placementTopNumberCombo.getText();
+ if (_placementTopUnitCombo.isEnabled()) {
+ placement += _placementTopUnitCombo.getText();
+ }
+
+ _style.setTop(placement);
+ }
+ });
+
+ _placementTopUnitCombo = new Combo(placementGroup, SWT.READ_ONLY);
+ _placementTopUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementTopUnitCombo.setLayoutData(data);
+ _placementTopUnitCombo.select(0);
+ _placementTopUnitCombo.setEnabled(false);
+ _placementTopUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String placement = _placementTopNumberCombo.getText();
+ if (_placementTopUnitCombo.isEnabled()) {
+ placement += _placementTopUnitCombo.getText();
+ }
+
+ _style.setTop(placement);
+ }
+ });
+
+ Label placementRightLabel = new Label(placementGroup, SWT.NONE);
+ placementRightLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Right")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ placementRightLabel.setLayoutData(data);
+
+ _placementRightNumberCombo = new Combo(placementGroup, SWT.NONE);
+ _placementRightNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementRightNumberCombo.setLayoutData(data);
+ _placementRightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _placementRightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_placementRightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _placementRightUnitCombo.setEnabled(false);
+ }
+
+ String placement = _placementRightNumberCombo.getText();
+ if (_placementRightUnitCombo.isEnabled()) {
+ placement += _placementRightUnitCombo.getText();
+ }
+
+ _style.setRight(placement);
+ }
+ });
+
+ _placementRightUnitCombo = new Combo(placementGroup, SWT.READ_ONLY);
+ _placementRightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementRightUnitCombo.setLayoutData(data);
+ _placementRightUnitCombo.select(0);
+ _placementRightUnitCombo.setEnabled(false);
+ _placementRightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String placement = _placementRightNumberCombo.getText();
+ if (_placementRightUnitCombo.isEnabled()) {
+ placement += _placementRightUnitCombo.getText();
+ }
+
+ _style.setRight(placement);
+ }
+ });
+
+ Label placementBottomLabel = new Label(placementGroup, SWT.NONE);
+ placementBottomLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Bottom")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ placementBottomLabel.setLayoutData(data);
+
+ _placementBottomNumberCombo = new Combo(placementGroup, SWT.NONE);
+ _placementBottomNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementBottomNumberCombo.setLayoutData(data);
+ _placementBottomNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _placementBottomUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_placementBottomNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _placementBottomUnitCombo.setEnabled(false);
+ }
+
+ String placement = _placementBottomNumberCombo.getText();
+ if (_placementBottomUnitCombo.isEnabled()) {
+ placement += _placementBottomUnitCombo.getText();
+ }
+
+ _style.setBottom(placement);
+ }
+ });
+
+ _placementBottomUnitCombo = new Combo(placementGroup, SWT.READ_ONLY);
+ _placementBottomUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementBottomUnitCombo.setLayoutData(data);
+ _placementBottomUnitCombo.select(0);
+ _placementBottomUnitCombo.setEnabled(false);
+ _placementBottomUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String placement = _placementBottomNumberCombo.getText();
+ if (_placementBottomUnitCombo.isEnabled()) {
+ placement += _placementBottomUnitCombo.getText();
+ }
+
+ _style.setBottom(placement);
+ }
+ });
+
+ Label placementLeftLabel = new Label(placementGroup, SWT.NONE);
+ placementLeftLabel.setText(DialogsMessages
+ .getString("BoxPreferencePage.Left")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ placementLeftLabel.setLayoutData(data);
+
+ _placementLeftNumberCombo = new Combo(placementGroup, SWT.NONE);
+ _placementLeftNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementLeftNumberCombo.setLayoutData(data);
+ _placementLeftNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _placementLeftUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_placementLeftNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _placementLeftUnitCombo.setEnabled(false);
+ }
+
+ String top = _placementLeftNumberCombo.getText();
+ if (_placementLeftUnitCombo.isEnabled()) {
+ top += _placementLeftUnitCombo.getText();
+ }
+
+ _style.setLeft(top);
+ }
+ });
+
+ _placementLeftUnitCombo = new Combo(placementGroup, SWT.READ_ONLY);
+ _placementLeftUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _placementLeftUnitCombo.setLayoutData(data);
+ _placementLeftUnitCombo.select(0);
+ _placementLeftUnitCombo.setEnabled(false);
+ _placementLeftUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String top = _placementLeftNumberCombo.getText();
+ if (_placementLeftUnitCombo.isEnabled()) {
+ top += _placementLeftUnitCombo.getText();
+ }
+
+ _style.setLeft(top);
+ }
+ });
+
+ Group clipGroup = new Group(top, SWT.NONE);
+ clipGroup.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Clip"));
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 3;
+ data.verticalSpan = 4;
+ clipGroup.setLayoutData(data);
+ layout = new GridLayout(3, false);
+ clipGroup.setLayout(layout);
+
+ Label clipTopLabel = new Label(clipGroup, SWT.NONE);
+ clipTopLabel
+ .setText(DialogsMessages.getString("BoxPreferencePage.Top")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ clipTopLabel.setLayoutData(data);
+
+ _clipTopNumberCombo = new Combo(clipGroup, SWT.NONE);
+ _clipTopNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipTopNumberCombo.setLayoutData(data);
+ _clipTopNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _clipTopUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_clipTopNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _clipTopUnitCombo.setEnabled(false);
+ }
+
+ String clip = _clipTopNumberCombo.getText();
+ if (_clipTopUnitCombo.isEnabled()) {
+ clip += _clipTopUnitCombo.getText();
+ }
+
+ _style.setClipTop(clip);
+ }
+ });
+
+ _clipTopUnitCombo = new Combo(clipGroup, SWT.READ_ONLY);
+ _clipTopUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipTopUnitCombo.setLayoutData(data);
+ _clipTopUnitCombo.select(0);
+ _clipTopUnitCombo.setEnabled(false);
+ _clipTopUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String clip = _clipTopNumberCombo.getText();
+ if (_clipTopUnitCombo.isEnabled()) {
+ clip += _clipTopUnitCombo.getText();
+ }
+
+ _style.setClipTop(clip);
+ }
+ });
+
+ Label clipRightLabel = new Label(clipGroup, SWT.NONE);
+ clipRightLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Right")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ clipRightLabel.setLayoutData(data);
+
+ _clipRightNumberCombo = new Combo(clipGroup, SWT.NONE);
+ _clipRightNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipRightNumberCombo.setLayoutData(data);
+ _clipRightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _clipRightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_clipRightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _clipRightUnitCombo.setEnabled(false);
+ }
+
+ String clip = _clipRightNumberCombo.getText();
+ if (_clipRightUnitCombo.isEnabled()) {
+ clip += _clipRightUnitCombo.getText();
+ }
+
+ _style.setClipRight(clip);
+ }
+ });
+
+ _clipRightUnitCombo = new Combo(clipGroup, SWT.READ_ONLY);
+ _clipRightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipRightUnitCombo.setLayoutData(data);
+ _clipRightUnitCombo.select(0);
+ _clipRightUnitCombo.setEnabled(false);
+ _clipRightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String clip = _clipRightNumberCombo.getText();
+ if (_clipRightUnitCombo.isEnabled()) {
+ clip += _clipRightUnitCombo.getText();
+ }
+
+ _style.setClipRight(clip);
+ }
+ });
+
+ Label clipBottomLabel = new Label(clipGroup, SWT.NONE);
+ clipBottomLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Bottom")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ clipBottomLabel.setLayoutData(data);
+
+ _clipBottomNumberCombo = new Combo(clipGroup, SWT.NONE);
+ _clipBottomNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipBottomNumberCombo.setLayoutData(data);
+ _clipBottomNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _clipBottomUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_clipBottomNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _clipBottomUnitCombo.setEnabled(false);
+ }
+
+ String clip = _clipBottomNumberCombo.getText();
+ if (_clipBottomUnitCombo.isEnabled()) {
+ clip += _clipBottomUnitCombo.getText();
+ }
+
+ _style.setClipBottom(clip);
+ }
+ });
+
+ _clipBottomUnitCombo = new Combo(clipGroup, SWT.READ_ONLY);
+ _clipBottomUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipBottomUnitCombo.setLayoutData(data);
+ _clipBottomUnitCombo.select(0);
+ _clipBottomUnitCombo.setEnabled(false);
+ _clipBottomUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String clip = _clipBottomNumberCombo.getText();
+ if (_clipBottomUnitCombo.isEnabled()) {
+ clip += _clipBottomUnitCombo.getText();
+ }
+
+ _style.setClipBottom(clip);
+ }
+ });
+
+ Label clipLeftLabel = new Label(clipGroup, SWT.NONE);
+ clipLeftLabel.setText(DialogsMessages
+ .getString("PositioningPreferencePage.Left")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ clipLeftLabel.setLayoutData(data);
+
+ _clipLeftNumberCombo = new Combo(clipGroup, SWT.NONE);
+ _clipLeftNumberCombo.setItems(IStyleConstants.AUTO);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipLeftNumberCombo.setLayoutData(data);
+ _clipLeftNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _clipLeftUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_clipLeftNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _clipLeftUnitCombo.setEnabled(false);
+ }
+
+ String top = _clipLeftNumberCombo.getText();
+ if (_clipLeftUnitCombo.isEnabled()) {
+ top += _clipLeftUnitCombo.getText();
+ }
+
+ _style.setClipLeft(top);
+ }
+ });
+
+ _clipLeftUnitCombo = new Combo(clipGroup, SWT.READ_ONLY);
+ _clipLeftUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _clipLeftUnitCombo.setLayoutData(data);
+ _clipLeftUnitCombo.select(0);
+ _clipLeftUnitCombo.setEnabled(false);
+ _clipLeftUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String top = _clipLeftNumberCombo.getText();
+ if (_clipLeftUnitCombo.isEnabled()) {
+ top += _clipLeftUnitCombo.getText();
+ }
+
+ _style.setClipLeft(top);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // position
+ String position = _style.getPosition();
+ if (!isEmptyString(position)) {
+ int index = _typeCombo.indexOf(position);
+ if (index != -1) {
+ _typeCombo.select(index);
+ } else {
+ _typeCombo.setText(position);
+ }
+ }
+
+ // visibility
+ String visibility = _style.getVisibility();
+ if (!isEmptyString(visibility)) {
+ int index = _visibilityCombo.indexOf(visibility);
+ if (index != -1) {
+ _visibilityCombo.select(index);
+ } else {
+ _visibilityCombo.setText(visibility);
+ }
+ }
+
+ // width
+ String width = _style.getWidth();
+ if (!isEmptyString(width)) {
+ int index = _widthNumberCombo.indexOf(width);
+ if (index != -1) {
+ _widthNumberCombo.select(index);
+ } else {
+ _widthNumberCombo.setText(width);
+ }
+ }
+
+ // z-index
+ String zindex = _style.getZIndex();
+ if (!isEmptyString(zindex)) {
+ int index = _zIndexCombo.indexOf(zindex);
+ if (index != -1) {
+ _zIndexCombo.select(index);
+ } else {
+ _zIndexCombo.setText(zindex);
+ }
+ }
+
+ // height
+ String height = _style.getHeight();
+ if (!isEmptyString(height)) {
+ int index = _heightNumberCombo.indexOf(height);
+ if (index != -1) {
+ _heightNumberCombo.select(index);
+ } else {
+ _heightNumberCombo.setText(height);
+ }
+ }
+
+ // overflow
+ String overflow = _style.getOverflow();
+ if (!isEmptyString(overflow)) {
+ int index = _overflowCombo.indexOf(overflow);
+ if (index != -1) {
+ _overflowCombo.select(index);
+ } else {
+ _overflowCombo.setText(overflow);
+ }
+ }
+
+ // placement
+ String placement = _style.getTop();
+ if (!isEmptyString(placement)) {
+ int index = _placementTopNumberCombo.indexOf(placement);
+ if (index != -1) {
+ _placementTopNumberCombo.select(index);
+ } else {
+ _placementTopNumberCombo.setText(placement);
+ }
+ }
+ placement = _style.getRight();
+ if (!isEmptyString(placement)) {
+ int index = _placementRightNumberCombo.indexOf(placement);
+ if (index != -1) {
+ _placementRightNumberCombo.select(index);
+ } else {
+ _placementRightNumberCombo.setText(placement);
+ }
+ }
+ placement = _style.getBottom();
+ if (!isEmptyString(placement)) {
+ int index = _placementBottomNumberCombo.indexOf(placement);
+ if (index != -1) {
+ _placementBottomNumberCombo.select(index);
+ } else {
+ _placementBottomNumberCombo.setText(placement);
+ }
+ }
+ placement = _style.getLeft();
+ if (!isEmptyString(placement)) {
+ int index = _placementLeftNumberCombo.indexOf(placement);
+ if (index != -1) {
+ _placementLeftNumberCombo.select(index);
+ } else {
+ _placementLeftNumberCombo.setText(placement);
+ }
+ }
+
+ // clip
+ String clip = _style.getClipTop();
+ if (!isEmptyString(clip)) {
+ int index = _clipTopNumberCombo.indexOf(clip);
+ if (index != -1) {
+ _clipTopNumberCombo.select(index);
+ } else {
+ _clipTopNumberCombo.setText(clip);
+ }
+ }
+ clip = _style.getClipRight();
+ if (!isEmptyString(clip)) {
+ int index = _clipRightNumberCombo.indexOf(clip);
+ if (index != -1) {
+ _clipRightNumberCombo.select(index);
+ } else {
+ _clipRightNumberCombo.setText(clip);
+ }
+ }
+ clip = _style.getClipBottom();
+ if (!isEmptyString(clip)) {
+ int index = _clipBottomNumberCombo.indexOf(clip);
+ if (index != -1) {
+ _clipBottomNumberCombo.select(index);
+ } else {
+ _clipBottomNumberCombo.setText(clip);
+ }
+ }
+ clip = _style.getClipLeft();
+ if (!isEmptyString(clip)) {
+ int index = _clipLeftNumberCombo.indexOf(clip);
+ if (index != -1) {
+ _clipLeftNumberCombo.select(index);
+ } else {
+ _clipLeftNumberCombo.setText(clip);
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleCombo.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleCombo.java
new file mode 100644
index 000000000..6e1efb31a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleCombo.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class StyleCombo extends Combo {
+
+ /**
+ * @param parent
+ * @param style
+ */
+ public StyleCombo(Composite parent, int style) {
+ super(parent, style);
+ this.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ Combo combo = (Combo) e.widget;
+ combo.setSelection(new Point(0, 0));
+ }
+ });
+ }
+
+ protected void checkSubclass() {
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleDialog.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleDialog.java
new file mode 100644
index 000000000..8ad3b9b2d
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/StyleDialog.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class StyleDialog extends PreferenceDialog {
+ /**
+ * @param parentShell
+ * @param manager
+ */
+ public StyleDialog(Shell parentShell, PreferenceManager manager,
+ IDOMElement element, CSSPropertyContext style) {
+ super(parentShell, manager);
+ manager.addToRoot(new TextPreferenceNode(element, style));
+ manager.addToRoot(new BackgroudPreferenceNode(element, style));
+ manager.addToRoot(new BlockPreferenceNode(element, style));
+ manager.addToRoot(new BoxPreferenceNode(element, style));
+ manager.addToRoot(new BorderPreferenceNode(element, style));
+ manager.addToRoot(new ListPreferenceNode(element, style));
+ manager.addToRoot(new PositioningPreferenceNode(element, style));
+ manager.addToRoot(new ExtensionsPreferenceNode(element, style));
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Control control = super.createDialogArea(parent);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(control,
+ PDPlugin.getResourceString("StyleDialog.help.id"));
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(
+ getTreeViewer().getControl(),
+ PDPlugin.getResourceString("StyleDialog.help.id"));
+ return control;
+ }
+
+ protected void update() {
+ super.update();
+ getShell().setText(DialogsMessages.getString("StyleDialog.Title"));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferenceNode.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferenceNode.java
new file mode 100644
index 000000000..5c6ca8888
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferenceNode.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TextPreferenceNode implements IPreferenceNode {
+ private TextPreferencePage _page;
+
+ private CSSPropertyContext _style;
+
+ private IDOMElement _element;
+
+ public TextPreferenceNode(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _element = element;
+ _style = style;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#add(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public void add(IPreferenceNode node) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#createPage()
+ */
+ public void createPage() {
+ _page = new TextPreferencePage(_element, _style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#disposeResources()
+ */
+ public void disposeResources() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#findSubNode(java.lang.String)
+ */
+ public IPreferenceNode findSubNode(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getId()
+ */
+ public String getId() {
+ return "Text";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelImage()
+ */
+ public Image getLabelImage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getLabelText()
+ */
+ public String getLabelText() {
+ return DialogsMessages.getString("TextPreferenceNode.LabelText");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getPage()
+ */
+ public IPreferencePage getPage() {
+ return _page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#getSubNodes()
+ */
+ public IPreferenceNode[] getSubNodes() {
+ return new IPreferenceNode[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(java.lang.String)
+ */
+ public IPreferenceNode remove(String id) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.preference.IPreferenceNode#remove(org.eclipse.jface.preference.IPreferenceNode)
+ */
+ public boolean remove(IPreferenceNode node) {
+ return false;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferencePage.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferencePage.java
new file mode 100644
index 000000000..da9ff6b14
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/ui/dialogs/TextPreferencePage.java
@@ -0,0 +1,522 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.ui.dialogs;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jst.pagedesigner.common.dialogfield.ColorButtonDialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
+import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class TextPreferencePage extends PreferencePage {
+ private CSSPropertyContext _style;
+
+ private StyleCombo _fontFamilyCombo, _fontSizeNumberCombo,
+ _fontSizeUnitCombo, _fontWeightCombo, _fontStyleCombo,
+ _fontVariantCombo, _fontLineHeightNumberCombo,
+ _fontLineHeightUnitCombo, _textTransformCombo;
+
+ private ColorButtonDialogField _colorField;
+
+ private Button _textDecorationUnderlineButton,
+ _textDecorationOverlineButton, _textDecorationLineThroughButton,
+ _textDecorationBlinkButton, _textDecorationNoneButton;
+
+ public TextPreferencePage(IDOMElement element, CSSPropertyContext style) {
+ super();
+ _style = style;
+
+ // Set the preference store for the preference page.
+ // IPreferenceStore store =
+ // JMTIntegrationPlugin.getDefault().getPreferenceStore();
+ // setPreferenceStore(store);
+ setTitle(DialogsMessages.getString("TextPreferencePage.Title")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.
+ * PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ GridLayout layout;
+ GridData data;
+
+ Composite top = new Composite(parent, SWT.NONE);
+ layout = new GridLayout(5, false);
+ data = new GridData(GridData.FILL_BOTH);
+ top.setLayout(layout);
+ top.setLayoutData(data);
+
+ Label fontLabel = new Label(top, SWT.NONE);
+ fontLabel.setText(DialogsMessages.getString("TextPreferencePage.Font")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ fontLabel.setLayoutData(data);
+
+ _fontFamilyCombo = new StyleCombo(top, SWT.NONE);
+ _fontFamilyCombo.setItems(IStyleConstants.FONT_FAMILY);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 4;
+ _fontFamilyCombo.setLayoutData(data);
+ _fontFamilyCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _style.setFontFamily(_fontFamilyCombo.getText());
+ }
+ });
+
+ Label sizeLabel = new Label(top, SWT.NONE);
+ sizeLabel.setText(DialogsMessages.getString("TextPreferencePage.Size")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ sizeLabel.setLayoutData(data);
+
+ _fontSizeNumberCombo = new StyleCombo(top, SWT.NONE);
+ _fontSizeNumberCombo.setItems(IStyleConstants.FONT_SIZE_NUMBER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontSizeNumberCombo.setLayoutData(data);
+ _fontSizeNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _fontSizeUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_fontSizeNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _fontSizeUnitCombo.setEnabled(false);
+ }
+
+ String size = _fontSizeNumberCombo.getText();
+ if (_fontSizeUnitCombo.isEnabled()) {
+ size += _fontSizeUnitCombo.getText();
+ }
+
+ _style.setFontSize(size);
+ }
+ });
+
+ _fontSizeUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _fontSizeUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontSizeUnitCombo.setLayoutData(data);
+ _fontSizeUnitCombo.select(0);
+ _fontSizeUnitCombo.setEnabled(false);
+ _fontSizeUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String size = _fontSizeNumberCombo.getText();
+ if (_fontSizeUnitCombo.isEnabled()) {
+ size += _fontSizeUnitCombo.getText();
+ }
+
+ _style.setFontSize(size);
+ }
+ });
+
+ Label weightLabel = new Label(top, SWT.NONE);
+ weightLabel.setText(DialogsMessages
+ .getString("TextPreferencePage.Weight")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ weightLabel.setLayoutData(data);
+
+ _fontWeightCombo = new StyleCombo(top, SWT.NONE);
+ _fontWeightCombo.setItems(IStyleConstants.FONT_WEIGHT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontWeightCombo.setLayoutData(data);
+ _fontWeightCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String weight = _fontWeightCombo.getText();
+ _style.setFontWeight(weight);
+ }
+ });
+
+ Label stylesLabel = new Label(top, SWT.NONE);
+ stylesLabel.setText(DialogsMessages
+ .getString("TextPreferencePage.Style")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ stylesLabel.setLayoutData(data);
+
+ _fontStyleCombo = new StyleCombo(top, SWT.NONE);
+ _fontStyleCombo.setItems(IStyleConstants.FONT_STYLE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontStyleCombo.setLayoutData(data);
+ _fontStyleCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String style = _fontStyleCombo.getText();
+ _style.setFontStyle(style);
+ }
+ });
+
+ new Label(top, SWT.NONE);
+
+ Label variantLabel = new Label(top, SWT.NONE);
+ variantLabel.setText(DialogsMessages
+ .getString("TextPreferencePage.Variant")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ variantLabel.setLayoutData(data);
+
+ _fontVariantCombo = new StyleCombo(top, SWT.NONE);
+ _fontVariantCombo.setItems(IStyleConstants.FONT_VARIANT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontVariantCombo.setLayoutData(data);
+ _fontVariantCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String variant = _fontVariantCombo.getText();
+ _style.setFontVariant(variant);
+ }
+ });
+
+ Label lineHeightLabel = new Label(top, SWT.NONE);
+ lineHeightLabel.setText(DialogsMessages
+ .getString("TextPreferencePage.LineHeight")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ lineHeightLabel.setLayoutData(data);
+
+ _fontLineHeightNumberCombo = new StyleCombo(top, SWT.NONE);
+ _fontLineHeightNumberCombo.setItems(IStyleConstants.NORMAL);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontLineHeightNumberCombo.setLayoutData(data);
+ _fontLineHeightNumberCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ _fontLineHeightUnitCombo.setEnabled(true);
+ try {
+ Integer.valueOf(_fontLineHeightNumberCombo.getText());
+ } catch (NumberFormatException ex) {
+ _fontLineHeightUnitCombo.setEnabled(false);
+ }
+
+ String height = _fontLineHeightNumberCombo.getText();
+ if (_fontLineHeightUnitCombo.isEnabled()) {
+ height += _fontLineHeightUnitCombo.getText();
+ }
+
+ _style.setLineHeight(height);
+ }
+ });
+
+ _fontLineHeightUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
+ _fontLineHeightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _fontLineHeightUnitCombo.setLayoutData(data);
+ _fontLineHeightUnitCombo.select(0);
+ _fontLineHeightUnitCombo.setEnabled(false);
+ _fontLineHeightUnitCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String height = _fontLineHeightNumberCombo.getText();
+ if (_fontLineHeightUnitCombo.isEnabled()) {
+ height += _fontLineHeightUnitCombo.getText();
+ }
+
+ _style.setLineHeight(height);
+ }
+ });
+
+ Label caseLabel = new Label(top, SWT.NONE);
+ caseLabel.setText(DialogsMessages.getString("TextPreferencePage.Case")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ caseLabel.setLayoutData(data);
+
+ _textTransformCombo = new StyleCombo(top, SWT.NONE);
+ _textTransformCombo.setItems(IStyleConstants.FONT_TEXTTRANSFORM);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ _textTransformCombo.setLayoutData(data);
+ _textTransformCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String textTransform = _textTransformCombo.getText();
+ _style.setTextTransform(textTransform);
+ }
+ });
+
+ Label decorationLabel = new Label(top, SWT.NONE);
+ decorationLabel.setText(DialogsMessages
+ .getString("TextPreferencePage.Decoration")); //$NON-NLS-1$
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ decorationLabel.setLayoutData(data);
+
+ Composite decorationComposite = new Composite(top, SWT.NONE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 4;
+ decorationComposite.setLayoutData(data);
+ layout = new GridLayout(5, true);
+ layout.marginWidth = 0;
+ decorationComposite.setLayout(layout);
+
+ _textDecorationUnderlineButton = new Button(decorationComposite,
+ SWT.CHECK);
+ _textDecorationUnderlineButton
+ .setText(IStyleConstants.TEXT_DECORATION[0]);
+ _textDecorationUnderlineButton
+ .addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (_textDecorationUnderlineButton.getSelection()) {
+ _textDecorationNoneButton.setSelection(false);
+ }
+ _style.setTextDecoration(getTextDecoration());
+ }
+ });
+
+ _textDecorationOverlineButton = new Button(decorationComposite,
+ SWT.CHECK);
+ _textDecorationOverlineButton
+ .setText(IStyleConstants.TEXT_DECORATION[1]);
+ _textDecorationOverlineButton
+ .addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (_textDecorationOverlineButton.getSelection()) {
+ _textDecorationNoneButton.setSelection(false);
+ }
+ _style.setTextDecoration(getTextDecoration());
+ }
+ });
+
+ _textDecorationLineThroughButton = new Button(decorationComposite,
+ SWT.CHECK);
+ _textDecorationLineThroughButton
+ .setText(IStyleConstants.TEXT_DECORATION[2]);
+ _textDecorationLineThroughButton
+ .addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (_textDecorationLineThroughButton.getSelection()) {
+ _textDecorationNoneButton.setSelection(false);
+ }
+ _style.setTextDecoration(getTextDecoration());
+ }
+ });
+
+ _textDecorationBlinkButton = new Button(decorationComposite, SWT.CHECK);
+ _textDecorationBlinkButton.setText(IStyleConstants.TEXT_DECORATION[3]);
+ _textDecorationBlinkButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (_textDecorationBlinkButton.getSelection()) {
+ _textDecorationNoneButton.setSelection(false);
+ }
+ _style.setTextDecoration(getTextDecoration());
+ }
+ });
+
+ _textDecorationNoneButton = new Button(decorationComposite, SWT.CHECK);
+ _textDecorationNoneButton.setText(IStyleConstants.TEXT_DECORATION[4]);
+ _textDecorationNoneButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (_textDecorationNoneButton.getSelection()) {
+ _textDecorationUnderlineButton.setSelection(false);
+ _textDecorationOverlineButton.setSelection(false);
+ _textDecorationLineThroughButton.setSelection(false);
+ _textDecorationBlinkButton.setSelection(false);
+ }
+ _style.setTextDecoration(getTextDecoration());
+ }
+ });
+
+ _colorField = new ColorButtonDialogField(SWT.BORDER);
+ _colorField.setLabelText(DialogsMessages
+ .getString("TextPreferencePage.Color"));
+
+ data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ _colorField.getLabelControl(null, top).setLayoutData(data);
+
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = false;
+ _colorField.getComboControl(null, top).setLayoutData(data);
+
+ data = new GridData();
+ _colorField.getChangeControl(null, top).setLayoutData(data);
+ _colorField
+ .setDialogFieldApplyListener(new IDialogFieldApplyListener() {
+ public void dialogFieldApplied(DialogField field) {
+ String color = _colorField.getText();
+ _style.setColor(color);
+ }
+ });
+
+ initializeControls();
+
+ return top;
+ }
+
+ private void initializeControls() {
+ // font-family
+ String fontFamily = _style.getFontFamily();
+ if (!isEmptyString(fontFamily)) {
+ int index = _fontFamilyCombo.indexOf(fontFamily);
+ if (index != -1) {
+ _fontFamilyCombo.select(index);
+ } else {
+ _fontFamilyCombo.setText(fontFamily);
+ }
+ }
+
+ // font-size
+ String fontSize = _style.getFontSize();
+ if (!isEmptyString(fontSize)) {
+ int index = _fontSizeNumberCombo.indexOf(fontSize);
+ if (index != -1) {
+ _fontSizeNumberCombo.select(index);
+ } else {
+ _fontSizeNumberCombo.setText(fontSize);
+ }
+ }
+
+ // font-weight
+ String fontWeight = _style.getFontWeight();
+ if (!isEmptyString(fontWeight)) {
+ int index = _fontWeightCombo.indexOf(fontWeight);
+ if (index != -1) {
+ _fontWeightCombo.select(index);
+ } else {
+ _fontWeightCombo.setText(fontWeight);
+ }
+ }
+
+ // font-style
+ String fontStyle = _style.getFontStyle();
+ if (!isEmptyString(fontStyle)) {
+ int index = _fontStyleCombo.indexOf(fontStyle);
+ if (index != -1) {
+ _fontStyleCombo.select(index);
+ } else {
+ _fontStyleCombo.setText(fontStyle);
+ }
+ }
+
+ // font-variant
+ String fontVariant = _style.getFontVariant();
+ if (!isEmptyString(fontVariant)) {
+ int index = _fontVariantCombo.indexOf(fontVariant);
+ if (index != -1) {
+ _fontVariantCombo.select(index);
+ } else {
+ _fontVariantCombo.setText(fontVariant);
+ }
+ }
+
+ // line-height
+ String lineHeight = _style.getLineHeight();
+ if (!isEmptyString(lineHeight)) {
+ int index = _fontLineHeightNumberCombo.indexOf(lineHeight);
+ if (index != -1) {
+ _fontLineHeightNumberCombo.select(index);
+ } else {
+ _fontLineHeightNumberCombo.setText(lineHeight);
+ }
+ }
+
+ // text-transform
+ String textTransform = _style.getTextTransform();
+ if (!isEmptyString(textTransform)) {
+ int index = _textTransformCombo.indexOf(textTransform);
+ if (index != -1) {
+ _textTransformCombo.select(index);
+ } else {
+ _textTransformCombo.setText(textTransform);
+ }
+ }
+
+ // text-decoration
+ String textDecoration = _style.getTextDecoration();
+ if (!isEmptyString(textDecoration)) {
+ int index = textDecoration
+ .indexOf(IStyleConstants.TEXT_DECORATION[0]);
+ if (index != -1) {
+ _textDecorationUnderlineButton.setSelection(true);
+ } else {
+ _textDecorationUnderlineButton.setSelection(false);
+ }
+
+ index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[1]);
+ if (index != -1) {
+ _textDecorationOverlineButton.setSelection(true);
+ } else {
+ _textDecorationOverlineButton.setSelection(false);
+ }
+
+ index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[2]);
+ if (index != -1) {
+ _textDecorationLineThroughButton.setSelection(true);
+ } else {
+ _textDecorationLineThroughButton.setSelection(false);
+ }
+
+ index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[3]);
+ if (index != -1) {
+ _textDecorationBlinkButton.setSelection(true);
+ } else {
+ _textDecorationBlinkButton.setSelection(false);
+ }
+
+ index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[4]);
+ if (index != -1) {
+ _textDecorationNoneButton.setSelection(true);
+ } else {
+ _textDecorationNoneButton.setSelection(false);
+ }
+ }
+
+ // color
+ String color = _style.getColor();
+ if (!isEmptyString(color)) {
+ _colorField.setTextWithoutUpdate(color);
+ }
+ }
+
+ private String getTextDecoration() {
+ StringBuffer textDecoration = new StringBuffer();
+ if (_textDecorationUnderlineButton.getSelection()) {
+ textDecoration.append(_textDecorationUnderlineButton.getText())
+ .append(' ');
+ }
+ if (_textDecorationOverlineButton.getSelection()) {
+ textDecoration.append(_textDecorationOverlineButton.getText())
+ .append(' ');
+ }
+ if (_textDecorationLineThroughButton.getSelection()) {
+ textDecoration.append(_textDecorationLineThroughButton.getText())
+ .append(' ');
+ }
+ if (_textDecorationBlinkButton.getSelection()) {
+ textDecoration.append(_textDecorationBlinkButton.getText()).append(
+ ' ');
+ }
+ if (_textDecorationNoneButton.getSelection()) {
+ textDecoration.append(_textDecorationNoneButton.getText()).append(
+ ' ');
+ }
+
+ return textDecoration.toString().trim();
+ }
+
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ getApplyButton().setVisible(false);
+ getDefaultsButton().setVisible(false);
+ }
+
+ private boolean isEmptyString(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/BodyHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/BodyHelper.java
new file mode 100644
index 000000000..ba0cf0a65
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/BodyHelper.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+
+import javax.xml.namespace.QName;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.adapters.IBodyInfo;
+import org.eclipse.jst.pagedesigner.adapters.internal.BodyInfo;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition2;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This class helps location insertion position to inside correct body or doc
+ * prefix. NOTE: this class only doing limited support on doc level position
+ * validation. Element specific position validation will be done in other
+ * places.
+ *
+ * @author mengbo
+ */
+public class BodyHelper {
+ // bit flags used for child skipping.
+ public static final int EMPTY_TEXT = 1;
+
+ public static final int COMMENT = 2;
+
+ public static final int HEADER = 3;
+
+ /**
+ *
+ * @param child
+ * @return
+ */
+ private static boolean isSkippableChild(Node parent, Node child, int flag) {
+ if ((flag & COMMENT) != 0 && child.getNodeType() == Node.COMMENT_NODE)
+ return true;
+ if ((flag & EMPTY_TEXT) != 0 && child instanceof IDOMText
+ && ((IDOMText) child).isElementContentWhitespace())
+ return true;
+
+ if ((flag & HEADER) != 0 && child.getNodeType() == Node.ELEMENT_NODE) {
+ String uri = CMUtil.getElementNamespaceURI((Element) child);
+ IBodyInfo parentInfo = getBodyInfo((IDOMNode) parent);
+ if (parentInfo != null
+ && parentInfo.isBodyHeader((IDOMNode) parent, uri,
+ ((Element) child).getLocalName()))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * check whether uri/tag should be header of any body container that is
+ * ancester of the start node.
+ *
+ * @param start
+ * @param uri
+ * @param tag
+ * @return
+ */
+ public static IDOMNode findHeaderContainer(IDOMNode start, String uri,
+ String tag) {
+ while (start != null) {
+ IBodyInfo designInfo = getBodyInfo(start);
+ if (designInfo != null && designInfo.isBodyContainer(start)) {
+ if (designInfo.isBodyHeader(start, uri, tag))
+ return start;
+ }
+ start = (IDOMNode) start.getParentNode();
+ }
+ return null;
+ }
+
+ /**
+ * find the closest body insertion point, to make it as deep as possible.
+ * (Move into as more body as possible)
+ *
+ * @param parent
+ * @param start
+ */
+ public static IDOMPosition findBodyInsertLocation(IDOMPosition position) {
+ // forward first.
+ Node reference = position.getNextSiblingNode();
+ Node container = position.getContainerNode();
+ while (reference != null) {
+ IBodyInfo info = getBodyInfo((IDOMNode) reference);
+ if (info != null && info.isBodyContainer((IDOMNode) reference)) {
+ // good, we find a body!
+ position = new DOMPosition(reference, 0);
+ return findBodyInsertLocation(position);
+ }
+ if (isSkippableChild(container, reference, EMPTY_TEXT | COMMENT
+ | HEADER)) {
+ reference = reference.getNextSibling();
+ continue;
+ } else
+ break;
+ }
+
+ // backward
+ reference = position.getPreviousSiblingNode();
+ while (reference != null) {
+ IBodyInfo info = getBodyInfo((IDOMNode) reference);
+ if (info != null && info.isBodyContainer((IDOMNode) reference)) {
+ // good, we find a body!
+ position = new DOMPosition(reference, reference.getChildNodes()
+ .getLength());
+ return findBodyInsertLocation(position);
+ }
+ // XXX: not skip header here. So if there is some header with wrong
+ // location, we will respect user.
+ if (isSkippableChild(container, reference, EMPTY_TEXT | COMMENT)) {
+ reference = reference.getPreviousSibling();
+ continue;
+ } else
+ break;
+ }
+
+ // not find any body at same level as the insertion point.
+ return position;
+ }
+
+ /**
+ * The element type identifiered by "uri" and "tag" is going to be inserted
+ * into the document. This method is used to adjust the insert position so
+ * it can be put into correct body or header section.
+ *
+ * @param parent
+ * @param reference
+ */
+ public static IDOMPosition adjustInsertPosition(String uri, String tag,
+ IDOMPosition position) {
+ IDOMNode parent = (IDOMNode) position.getContainerNode();
+ IBodyInfo designInfo = getBodyInfo(parent);
+ if (designInfo == null) {
+ return position; // should not happen.
+ }
+
+ IDOMNode headerContainer = findHeaderContainer(parent, uri, tag);
+
+ if (headerContainer == null) {
+ // the new node is not header.
+ if (shouldIgnoreAdjust(uri, tag)) {
+ return position;
+ }
+
+ // new node is not body header. So should inside the inner most
+ // body.
+ if (!designInfo.isBodyContainer(parent)) {
+ return position; // it's parent is not body, so we suggest
+ // it's parent already correctly located, and respect user's
+ // choice.
+ }
+
+ // ok, we are inside some body, but we don't know whether we are in
+ // the inner most body.
+ // try to find a body container at same level and see whether we can
+ // move into that body.
+ return findBodyInsertLocation(position);
+ } else {
+ // good, we find a body container and the new node should be header
+ // of it.
+ Node child = headerContainer.getFirstChild();
+ Node refNode = position.getNextSiblingNode();
+ // if parent is different from headerContainer, then
+ // child!=referenceHolder[0] will always be true
+ while (child != null) // && child != refNode)
+ {
+ Comparator comp = NodeLocationComparator.getInstance();
+ // Currently the comparator deels with tags like taglib and
+ // loadbundle particularly, comparasion result 0
+ // means it didn't compare the tags.
+ if (comp.compare(child, tag) < 0
+ || (comp.compare(child, tag) == 0 && isSkippableChild(
+ headerContainer, child, COMMENT | EMPTY_TEXT
+ | HEADER))) {
+ child = child.getNextSibling();
+ } else {
+ break;
+ }
+ }
+ if (child != null) {
+ return new DOMRefPosition(child, false);
+ } else {
+ return new DOMPosition(parent, parent.getChildNodes()
+ .getLength());
+ }
+ // parentHolder[0] = headerContainer;
+ // referenceHolder[0] = child;
+ // return;
+ }
+ }
+
+ /**
+ * Find the position to insert a header element into the specified parent.
+ *
+ * @param uri
+ * @param tag
+ * @param parent
+ */
+ public static void findHeaderInsertPosition(String uri, String tag,
+ Node parent, Node[] ref) {
+ Node child = parent.getFirstChild();
+ while (child != null) {
+ Comparator comp = NodeLocationComparator.getInstance();
+ if (comp.compare(child, tag) < 0
+ || (comp.compare(child, tag) == 0 && isSkippableChild(
+ parent, child, COMMENT | EMPTY_TEXT | HEADER))) {
+ child = child.getNextSibling();
+ } else {
+ break;
+ }
+ }
+ ref[0] = child;
+ return;
+ }
+
+ public static IDOMPosition insertBody(IDOMPosition position, QName body,
+ String defaultPrefix) {
+ IBodyInfo bodyInfo = getBodyInfo((IDOMNode) position.getContainerNode());
+
+ Node node = position.getContainerNode();
+ Node originalContainer = node;
+ Node nextSibling = position.getNextSiblingNode();
+
+ // create the body element first.
+ Document ownerDoc;
+ if (node instanceof Document) {
+ ownerDoc = (Document) node;
+ } else {
+ ownerDoc = node.getOwnerDocument();
+ }
+ if (ownerDoc == null) {
+ return null; // should not happen
+ }
+
+ String prefix = JSPUtil.getOrCreatePrefix(((IDOMNode) node).getModel(),
+ body.getNamespaceURI(), defaultPrefix);
+ Element ele = ownerDoc.createElement((prefix == null ? ""
+ : (prefix + ":"))
+ + body.getLocalPart());
+
+ // need to find out the insertion point
+ while (node instanceof IDOMNode) {
+ if (bodyInfo.isBodyContainer((IDOMNode) node)) {
+ // ok, node is a body container.
+ // we could create the new node as child of node and move all
+ // node's none header children
+ // as children of the new node.
+
+ NodeList nl = node.getChildNodes();
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node child = (Node) nl.item(i);
+ if (isSkippableChild(node, child, HEADER | COMMENT
+ | EMPTY_TEXT)) {
+ continue;
+ }
+ list.add(nl.item(i));
+ }
+ for (int i = 0; i < list.size(); i++) {
+ ele.appendChild((Node) list.get(i));
+ }
+ node.appendChild(ele);
+
+ if (node == originalContainer) {
+ if (nextSibling == null) {
+ return new DOMRefPosition2(ele, true);
+ } else if (nextSibling.getParentNode() == ele) {
+ // next sibling is not in header part
+ return new DOMRefPosition(nextSibling, false);
+ } else {
+ return new DOMPosition(ele, 0);
+ }
+ } else {
+ return position;
+ }
+ }
+ node = node.getParentNode();
+ }
+ // should not happen, because document and documentfragment node will
+ // always be body node
+ // so if reach here, means the position is not in document.
+ return null;
+ }
+
+ /**
+ * For certain special tags, do not following the "header"/"body" separation
+ * and can't fit into the relocation process.
+ *
+ * @param uri
+ * @param tag
+ * @return
+ */
+ public static boolean shouldIgnoreAdjust(String uri, String tag) {
+ // FIXME:
+ return (IJMTConstants.URI_HTML.equals(uri) && "script"
+ .equalsIgnoreCase(tag))
+ || (IJMTConstants.URI_JSP.equals(uri));
+ }
+
+ public static IBodyInfo getBodyInfo(IDOMNode node) {
+ // TODO: in the future, when bodyinfo is no longer singleton, we'll use
+ // adapter mechanism.
+ return BodyInfo.getInstance();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CMUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CMUtil.java
new file mode 100644
index 000000000..b5cc8c305
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CMUtil.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLElementDeclaration;
+import org.eclipse.wst.html.core.internal.provisional.HTMLCMProperties;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMNodeWrapper;
+import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
+import org.w3c.dom.Element;
+
+/**
+ * Utility class to content model related information.
+ *
+ * @author mengbo
+ */
+public class CMUtil {
+ /**
+ * If the element is a custom tag, get the URI of it. If the element is a
+ * standard JSP tag, return null. If is not jsp tag, then return null
+ *
+ * @param element
+ * @return
+ */
+ public static String getTagURI(CMElementDeclaration decl) {
+ if (decl instanceof CMNodeWrapper) {
+ decl = (CMElementDeclaration) ((CMNodeWrapper) decl)
+ .getOriginNode();
+ }
+ if (decl instanceof TLDElementDeclaration) {
+ CMDocument doc = ((TLDElementDeclaration) decl).getOwnerDocument();
+ if (doc instanceof TLDDocument) {
+ return ((TLDDocument) doc).getUri();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Test whether this is the JSP core tag.
+ *
+ * @param decl
+ * @return
+ */
+ public static boolean isJSP(CMElementDeclaration decl) {
+ if (!decl.supports(HTMLCMProperties.IS_JSP)) {
+ return false;
+ }
+ Boolean b = (Boolean) decl.getProperty(HTMLCMProperties.IS_JSP);
+ return b.booleanValue();
+ }
+
+ public static boolean isHTML(CMElementDeclaration decl) {
+ if (!isJSP(decl) && (decl instanceof HTMLElementDeclaration)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * get element declaration of specified element
+ *
+ * @param element
+ * @return null if can't get it.
+ */
+ public static CMElementDeclaration getElementDeclaration(Element element) {
+ if (element == null) {
+ return null;
+ }
+ INodeNotifier notifier = (INodeNotifier) element.getOwnerDocument();
+ if (notifier == null) {
+ return null;
+ }
+ ModelQueryAdapter mqa = (ModelQueryAdapter) notifier
+ .getAdapterFor(ModelQueryAdapter.class);
+ if (mqa == null) {
+ return null;
+ }
+ return mqa.getModelQuery().getCMElementDeclaration(element);
+ }
+
+ public static TLDElementDeclaration getTLDElementDeclaration(Element element) {
+ CMNode decl = getElementDeclaration(element);
+ if (decl instanceof CMNodeWrapper) {
+ decl = ((CMNodeWrapper) decl).getOriginNode();
+ }
+ if (decl instanceof TLDElementDeclaration) {
+ return (TLDElementDeclaration) decl;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * give an element, get its namespace URI.
+ *
+ * @param element
+ * @return
+ */
+ public static String getElementNamespaceURI(Element element) {
+ CMElementDeclaration decl = getElementDeclaration(element);
+ if (decl == null) {
+ return null;
+ }
+
+ if (isJSP(decl)) {
+ return IJMTConstants.URI_JSP;
+ } else if (isHTML(decl)) {
+ return IJMTConstants.URI_HTML;
+ }
+
+ return getTagURI(decl);
+ }
+
+ /**
+ * @param element
+ * @return
+ */
+ public static boolean canHaveDirectTextChild(Element element) {
+ CMElementDeclaration decl = getElementDeclaration(element);
+ if (decl == null) {
+ return true;
+ }
+ int contentType = decl.getContentType();
+ return contentType != CMElementDeclaration.ELEMENT
+ && contentType != CMElementDeclaration.EMPTY;
+
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CacheManager.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CacheManager.java
new file mode 100644
index 000000000..114766820
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CacheManager.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * This is a cache manager. It will use the ICacheEntryCreator interface to
+ * manage creating new item and dispose old item.
+ *
+ * @author mengbo
+ * @version 1.5
+ */
+public class CacheManager {
+ ICacheEntryCreator _creator;
+
+ int _maxSize;
+
+ // key --> value
+ Map _map = new HashMap();
+
+ // keep track of LRU
+ LinkedList _keys = new LinkedList();
+
+ public CacheManager(ICacheEntryCreator creator, int maxSize) {
+ _creator = creator;
+ _maxSize = maxSize;
+ if (_maxSize <= 0) {
+ _maxSize = 10;
+ }
+ }
+
+ public Object getEntry(Object key) {
+ Object result = _map.get(key);
+ if (result == null) {
+ // not existed yet.
+ if (_map.size() >= _maxSize) {
+ // we need to remove the oldest one.
+ Object keyRemove = _keys.removeFirst();
+ Object objToRemove = _map.remove(keyRemove);
+ _creator.dispose(keyRemove, objToRemove);
+ }
+ result = _creator.createEntry(key);
+ _keys.addLast(key);
+ _map.put(key, result);
+ return result;
+ } else {
+ _keys.remove(key);
+ _keys.addLast(key);
+ return result;
+ }
+ }
+
+ public void disposeAll() {
+ _keys.clear();
+ for (Iterator iter = _map.keySet().iterator(); iter.hasNext();) {
+ Object key = iter.next();
+ Object entry = _map.get(key);
+ _creator.dispose(key, entry);
+ }
+ _map.clear();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CommandUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CommandUtil.java
new file mode 100644
index 000000000..e3f30daef
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/CommandUtil.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.dom.JSFValidatorSupport;
+import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemDescriptor;
+import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteElementTemplateHelper;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CommandUtil {
+ private static final Logger _log = PDPlugin.getLogger(CommandUtil.class);
+
+ public static Element excuteInsertion(IPaletteItemDescriptor itemDes,
+ IHTMLGraphicalViewer viewer, IDOMPosition domPosition) {
+ return excuteInsertion(itemDes, viewer.getModel(), domPosition);
+ }
+
+ public static Element excuteInsertion(IPaletteItemDescriptor itemDes,
+ IDOMModel model, IDOMPosition domPosition) {
+ try {
+ IDOMPosition position = DOMPositionHelper.splitText(domPosition);
+
+ String uri = itemDes.getURI();
+ String localname = itemDes.getTagName();
+ if (IJMTConstants.URI_HTML.equals(uri)) {
+ localname = localname.toUpperCase();
+ }
+ position = BodyHelper
+ .adjustInsertPosition(uri, localname, position);
+
+ position = prepareJSFValidity(position, itemDes);
+ if (position == null) {
+ // user cancelled
+ return null;
+ }
+
+ // because the next call of getPrefix() may insert new taglib node
+ // into the document, if we use the normal
+ // DOMPositin which use index, maybe it will be invalidated by the
+ // new taglib node. So use RefPosition here.
+ position = DOMPositionHelper.toDOMRefPosition(position);
+
+ String prefix = getPrefix(uri, model, itemDes.getDefaultPrefix());
+ Element ele = model.getDocument().createElement(localname);
+
+ // XXX: we are using "startsWith("directive.")" to test whether
+ // should setJSPTag, this
+ // maybe is not the best way. Need check whether SSE have special
+ // API for it.
+ if (IJMTConstants.URI_JSP.equals(uri)
+ && (ele.getLocalName().startsWith("directive.")
+ || "declaration".equals(ele.getLocalName())
+ || "expression".equals(ele.getLocalName()) || "scriptlet"
+ .equals(ele.getLocalName()))) {
+ // it is a jsp tag
+ ((IDOMElement) ele).setJSPTag(true);
+ }
+ if (prefix != null) {
+ ele.setPrefix(prefix);
+ }
+ // Generate the node according to template.
+ PaletteElementTemplateHelper.applyTemplate(model, ele, itemDes);
+
+ Map map = itemDes.getInitialAttributes();
+ if (map != null) {
+ for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
+ String attrname = (String) iter.next();
+ String attrvalue = (String) map.get(attrname);
+ ele.setAttribute(attrname, attrvalue);
+ }
+ }
+ if (position.getNextSiblingNode() == null) {
+ position.getContainerNode().appendChild(ele);
+ } else {
+ position.getContainerNode().insertBefore(ele,
+ position.getNextSiblingNode());
+ }
+
+ return ele;
+ } catch (Exception e) {
+ _log.info("Invalid insertion in position:" + domPosition + "\n", e);
+ return null;
+ }
+ }
+
+ public static IDOMPosition prepareJSFValidity(IDOMPosition position,
+ IPaletteItemDescriptor item) {
+ if (item.isJSFComponent()) {
+ return JSFValidatorSupport.prepareInsertJSFComponent(position, item
+ .getURI(), item.getTagName(), item.isRequireHForm());
+ } else {
+ return position;
+ }
+ }
+
+ // /**
+ // * Simple validity checking. Currently only support automatically insert
+ // <f:view>and <f:form>tag for user.
+ // * @param position
+ // * @param uri
+ // * @param localname
+ // * @return
+ // */
+ // private static IDOMPosition checkValidity(IDOMPosition position, String
+ // uri, String localname)
+ // {
+ // if (IJMTConstants.URI_JSF_CORE.equals(uri) ||
+ // IJMTConstants.URI_JSF_HTML.equals(uri))
+ // {
+ // return JSFValidatorSupport.prepareInsertJSFComponent(position, uri,
+ // localname);
+ // }
+ // return position;
+ // }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.requests.NodeCreationFactory#getPrefix(int)
+ */
+ private static String getPrefix(String uri, IDOMModel model,
+ String suggested) {
+ if (IJMTConstants.URI_HTML.equals(uri)
+ || IJMTConstants.URI_JSP.equals(uri)) {
+ return null;
+ }
+
+ // now handles custom tag lib
+ return JSPUtil.getOrCreatePrefix(model, uri, suggested);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/DOMUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/DOMUtil.java
new file mode 100644
index 000000000..3ef4425b4
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/DOMUtil.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.wst.xml.core.internal.document.ElementImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class DOMUtil {
+ public static List getChildElementsByTagIgnoreCase(Element parent,
+ String tag) {
+ List ret = new ArrayList();
+ NodeList nodeList = parent.getChildNodes();
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node node = nodeList.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ String t = node.getNodeName();
+ if (tag.equalsIgnoreCase(t)) {
+ ret.add(node);
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * @param ele
+ * @return
+ */
+ public static String getTextElementValue(Element ele) {
+ StringBuffer buffer = new StringBuffer();
+ Node node = ele.getFirstChild();
+ while (node != null) {
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ buffer.append(node.getNodeValue());
+ } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
+ buffer.append(node.getNodeValue());
+ }
+ node = node.getNextSibling();
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * @param element
+ * @param string
+ * @return
+ */
+ public static String getAttributeIgnoreCase(Element element, String string) {
+ NamedNodeMap map = element.getAttributes();
+ for (int i = 0; i < map.getLength(); i++) {
+ Node attr = map.item(i);
+ if (string.equalsIgnoreCase(attr.getNodeName())) {
+ return attr.getNodeValue();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param tr
+ * @param strings
+ * @return
+ */
+ public static List getChildrenByTagsIgnoreCase(Element parent, String[] tags) {
+ List result = new ArrayList();
+ NodeList nodeList = parent.getChildNodes();
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node node = nodeList.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ String t = node.getNodeName();
+ for (int k = 0; k < tags.length; k++) {
+ if (tags[k].equalsIgnoreCase(t)) {
+ result.add(node);
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ public static void removeAllChildren(Element ele) {
+ ((ElementImpl) ele).removeChildNodes();
+ }
+
+ public static void setTextElementValue(Element ele, String value) {
+ removeAllChildren(ele);
+ Text txt = ele.getOwnerDocument().createTextNode(value);
+ ele.appendChild(txt);
+ }
+
+ /**
+ * @param htmlElement
+ * @param string
+ * @param i
+ * @return
+ */
+ public static int getIntAttributeIgnoreCase(Element ele, String attr,
+ int defaultvalue) {
+ if (ele == null) {
+ return defaultvalue;
+ }
+ String attrvalue = getAttributeIgnoreCase(ele, attr);
+ if (attrvalue == null) {
+ return defaultvalue;
+ } else {
+ try {
+ return Integer.parseInt(attrvalue);
+ } catch (Exception ex) {
+ return defaultvalue;
+ }
+ }
+ }
+
+ /**
+ * get all child elements
+ *
+ * @param ele
+ * @return
+ */
+ public static List getElementChildren(Element ele) {
+ List ret = new ArrayList();
+ NodeList nodeList = ele.getChildNodes();
+ for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+ Node node = nodeList.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ ret.add(node);
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * judge whether element has an attribute named attrName
+ *
+ * @param ele
+ * @param attrName
+ * @return
+ */
+ public static boolean hasAttribute(Element ele, String attrName) {
+ NamedNodeMap map = ele.getAttributes();
+ for (int i = 0; i < map.getLength(); i++) {
+ Node attr = map.item(i);
+ if (attr.getNodeName().equalsIgnoreCase(attrName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void nodeToString(Node node, StringBuffer sb) {
+ int type = node.getNodeType();
+ switch (type) {
+ case Node.DOCUMENT_NODE:
+ sb.append("<?xml version=\"1.0\" ?>");
+ nodeToString(((Document) node).getDocumentElement(), sb);
+ break;
+
+ case Node.ELEMENT_NODE:
+ sb.append("<");
+ sb.append(node.getNodeName());
+ NamedNodeMap attrs = node.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Node attr = attrs.item(i);
+ sb.append(" " + attr.getNodeName() + "=\""
+ + attr.getNodeValue() + "\"");
+ }
+
+ NodeList children = node.getChildNodes();
+ if (children != null) {
+ int len = children.getLength();
+ if (len != 0) {
+ sb.append(">");
+ }
+ for (int i = 0; i < len; i++) {
+ nodeToString(children.item(i), sb);
+ }
+ }
+ break;
+
+ case Node.ENTITY_REFERENCE_NODE:
+ sb.append("&");
+ sb.append(node.getNodeName());
+ sb.append(";");
+ break;
+
+ case Node.CDATA_SECTION_NODE:
+ sb.append("<![CDATA[");
+ sb.append(node.getNodeValue());
+ sb.append("]]>");
+ break;
+
+ case Node.TEXT_NODE:
+ sb.append(node.getNodeValue());
+ break;
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ sb.append("<?");
+ sb.append(node.getNodeName());
+ String data = node.getNodeValue();
+ {
+ sb.append(" ");
+ sb.append(data);
+ }
+ sb.append("?>");
+ break;
+ }
+
+ if (type == Node.ELEMENT_NODE) {
+ if (node.getFirstChild() != null) {
+ sb.append("</");
+ sb.append(node.getNodeName());
+ sb.append(">");
+ } else {
+ sb.append("/>");
+ }
+
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/EntityMap.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/EntityMap.java
new file mode 100644
index 000000000..3d74044d9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/EntityMap.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+
+/**
+ * @author mengbo
+ */
+public class EntityMap {
+ private static Logger _log = PDPlugin.getLogger(EntityMap.class);
+
+ public static String translate(String s) {
+ char[] array = s.toCharArray();
+ StringBuffer buffer = new StringBuffer();
+ int posi = 0;
+ int len = array.length;
+ while (posi < len) {
+ if (array[posi] != '&') {
+ buffer.append(replaceBadEntity(array[posi++]));
+ continue;
+ }
+
+ // now array[posi] == '&'
+ int lastPosi = posi;
+ posi++;
+ if (posi < len && array[posi] == '#') {
+ posi++;
+ }
+ while (posi < len) {
+ if (!Character.isLetterOrDigit(array[posi]))
+ break;
+ else
+ posi++;
+ }
+ // now posi>=array.length or array[posi] is non letter or digit
+ String str = new String(array, lastPosi, posi - lastPosi);
+ if (translateEntity(str, buffer)) {
+ // translated, skip the ';'
+ if (posi < len && array[posi] == ';') {
+ posi++;
+ }
+ }
+
+ if (posi == len) {
+ return buffer.toString();
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Translate entity maps and compact whitespace. For heading and training
+ * space, will not trim, only compact (making multiple whitespace to become
+ * a single ' ' char).
+ */
+ public static String translateAndCompact(String s) {
+ char[] array = s.toCharArray();
+ StringBuffer buffer = new StringBuffer();
+ int posi = 0;
+ int len = array.length;
+ while (posi < len) {
+ if (HTMLUtil.isHTMLWhitespace(array[posi])) {
+ while (++posi < len && HTMLUtil.isHTMLWhitespace(array[posi]))
+ ;
+ buffer.append(' ');
+ continue;
+ }
+ if (array[posi] != '&') {
+ buffer.append(replaceBadEntity(array[posi++]));
+ continue;
+ }
+
+ // now array[posi] == '&'
+ int lastPosi = posi;
+ posi++;
+ if (posi < len && array[posi] == '#') {
+ posi++;
+ }
+ while (posi < len) {
+ if (!Character.isLetterOrDigit(array[posi])) {
+ break;
+ } else {
+ posi++;
+ }
+ }
+ // now posi>=array.length or array[posi] is non letter or digit
+ String str = new String(array, lastPosi, posi - lastPosi);
+
+ if (translateEntity(str, buffer)) {
+ // translated, skip the ';'
+ if (posi < len && array[posi] == ';') {
+ posi++;
+ }
+ }
+
+ if (posi == len) {
+ return buffer.toString();
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * if can translate will return true and append the result string if can't
+ * translate will return false and append original string
+ *
+ * @param s
+ * the form &#number or &letterordigit without the trailing ";"
+ */
+ public static boolean translateEntity(String s, StringBuffer strBuf) {
+ int i = HTMLSpecialCharHelper.getSpecial(s); // HTMLSpecialCharHelper
+ // support without
+ // traning ';'
+ if (i != -1) {
+ strBuf.append((char) i);
+ return true;
+ }
+ if (s.length() > 2 && s.charAt(1) == '#') {
+ String number;
+ number = s.substring(2);
+ try {
+ int n;
+ if (number.length() > 0
+ && (number.charAt(0) == 'x' || number.charAt(0) == 'X')) {
+ n = Integer.parseInt(number.substring(1), 16);
+ } else {
+ n = Integer.parseInt(number);
+ }
+ strBuf.append(replaceBadEntity((char) n));
+ return true;
+ } catch (Exception ex) {
+ // Error in integer formating
+ _log.info("Debug.EntityMap.0", ex); //$NON-NLS-1$
+ strBuf.append(s);
+ return false;
+ }
+ } else {
+ strBuf.append(s);
+ return false;
+ }
+ }
+
+ /**
+ * In HTML &#149; is sometimes used (mostly based on CP 1252), but is
+ * illegal, because it does not exist in Unicode
+ *
+ * @param n
+ * @return
+ * @see http://www.w3.org/Talks/1999/0830-tutorial-unicode-mjd/slide27-0.html
+ */
+ private static char replaceBadEntity(char n) {
+ if (n < 132 || n > 156)
+ return n;
+ switch ((int) n) {
+ case 132:
+ return (char) 8222;
+ case 133:
+ return (char) 8230;
+ case 134:
+ return (char) 8224;
+ case 135:
+ return (char) 8225;
+ case 139:
+ return (char) 8249;
+ case 140:
+ return (char) 338;
+ case 145:
+ return (char) 8216;
+ case 146:
+ return (char) 8217;
+ case 147:
+ return (char) 8220;
+ case 148:
+ return (char) 8221;
+ case 149:
+ return (char) 8226;
+ case 151:
+ return (char) 8212;
+ case 153:
+ return (char) 8482;
+ case 155:
+ return (char) 8250;
+ case 156:
+ return (char) 339;
+ default:
+ return n;
+ }
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLSpecialCharHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLSpecialCharHelper.java
new file mode 100644
index 000000000..6d7539f17
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLSpecialCharHelper.java
@@ -0,0 +1,422 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+
+/**
+ * entity map support.
+ *
+ * @author mengbo
+ */
+public class HTMLSpecialCharHelper {
+ private static Logger _log = PDPlugin
+ .getLogger(HTMLSpecialCharHelper.class);
+
+ private static Hashtable _table;
+
+ private static Hashtable _reverse;
+ static {
+ _table = new Hashtable(256);
+
+ _table.put(new Integer(34), "&quot;"); //$NON-NLS-1$
+ _table.put(new Integer(38), "&amp;"); //$NON-NLS-1$
+ _table.put(new Integer(60), "&lt;"); //$NON-NLS-1$
+ _table.put(new Integer(62), "&gt;"); //$NON-NLS-1$
+
+ _table.put(new Integer(160), "&nbsp;"); //$NON-NLS-1$
+ _table.put(new Integer(161), "&iexcl;"); //$NON-NLS-1$
+ _table.put(new Integer(162), "&cent;"); //$NON-NLS-1$
+ _table.put(new Integer(163), "&pound;"); //$NON-NLS-1$
+ _table.put(new Integer(164), "&curren;"); //$NON-NLS-1$
+ _table.put(new Integer(165), "&yen;"); //$NON-NLS-1$
+ _table.put(new Integer(166), "&brvbar;"); //$NON-NLS-1$
+ _table.put(new Integer(167), "&sect;"); //$NON-NLS-1$
+ _table.put(new Integer(168), "&uml;"); //$NON-NLS-1$
+ _table.put(new Integer(169), "&copy;"); //$NON-NLS-1$
+ _table.put(new Integer(170), "&ordf;"); //$NON-NLS-1$
+ _table.put(new Integer(171), "&laquo;"); //$NON-NLS-1$
+ _table.put(new Integer(172), "&not;"); //$NON-NLS-1$
+ _table.put(new Integer(173), "&shy;"); //$NON-NLS-1$
+ _table.put(new Integer(174), "&reg;"); //$NON-NLS-1$
+ _table.put(new Integer(175), "&macr;"); //$NON-NLS-1$
+ _table.put(new Integer(176), "&deg;"); //$NON-NLS-1$
+ _table.put(new Integer(177), "&plusmn;"); //$NON-NLS-1$
+ _table.put(new Integer(178), "&sup2;"); //$NON-NLS-1$
+ _table.put(new Integer(179), "&sup3;"); //$NON-NLS-1$
+ _table.put(new Integer(180), "&acute;"); //$NON-NLS-1$
+ _table.put(new Integer(181), "&micro;"); //$NON-NLS-1$
+ _table.put(new Integer(182), "&para;"); //$NON-NLS-1$
+ _table.put(new Integer(183), "&middot;"); //$NON-NLS-1$
+ _table.put(new Integer(184), "&cedil;"); //$NON-NLS-1$
+ _table.put(new Integer(185), "&sup1;"); //$NON-NLS-1$
+ _table.put(new Integer(186), "&ordm;"); //$NON-NLS-1$
+ _table.put(new Integer(187), "&raquo;"); //$NON-NLS-1$
+ _table.put(new Integer(188), "&frac14;"); //$NON-NLS-1$
+ _table.put(new Integer(189), "&frac12;"); //$NON-NLS-1$
+ _table.put(new Integer(190), "&frac34;"); //$NON-NLS-1$
+ _table.put(new Integer(191), "&iquest;"); //$NON-NLS-1$
+ _table.put(new Integer(192), "&Agrave;"); //$NON-NLS-1$
+ _table.put(new Integer(193), "&Aacute;"); //$NON-NLS-1$
+ _table.put(new Integer(194), "&Acirc;"); //$NON-NLS-1$
+ _table.put(new Integer(195), "&Atilde;"); //$NON-NLS-1$
+ _table.put(new Integer(196), "&Auml;"); //$NON-NLS-1$
+ _table.put(new Integer(197), "&Aring;"); //$NON-NLS-1$
+ _table.put(new Integer(198), "&AElig;"); //$NON-NLS-1$
+ _table.put(new Integer(199), "&Ccedil;"); //$NON-NLS-1$
+ _table.put(new Integer(200), "&Egrave;"); //$NON-NLS-1$
+ _table.put(new Integer(201), "&Eacute;"); //$NON-NLS-1$
+ _table.put(new Integer(202), "&Ecirc;"); //$NON-NLS-1$
+ _table.put(new Integer(203), "&Euml;"); //$NON-NLS-1$
+ _table.put(new Integer(204), "&Igrave;"); //$NON-NLS-1$
+ _table.put(new Integer(205), "&Iacute;"); //$NON-NLS-1$
+ _table.put(new Integer(206), "&Icirc;"); //$NON-NLS-1$
+ _table.put(new Integer(207), "&Iuml;"); //$NON-NLS-1$
+ _table.put(new Integer(208), "&ETH;"); //$NON-NLS-1$
+ _table.put(new Integer(209), "&Ntilde;"); //$NON-NLS-1$
+ _table.put(new Integer(210), "&Ograve;"); //$NON-NLS-1$
+ _table.put(new Integer(211), "&Oacute;"); //$NON-NLS-1$
+ _table.put(new Integer(212), "&Ocirc;"); //$NON-NLS-1$
+ _table.put(new Integer(213), "&Otilde;"); //$NON-NLS-1$
+ _table.put(new Integer(214), "&Ouml;"); //$NON-NLS-1$
+ _table.put(new Integer(215), "&times;"); //$NON-NLS-1$
+ _table.put(new Integer(216), "&Oslash;"); //$NON-NLS-1$
+ _table.put(new Integer(217), "&Ugrave;"); //$NON-NLS-1$
+ _table.put(new Integer(218), "&Uacute;"); //$NON-NLS-1$
+ _table.put(new Integer(219), "&Ucirc;"); //$NON-NLS-1$
+ _table.put(new Integer(220), "&Uuml;"); //$NON-NLS-1$
+ _table.put(new Integer(221), "&Yacute;"); //$NON-NLS-1$
+ _table.put(new Integer(222), "&THORN;"); //$NON-NLS-1$
+ _table.put(new Integer(223), "&szlig;"); //$NON-NLS-1$
+ _table.put(new Integer(224), "&agrave;"); //$NON-NLS-1$
+ _table.put(new Integer(225), "&aacute;"); //$NON-NLS-1$
+ _table.put(new Integer(226), "&acirc;"); //$NON-NLS-1$
+ _table.put(new Integer(227), "&atilde;"); //$NON-NLS-1$
+ _table.put(new Integer(228), "&auml;"); //$NON-NLS-1$
+ _table.put(new Integer(229), "&aring;"); //$NON-NLS-1$
+ _table.put(new Integer(230), "&aelig;"); //$NON-NLS-1$
+ _table.put(new Integer(231), "&ccedil;"); //$NON-NLS-1$
+ _table.put(new Integer(232), "&egrave;"); //$NON-NLS-1$
+ _table.put(new Integer(233), "&eacute;"); //$NON-NLS-1$
+ _table.put(new Integer(234), "&ecirc;"); //$NON-NLS-1$
+ _table.put(new Integer(235), "&euml;"); //$NON-NLS-1$
+ _table.put(new Integer(236), "&igrave;"); //$NON-NLS-1$
+ _table.put(new Integer(237), "&iacute;"); //$NON-NLS-1$
+ _table.put(new Integer(238), "&icirc;"); //$NON-NLS-1$
+ _table.put(new Integer(239), "&iuml;"); //$NON-NLS-1$
+ _table.put(new Integer(240), "&eth;"); //$NON-NLS-1$
+ _table.put(new Integer(241), "&ntilde;"); //$NON-NLS-1$
+ _table.put(new Integer(242), "&ograve;"); //$NON-NLS-1$
+ _table.put(new Integer(243), "&oacute;"); //$NON-NLS-1$
+ _table.put(new Integer(244), "&ocirc;"); //$NON-NLS-1$
+ _table.put(new Integer(245), "&otilde;"); //$NON-NLS-1$
+ _table.put(new Integer(246), "&ouml;"); //$NON-NLS-1$
+ _table.put(new Integer(247), "&divide;"); //$NON-NLS-1$
+ _table.put(new Integer(248), "&oslash;"); //$NON-NLS-1$
+ _table.put(new Integer(249), "&ugrave;"); //$NON-NLS-1$
+ _table.put(new Integer(250), "&uacute;"); //$NON-NLS-1$
+ _table.put(new Integer(251), "&ucirc;"); //$NON-NLS-1$
+ _table.put(new Integer(252), "&uuml;"); //$NON-NLS-1$
+ _table.put(new Integer(253), "&yacute;"); //$NON-NLS-1$
+ _table.put(new Integer(254), "&thorn;"); //$NON-NLS-1$
+ _table.put(new Integer(255), "&yuml;"); //$NON-NLS-1$
+ _table.put(new Integer(402), "&fnof;"); //$NON-NLS-1$
+ _table.put(new Integer(913), "&Alpha;"); //$NON-NLS-1$
+ _table.put(new Integer(914), "&Beta;"); //$NON-NLS-1$
+ _table.put(new Integer(915), "&Gamma;"); //$NON-NLS-1$
+ _table.put(new Integer(916), "&Delta;"); //$NON-NLS-1$
+ _table.put(new Integer(917), "&Epsilon;"); //$NON-NLS-1$
+ _table.put(new Integer(918), "&Zeta;"); //$NON-NLS-1$
+ _table.put(new Integer(919), "&Eta;"); //$NON-NLS-1$
+ _table.put(new Integer(920), "&Theta;"); //$NON-NLS-1$
+ _table.put(new Integer(921), "&Iota;"); //$NON-NLS-1$
+ _table.put(new Integer(922), "&Kappa;"); //$NON-NLS-1$
+ _table.put(new Integer(923), "&Lambda;"); //$NON-NLS-1$
+ _table.put(new Integer(924), "&Mu;"); //$NON-NLS-1$
+ _table.put(new Integer(925), "&Nu;"); //$NON-NLS-1$
+ _table.put(new Integer(926), "&Xi;"); //$NON-NLS-1$
+ _table.put(new Integer(927), "&Omicron;"); //$NON-NLS-1$
+ _table.put(new Integer(928), "&Pi;"); //$NON-NLS-1$
+ _table.put(new Integer(929), "&Rho;"); //$NON-NLS-1$
+ _table.put(new Integer(931), "&Sigma;"); //$NON-NLS-1$
+ _table.put(new Integer(932), "&Tau;"); //$NON-NLS-1$
+ _table.put(new Integer(933), "&Upsilon;"); //$NON-NLS-1$
+ _table.put(new Integer(934), "&Phi;"); //$NON-NLS-1$
+ _table.put(new Integer(935), "&Chi;"); //$NON-NLS-1$
+ _table.put(new Integer(936), "&Psi;"); //$NON-NLS-1$
+ _table.put(new Integer(937), "&Omega;"); //$NON-NLS-1$
+ _table.put(new Integer(945), "&alpha;"); //$NON-NLS-1$
+ _table.put(new Integer(946), "&beta;"); //$NON-NLS-1$
+ _table.put(new Integer(947), "&gamma;"); //$NON-NLS-1$
+ _table.put(new Integer(948), "&delta;"); //$NON-NLS-1$
+ _table.put(new Integer(949), "&epsilon;"); //$NON-NLS-1$
+ _table.put(new Integer(950), "&zeta;"); //$NON-NLS-1$
+ _table.put(new Integer(951), "&eta;"); //$NON-NLS-1$
+ _table.put(new Integer(952), "&theta;"); //$NON-NLS-1$
+ _table.put(new Integer(953), "&iota;"); //$NON-NLS-1$
+ _table.put(new Integer(954), "&kappa;"); //$NON-NLS-1$
+ _table.put(new Integer(955), "&lambda;"); //$NON-NLS-1$
+ _table.put(new Integer(956), "&mu;"); //$NON-NLS-1$
+ _table.put(new Integer(957), "&nu;"); //$NON-NLS-1$
+ _table.put(new Integer(958), "&xi;"); //$NON-NLS-1$
+ _table.put(new Integer(959), "&omicron;"); //$NON-NLS-1$
+ _table.put(new Integer(960), "&pi;"); //$NON-NLS-1$
+ _table.put(new Integer(961), "&rho;"); //$NON-NLS-1$
+ _table.put(new Integer(962), "&sigmaf;"); //$NON-NLS-1$
+ _table.put(new Integer(963), "&sigma;"); //$NON-NLS-1$
+ _table.put(new Integer(964), "&tau;"); //$NON-NLS-1$
+ _table.put(new Integer(965), "&upsilon;"); //$NON-NLS-1$
+ _table.put(new Integer(966), "&phi;"); //$NON-NLS-1$
+ _table.put(new Integer(967), "&chi;"); //$NON-NLS-1$
+ _table.put(new Integer(968), "&psi;"); //$NON-NLS-1$
+ _table.put(new Integer(969), "&omega;"); //$NON-NLS-1$
+ _table.put(new Integer(977), "&thetasym;"); //$NON-NLS-1$
+ _table.put(new Integer(978), "&upsih;"); //$NON-NLS-1$
+ _table.put(new Integer(982), "&piv;"); //$NON-NLS-1$
+ _table.put(new Integer(8226), "&bull;"); //$NON-NLS-1$
+ _table.put(new Integer(8230), "&hellip;"); //$NON-NLS-1$
+ _table.put(new Integer(8242), "&prime;"); //$NON-NLS-1$
+ _table.put(new Integer(8243), "&Prime;"); //$NON-NLS-1$
+ _table.put(new Integer(8254), "&oline;"); //$NON-NLS-1$
+ _table.put(new Integer(8260), "&frasl;"); //$NON-NLS-1$
+ _table.put(new Integer(8472), "&weierp;"); //$NON-NLS-1$
+ _table.put(new Integer(8465), "&image;"); //$NON-NLS-1$
+ _table.put(new Integer(8476), "&real;"); //$NON-NLS-1$
+ _table.put(new Integer(8482), "&trade;"); //$NON-NLS-1$
+ _table.put(new Integer(8501), "&alefsym;"); //$NON-NLS-1$
+ _table.put(new Integer(8592), "&larr;"); //$NON-NLS-1$
+ _table.put(new Integer(8593), "&uarr;"); //$NON-NLS-1$
+ _table.put(new Integer(8594), "&rarr;"); //$NON-NLS-1$
+ _table.put(new Integer(8595), "&darr;"); //$NON-NLS-1$
+ _table.put(new Integer(8596), "&harr;"); //$NON-NLS-1$
+ _table.put(new Integer(8629), "&crarr;"); //$NON-NLS-1$
+ _table.put(new Integer(8656), "&lArr;"); //$NON-NLS-1$
+ _table.put(new Integer(8657), "&uArr;"); //$NON-NLS-1$
+ _table.put(new Integer(8658), "&rArr;"); //$NON-NLS-1$
+ _table.put(new Integer(8659), "&dArr;"); //$NON-NLS-1$
+ _table.put(new Integer(8660), "&hArr;"); //$NON-NLS-1$
+ _table.put(new Integer(8704), "&forall;"); //$NON-NLS-1$
+ _table.put(new Integer(8706), "&part;"); //$NON-NLS-1$
+ _table.put(new Integer(8707), "&exist;"); //$NON-NLS-1$
+ _table.put(new Integer(8709), "&empty;"); //$NON-NLS-1$
+ _table.put(new Integer(8711), "&nabla;"); //$NON-NLS-1$
+ _table.put(new Integer(8712), "&isin;"); //$NON-NLS-1$
+ _table.put(new Integer(8713), "&notin;"); //$NON-NLS-1$
+ _table.put(new Integer(8715), "&ni;"); //$NON-NLS-1$
+ _table.put(new Integer(8719), "&prod;"); //$NON-NLS-1$
+ _table.put(new Integer(8722), "&sum;"); //$NON-NLS-1$
+ _table.put(new Integer(8722), "&minus;"); //$NON-NLS-1$
+ _table.put(new Integer(8727), "&lowast;"); //$NON-NLS-1$
+ _table.put(new Integer(8730), "&radic;"); //$NON-NLS-1$
+ _table.put(new Integer(8733), "&prop;"); //$NON-NLS-1$
+ _table.put(new Integer(8734), "&infin;"); //$NON-NLS-1$
+ _table.put(new Integer(8736), "&ang;"); //$NON-NLS-1$
+ _table.put(new Integer(8869), "&and;"); //$NON-NLS-1$
+ _table.put(new Integer(8870), "&or;"); //$NON-NLS-1$
+ _table.put(new Integer(8745), "&cap;"); //$NON-NLS-1$
+ _table.put(new Integer(8746), "&cup;"); //$NON-NLS-1$
+ _table.put(new Integer(8747), "&int;"); //$NON-NLS-1$
+ _table.put(new Integer(8756), "&there4;"); //$NON-NLS-1$
+ _table.put(new Integer(8764), "&sim;"); //$NON-NLS-1$
+ _table.put(new Integer(8773), "&cong;"); //$NON-NLS-1$
+ _table.put(new Integer(8773), "&asymp;"); //$NON-NLS-1$
+ _table.put(new Integer(8800), "&ne;"); //$NON-NLS-1$
+ _table.put(new Integer(8801), "&equiv;"); //$NON-NLS-1$
+ _table.put(new Integer(8804), "&le;"); //$NON-NLS-1$
+ _table.put(new Integer(8805), "&ge;"); //$NON-NLS-1$
+ _table.put(new Integer(8834), "&sub;"); //$NON-NLS-1$
+ _table.put(new Integer(8835), "&sup;"); //$NON-NLS-1$
+ _table.put(new Integer(8836), "&nsub;"); //$NON-NLS-1$
+ _table.put(new Integer(8838), "&sube;"); //$NON-NLS-1$
+ _table.put(new Integer(8839), "&supe;"); //$NON-NLS-1$
+ _table.put(new Integer(8853), "&oplus;"); //$NON-NLS-1$
+ _table.put(new Integer(8855), "&otimes;"); //$NON-NLS-1$
+ _table.put(new Integer(8869), "&perp;"); //$NON-NLS-1$
+ _table.put(new Integer(8901), "&sdot;"); //$NON-NLS-1$
+ _table.put(new Integer(8968), "&lceil;"); //$NON-NLS-1$
+ _table.put(new Integer(8969), "&rceil;"); //$NON-NLS-1$
+ _table.put(new Integer(8970), "&lfloor;"); //$NON-NLS-1$
+ _table.put(new Integer(8971), "&rfloor;"); //$NON-NLS-1$
+ _table.put(new Integer(9001), "&lang;"); //$NON-NLS-1$
+ _table.put(new Integer(9002), "&rang;"); //$NON-NLS-1$
+ _table.put(new Integer(9674), "&loz;"); //$NON-NLS-1$
+ _table.put(new Integer(9824), "&spades;"); //$NON-NLS-1$
+ _table.put(new Integer(9827), "&clubs;"); //$NON-NLS-1$
+ _table.put(new Integer(9829), "&hearts;"); //$NON-NLS-1$
+ _table.put(new Integer(9830), "&diams;"); //$NON-NLS-1$
+
+ _table.put(new Integer(338), "&OElig;"); //$NON-NLS-1$
+ _table.put(new Integer(339), "&oelig;"); //$NON-NLS-1$
+ _table.put(new Integer(352), "&Scaron;"); //$NON-NLS-1$
+ _table.put(new Integer(353), "&scaron;"); //$NON-NLS-1$
+ _table.put(new Integer(376), "&Yuml;"); //$NON-NLS-1$
+ _table.put(new Integer(710), "&circ;"); //$NON-NLS-1$
+ _table.put(new Integer(732), "&tilde;"); //$NON-NLS-1$
+ _table.put(new Integer(8194), "&ensp;"); //$NON-NLS-1$
+ _table.put(new Integer(8195), "&emsp;"); //$NON-NLS-1$
+ _table.put(new Integer(8201), "&thinsp;"); //$NON-NLS-1$
+ _table.put(new Integer(8204), "&zwnj;"); //$NON-NLS-1$
+ _table.put(new Integer(8205), "&zwj;"); //$NON-NLS-1$
+ _table.put(new Integer(8206), "&lrm;"); //$NON-NLS-1$
+ _table.put(new Integer(8207), "&rlm;"); //$NON-NLS-1$
+ _table.put(new Integer(8211), "&ndash;"); //$NON-NLS-1$
+ _table.put(new Integer(151), "&mdash;"); //$NON-NLS-1$
+ _table.put(new Integer(8216), "&lsquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8217), "&rsquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8218), "&sbquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8220), "&ldquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8221), "&rdquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8222), "&bdquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8224), "&dagger;"); //$NON-NLS-1$
+ _table.put(new Integer(8225), "&Dagger;"); //$NON-NLS-1$
+ _table.put(new Integer(8240), "&permil;"); //$NON-NLS-1$
+ _table.put(new Integer(8249), "&lsaquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8250), "&rsaquo;"); //$NON-NLS-1$
+ _table.put(new Integer(8364), "&euro;"); //$NON-NLS-1$
+
+ _reverse = new Hashtable(256);
+ for (Enumeration e = _table.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ String value = (String) _table.get(key);
+ _reverse.put(value, key);
+ // also support without the training ';'
+ _reverse.put(value.substring(0, value.length() - 1), key);
+ }
+ }
+
+ /**
+ * @return if not in the special list
+ */
+ public static String getSpecial(int ch) {
+ return (String) _table.get(new Integer(ch));
+ }
+
+ public static int getSpecial(String str) {
+ Integer result = (Integer) _reverse.get(str);
+ if (result == null) {
+ return -1;
+ } else {
+ return result.intValue();
+ }
+ }
+
+ public static void encode(String str, int start, int end, Writer writer)
+ throws IOException {
+ for (int i = start; i < end; i++) {
+ char ch = str.charAt(i);
+ String special = getSpecial((int) ch);
+ if (special != null) {
+ writer.write(special);
+ } else {
+ if ((ch & 0xff) != 0) {
+ writer.write("&#"); //$NON-NLS-1$
+ writer.write(Integer.toString((int) ch));
+ writer.write(";"); //$NON-NLS-1$
+ } else {
+ writer.write(ch);
+ }
+ }
+ }
+ }
+
+ public static StringBuffer encode(String str, StringBuffer result) {
+ return encode(str, 0, str.length(), result);
+ }
+
+ public static StringBuffer encode(String str, int start, int end,
+ StringBuffer result) {
+ for (int i = start; i < end; i++) {
+ char ch = str.charAt(i);
+ String special = getSpecial((int) ch);
+ if (special != null) {
+ result.append(special);
+ } else {
+ if ((ch & 0xff00) != 0) {
+ result.append("&#"); //$NON-NLS-1$
+ result.append(Integer.toString((int) ch));
+ result.append(";"); //$NON-NLS-1$
+ } else {
+ result.append(ch);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static StringBuffer decode(String str, StringBuffer buffer)
+ throws RuntimeException {
+ return decode(str, 0, str.length(), buffer);
+ }
+
+ public static StringBuffer decode(String str, int start, int end,
+ StringBuffer buffer) throws RuntimeException {
+ int pos = start;
+ do {
+ char ch = str.charAt(pos);
+ if (ch == '&') {
+ int stop = str.indexOf(';', pos + 1);
+ if (stop < 0 || stop >= end) {
+ _log.error("HTMLSpecialCharHelper.3"); //$NON-NLS-1$
+ throw new RuntimeException("HTMLSpecialCharHelper.2"); //$NON-NLS-1$
+ }
+ String sp = str.substring(pos, stop + 1);
+ int special = getSpecial(sp);
+ if (special != -1) {
+ buffer.append((char) special);
+ } else {
+ ch = sp.charAt(1);
+ if (ch != '#')
+ throw new RuntimeException("HTMLSpecialCharHelper.1"); //$NON-NLS-1$
+ try {
+ buffer.append((char) Integer.parseInt(sp.substring(2,
+ sp.length() - 1)));
+ } catch (NumberFormatException ex) {
+ _log.info("HTMLSpecialCharHelper.0", ex); //$NON-NLS-1$
+ throw new RuntimeException("illegal: " + sp); //$NON-NLS-1$
+ }
+ }
+ pos = stop + 1;
+ } else {
+ buffer.append(ch);
+ pos++;
+ }
+ } while (pos < end);
+ return buffer;
+ }
+
+ public static int decodeEntity(String entityRef) {
+ Integer result = (Integer) _reverse.get(entityRef);
+ if (result != null) {
+ return result.intValue();
+ }
+ if (entityRef.length() >= 2 && entityRef.charAt(1) == '#') {
+ String s = entityRef.substring(2);
+ if (s.endsWith(";")) {
+ s = s.substring(0, s.length() - 1);
+ }
+ try {
+ return Integer.parseInt(s);
+ } catch (Exception ex) {
+ // ignore
+ }
+ }
+ return -1;
+ }
+}
+
+// FIXME: will it better to use Character instead of Integer ? (yang)
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLUtil.java
new file mode 100644
index 000000000..0d9111ec8
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/HTMLUtil.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.Arrays;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class HTMLUtil {
+ /**
+ * check whether a char is a HTML whitespace.
+ *
+ * @param ch
+ * @return
+ * @see <a href="http://www.w3.org/TR/html4/struct/text.html#h-9.1">white
+ * space </a>
+ */
+ public static boolean isHTMLWhitespace(char ch) {
+ return ch == ' ' || ch == 0x09 || ch == 0x0c || ch == 0x0d
+ || ch == 0x0a || ch == 0x200b;
+ }
+
+ /**
+ * @param text
+ * @return
+ */
+ public static boolean isHTMLWhitespaceString(String text) {
+ for (int i = 0, size = text.length(); i < size; i++) {
+ if (!isHTMLWhitespace(text.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static final String[] HiddenTags = new String[] {
+ IHTMLConstants.TAG_APPLET, IHTMLConstants.TAG_AREA,
+ IHTMLConstants.TAG_BASE, IHTMLConstants.TAG_BASEFONT,
+ IHTMLConstants.TAG_HEAD, IHTMLConstants.TAG_IFRAME,
+ IHTMLConstants.TAG_ISINDEX, IHTMLConstants.TAG_META,
+ IHTMLConstants.TAG_NOEMBED, IHTMLConstants.TAG_NOFRAMES,
+ IHTMLConstants.TAG_NOSCRIPT, IHTMLConstants.TAG_SCRIPT,
+ IHTMLConstants.TAG_STYLE, IHTMLConstants.TAG_TITLE,
+ IHTMLConstants.TAG_PARAM };
+
+ public static boolean isVisualHtmlElement(String tag) {
+ return !Arrays.asList(HiddenTags).contains(tag.toLowerCase());
+ }
+
+ /**
+ * Handling white space. Basically, for leading and trailing whitespace,
+ * will handle according whether the text is just after tag start or before
+ * tag close.
+ * <p>
+ * For consequent whitespace, will compact them.
+ *
+ * @param data
+ * @return
+ * @see http://www.w3.org/TR/html4/struct/text.html#h-9.1
+ */
+ // XXX: currently, the whitespace handling is in this class, in the future
+ // may consider move it
+ // into lower layer (display/CSS layer)
+ public static String compactWhitespaces(Text textNode, String s) {
+ char[] array = s.toCharArray();
+ StringBuffer buffer = new StringBuffer(array.length);
+ int posi = 0;
+ int len = array.length;
+
+ while (posi < len) {
+ if (HTMLUtil.isHTMLWhitespace(array[posi])) {
+ while (++posi < len && HTMLUtil.isHTMLWhitespace(array[posi]))
+ ;
+ buffer.append(' ');
+ continue;
+ }
+ buffer.append(array[posi++]);
+ continue;
+ }
+ return buffer.toString();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ICacheEntryCreator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ICacheEntryCreator.java
new file mode 100644
index 000000000..8edf74945
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ICacheEntryCreator.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+public interface ICacheEntryCreator {
+ public Object createEntry(Object key);
+
+ public void dispose(Object key, Object entry);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ImageResolver.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ImageResolver.java
new file mode 100644
index 000000000..e24ea9698
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ImageResolver.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class ImageResolver {
+ /**
+ *
+ * @param element
+ * @param attrName
+ * @return
+ */
+ static String getResolvedURL(Element element, String attrName) {
+ URIResolver resolver = null;
+ if (element instanceof IDOMNode) {
+ resolver = ((IDOMNode) element).getModel().getResolver();
+ }
+ if (null == resolver) {
+ return null;
+ }
+ String src = DOMUtil.getAttributeIgnoreCase(element, attrName);
+ if (src != null && src.length() > 0) {
+ return resolver.getLocationByURI(src);
+ }
+ return null;
+ }
+
+ /**
+ * given the element and an attribute name identifying the src of the image,
+ * create a image.
+ *
+ * @param element
+ * @param attrName
+ * @return
+ */
+ public static Image initializeImage(Element element, String attrName) {
+ try {
+ String url = getResolvedURL(element, attrName);
+ if (url == null)
+ return null;
+ return new Image(null, url);
+ } catch (Throwable ex) {
+ // skip exception
+ // ex.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/IntFlexArray.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/IntFlexArray.java
new file mode 100644
index 000000000..e90b41695
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/IntFlexArray.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+/**
+ * Flexible int array. You can set/get of any index value. The array size will
+ * be automatically adjusted.
+ *
+ * @author mengbo
+ */
+public class IntFlexArray {
+ int[] array;
+
+ int size = 0;
+
+ public IntFlexArray() {
+ this(10);
+ }
+
+ public IntFlexArray(int initCapacity) {
+ if (initCapacity <= 0)
+ initCapacity = 10;
+ array = new int[initCapacity];
+ }
+
+ public void setAt(int idx, int obj) {
+ ensureCapacity(idx + 1);
+ array[idx] = obj;
+ if (idx + 1 > size)
+ size = idx + 1;
+ }
+
+ public int getAt(int idx) {
+ if (idx < array.length)
+ return array[idx];
+ else
+ return 0;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ private void ensureCapacity(int size) {
+ if (size <= array.length)
+ return;
+ int[] temp = array;
+ array = new int[2 * temp.length];
+ System.arraycopy(temp, 0, array, 0, temp.length);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JSPUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JSPUtil.java
new file mode 100644
index 000000000..57c4caa92
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JSPUtil.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibController;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TLDCMDocumentManager;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TaglibTracker;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
+import org.eclipse.jst.jsp.core.taglib.TaglibIndex;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.wst.html.core.internal.format.HTMLFormatProcessorImpl;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * utility class for JSP related information.
+ *
+ * @author mengbo
+ */
+public class JSPUtil {
+ /**
+ * find out whether the specified taglib has been defined in the IDOMModel.
+ * If found, then return the prefix. If can't find, then will try to add a
+ * taglib declaration into the model, and try to use the specified default
+ * prefix
+ *
+ * @param model
+ * @param uri
+ * @return
+ */
+ public static String getOrCreatePrefix(IDOMModel model, String uri,
+ String defaultPrefix) {
+ return getOrCreatePrefix(model, uri, defaultPrefix, null);
+ }
+
+ /**
+ *
+ * @param model
+ * @param uri
+ * @param defaultPrefix
+ * @param nodes
+ * if a taglib node is created, then the created tag lib node is
+ * returned in this.
+ * @return
+ */
+ public static String getOrCreatePrefix(IDOMModel model, String uri,
+ String defaultPrefix, Node[] nodes) {
+ String prefix = getPrefix(model, uri);
+ if (prefix != null) {
+ return prefix;
+ }
+ String s = findUnusedPrefix(model, defaultPrefix);
+
+ // TODO: should create the taglib inside the IDOMModel
+ Node[] ref = new Node[1];
+ BodyHelper.findHeaderInsertPosition(IJMTConstants.URI_JSP, "taglib",
+ model.getDocument(), ref);
+ Element ele = model.getDocument().createElement("jsp:directive.taglib");
+ ((IDOMElement) ele).setJSPTag(true);
+ ele.setAttribute(ICSSPropertyID.ATTR_URI, uri);
+ ele.setAttribute(ICSSPropertyID.ATTR_PREFIX, s);
+ if (nodes != null && nodes.length > 0) {
+ nodes[0] = ele;
+ }
+ model.getDocument().insertBefore(ele, ref[0]);
+ new HTMLFormatProcessorImpl().formatNode(ele);
+ return s;
+ }
+
+ /**
+ *
+ * @param model
+ * @param uri
+ * @return null means this is tld is not declared in the jsp file
+ */
+ public static String getPrefix(IDOMModel model, String uri) {
+ TLDCMDocumentManager m = TaglibController.getTLDCMDocumentManager(model
+ .getStructuredDocument());
+ if (m == null) {
+ return null;
+ }
+ List trackers = m.getTaglibTrackers();
+ for (Iterator iter = trackers.iterator(); iter.hasNext();) {
+ TaglibTracker tracker = (TaglibTracker) iter.next();
+ if (uri.equals(tracker.getURI())) {
+ return tracker.getPrefix();
+ } else {
+ CMDocument cmdoc = tracker.getDocument();
+ if (cmdoc instanceof TLDDocument
+ && uri.equals(((TLDDocument) cmdoc).getUri())) {
+ return tracker.getPrefix();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * create specified taglib declaration
+ *
+ * @param model
+ * @param uri
+ * @param prefix
+ * @return
+ */
+ public static Element createTaglibDeclaration(IDOMModel model, String uri,
+ String prefix) {
+ Node[] ref = new Node[1];
+ BodyHelper.findHeaderInsertPosition(IJMTConstants.URI_JSP, "taglib",
+ model.getDocument(), ref);
+ Element ele = model.getDocument().createElement("jsp:directive.taglib");
+ ((IDOMElement) ele).setJSPTag(true);
+ ele.setAttribute("uri", uri);
+ ele.setAttribute("prefix", prefix);
+ model.getDocument().insertBefore(ele, ref[0]);
+ return ele;
+ }
+
+ public static String findUnusedPrefix(IDOMModel model, String suggestion) {
+ if (suggestion == null) {
+ suggestion = "p";
+ }
+ TLDCMDocumentManager m = TaglibController.getTLDCMDocumentManager(model
+ .getStructuredDocument());
+ if (m == null) {
+ return suggestion;
+ }
+ List trackers = m.getTaglibTrackers();
+ Set map = new HashSet();
+ for (Iterator iter = trackers.iterator(); iter.hasNext();) {
+ TaglibTracker tracker = (TaglibTracker) iter.next();
+ map.add(tracker.getPrefix());
+ }
+ if (!map.contains(suggestion)) {
+ return suggestion;
+ }
+ for (int i = 1;; i++) {
+ if (!map.contains(suggestion + i)) {
+ return suggestion + i;
+ }
+ }
+ }
+
+ /**
+ * given the prefix, find the corresponding jsp tld URI.
+ *
+ * @param model
+ * @param prefix
+ * @return
+ */
+ public static String findURIForPrefix(IDOMModel model, String prefix) {
+ if (prefix == null || model == null) {
+ return null;
+ }
+ TLDCMDocumentManager m = TaglibController.getTLDCMDocumentManager(model
+ .getStructuredDocument());
+ if (m == null) {
+ return null;
+ }
+ List trackers = m.getTaglibTrackers();
+ for (Iterator iter = trackers.iterator(); iter.hasNext();) {
+ TaglibTracker tracker = (TaglibTracker) iter.next();
+ if (prefix.equals(tracker.getPrefix())) {
+ CMDocument cmdoc = tracker.getDocument();
+ if (cmdoc instanceof TLDDocument) {
+ return ((TLDDocument) cmdoc).getUri();
+ } else {
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * judge whether the the baseFile belonged project can support uri specified
+ * tag lib
+ *
+ * @param uri
+ * tag lib uri
+ * @param baseFile
+ * @return
+ */
+ public static boolean supportTaglib(String uri, IFile baseFile) {
+ IPath location = baseFile.getLocation();
+ if (location != null) {
+ return TaglibIndex.resolve(location.toString(), uri, false) != null;
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JavaUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JavaUtil.java
new file mode 100644
index 000000000..c444b7e65
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/JavaUtil.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.internal.core.JarEntryFile;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+
+/**
+ * @author mengbo
+ */
+public class JavaUtil {
+ /**
+ *
+ * @param javaProject
+ * @param parent
+ * @return
+ * @author mengbo
+ */
+ public static IPath getPathOnClasspath(IJavaProject javaProject,
+ Object parent) {
+ IPath result = null;
+ if (javaProject == null || parent == null) {
+ return new Path("");
+ }
+ IClasspathEntry[] entries = javaProject.readRawClasspath();
+ IPath classPath = null;
+ if (parent instanceof IResource) {
+ if (((javaProject != null) && !javaProject
+ .isOnClasspath((IResource) parent))) {
+ return new Path("");
+ }
+ if (parent instanceof IFile) {
+ IPath elementPath = ((IFile) parent).getFullPath();
+ if (((IFile) parent).getFileExtension().equalsIgnoreCase(
+ IFileFolderConstants.EXT_PROPERTIES)) {
+ int machings = 0;
+ try {
+ for (int i = 0; i < entries.length; i++) {
+ // Determine whether on this classentry's path
+ machings = entries[i].getPath()
+ .matchingFirstSegments(elementPath);
+ if (machings > 0) {
+ // Get package name
+ classPath = elementPath.removeFirstSegments(
+ machings).removeLastSegments(1);
+ break;
+ }
+ }
+ // Not on the classpath?
+ if (classPath == null) {
+ return null;
+ } else if (classPath.segmentCount() > 0)
+ result = javaProject.findElement(classPath)
+ .getPath().removeFirstSegments(machings)
+ .append(((IFile) parent).getName());
+ else
+ result = ((IFile) parent).getFullPath()
+ .removeFirstSegments(machings);
+ } catch (Exception e) {
+ // Error.DesignerPropertyTool.NatureQuerying = Error in
+ // project java nature querying
+ PDPlugin.getLogger(JavaUtil.class).error(
+ "Error.DesignerPropertyTool.NatureQuerying", e);
+ return null;
+ }
+ }
+ }
+ } else if (parent instanceof JarEntryFile) {
+ IPath elementPath = ((JarEntryFile) parent).getFullPath();
+ if (elementPath.getFileExtension().equalsIgnoreCase(
+ IFileFolderConstants.EXT_PROPERTIES)) {
+ result = elementPath;
+ }
+ }
+ if (result != null) {
+ return result;
+ }
+ return new Path("");
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/NodeLocationComparator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/NodeLocationComparator.java
new file mode 100644
index 000000000..21ea6a1ba
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/NodeLocationComparator.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.text.Assert;
+import org.w3c.dom.Node;
+
+/**
+ * To sort the location of tags, this comparator is used to compare tags' order.
+ *
+ * @author mengbo
+ */
+public class NodeLocationComparator implements Comparator {
+ private final static Map orders = new HashMap();
+
+ private final static Integer DEFAULT_ORDER = new Integer(Integer.MAX_VALUE);
+
+ private static NodeLocationComparator _instance = new NodeLocationComparator();
+ static {
+ orders.put("taglib", new Integer(0));
+ orders.put("directive.taglib", new Integer(0));
+ orders.put("head", new Integer(1));
+ }
+
+ private NodeLocationComparator() {
+ }
+
+ public static NodeLocationComparator getInstance() {
+ return _instance;
+ }
+
+ /**
+ * The object to be compared could be Node or tag name.
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ Assert.isTrue((o1 instanceof Node || o1 instanceof String)
+ && (o2 instanceof Node || o2 instanceof String));
+ Integer i1 = getOrder(o1);
+ Integer i2 = getOrder(o2);
+ return i1.compareTo(i2);
+ }
+
+ private Integer getOrder(Object n) {
+ String name = null;
+ if (n instanceof Node) {
+ name = ((Node) n).getLocalName();
+ } else {
+ name = (String) n;
+ }
+ if (name != null) {
+ Object order = orders.get(name);
+ if (order != null) {
+ return (Integer) order;
+ }
+ }
+ return DEFAULT_ORDER;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/PreviewUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/PreviewUtil.java
new file mode 100644
index 000000000..92321f445
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/PreviewUtil.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.PathUtil;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.ui.IEditorInput;
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ */
+public class PreviewUtil {
+ /** Create the logger for this class */
+ private static Logger _log = PDPlugin.getLogger(PreviewUtil.class);
+
+ /** line separator */
+ public static final String LINE_SEPARATOR = System
+ .getProperty("line.separator"); //$NON-NLS-1$
+
+ /** web root path */
+ public static String WEBROOT_PATH = null;
+
+ /** the file being previewed */
+ public static IFile CURRENT_FILE = null;
+
+ /** the property bundel */
+ public static PropertyResourceBundle BUNDLE = null;
+
+ /** the property bundel map used for loadbundle preview action */
+ public static Map BUNDLE_MAP = null;
+
+ /** the variable name used for loadbundel preview action */
+ public static String VAR = null;
+
+ /** key is prefix value is uri */
+ private static Map _taglibMap = new HashMap();
+
+ private static final String PAGE_EXTEND = "_jsppreview_.html"; //$NON-NLS-1$
+
+ /**
+ * @return Returns the _taglibMap.
+ */
+ public static Map getTaglibMap() {
+ return _taglibMap;
+ }
+
+ /**
+ * @param map
+ * The _taglibMap to set.
+ */
+ public static void setTaglibMap(Map map) {
+ _taglibMap = map;
+ }
+
+ /**
+ * Get tag attribute string from attribute map
+ *
+ * @param map
+ * tag attribute map
+ */
+ public static String getAttributesAsString(Map map) {
+ return getAttributesAsString(map, true);
+ }
+
+ /**
+ * Get file path from uri
+ *
+ * @param uri
+ * taglib uri
+ */
+ public static String getPathFromURI(String uri) {
+ if (uri == null) {
+ return uri;
+ }
+
+ if (uri.startsWith(IFileFolderConstants.PATH_SEPARATOR)) {
+ return PreviewUtil.WEBROOT_PATH + uri;
+ }
+ IFile curFile = PreviewUtil.CURRENT_FILE;
+ if (curFile != null) {
+ IContainer con = curFile.getParent();
+ if (con != null) {
+ IPath path = con.getLocation();
+ if (path != null) {
+ String aPath = path.toString() + File.separator + uri;
+
+ aPath = aPath.replace('/', File.separatorChar);
+ aPath = aPath.replace('\\', File.separatorChar);
+ if (aPath.endsWith(File.separator)) {
+ aPath += File.separator;
+ }
+ File file = new File(aPath);
+ if (file.exists()) {
+ return aPath;
+ } else {
+ return uri;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get bundle value for expression
+ *
+ * @param attrValue
+ * expression
+ */
+ public static String getValueOFEP(String attrValue) {
+ if (attrValue != null) {
+ if (attrValue.startsWith("#{")) //$NON-NLS-1$
+ {
+ String key, value = null;
+ int i = attrValue.lastIndexOf("."); //$NON-NLS-1$
+ if (i > 0) {
+ key = attrValue.substring(i + 1, attrValue.length() - 1)
+ .trim();
+ String bundleVariable = attrValue.substring(2, i).trim();
+ if (BUNDLE_MAP == null) {
+ return attrValue; //$NON-NLS-1$
+ }
+ PropertyResourceBundle bundle = (PropertyResourceBundle) BUNDLE_MAP
+ .get(bundleVariable);
+
+ if (bundle != null) {
+ try {
+ value = bundle.getString(key);
+ if (value != null) {
+ return value;
+ } else {
+ return attrValue; //$NON-NLS-1$
+ }
+ } catch (MissingResourceException e1) {
+ // "Error in resource bundle processing:"
+ _log.info("PreviewUtil.Error.0", e1); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ return attrValue;
+ }
+
+ /**
+ * Get tag attribute string from attribute map
+ *
+ * @param map
+ * tag attribute map
+ * @param flag
+ * state
+ */
+ public static String getAttributesAsString(Map map, boolean flag) {
+ if (map == null) {
+ return null;
+ }
+
+ StringBuffer stringbuffer = new StringBuffer();
+ for (Iterator e = map.keySet().iterator(); e.hasNext();) {
+ String attrName = (String) e.next();
+ String attrValue = (String) map.get(attrName);
+ attrValue = getValueOFEP(attrValue);
+ if (ICSSPropertyID.ATTR_SRC.equalsIgnoreCase(attrName)
+ || ICSSPropertyID.ATTR_HREF.equalsIgnoreCase(attrName)
+ || ICSSPropertyID.ATTR_URI.equalsIgnoreCase(attrName)
+ || ICSSPropertyID.ATTR_BINDING.equalsIgnoreCase(attrName)
+ || ICSSPropertyID.ATTR_PAGE.equalsIgnoreCase(attrName)) {
+ if (PreviewUtil.WEBROOT_PATH != null && attrValue != null
+ && !attrValue.startsWith("http") //$NON-NLS-1$
+ && !attrValue.startsWith("file")) //$NON-NLS-1$
+ {
+ attrValue = getPathFromURI(attrValue);
+ }
+ }
+ if (attrValue != null) {
+ stringbuffer.append(" ").append(attrName); //$NON-NLS-1$
+ if (attrValue.indexOf(34) != -1) {
+ StringBuffer stringbuffer1 = new StringBuffer();
+ for (int j = 0; j < attrValue.length(); j++) {
+ char c = attrValue.charAt(j);
+ if (c != '"') {
+ stringbuffer1.append(c);
+ }
+ }
+
+ attrValue = stringbuffer1.toString();
+ }
+ if (attrValue != null && attrValue.startsWith("#{")) //$NON-NLS-1$
+ {
+ attrValue = ""; //$NON-NLS-1$
+ }
+ stringbuffer.append("=\"").append(attrValue).append('"'); //$NON-NLS-1$
+ }
+ }
+ // System.out.println("BBBB:" +stringbuffer.toString());
+
+ return stringbuffer.toString();
+ }
+
+ /**
+ * Change NamedNodeMap type to Map type
+ *
+ * @param nodeMap
+ * NamedNodeMap type
+ */
+ public static Map getAttributeMap(NamedNodeMap nodeMap) {
+ if (nodeMap != null) {
+ int len = nodeMap.getLength();
+ HashMap map = new HashMap();
+ for (int i = 0; i < len; i++) {
+ Node node = nodeMap.item(i);
+ String name = node.getNodeName();
+ String value = node.getNodeValue();
+ if (name != null
+ && !name.trim().equalsIgnoreCase("") && value != null) //$NON-NLS-1$
+ {
+ map.put(name, value);
+ }
+ }
+ return map;
+ }
+ return null;
+ }
+
+ /**
+ * @param result
+ * @param editorInput
+ * @return
+ */
+ public static File toFile(StringBuffer result, IEditorInput editorInput) {
+ try {
+ File file = File.createTempFile("previewtmp", ".html"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ FileOutputStream fos = new FileOutputStream(file);
+ PrintStream ps = new PrintStream(fos, true, "UTF-8"); //$NON-NLS-1$
+ ps.print(result.toString());
+ ps.close();
+ fos.close();
+ return file;
+ } catch (IOException e) {
+ // "Error in file open:"
+ _log.info("PreviewUtil.Error.3", e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ * do preivew on Node recursively translate escape char for Node and Node's
+ * child translate relative path for Node and Node's child
+ *
+ * @param node
+ * root node that will be previewed
+ */
+ public static void previewNode(Node node) {
+ if (node == null) {
+ return;
+ }
+ NodeList nodeList = node.getChildNodes();
+ if (nodeList == null) {
+ return;
+ }
+ NamedNodeMap attrMap = node.getAttributes();
+
+ if (attrMap != null) {
+ for (int i = 0, n = attrMap.getLength(); i < n; i++) {
+ Node attrNode = attrMap.item(i);
+ if (attrNode != null && attrNode instanceof Attr) {
+ Attr attr = (Attr) attrNode;
+ attr.setNodeValue(getValueOFEP(attr.getNodeValue()));
+ attr.setNodeValue(PathUtil.convertToAbsolutePath(attr
+ .getNodeValue(), null));
+ StringBuffer buf = new StringBuffer();
+ String attrValue = attr.getNodeValue();
+ }
+ }
+ }
+ for (int i = 0, n = nodeList.getLength(); i < n; i++) {
+ previewNode(nodeList.item(i));
+ }
+ }
+
+ // /**
+ // * handle escape attebute of tag
+ // *
+ // * @param node
+ // * @return
+ // */
+ // public static boolean escapeFoeNode(Node node)
+ // {
+ // if (node == null)
+ // {
+ // return false;
+ // }
+ // NamedNodeMap attrMap = node.getAttributes();
+ // if (attrMap != null)
+ // {
+ // for (int i = 0, n = attrMap.getLength(); i < n; i++)
+ // {
+ // Node attrNode = attrMap.item(i);
+ // if (attrNode != null && attrNode instanceof Attr)
+ // {
+ // if ("escape".equalsIgnoreCase(attrNode.getNodeName())
+ // && "true".equalsIgnoreCase(attrNode.getNodeValue()))
+ // {
+ // return true;
+ // }
+ // }
+ // }
+ // }
+ // return false;
+ // }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ProjectResolver.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ProjectResolver.java
new file mode 100644
index 000000000..7b119630a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/ProjectResolver.java
@@ -0,0 +1,488 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.common.utils.ResourceUtils;
+import org.eclipse.jst.pagedesigner.common.utils.WebrootUtil;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.wst.common.uriresolver.internal.util.URIHelper;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class ProjectResolver implements URIResolver {
+ private static final String TLD_TAG_URI = "uri";
+
+ private static final String URI_PREFIX_HTTP = "http";
+
+ private static final String FILE_PROTOCOL = "file";
+
+ /** Create the logger for this class */
+ private static Logger _log = PDPlugin.getLogger(ProjectResolver.class);
+
+ private IProject _project = null;
+
+ private String _fileBaseLocation = null;
+
+ private static Map _uriMap = null;
+
+ /**
+ * It is strongly recommended that clients use
+ * project.getAdapter(URIResolver.class) to obtain a URIResolver aware of
+ * the Project's special requirements. Note that a URIResolver may not be
+ * returned at all so manually creating this object may still be required.
+ */
+ public ProjectResolver(IProject project) {
+ super();
+ _project = project;
+ }
+
+ public void seekTld(IFolder path) {
+ if (path == null) {
+ return;
+ }
+ if (_uriMap == null) {
+ _uriMap = new HashMap();
+ }
+
+ try {
+ IResource[] res = path.members();
+ if (null == res) {
+ return;
+ }
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] instanceof IFolder) {
+ seekTld((IFolder) res[i]);
+ }
+ String ext = res[i].getFileExtension();
+ if (IFileFolderConstants.EXT_TAGLIB.equalsIgnoreCase(ext)) {
+ IFile tldFile = (IFile) res[i];
+ String uri = getURIfromTLD(tldFile);
+ String locate = tldFile.getLocation().toOSString();
+ if (uri != null && _uriMap.get(uri) == null) {
+ _uriMap.put(uri, locate);
+ }
+ }
+ }
+ } catch (CoreException e) {
+ _log.error("Error.ProjectResolver.GetlocationByURI.0", e);
+ }
+ }
+
+ public void seekTld(File path) {
+ if (path == null || !path.isDirectory()) {
+ return;
+ }
+ if (_uriMap == null) {
+ _uriMap = new HashMap();
+ }
+
+ try {
+ File[] res = path.listFiles();
+ if (null == res) {
+ return;
+ }
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] instanceof IFolder) {
+ seekTld(res[i]);
+ }
+
+ if (res[i].getName().endsWith(
+ IFileFolderConstants.DOT
+ + IFileFolderConstants.EXT_TAGLIB)) {
+ String uri = getURIfromTLD(res[i]);
+ String locate;
+
+ locate = res[i].getCanonicalPath();
+
+ if (uri != null && _uriMap.get(uri) == null) {
+ _uriMap.put(uri, locate);
+ }
+ }
+ }
+ } catch (IOException e1) {
+ _log.error("Error.ProjectResolver.GetlocationByURI.0", e1);
+ }
+ }
+
+ public String getURIfromTLD(File tldFile) {
+
+ if (tldFile == null) {
+ return null;
+ }
+ IDOMModel tldModel;
+
+ InputStream in = null;
+ try {
+ in = new FileInputStream(tldFile);
+ } catch (FileNotFoundException e) {
+ _log.error("RenderingTraverser.Error.FileNotFound", e);
+ }
+ IDOMModel xmlModel = null;
+
+ try {
+ tldModel = (IDOMModel) PDPlugin.getModelManager().getModelForRead(
+ tldFile.getAbsolutePath(), in, null);
+ NodeList uriList = tldModel.getDocument().getElementsByTagName(
+ TLD_TAG_URI);
+ for (int i = 0, n = uriList.getLength(); i < n; i++) {
+ Node uri = uriList.item(i);
+ return uri.getChildNodes().item(0).getNodeValue();
+ }
+ } catch (UnsupportedEncodingException e1) {
+ _log.error("RenderingTraverser.Error.UnsupportedEncoding", e1);
+ } catch (IOException e1) {
+ _log.error("RenderingTraverser.Error.IO", e1);
+ } finally {
+ ResourceUtils.ensureClosed(in);
+ }
+
+ return null;
+ }
+
+ public String getURIfromTLD(IFile tldFile) {
+ if (tldFile == null) {
+ return null;
+ }
+ IDOMModel tldModel;
+
+ try {
+ tldModel = (IDOMModel) getModelManager().getModelForRead(tldFile);
+ NodeList uriList = tldModel.getDocument().getElementsByTagName(
+ TLD_TAG_URI);
+ for (int i = 0, n = uriList.getLength(); i < n; i++) {
+ Node uri = uriList.item(i);
+ return uri.getChildNodes().item(0).getNodeValue();
+ }
+ } catch (IOException e) {
+ // Error in taglib locating.
+ _log.error("Error.ProjectResolver.GetlocationByURI.0", e); //$NON-NLS-1$
+ } catch (CoreException e1) {
+ _log.error("Error.ProjectResolver.GetlocationByURI.0", e1);
+ }
+ return null;
+ }
+
+ public void initTldMap() {
+ if (_uriMap == null) {
+ _uriMap = new HashMap();
+ }
+ if (_project == null) {
+ return;
+ }
+ if (WebrootUtil.getWebContentFolder(_project) == null) {
+ return;
+ }
+ IFolder webinf = WebrootUtil.getWebContentFolder(_project).getFolder(
+ IFileFolderConstants.FOLDER_WEBINF);
+ if (webinf != null && webinf.exists()) {
+ seekTld(webinf);
+ }
+
+ String locate = PDPlugin.getInstallLocation().append("/jsf-tld")
+ .toString();
+ File jsfDir = new File(locate);
+ seekTld(jsfDir);
+
+ }
+
+ public java.lang.String getFileBaseLocation() {
+ return _fileBaseLocation;
+ }
+
+ public java.lang.String getLocationByURI(String uri) {
+ // System.out.println(getLocationByURI(uri, getFileBaseLocation()));
+ return getLocationByURI(uri, getFileBaseLocation());
+ }
+
+ private IModelManager getModelManager() {
+ return StructuredModelManager.getModelManager();
+ }
+
+ private String getLocationFromWEBXML(String uri, String baseReference) {
+ if (uri == null) {
+ return null;
+ }
+ try {
+ // if (_project.hasNature(ICommonConstants.NATURE_WEBAPP))
+ // {
+ if (uri.startsWith(IFileFolderConstants.PATH_SEPARATOR)) {
+ uri = _project.getProject().getLocation().toString()
+ + IFileFolderConstants.PATH_SEPARATOR
+ + WebrootUtil.getWebContentFolderName(_project) + uri;
+ }
+ if (uri.startsWith(URI_PREFIX_HTTP)) {
+ IFile webxml = WebrootUtil.getWebContentFolder(_project)
+ .getFolder(IFileFolderConstants.FOLDER_WEBINF).getFile(
+ IFileFolderConstants.FILE_WEB_XML);
+ IDOMModel xmlModel;
+
+ if (webxml.exists()) {
+ try {
+ xmlModel = (IDOMModel) getModelManager()
+ .getModelForRead(webxml);
+
+ NodeList taglibNodeList = xmlModel
+ .getDocument()
+ .getElementsByTagName(ICSSPropertyID.TAG_TAGLIB);
+
+ for (int i = 0, size = taglibNodeList.getLength(); i < size; i++) {
+ Node taglibNode = taglibNodeList.item(i);
+
+ NodeList childList = taglibNode.getChildNodes();
+ String taguri = "";
+ String taglocation = "";
+ for (int j = 0, childSize = childList.getLength(); j < childSize; j++) {
+ Node childTaglibNode = childList.item(j);
+ if (ICSSPropertyID.ATTR_TAGLIB_URI
+ .equalsIgnoreCase(childTaglibNode
+ .getNodeName())) {
+ taguri = childTaglibNode.getChildNodes()
+ .item(0).getNodeValue();
+ }
+ if (ICSSPropertyID.ATTR_TAGLIB_LOCATION
+ .equalsIgnoreCase(childTaglibNode
+ .getNodeName())) {
+ taglocation = childTaglibNode
+ .getChildNodes().item(0)
+ .getNodeValue();
+ }
+
+ }
+ if (uri.equalsIgnoreCase(taguri))
+ uri = _project.getProject().getLocation()
+ .toString()
+ + IFileFolderConstants.PATH_SEPARATOR
+ + WebrootUtil
+ .getWebContentFolderName(_project)
+ + taglocation;
+ }
+ xmlModel.releaseFromRead();
+ } catch (IOException e) {
+
+ // Error in taglib locating.
+ _log.error(
+ "Error.ProjectResolver.GetlocationByURI.0", e); //$NON-NLS-1$
+ } catch (CoreException e1) {
+ e1.printStackTrace();
+ _log.error("Error.ProjectResolver.GetlocationByURI.0",
+ e1);
+ }
+
+ }
+ }
+ // }
+ } catch (DOMException e1) {
+ // Error in taglib locating.
+ _log.error("Error.ProjectResolver.GetlocationByURI.0", e1); //$NON-NLS-1$
+ }
+ // catch (CoreException e1)
+ // {
+ //
+ // _log.error("Error.ProjectResolver.GetlocationByURI.0", e1);
+ // }
+
+ if (isFileURL(uri)) {
+ try {
+ URL url = new URL(uri);
+ return getPath(url);
+ } catch (MalformedURLException e) {
+ _log.error("Error.ProjectResolver.GetlocationByURI.0", e);
+ }
+ }
+ // defect 244817 end
+ return URIHelper.normalize(uri, baseReference, getRootLocationString());
+
+ }
+
+ public String getLocationByURI(String uri, String baseReference) {
+ // DataWindow may generate URL like "d:\somefile" (dos path). We may
+ // need some
+ // special support. (lium)
+ int columnIndex = uri.indexOf(":");
+ int slashIndex = uri.indexOf("/");
+ if (columnIndex != -1 && (slashIndex == -1 || columnIndex < slashIndex)) {
+ return uri;
+ }
+
+ String result = getLocationFromWEBXML(uri, baseReference);
+ if (result != null && !result.equals(uri)) {
+ return result;
+ }
+ if (_uriMap == null) {
+ initTldMap();
+ }
+ if (_uriMap != null) {
+ return (String) _uriMap.get(uri);
+ }
+ return null;
+ }
+
+ // defect 244817 start
+ /**
+ * @param passedSpec
+ * @return boolean
+ */
+ private boolean isFileURL(String passedSpec) {
+ if (passedSpec == null) {
+ return false;
+ }
+ final String spec = passedSpec.trim();
+ if (spec.length() == 0) {
+ return false;
+ }
+ String newProtocol = null;
+ for (int index = 0, limit = spec.length(); index < limit; index++) {
+ final char p = spec.charAt(index);
+ if (p == '/') {
+ //$NON-NLS-1$
+ break;
+ }
+ if (p == ':') {
+ //$NON-NLS-1$
+ newProtocol = spec.substring(0, index);
+ break;
+ }
+ }
+ return (newProtocol != null && newProtocol
+ .compareToIgnoreCase(FILE_PROTOCOL) == 0); //$NON-NLS-1$
+ }
+
+ /**
+ * @param url
+ * @return String
+ */
+ private String getPath(URL url) {
+ String ref = url.getRef() == null ? "" : "#" + url.getRef(); //$NON-NLS-1$ //$NON-NLS-2$
+ String strPath = url.getFile() + ref;
+ IPath path;
+ if (strPath.length() == 0) {
+ path = Path.ROOT;
+ } else {
+ path = new Path(strPath);
+ String query = null;
+ StringTokenizer parser = new StringTokenizer(strPath, "?"); //$NON-NLS-1$
+ int tokenCount = parser.countTokens();
+ if (tokenCount == 2) {
+ path = new Path((String) parser.nextElement());
+ query = (String) parser.nextElement();
+ }
+ if (query == null) {
+ parser = new StringTokenizer(path.toString(), "#"); //$NON-NLS-1$
+ tokenCount = parser.countTokens();
+ if (tokenCount == 2) {
+ path = new Path((String) parser.nextElement());
+ }
+ }
+ }
+ return getPath(path, url.getHost());
+ }
+
+ /**
+ * @param path
+ * @param host
+ * @return String
+ */
+ private String getPath(IPath path, String host) {
+ IPath newPath = path;
+ // They are potentially for only Windows operating system.
+ // a.) if path has a device, and if it begins with IPath.SEPARATOR,
+ // remove it
+ final String device = path.getDevice();
+ if ((device != null) && (device.length() > 0)) {
+ if (device.charAt(0) == IPath.SEPARATOR) {
+ final String newDevice = device.substring(1);
+ newPath = path.setDevice(newDevice);
+ }
+ }
+ // b.) if it has a hostname, it is UNC name... Any java or eclipse api
+ // helps it ??
+ if (path != null && host != null && host.length() != 0) {
+ IPath uncPath = new Path(host);
+ uncPath = uncPath.append(path);
+ newPath = uncPath.makeUNC(true);
+ }
+ return newPath.toString();
+ }
+
+ /**
+ * Resolve the (possibly relative) URI acording to RFC1808 using the default
+ * file base location. Resolves resource references into absolute resource
+ * locations without ensuring that the resource actually exists. Note:
+ * currently resolveCrossProjectLinks is ignored in this implementation.
+ */
+ public java.lang.String getLocationByURI(String uri,
+ boolean resolveCrossProjectLinks) {
+ return getLocationByURI(uri, getFileBaseLocation(),
+ resolveCrossProjectLinks);
+ }
+
+ /**
+ * Perform the getLocationByURI action using the baseReference as the point
+ * of reference instead of the default for this resolver Note: currently
+ * resolveCrossProjectLinks is ignored in this implementation.
+ */
+ public java.lang.String getLocationByURI(String uri, String baseReference,
+ boolean resolveCrossProjectLinks) {
+ return getLocationByURI(uri, baseReference);
+ }
+
+ public org.eclipse.core.resources.IProject getProject() {
+ return _project;
+ }
+
+ public org.eclipse.core.resources.IContainer getRootLocation() {
+ return _project;
+ }
+
+ protected String getRootLocationString() {
+ return null;
+ }
+
+ public void setFileBaseLocation(java.lang.String newFileBaseLocation) {
+ _fileBaseLocation = newFileBaseLocation;
+ }
+
+ public void setProject(org.eclipse.core.resources.IProject newProject) {
+ _project = newProject;
+ }
+
+ public InputStream getURIStream(String uri) {
+ return null;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectManyHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectManyHelper.java
new file mode 100644
index 000000000..6fd8d89d9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectManyHelper.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author mengbo
+ */
+public class SelectManyHelper {
+ private static final String OPTION_VISUAL_PREFIX = "option: "; //$NON-NLS-1$
+
+ private static final String OPTION_VISUAL_PREFIX_BINDING = "option(binding): "; //$NON-NLS-1$
+
+ private static final String OPTION_VISUAL_PREFIX_VALUE = "option(value): "; //$NON-NLS-1$
+
+ private static final String NO_VALUE = "<no value>"; //$NON-NLS-1$
+
+ public static HashSet JSF_SELECT_TAGS, HTML_SELECT_TAGS;
+
+ public static HashSet HTML_SELECT_TAG_OPTIONS, JSF_SELECT_TAG_OPTIONS;
+
+ static {
+ HTML_SELECT_TAGS = new HashSet(10);
+ HTML_SELECT_TAGS.add(IHTMLConstants.TAG_SELECT);
+ HTML_SELECT_TAGS.add(IHTMLConstants.TAG_OPTGROUP);
+ HTML_SELECT_TAG_OPTIONS = new HashSet(10);
+ HTML_SELECT_TAG_OPTIONS.add(IHTMLConstants.TAG_OPTGROUP);
+ HTML_SELECT_TAG_OPTIONS.add(IHTMLConstants.TAG_OPTION);
+
+ JSF_SELECT_TAG_OPTIONS = new HashSet(10);
+ JSF_SELECT_TAG_OPTIONS.add(IJSFConstants.TAG_SELECTITEM);
+ JSF_SELECT_TAG_OPTIONS.add(IJSFConstants.TAG_SELECTITEMS);
+ JSF_SELECT_TAGS = new HashSet(10);
+ JSF_SELECT_TAGS.add(IJSFConstants.TAG_SELECTONELISTBOX);
+ JSF_SELECT_TAGS.add(IJSFConstants.TAG_SELECTONEMENU);
+ JSF_SELECT_TAGS.add(IJSFConstants.TAG_SELECTMANYLISTBOX);//
+ JSF_SELECT_TAGS.add(IJSFConstants.TAG_SELECTMANYMENU);//
+ JSF_SELECT_TAGS.add(IJSFConstants.TAG_SELECTMANYCHECKBOX);
+ }
+
+ public static Object[] getSelectOptions(Element node) {
+ if (node == null) {
+ return null;
+ }
+ IDOMModel xmlModel = null;
+ if (node instanceof IDOMNode) {
+ xmlModel = ((IDOMNode) node).getModel();
+ }
+ if (xmlModel == null) {
+ return null;
+ }
+ // TODO: this query is not cached.
+ String prefixNode = JSPUtil.getPrefix(xmlModel,
+ IJMTConstants.URI_JSF_HTML);
+ if (prefixNode != null && node.getPrefix() != null
+ && node.getPrefix().equals(prefixNode)) {
+ if (JSF_SELECT_TAGS.contains(node.getLocalName())) {
+ String prefixItem = JSPUtil.getPrefix(xmlModel,
+ IJMTConstants.URI_JSF_CORE);
+ List result = new ArrayList();
+ NodeList items = node.getElementsByTagName(prefixItem
+ + ":" + IJSFConstants.TAG_SELECTITEM); //$NON-NLS-1$
+ for (int i = 0, n = items.getLength(); i < n; i++) {
+ result.add(items.item(i));
+ }
+ items = node.getElementsByTagName(prefixItem
+ + ":" + IJSFConstants.TAG_SELECTITEMS); //$NON-NLS-1$
+ for (int i = 0, n = items.getLength(); i < n; i++) {
+ result.add(items.item(i));
+ }
+ return result.size() > 0 ? result.toArray(new Node[result
+ .size()]) : null;
+ }
+ }
+ if (node.getPrefix() == null) {
+ if (HTML_SELECT_TAGS.contains(node.getNodeName().toLowerCase())) {
+ List result = new ArrayList();
+ NodeList options = node
+ .getElementsByTagName(IHTMLConstants.TAG_OPTION);
+ NodeList optionGroups = node
+ .getElementsByTagName(IHTMLConstants.TAG_OPTGROUP);
+ for (int i = 0, n = options.getLength(); i < n; i++) {
+ result.add(options.item(i));
+ }
+ for (int i = 0, n = optionGroups.getLength(); i < n; i++) {
+ result.add(optionGroups.item(i));
+ }
+ return result.toArray(new Node[result.size()]);
+ }
+ }
+ return null;
+ }
+
+ public static String[] getSelectOptionsString(Element node) {
+ if (node == null) {
+ return null;
+ }
+ Object[] options = getSelectOptions(node);
+ if (null == options || options[0] == null) {
+ return null;
+ }
+ List result = new ArrayList();
+ for (int i = 0, n = options.length; i < n; i++) {
+ if (options[i] instanceof Element) {
+ Element element = (Element) options[i];
+ Node value = null;
+ if (element.getNodeName()
+ .indexOf(IJSFConstants.TAG_SELECTITEMS) >= 0) {
+ value = element.getAttributeNode(IJSFConstants.ATTR_VALUE);
+ } else if (element.getNodeName().indexOf(
+ IJSFConstants.TAG_SELECTITEM) >= 0) {
+ value = element
+ .getAttributeNode(ICSSPropertyID.ATTR_ITEMLABEL);
+ }
+ if (value != null) {
+ result.add(value.getNodeValue());
+ }
+ }
+ }
+ return (String[]) result.toArray(new String[] {});
+ }
+
+ public static boolean hasSelectOptions(Element node) {
+ if (node == null) {
+ return false;
+ }
+ String uri = CMUtil.getElementNamespaceURI(node);
+ if (IJMTConstants.URI_JSF_HTML.equals(uri)) {
+
+ if (JSF_SELECT_TAGS.contains(node.getLocalName())) {
+ IDOMModel model = ((IDOMElement) node).getModel();
+ String jsfcorePrefix = JSPUtil.getPrefix(model,
+ IJMTConstants.URI_JSF_CORE);
+ if (jsfcorePrefix != null) {
+ NodeList nl = node.getElementsByTagName(jsfcorePrefix + ":"
+ + IJSFConstants.TAG_SELECTITEM);
+ NodeList nl1 = node.getElementsByTagName(jsfcorePrefix
+ + ":" + IJSFConstants.TAG_SELECTITEMS);
+ return nl.getLength() > 0 || nl1.getLength() > 0;
+ } else {
+ return false;
+ }
+ }
+ }
+ if (IJMTConstants.URI_HTML.equals(uri)) {
+ if (HTML_SELECT_TAGS.contains(node.getNodeName().toLowerCase())) {
+ NodeList nl = node
+ .getElementsByTagName(IHTMLConstants.TAG_OPTION);
+ NodeList nl1 = node
+ .getElementsByTagName(IHTMLConstants.TAG_OPTGROUP);
+ return nl.getLength() > 0 || nl1.getLength() > 0;
+ }
+ }
+ return false;
+ }
+
+ public static boolean supportSections(Element node) {
+ String uri = CMUtil.getElementNamespaceURI(node);
+ if (IJMTConstants.URI_JSF_HTML.equals(uri)) {
+ return JSF_SELECT_TAGS.contains(node.getLocalName());
+ }
+ if (IJMTConstants.URI_HTML.equals(uri)) {
+ return HTML_SELECT_TAGS.contains(node.getNodeName().toLowerCase());
+ }
+ return false;
+ }
+
+ public static String getJsfSelectionVisualLabel(Element element) {
+ /*
+ * if (ele.getAttribute(ICSSPropertyID.ATTR_ITEMLABEL) != null) { return
+ * OPTION_VISUAL_PREFIX +
+ * ele.getAttribute(ICSSPropertyID.ATTR_ITEMLABEL); //$NON-NLS-1$ } else
+ * if (ele.getAttribute(ICSSPropertyID.ATTR_BINDING) != null) { return
+ * OPTION_VISUAL_PREFIX_BINDING +
+ * ele.getAttribute(ICSSPropertyID.ATTR_BINDING); //$NON-NLS-1$ } else
+ * if (ele.getAttribute(ICSSPropertyID.ATTR_ITEMVALUE) != null) { return
+ * OPTION_VISUAL_PREFIX_VALUE +
+ * ele.getAttribute(ICSSPropertyID.ATTR_ITEMVALUE); //$NON-NLS-1$ }
+ *
+ * return NO_VALUE; //$NON-NLS-1$
+ */
+ if (element != null) {
+ return element.getNodeName();
+ } else {
+ return NO_VALUE;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectionHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectionHelper.java
new file mode 100644
index 000000000..7e79be45a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/SelectionHelper.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition2;
+import org.eclipse.jst.pagedesigner.dom.DOMUtil;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRange;
+import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class SelectionHelper {
+ /**
+ * convert the text selection to a Node. Will use the start offset of the
+ * text selection.
+ *
+ * @param model
+ * @param textSel
+ * @return
+ */
+ public static Node toNode(IStructuredModel model, ITextSelection textSel) {
+ // FIXME: currently always normalize to a single node. should also
+ // consider change into DesignRange
+ // on text selection, find the appropriate Node
+ Object inode = model.getIndexedRegion(textSel.getOffset());
+ if (inode instanceof Node) {
+ return (Node) inode;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * convert a structured selection of NodeEditPart or Node into the first
+ * node.
+ *
+ * @param selection
+ * @return
+ */
+ public static Node toNode(IStructuredSelection selection) {
+ if (selection.isEmpty()) {
+ return null;
+ }
+ Object first = selection.getFirstElement();
+ if (first instanceof Node) {
+ return (Node) first;
+ } else if (first instanceof NodeEditPart) {
+ return ((NodeEditPart) first).getIDOMNode();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * convert a DesignRange into a single node.
+ *
+ * @param range
+ * @return
+ */
+ public static Node toNode(DesignRange range) {
+ if (range.isValid()) {
+ Node node1 = range.getStartPosition().getContainerNode();
+ Node node2 = range.getEndPosition().getContainerNode();
+ return DOMUtil.findCommonAncester(node1, node2);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param model
+ * @param region
+ * if null, then will calculate it using offset.
+ * @param offset
+ * offset in source.
+ * @return
+ */
+ public static IDOMPosition toDOMPosition(IDOMModel model,
+ IndexedRegion region, int offset) {
+ if (region == null) {
+ region = model.getIndexedRegion(offset);
+ }
+ if (region == null && offset > 0) {
+ // in case this is at end of file.
+ offset = offset - 1;
+ region = model.getIndexedRegion(offset);
+ if (region != null) {
+ if (region.getEndOffset() >= offset + 1) {
+ offset += 1; // restore offset.
+ }
+ }
+ }
+ if (region == null) {
+ return new DOMPosition(model.getDocument(), 0);
+ }
+ IDOMNode node = (IDOMNode) region;
+ int start = node.getStartOffset();
+ if (offset <= start) {
+ return new DOMRefPosition(node, false);
+ }
+ int end = node.getEndOffset();
+ if (offset >= end) {
+ return new DOMRefPosition(node, true);
+ }
+ if (node instanceof CharacterData) {
+ String data = ((CharacterData) node).getData();
+ String source = node.getSource();
+ if (data.equals(source)) {
+ return new DOMPosition(node, offset - start);
+ }
+ IStructuredDocumentRegion r = node
+ .getFirstStructuredDocumentRegion();
+ int countedData = 0;
+ int offsetInNode = offset - start;
+ while (r != null) {
+ if (DOMRegionContext.XML_CHAR_REFERENCE.equals(r.getType())
+ || DOMRegionContext.XML_ENTITY_REFERENCE.equals(r
+ .getType())) {
+ countedData += 1; // FIXME: what if the entity reference's
+ // corresponding data is more than 1
+ // char?
+ // where can we get that information?
+ if (r.getEnd() >= offset) {
+ return new DOMPosition(node, countedData);
+ }
+ } else {
+ if (r.getEnd() >= offset) {
+ return new DOMPosition(node, countedData + offset
+ - r.getStart());
+ }
+ countedData += r.getLength();
+ }
+ r = r.getNext();
+ }
+ return new DOMRefPosition(node, true);
+ } else if (node instanceof Element) {
+ CMElementDeclaration cm = CMUtil
+ .getElementDeclaration((Element) node);
+ if (cm != null && cm.getContentType() == CMElementDeclaration.EMPTY) {
+ // this node can't have children.
+ return new DOMRefPosition(node, true);
+ }
+ IStructuredDocumentRegion startRegion = node
+ .getStartStructuredDocumentRegion();
+ if (startRegion == null) {
+ return new DOMRefPosition(node, true);
+ } else {
+ int startRegionEnd = node.getStartStructuredDocumentRegion()
+ .getEnd();
+ if (offset <= startRegionEnd) {
+ // it is in the start tag region. So put position at first
+ // child position.
+ return new DOMRefPosition2(node, false);
+ } else {
+ return new DOMRefPosition2(node, true);
+ }
+ }
+ } else {
+ return new DOMRefPosition(node, true);
+ }
+ // XXX: the implementation in EditModelQuery seemed to be very complex.
+ // Need revisit that
+ // and refactor the implementation to this class later. (lium)
+ }
+
+ /**
+ * Give a text selection with offset and length, convert it into a Designer
+ * selection (IStrucuturedSelection of editpart or DesignerRange). If the
+ * text selection include just a single element node, we'll create a
+ * IStructuredSelection, otherwise we'll create a DesignerRange.
+ *
+ * @param graphicViewer
+ * @param offset
+ * @param length
+ */
+ public static ISelection convertToDesignerSelection(
+ IHTMLGraphicalViewer graphicViewer, int offset, int length) {
+ IDOMModel model = graphicViewer.getModel();
+ IndexedRegion region1 = model.getIndexedRegion(offset);
+ IndexedRegion region2 = model.getIndexedRegion(offset + length);
+ IDOMNode node1 = (IDOMNode) region1;
+
+ if (node1 == null) {
+ IDOMPosition endOfDoc = new DOMRefPosition2(model.getDocument(),
+ true);
+ DesignPosition p = DOMPositionHelper.toDesignPosition(endOfDoc);
+ return new DesignRange(p, p);
+ }
+
+ if ((region1 == region2 || node1.getEndOffset() == offset + length)
+ && !(node1 instanceof Text)) {
+ // ok, we selected a single node.
+ EditPart part = (EditPart) node1.getAdapterFor(EditPart.class);
+ if (part != null) {
+ return new StructuredSelection(part);
+ }
+ }
+
+ // when we reach here, we'll create a DesignerRange
+ IDOMPosition position1 = toDOMPosition(model, region1, offset);
+ IDOMPosition position2 = (length == 0 ? position1 : toDOMPosition(
+ model, region2, offset + length));
+
+ if (position1 == null || position2 == null) {
+ return new DesignRange(null, null);
+ }
+ DesignPosition p1 = DOMPositionHelper.toDesignPosition(position1);
+ DesignPosition p2 = (length == 0 ? p1 : DOMPositionHelper
+ .toDesignPosition(position2));
+ if (p1 == null || p2 == null) {
+ return new DesignRange(null, null);
+ }
+
+ return new DesignRange(p1, p2);
+
+ }
+
+ /**
+ * convert a IDOMPosition into index in the source.
+ *
+ * @param p
+ * @return
+ */
+ private static int getIndexedRegionLocation(IDOMPosition p) {
+ if (!EditValidateUtil.validPosition(p)) {
+ return 0;
+ }
+
+ IDOMNode parent = (IDOMNode) p.getContainerNode();
+ if (p.isText()) {
+ String text = ((CharacterData) parent).getData();
+ String source = parent.getSource();
+ if (text.length() == source.length()) {
+ // no entity reference.
+ return parent.getStartOffset() + p.getOffset();
+ }
+ // CR404708. Need to handle entity reference in the text.
+ int offset = p.getOffset();
+ int counted = 0;
+ IStructuredDocumentRegion r = parent
+ .getFirstStructuredDocumentRegion();
+ while (r != null && counted < offset) {
+ if (DOMRegionContext.XML_CHAR_REFERENCE.equals(r.getType())
+ || DOMRegionContext.XML_ENTITY_REFERENCE.equals(r
+ .getType())) {
+ counted++;
+ if (counted >= offset) {
+ return r.getEndOffset();
+ }
+ } else {
+ int length = r.getLength();
+ if (counted + length >= offset) {
+ return r.getStartOffset() + offset - counted;
+ }
+ counted += length;
+ }
+ r = r.getNext();
+ }
+ return parent.getStartOffset() + p.getOffset();
+ } else {
+ IDOMNode previous = (IDOMNode) p.getPreviousSiblingNode();
+ if (previous != null) {
+ return previous.getEndOffset();
+ }
+ IDOMNode next = (IDOMNode) p.getNextSiblingNode();
+ if (next != null) {
+ return next.getStartOffset();
+ }
+ IStructuredDocumentRegion r = parent
+ .getStartStructuredDocumentRegion();
+ if (r != null) {
+ return r.getEnd();
+ } else {
+ // r == null normally means the parent is the document node.
+ return parent.getEndOffset();
+ }
+ }
+ }
+
+ /**
+ * convert design selection of structured selection of NodeEditPart into
+ * structured selection of Node
+ *
+ * @param sel
+ * @return
+ */
+ public static IStructuredSelection convertFromDesignSelection(
+ IStructuredSelection sel) {
+ List list = sel.toList();
+ if (list != null) {
+ List result = new ArrayList(list.size());
+ for (int i = 0, size = list.size(); i < size; i++) {
+ NodeEditPart part = (NodeEditPart) list.get(i);
+ result.add(part.getIDOMNode());
+ }
+ return new StructuredSelection(result);
+ } else {
+ return new StructuredSelection();
+ }
+ }
+
+ /**
+ *
+ * @param selection
+ * selection from designer, could be IStructuredSelection of
+ * NodeEditPart, or DesignRange.
+ * @return
+ */
+ public static ITextSelection convertFromDesignSelection(DesignRange range) {
+ if (range.isValid()) {
+ IDOMPosition start = DOMPositionHelper.toDOMPosition(range
+ .getStartPosition());
+ IDOMPosition end = DOMPositionHelper.toDOMPosition(range
+ .getEndPosition());
+ // We should not encounter invalid position.
+ if (EditValidateUtil.validPosition(start)
+ && EditValidateUtil.validPosition(end)) {
+ int offset = getIndexedRegionLocation(start);
+ int endoffset = getIndexedRegionLocation(end);
+ if (offset > endoffset) {
+ int temp = offset;
+ offset = endoffset;
+ endoffset = temp;
+ }
+ return new TextSelection(offset, endoffset - offset);
+ } else {
+ return new TextSelection(0, 0);
+ }
+ } else {
+ return new TextSelection(0, 0);
+ }
+ }
+
+ public static ITextSelection convertFromDesignSelectionToTextSelection(
+ ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection nodes = convertFromDesignSelection((IStructuredSelection) selection);
+ IDOMNode node = (IDOMNode) nodes.getFirstElement();
+ if (node != null && node.getNodeType() != Node.DOCUMENT_NODE) {
+ return new TextSelection(node.getStartOffset(), node
+ .getEndOffset()
+ - node.getStartOffset());
+ } else {
+ return new TextSelection(0, 0);
+ }
+ } else if (selection instanceof DesignRange) {
+ return convertFromDesignSelection((DesignRange) selection);
+ } else {
+ return new TextSelection(0, 0);
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/StructuredModelUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/StructuredModelUtil.java
new file mode 100644
index 000000000..88539757b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/StructuredModelUtil.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+/**
+ * @author mengbo
+ */
+public class StructuredModelUtil {
+
+ /**
+ * this method is copied from ModelManagerImpl of wtp. Because it is
+ * internal.
+ *
+ * @param model
+ * @return null if can't get file.
+ */
+ // TODO: replace (or supplement) this is a "model info" association to the
+ // IFile that created the model
+ public static IFile getFileFor(IStructuredModel model) {
+ if (model == null)
+ return null;
+ String path = model.getBaseLocation();
+ if (path == null || path.length() == 0) {
+ Object id = model.getId();
+ if (id == null)
+ return null;
+ path = id.toString();
+ }
+ // TODO needs rework for linked resources
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ try {
+ IFile file = root.getFile(new Path(path));
+ // IFile file = root.getFileForLocation(new Path(path));
+ return file;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ /**
+ *
+ * @param model
+ * @return null if can't find project for the model
+ */
+ public static IProject getProjectFor(IStructuredModel model) {
+ IProject project = null;
+
+ IFile file = getFileFor(model);
+ if (file != null) {
+ project = file.getProject();
+ }
+ return project;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/UriAdapterFactory.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/UriAdapterFactory.java
new file mode 100644
index 000000000..7a717b329
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/UriAdapterFactory.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.wst.sse.core.internal.util.URIResolver;
+
+/**
+ * @author mengbo comment go to Window - Preferences - Java - Code Style - Code
+ * Templates
+ */
+public class UriAdapterFactory implements IAdapterFactory {
+ /** Create the logger for this class */
+ private static Logger _log = PDPlugin.getLogger(UriAdapterFactory.class);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object,
+ * java.lang.Class)
+ */
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (URIResolver.class.equals(adapterType)) {
+ IProject project = (IProject) adaptableObject;
+ URIResolver fProjectResolver = new ProjectResolver(project);
+ return fProjectResolver;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ public Class[] getAdapterList() {
+ Class[] classes = new Class[1];
+ classes[0] = URIResolver.class;
+ return classes;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/WebAppUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/WebAppUtil.java
new file mode 100644
index 000000000..f45ef56f7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/WebAppUtil.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jst.j2ee.internal.web.deployables.WebDeployableArtifactUtil;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class WebAppUtil {
+ private final static String FACES_SERVLET_NAME = "javax.faces.webapp.FacesServlet";
+
+ public static String transformJSPURL(String url, IFile openedFile) {
+ boolean canSupportJSF = JSPUtil.supportTaglib(
+ IJMTConstants.URI_JSF_HTML, openedFile);
+ if (canSupportJSF
+ && url != null
+ && url.endsWith(IFileFolderConstants.DOT
+ + IFileFolderConstants.EXT_JSP)) {
+ String urlPattern = "";
+ IVirtualResource[] resources = ComponentCore
+ .createResources(openedFile);
+ IVirtualComponent component = null;
+ if (resources[0] != null) {
+ component = resources[0].getComponent();
+ }
+ if (component != null) {
+ urlPattern = WebDeployableArtifactUtil.getServletMapping(
+ openedFile.getProject(), true, FACES_SERVLET_NAME,
+ component.getName());
+ }
+ if (urlPattern.lastIndexOf(IFileFolderConstants.DOT) != -1) {
+ String extension = urlPattern.substring(urlPattern
+ .lastIndexOf(IFileFolderConstants.DOT));
+ url = url.substring(0, url.lastIndexOf(IFileFolderConstants.DOT
+ + IFileFolderConstants.EXT_JSP))
+ + extension;
+ }
+ }
+ return url;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/XMLUtil.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/XMLUtil.java
new file mode 100644
index 000000000..89f0cd1e0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/utils/XMLUtil.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.utils;
+
+/**
+ * @author mengbo
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.w3c.dom.Document;
+
+public class XMLUtil {
+ private static Logger _log = PDPlugin.getLogger(XMLUtil.class);
+
+ /**
+ * Returns a DocumentBuilder capable of creating a DOM Document from input.
+ *
+ * @return
+ */
+ public synchronized static DocumentBuilder getDocumentBuilder() {
+ DocumentBuilder result = null;
+ try {
+ result = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ // "Error in create documentBuilder"
+ _log.info("XMLUtil.Error.0", e); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ public synchronized static DocumentBuilder getDocumentBuilder(
+ boolean validating) {
+ DocumentBuilder result = null;
+ try {
+ DocumentBuilderFactory instance = DocumentBuilderFactory
+ .newInstance();
+ instance.setValidating(validating);
+ result = instance.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ // "Error in create documentBuilder"
+ _log.info("XMLUtil.Error.0", e); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ /**
+ * Transforms a DOM document into a lightly-formatted UTF-8 represntation
+ * and outputs it to an outputstream
+ *
+ * @param document
+ * @param ostream
+ * @throws IOException
+ */
+ public static void serialize(Document document, OutputStream ostream)
+ throws IOException {
+ Source domSource = new DOMSource(document);
+ try {
+ Transformer serializer = TransformerFactory.newInstance()
+ .newTransformer();
+ try {
+ serializer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ serializer.setOutputProperty(
+ "{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
+ serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // "Error in object persistance:"
+ _log.info("XMLUtil.Error.2", e); //$NON-NLS-1$
+ }
+ serializer.transform(domSource, new StreamResult(ostream));
+ } catch (TransformerConfigurationException e) {
+ // "Error in object persistance:"
+ _log.info("XMLUtil.Error.2", e); //$NON-NLS-1$
+ throw new IOException(e.getMessage());
+ } catch (TransformerFactoryConfigurationError e) {
+ // "Error in object persistance:"
+ _log.info("XMLUtil.Error.2", e); //$NON-NLS-1$
+ throw new IOException(e.getMessage());
+ } catch (TransformerException e) {
+ // "Error in object persistance:"
+ _log.info("XMLUtil.Error.2", e); //$NON-NLS-1$
+ throw new IOException(e.getMessage());
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ActionData.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ActionData.java
new file mode 100644
index 000000000..252c5db00
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ActionData.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * This method represents the an user action, the 'data' could be any related
+ * data that will be referenced later in the action processing. For example.
+ * when user do DnD, the localData will be referenced as _data.
+ *
+ * @author mengbo
+ */
+public class ActionData {
+ public static final int PALETTE_DND = 1;
+
+ public static final int DATABINDING_DND = 2;
+
+ public static final int OTHER_DND = 3;
+
+ public static final int KEYBOARD_NAVAGATION = 4;
+
+ public static final int INLINE_EDIT = 5;
+
+ public static final int COMPONENT_MOVE = 6;
+
+ public static final int UNKNOWN = 0;
+
+ private int _actionType;
+
+ private Object _data;
+
+ /**
+ *
+ */
+ public ActionData(int action, Object data) {
+ _actionType = action;
+ if (data != null) {
+ _data = data;
+ } else {
+ _data = new Object();
+ }
+ }
+
+ /**
+ * @return Returns the _actionType.
+ */
+ public final int getActionType() {
+ return _actionType;
+ }
+
+ /**
+ * @return Returns the _data.
+ */
+ public final Object getData() {
+ return _data;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicMovementRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicMovementRule.java
new file mode 100644
index 000000000..ac8d97d2f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicMovementRule.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class BasicMovementRule extends DefaultMovementRule {
+
+ /**
+ * @param actionData
+ */
+ public BasicMovementRule(ActionData actionData) {
+ super(actionData);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IMovementRule#allowsMoveIn(org.eclipse.jst.pagedesigner.validation.caret.Target)
+ */
+ public boolean allowsMoveIn(Target target) {
+ if (_actionData.getActionType() == ActionData.INLINE_EDIT) {
+ Node node = target.getNode();
+ return EditModelQuery.isText(node) || node.hasChildNodes();
+ }
+ return super.allowsMoveIn(target);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicPositionRule.java
new file mode 100644
index 000000000..f64159f11
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/BasicPositionRule.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.w3c.dom.Node;
+
+/**
+ * Deal with widget.
+ *
+ * @author mengbo
+ */
+public class BasicPositionRule extends DefaultPositionRule {
+
+ /**
+ * @param mediator
+ */
+ public BasicPositionRule(IPositionMediator mediator, ActionData actionData) {
+ super(mediator, actionData);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#hasEditableArea(org.eclipse.gef.EditPart)
+ */
+ public boolean hasEditableArea(Target target) {
+ if (target == null || target.getPart() == null) {
+ return false;
+ }
+ if (!EditValidateUtil.validNode(target.getNode())) {
+ return false;
+ }
+ Node node = target.getNode();
+ String name = node.getLocalName();
+ if (DefaultPositionRule.isWidget(target.getPart())) {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.gef.EditPart)
+ */
+ public boolean isEditable(Target target) {
+ if (target.getPart() == null) {
+ return false;
+ }
+ Node node = target.getNode();
+
+ // text is depending on parent.
+ if (EditModelQuery.isText(node)) {
+ return _mediator.isEditable(new Target(node.getParentNode()));
+ }
+ String name = node.getLocalName();
+ // Name is null, the node should not be Element
+ if (name == null && !EditModelQuery.isDocument(node)
+ && !EditModelQuery.isText(node)) {
+ return false;
+ }
+ // if is widget, return false;
+ if (DefaultPositionRule.isWidget(target.getPart())) {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#canStopHere(org.w3c.dom.Node)
+ */
+ public boolean canReference(Target target, boolean atRight) {
+ Node node = target.getNode();
+ if (target.getPart() == null || node.getNodeType() != Node.ELEMENT_NODE
+ && !EditModelQuery.isText(node)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ContainerMoveInAndOutRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ContainerMoveInAndOutRule.java
new file mode 100644
index 000000000..0094d182a
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/ContainerMoveInAndOutRule.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import java.util.Arrays;
+
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class ContainerMoveInAndOutRule extends DefaultMovementRule {
+ public final String[] HTML_CONTAINERS = { IHTMLConstants.TAG_TABLE };
+
+ public final String[] NONE_HTML_CONTAINERS = {};
+
+ public final String[] SPECIAL_HTML_CONTAINERS = {
+ IJSFConstants.TAG_OUTPUTLINK, IJSFConstants.TAG_COMMANDLINK,
+ IJSFConstants.TAG_FACET, IJSFConstants.TAG_VERBATIM };
+
+ /**
+ * @param actionData
+ */
+ public ContainerMoveInAndOutRule(ActionData actionData) {
+ super(actionData);
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IMovementRule#canEnter(org.w3c.dom.Node)
+ */
+ public boolean allowsMoveIn(Target target) {
+ Node node = target.getNode();
+ if (node.getLocalName() != null && //
+ (Arrays.asList(HTML_CONTAINERS).contains(node.getLocalName()
+ .toLowerCase())) || //
+ Arrays.asList(NONE_HTML_CONTAINERS).contains(
+ node.getLocalName()) || //
+ Arrays.asList(SPECIAL_HTML_CONTAINERS).contains(
+ node.getLocalName())) {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IMovementRule#canMoveOut(org.eclipse.gef.EditPart)
+ */
+ public boolean allowsMoveOut(Target target) {
+ Node node = target.getNode();
+ if (EditModelQuery.isDocument(node)) {
+ return false;
+ }
+
+ if (_actionData.getActionType() == ActionData.INLINE_EDIT
+ && (IHTMLConstants.TAG_TD.equalsIgnoreCase(node.getLocalName()) || IHTMLConstants.TAG_TH
+ .equalsIgnoreCase(node.getLocalName()))) {
+ return false;
+ }
+ if (node.getLocalName() != null && //
+ (Arrays.asList(HTML_CONTAINERS).contains(node.getLocalName()
+ .toLowerCase())) || //
+ Arrays.asList(NONE_HTML_CONTAINERS).contains(
+ node.getLocalName())) {
+ return false;
+ }
+
+ if (node.getLocalName() != null
+ && (Arrays.asList(
+ RootContainerPositionRule.HTML_ROOT_CONTAINERS)
+ .contains(node.getLocalName().toLowerCase()) || //
+ Arrays.asList(JSFRootContainerPositionRule.JSF_ROOT_CONTAINERS)
+ .contains(node.getLocalName()))) {
+ if (!EditModelQuery.isChild(
+ JSFRootContainerPositionRule.JSF_ROOT_CONTAINERS, node,
+ false, true)
+ && //
+ !EditModelQuery.isChild(
+ RootContainerPositionRule.HTML_ROOT_CONTAINERS,
+ node, true, true)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultMovementRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultMovementRule.java
new file mode 100644
index 000000000..0c1d6afd7
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultMovementRule.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * @author mengbo
+ */
+public class DefaultMovementRule implements IMovementRule {
+ ActionData _actionData;
+
+ /**
+ *
+ */
+ public DefaultMovementRule(ActionData actionData) {
+ super();
+ _actionData = actionData;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IMovementRule#allowsMoveIn(org.eclipse.jst.pagedesigner.validation.caret.Target)
+ */
+ public boolean allowsMoveIn(Target target) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IMovementRule#allowsMoveOut(org.eclipse.jst.pagedesigner.validation.caret.Target)
+ */
+ public boolean allowsMoveOut(Target target) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionRule.java
new file mode 100644
index 000000000..70bf749b0
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionRule.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+
+/**
+ * @author mengbo
+ */
+public class DefaultPositionRule implements IPositionRule {
+
+ protected IPositionMediator _mediator;
+
+ protected ActionData _actionData;
+
+ /**
+ *
+ */
+ public DefaultPositionRule(IPositionMediator mediator, ActionData actionData) {
+ super();
+ _mediator = mediator;
+ if (_actionData != null) {
+ _actionData = actionData;
+ } else {
+ _actionData = new ActionData(ActionData.UNKNOWN, new Object());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#hasEditableArea(org.w3c.dom.Node)
+ */
+ public boolean hasEditableArea(Target target) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.gef.EditPart)
+ */
+ public boolean isEditable(Target target) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isTransparent(org.eclipse.gef.EditPart,
+ * org.eclipse.draw2d.geometry.Point)
+ */
+ public boolean canReference(Target target, boolean atRight) {
+ return true;
+ }
+
+ /**
+ * If container is inEditable and can be referenced, the position is
+ * invalid, otherwise as default the position is valid. (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isValidPosition(org.eclipse.jst.pagedesigner.dom.IDOMPosition)
+ */
+ public boolean isValidPosition(IDOMPosition position) {
+ boolean result = isEditable(new Target(position.getContainerNode()));
+ if (result) {
+ if (position.getOffset() == 0
+ || position.getOffset() == position.getContainerNode()
+ .getChildNodes().getLength()) {
+ result = true;
+ } else {
+ boolean dir;
+ Target target = null;
+ if (position instanceof DOMRefPosition) {
+ target = new Target(((DOMRefPosition) position)
+ .getReferenceNode());
+ dir = ((DOMRefPosition) position).isForward();
+ result = canReference(target, dir);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param host
+ * @param tagName
+ * @return
+ */
+ public static boolean isWidget(EditPart host) {
+ if (host instanceof NodeEditPart) {
+ return ((NodeEditPart) host).isWidget();
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionValidator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionValidator.java
new file mode 100644
index 000000000..34d0a15ff
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DefaultPositionValidator.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.EditHelper;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class DefaultPositionValidator implements IPositionMediator {
+ private List _rules = new ArrayList();
+
+ ActionData _actionData;
+
+ /**
+ * @return Returns the _actionData.
+ */
+ public ActionData getActionData() {
+ return _actionData;
+ }
+
+ /**
+ *
+ */
+ protected DefaultPositionValidator(ActionData actionData) {
+ _actionData = actionData;
+ initRules();
+ }
+
+ protected void initRules() {
+ _rules.clear();
+ _rules.add(new BasicPositionRule(this, _actionData));
+ _rules.add(new IETablePositionRule(this, _actionData));
+ _rules.add(new RootContainerPositionRule(this, _actionData));
+ _rules.add(new JSFRootContainerPositionRule(this, _actionData));
+ _rules.add(new WhitespacePositionMoveRule(this, _actionData));
+ }
+
+ /**
+ * @return Returns the _rules.
+ */
+ public List getRules() {
+ return _rules;
+ }
+
+ /**
+ * @param _rules
+ * The _rules to set.
+ */
+ protected void setRules(List rules) {
+ _rules = rules;
+ }
+
+ protected void addRule(IValidationRule rule) {
+ _rules.add(rule);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IValidator#hasEditableArea(org.w3c.dom.Node)
+ */
+ public boolean hasEditableArea(Target target) {
+ boolean result = true;
+ List _rules = getRules();
+ for (int i = 0, n = _rules.size(); i < n; i++) {
+ Object rule = _rules.get(i);
+ if (rule instanceof IPositionRule) {
+ result &= ((IPositionRule) rule).hasEditableArea(target);
+ }
+ if (!result) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IValidator#isEditable(org.w3c.dom.Node)
+ */
+ public boolean isEditable(Target target) {
+ Node node = target.getNode();
+ boolean result = true;
+ List _rules = getRules();
+ for (int i = 0, n = _rules.size(); i < n; i++) {
+ Object rule = _rules.get(i);
+ if (rule instanceof IPositionRule) {
+ result &= ((IPositionRule) rule).isEditable(new Target(node));
+ }
+ if (!result) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IValidator#isValidPosition(org.eclipse.jst.pagedesigner.viewer.DesignPosition)
+ */
+ public boolean isValidPosition(DesignPosition position) {
+ return isValidPosition(DOMPositionHelper.toDOMPosition(position));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IValidator#isValidPosition(org.eclipse.jst.pagedesigner.dom.IDOMPosition)
+ */
+ public boolean isValidPosition(IDOMPosition position) {
+ position = EditHelper.ensureDOMPosition(position);
+ boolean refLeft = true, refRight = true, result = true;
+ if (position == null) {
+ return false;
+ }
+ List _rules = getRules();
+ for (int i = 0, n = _rules.size(); i < n; i++) {
+ Object rule = _rules.get(i);
+ if (rule instanceof IPositionRule) {
+ // editable?
+ result &= ((IPositionRule) rule).isEditable(new Target(position
+ .getContainerNode()));
+ if (result) {
+ if (!position.isText()) {
+
+ // ref1?
+ Node node = EditModelQuery.getInstance().getSibling(
+ position, true);
+ if (node != null & refLeft) {
+ refLeft &= ((IPositionRule) rule).canReference(
+ new Target(node), false);
+ }
+ // ref2?
+ node = EditModelQuery.getInstance().getSibling(
+ position, false);
+ if (node != null & refRight) {
+ refRight = ((IPositionRule) rule).canReference(
+ new Target(node), true);
+ }
+ if (!(refLeft | refRight)) {
+ result = false;
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ // }
+ }
+ }
+ return (result & (refLeft | refRight));
+ }
+
+ /**
+ * Adjust the position to an editable area.
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IValidator#getEditableContainer(org.eclipse.gef.EditPart)
+ */
+ public EditPart getEditableContainer(Target target) {
+ EditPart part = target.getPart();
+ if (hasEditableArea(target)) {
+ return target.getPart();
+ }
+ while (part != null && !(part instanceof DocumentEditPart)) {
+ if (hasEditableArea(target)) {
+ break;
+ }
+ part = part.getParent();
+ target = new Target(part);
+ }
+ if (part instanceof DocumentEditPart
+ && RootContainerPositionRule.hasBasicContainers((Document) part
+ .getModel())) {
+ Node node = RootContainerPositionRule
+ .getBasicContainer((Document) part.getModel());
+ part = Target.resolvePart(node);
+ }
+ return part;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IValidator#canReference(org.w3c.dom.Node)
+ */
+ public boolean canReference(Target target, boolean atRight) {
+ boolean result = true;
+ List _rules = getRules();
+ for (int i = 0, n = _rules.size(); i < n; i++) {
+ Object rule = _rules.get(i);
+ if (rule instanceof IPositionRule) {
+ result &= ((IPositionRule) rule).canReference(target, atRight);
+ }
+ if (!result) {
+ break;
+ }
+ }
+ return result;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DnDPositionValidator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DnDPositionValidator.java
new file mode 100644
index 000000000..31e128f68
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/DnDPositionValidator.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * This validator is used for caret positioning when user do drag & drop on the
+ * screen.
+ *
+ * @author mengbo
+ */
+public class DnDPositionValidator extends DefaultPositionValidator {
+ private static DnDPositionValidator _instance;
+
+ private ActionData _data;
+
+ /**
+ * @param actionData
+ */
+ public DnDPositionValidator(ActionData actionData) {
+ super(actionData);
+ // TODO Auto-generated constructor stub
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/HeadDataPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/HeadDataPositionRule.java
new file mode 100644
index 000000000..4bacd8f67
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/HeadDataPositionRule.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * Ensure the DnD for loadBundle or taglib is in head area.
+ *
+ * @author mengbo
+ */
+public class HeadDataPositionRule extends DefaultPositionRule {
+
+ /**
+ * @param data
+ */
+ public HeadDataPositionRule(IPositionMediator mediator, ActionData data) {
+ super(mediator, data);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IEPanelgridPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IEPanelgridPositionRule.java
new file mode 100644
index 000000000..86b5198d6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IEPanelgridPositionRule.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.jst.pagedesigner.IJSFConstants;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Node;
+
+/**
+ * In some place, wen can't do inline editing, like the area between td, in
+ * panelGrid, etc. In these places we can't place caret
+ *
+ * @author mengbo
+ */
+public class IEPanelgridPositionRule extends DefaultPositionRule {
+ public IEPanelgridPositionRule(IPositionMediator mediator,
+ ActionData actionData) {
+ super(mediator, actionData);
+ }
+
+ /**
+ * PanelGrid is not editable.
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.gef.EditPart)
+ */
+ public boolean isEditable(Target target) {
+ Node node = target.getNode();
+ return !EditModelQuery.isChild(new String[] {
+ IJSFConstants.TAG_PANELGRID, IJSFConstants.TAG_DATATABLE },
+ node, false, false);
+ }
+
+ public boolean hasEditableArea(Target target) {
+ Node node = target.getNode();
+ return !EditModelQuery.isChild(new String[] {
+ IJSFConstants.TAG_PANELGRID, IJSFConstants.TAG_DATATABLE },
+ node, false, false);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IETablePositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IETablePositionRule.java
new file mode 100644
index 000000000..488a910a9
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IETablePositionRule.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
+import org.w3c.dom.Node;
+
+/**
+ * This rule constains the operation within a table: 1. The inputing position
+ * can only be in 'td' 2. Table structure must be valid.
+ *
+ * @author mengbo
+ */
+public class IETablePositionRule extends DefaultPositionRule {
+ // We will introduce validation based on DtD later, this is not final
+ // solution.
+ private final String[] CONTAINER = { IHTMLConstants.TAG_THEAD,
+ IHTMLConstants.TAG_TBODY, IHTMLConstants.TAG_TFOOT };
+
+ /**
+ * @param mediator
+ */
+ public IETablePositionRule(IPositionMediator mediator, ActionData actionData) {
+ super(mediator, actionData);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#hasEditableArea(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public boolean hasEditableArea(Target target) {
+ if (EditModelQuery.isChild(IHTMLConstants.TAG_TABLE, target.getNode(),
+ true)) {
+ if (target.getPart() == null) {
+ return false;
+ }
+ Node node = target.getNode();
+ // The target must be in a valid table structure.
+ String name = node.getLocalName();
+ if (node.hasChildNodes()) {
+ // for constrained container, depends on its children.
+ if (name != null
+ && (IHTMLConstants.TAG_TABLE.equalsIgnoreCase(name) || //
+ Arrays.asList(CONTAINER).contains(
+ name.toLowerCase()) || //
+ IHTMLConstants.TAG_TR.equalsIgnoreCase(name))) {
+ List children = target.getPart().getChildren();
+ for (int i = 0, n = children.size(); i < n; i++) {
+ if (hasEditableArea(new Target((EditPart) children
+ .get(i)))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ } else {
+ if (!isEditable(new Target(node))) {
+ return false;
+ }
+ }
+ }
+ return super.hasEditableArea(target);
+ }
+
+ /*
+ * Used to valid the structure of table, later will use dtd to do that.
+ * @param node @return
+ */
+ public boolean isInValidTable(Node container) {
+ boolean result = false;
+ try {
+ if (EditValidateUtil.validNode(container)) {
+ if (EditModelQuery.isText(container)) {
+ container = container.getParentNode();
+ }
+ String name = container.getLocalName();
+ if (EditModelQuery.isChild(IHTMLConstants.TAG_TABLE, container,
+ true)) {
+ List ancestors = EditModelQuery.getAncestors(container,
+ IHTMLConstants.TAG_TABLE, true);
+ int offset = ancestors.size();
+ // remove 'table'
+ Node temp = (Node) ancestors.remove(offset - 1);
+ if (temp == container) {
+ return true;
+ }
+ offset--;
+ result = checkValidTrTd(ancestors, container);
+ if (!result) {
+ // thead->tr->td
+ temp = (Node) ancestors.get(offset - 1);
+ name = temp.getNodeName();
+ if (Arrays.asList(CONTAINER).contains(
+ name.toLowerCase())) {
+ if (temp == container) {
+ result = true;
+ } else {
+ // remove 'thead'
+ ancestors.remove(offset - 1);
+ offset--;
+ result = checkValidTrTd(ancestors, container);
+ }
+ }
+ }
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ // The exception means the structure is not a valid table, don't
+ // need to report.
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public boolean isEditable(Target target) {
+ if (EditModelQuery.isChild(IHTMLConstants.TAG_TABLE, target.getNode(),
+ false)) {
+ if (isInValidTable(target.getNode())) {
+ List ancestors = EditModelQuery.getAncestors(target.getNode(),
+ IHTMLConstants.TAG_TABLE, true);
+ if (ancestors.size() >= 3) {
+ if (IHTMLConstants.TAG_TH
+ .equalsIgnoreCase(((Node) ancestors.get(ancestors
+ .size() - 3)).getNodeName())
+ || //
+ IHTMLConstants.TAG_TD
+ .equalsIgnoreCase(((Node) ancestors
+ .get(ancestors.size() - 3))
+ .getNodeName())) {
+ return true;
+ } else if (ancestors.size() >= 4 //
+ && (IHTMLConstants.TAG_TH
+ .equalsIgnoreCase(((Node) ancestors
+ .get(ancestors.size() - 4))
+ .getNodeName()) || //
+ IHTMLConstants.TAG_TD
+ .equalsIgnoreCase(((Node) ancestors
+ .get(ancestors.size() - 4))
+ .getNodeName()))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ return super.isEditable(target);
+ }
+
+ private boolean checkValidTrTd(List ancestors, Node node) {
+ int offset = ancestors.size();
+ if (IHTMLConstants.TAG_TR.equalsIgnoreCase(((Node) ancestors
+ .get(offset - 1)).getLocalName())) {
+ if (ancestors.get(offset - 1) == node) {
+ return true;
+ } else if (IHTMLConstants.TAG_TH.equalsIgnoreCase(((Node) ancestors
+ .get(offset - 2)).getLocalName())
+ || //
+ IHTMLConstants.TAG_TD.equalsIgnoreCase(((Node) ancestors
+ .get(offset - 2)).getLocalName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isValidTrTd(List ancestors) {
+ String name;
+ int offset = ancestors.size();
+ if (offset >= 2) {
+ return IHTMLConstants.TAG_TR.equalsIgnoreCase(((Node) ancestors
+ .get(offset - 1)).getLocalName())
+ && //
+ (IHTMLConstants.TAG_TH.equalsIgnoreCase(((Node) ancestors
+ .get(offset - 2)).getLocalName()) || //
+ IHTMLConstants.TAG_TD.equalsIgnoreCase(((Node) ancestors
+ .get(offset - 2)).getLocalName()));
+ }
+ return false;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementMediator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementMediator.java
new file mode 100644
index 000000000..a1ff20d4b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementMediator.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.gef.EditPart;
+
+/**
+ * @author mengbo
+ */
+public interface IMovementMediator extends IPositionMediator {
+ public boolean allowsMoveIn(Target target);
+
+ public boolean allowsMoveOut(Target target);
+
+ /**
+ * Return a closest parent part which is editable, and it can't moveout.
+ *
+ * @param target
+ * @return if taget part is editable, then returns itself.
+ */
+ public EditPart getConstainedEditableContainer(Target target);
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementRule.java
new file mode 100644
index 000000000..b1017d68b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IMovementRule.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * @author mengbo
+ */
+public interface IMovementRule extends IValidationRule {
+ public boolean allowsMoveIn(Target target);
+
+ public boolean allowsMoveOut(Target target);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionMediator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionMediator.java
new file mode 100644
index 000000000..534b21715
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionMediator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+
+/**
+ * @author mengbo
+ */
+public interface IPositionMediator {
+ public ActionData getActionData();
+
+ /**
+ * To see if the node itself or its descendent is editable.
+ *
+ * @param node
+ * @return
+ */
+ public boolean hasEditableArea(Target target);
+
+ /**
+ * To see if the position is valid.
+ *
+ * @param position
+ * @return
+ */
+ public boolean isValidPosition(IDOMPosition position);
+
+ public boolean isValidPosition(DesignPosition position);
+
+ /**
+ * To see if the node is editable.
+ *
+ * @param node
+ * @return
+ */
+ public boolean isEditable(Target target);
+
+ public boolean canReference(Target target, boolean atRight);
+
+ /**
+ * Return a node which contains 'node', and it has editable area.
+ *
+ * @param target
+ * @return if part is editable, then itself is returned, otherwise a parent
+ * is returned.
+ */
+ public EditPart getEditableContainer(Target target);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionRule.java
new file mode 100644
index 000000000..86cfb2171
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IPositionRule.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+
+/**
+ * @author mengbo
+ */
+public interface IPositionRule extends IValidationRule {
+ /**
+ * To see if the node is editable. For inline editing, this means whether
+ * can we input something into the target. For DnD, this means whether can
+ * we drag and drop something into it.
+ *
+ * @param node
+ * @return
+ */
+ public boolean isEditable(Target target);
+
+ /**
+ * To see if the node itself or its descendent is editable.
+ *
+ * @see isEditable for other details.
+ * @param node
+ * @return
+ */
+ public boolean hasEditableArea(Target target);
+
+ /**
+ * Whether can we place caret against this part's border. Some container we
+ * are consider white box, and whitespace may not be suitable for caret
+ * reference.
+ *
+ * @param target
+ * @param atRight
+ * TODO
+ * @return
+ */
+ public boolean canReference(Target target, boolean atRight);
+
+ /**
+ * To see if the position is valid. Please note, the container is editable
+ * means there is a child area whithin it is editable, the position may be
+ * in an inEditable place. So this method is different from hasEditableArea
+ * and isEditable.
+ *
+ * @param position
+ * @return
+ */
+ public boolean isValidPosition(IDOMPosition position);
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IValidationRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IValidationRule.java
new file mode 100644
index 000000000..42a173ac5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/IValidationRule.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * @author mengbo
+ */
+public interface IValidationRule {
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingNavigationMediator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingNavigationMediator.java
new file mode 100644
index 000000000..e076923b5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingNavigationMediator.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import java.util.List;
+
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gef.editparts.ScalableRootEditPart;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.tools.ExposeHelper;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class InlineEditingNavigationMediator extends
+ InlineEditingPositionMediator implements IMovementMediator {
+
+ /**
+ * @param actionData
+ */
+ public InlineEditingNavigationMediator(ActionData actionData) {
+ super(actionData);
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.DefaultPositionValidator#initRules(org.eclipse.jst.pagedesigner.caret.ActionData)
+ */
+ protected void initRules() {
+ super.initRules();
+ this.addRule(new ContainerMoveInAndOutRule(_actionData));
+ this.addRule(new BasicMovementRule(_actionData));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IMovementValidator#allowsMoveIn(org.eclipse.gef.EditPart)
+ */
+ public boolean allowsMoveIn(Target target) {
+ boolean result = true;
+ List _rules = getRules();
+ for (int i = 0, n = _rules.size(); i < n; i++) {
+ Object rule = _rules.get(i);
+ if (rule instanceof IMovementRule) {
+ result &= ((IMovementRule) rule).allowsMoveIn(target);
+ } else if (rule instanceof IPositionRule) {
+ result &= ((IPositionRule) rule).hasEditableArea(target);
+ }
+ if (!result) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IMovementValidator#allowsMoveOut(org.eclipse.gef.EditPart)
+ */
+ public boolean allowsMoveOut(Target target) {
+ boolean result = true;
+ List _rules = getRules();
+ for (int i = 0, n = _rules.size(); i < n; i++) {
+ Object rule = _rules.get(i);
+ if (rule instanceof IMovementRule) {
+ result &= ((IMovementRule) rule).allowsMoveOut(target);
+ }
+ if (!result) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator#getConstainedEditableContainer(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public EditPart getRootConstainedEditableContainer(Target target) {
+ // if (EditModelQuery.isDocument(target.getNode()))
+ // {
+ // return target.getPart();
+ // }
+ EditPart part = target.getPart();
+ while (part != null) {
+ if (hasEditableArea(target) && !allowsMoveOut(target)) {
+ break;
+ }
+ part = part.getParent();
+ target = new Target(part);
+ }
+ if (part instanceof DocumentEditPart
+ && RootContainerPositionRule.hasBasicContainers((Document) part
+ .getModel())) {
+ Node node = RootContainerPositionRule
+ .getBasicContainer((Document) part.getModel());
+ part = Target.resolvePart(node);
+ }
+
+ return part;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator#getConstainedEditableContainer(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public EditPart getConstainedEditableContainer(Target target) {
+ EditPart part = target.getPart();
+ while (part != null) {
+ if (hasEditableArea(target)) {
+ break;
+ }
+ part = part.getParent();
+ target = new Target(part);
+ }
+ if (part instanceof DocumentEditPart
+ && RootContainerPositionRule.hasBasicContainers((Document) part
+ .getModel())) {
+ Node node = RootContainerPositionRule
+ .getBasicContainer((Document) part.getModel());
+ part = Target.resolvePart(node);
+ }
+ return part;
+ }
+
+ /**
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator#getConstainedEditableContainer(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public EditPart getConstainedEditableContainer(DesignPosition position,
+ Point p, GraphicalViewer viewer) {
+ Rectangle rect = new Rectangle(p.x, p.y, 1, 1);
+ Viewport port = ((HTMLGraphicalViewer) viewer).getViewport();
+
+ Point viewLocation = port.getViewLocation();
+ Point lastLocation = viewLocation.getCopy();
+ new ExposeHelper((HTMLGraphicalViewer) viewer).exposeArea(rect);
+ viewLocation = port.getViewLocation();
+ Dimension offset = lastLocation.getDifference(viewLocation);
+
+ p.translate(offset.width, offset.height);
+ EditPart part = viewer.findObjectAt(p);
+ if (part != null && !(part instanceof ScalableRootEditPart)) {
+ while (part != null) {
+ Target target = new Target(part);
+ if (hasEditableArea(target)) {
+ if (allowsMoveIn(target)
+ || EditModelQuery.isChild(target.getNode(),
+ position.getContainerNode())) {
+ break;
+ }
+ }
+ part = part.getParent();
+ }
+ if (part instanceof DocumentEditPart
+ && RootContainerPositionRule
+ .hasBasicContainers((Document) part.getModel())) {
+ Node node = RootContainerPositionRule
+ .getBasicContainer((Document) part.getModel());
+ part = Target.resolvePart(node);
+ }
+ return part;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingPositionMediator.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingPositionMediator.java
new file mode 100644
index 000000000..40b5e9907
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/InlineEditingPositionMediator.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * This validtor is used for inline editing, caret positioning with mouse.
+ *
+ * @author mengbo
+ */
+public class InlineEditingPositionMediator extends DefaultPositionValidator {
+
+ /**
+ * @param actionData
+ */
+ public InlineEditingPositionMediator(ActionData actionData) {
+ super(actionData);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.DefaultPositionValidator#initRules()
+ */
+ protected void initRules() {
+ super.initRules();
+ addRule(new IEPanelgridPositionRule(this, _actionData));
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/JSFRootContainerPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/JSFRootContainerPositionRule.java
new file mode 100644
index 000000000..8c957287f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/JSFRootContainerPositionRule.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.IJMTConstants;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.itemcreation.ItemCreationRequest;
+import org.eclipse.jst.pagedesigner.utils.JSPUtil;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Ensure the DnD of jsf component should be within f:view or f:subview.
+ *
+ * @author mengbo
+ */
+public class JSFRootContainerPositionRule extends DefaultPositionRule {
+ public static final String[] JSF_ROOT_CONTAINERS = { "view", "subview" };
+
+ /**
+ * @param mediator
+ * @param actionData
+ */
+ public JSFRootContainerPositionRule(IPositionMediator mediator,
+ ActionData actionData) {
+ super(mediator, actionData);
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#hasEditableArea(org.eclipse.jst.pagedesigner.validation.caret.Target)
+ */
+ public boolean hasEditableArea(Target target) {
+ Node node = target.getNode();
+ if (hasBasicContainers(EditModelQuery.getDocumentNode(node))) {
+ if (_actionData.getActionType() == ActionData.PALETTE_DND
+ || _actionData.getActionType() == ActionData.COMPONENT_MOVE) {
+ if (_actionData.getData() instanceof ItemCreationRequest) {
+ String uri = ((ItemCreationRequest) _actionData.getData())
+ .getItemDescriptor().getURI();
+ if (IJMTConstants.URI_JSF_HTML.equalsIgnoreCase(uri)
+ || IJMTConstants.URI_JSF_CORE.equalsIgnoreCase(uri)) {
+ boolean result = EditModelQuery.isChild(
+ JSF_ROOT_CONTAINERS, node, true, false);
+ return result
+ | EditModelQuery.getChild(node,
+ JSF_ROOT_CONTAINERS, 3, false) != null;
+ }
+ } else if (_actionData.getData() instanceof List) {
+ IDOMNode carriedNode = ((IDOMNode) Target
+ .resolveNode((EditPart) ((List) _actionData
+ .getData()).get(0)));
+ IDOMModel model = carriedNode.getModel();
+ String uri = JSPUtil.findURIForPrefix(model, carriedNode
+ .getPrefix());
+ if (IJMTConstants.URI_JSF_HTML.equalsIgnoreCase(uri)
+ || IJMTConstants.URI_JSF_CORE.equalsIgnoreCase(uri)) {
+ return EditModelQuery.isChild(JSF_ROOT_CONTAINERS,
+ node, true, false);
+ }
+ }
+ } else if (_actionData.getActionType() == ActionData.DATABINDING_DND) {
+ boolean result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS,
+ node, true, false);
+ return result
+ | EditModelQuery.getChild(node, JSF_ROOT_CONTAINERS, 3,
+ false) != null;
+ }
+ }
+ return super.isEditable(target);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#isEditable(org.eclipse.jst.pagedesigner.validation.caret.Target)
+ */
+ public boolean isEditable(Target target) {
+ boolean result = true;
+ Node node = target.getNode();
+ if (hasBasicContainers(EditModelQuery.getDocumentNode(node))) {
+ if (_actionData.getActionType() == ActionData.PALETTE_DND
+ || _actionData.getActionType() == ActionData.COMPONENT_MOVE) {
+ if (_actionData.getData() instanceof ItemCreationRequest) {
+ String uri = ((ItemCreationRequest) _actionData.getData())
+ .getItemDescriptor().getURI();
+ if (IJMTConstants.URI_JSF_HTML.equalsIgnoreCase(uri)
+ || IJMTConstants.URI_JSF_CORE.equalsIgnoreCase(uri)) {
+ result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS,
+ node, true, false);
+ }
+ } else if (_actionData.getData() instanceof List) {
+ IDOMNode carriedNode = ((IDOMNode) Target
+ .resolveNode((EditPart) ((List) _actionData
+ .getData()).get(0)));
+ IDOMModel model = carriedNode.getModel();
+ String uri = JSPUtil.findURIForPrefix(model, carriedNode
+ .getPrefix());
+ if (IJMTConstants.URI_JSF_HTML.equalsIgnoreCase(uri)
+ || IJMTConstants.URI_JSF_CORE.equalsIgnoreCase(uri)) {
+ result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS,
+ node, true, false);
+ }
+ }
+ } else if (_actionData.getActionType() == ActionData.DATABINDING_DND) {
+ result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS, node,
+ true, false);
+ }
+ return result;
+ }
+ return super.isEditable(target);
+ }
+
+ public static boolean isWithinkBasicContainer(Node node) {
+ return EditModelQuery.isChild(JSF_ROOT_CONTAINERS, node, false, false);
+ }
+
+ public static Node getBasicContainer(Document document) {
+ Node node = EditModelQuery.getChild(document, JSF_ROOT_CONTAINERS, 3,
+ false);
+ return node;
+ }
+
+ /**
+ * We need to see if body, view are there. and they should be at first or
+ * second level.
+ *
+ * @param document
+ * @return
+ */
+ public static boolean hasBasicContainers(Document document) {
+ return getBasicContainer(document) != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#canReference(org.eclipse.jst.pagedesigner.validation.caret.Target,
+ * boolean)
+ */
+ public boolean canReference(Target target, boolean atRight) {
+ Node node = target.getNode();
+ if (node.getLocalName() != null) {
+ if (Arrays.asList(JSF_ROOT_CONTAINERS).contains(
+ node.getLocalName().toLowerCase())) {
+ return EditModelQuery.isChild(
+ RootContainerPositionRule.HTML_ROOT_CONTAINERS, node,
+ false, false)
+ || EditModelQuery.isChild(JSF_ROOT_CONTAINERS, node,
+ false, false);
+ }
+ }
+ return super.canReference(target, atRight);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/NodeConstructionPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/NodeConstructionPositionRule.java
new file mode 100644
index 000000000..0045421d2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/NodeConstructionPositionRule.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+/**
+ * @author mengbo
+ */
+public class NodeConstructionPositionRule extends DefaultPositionRule {
+
+ /**
+ *
+ */
+ public NodeConstructionPositionRule(IPositionMediator mediator,
+ ActionData actionData) {
+ super(mediator, actionData);
+ }
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/RootContainerPositionRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/RootContainerPositionRule.java
new file mode 100644
index 000000000..7d7134d49
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/RootContainerPositionRule.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import java.util.Arrays;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * This rule deal with containers 'body', 'view', 'subview'.
+ *
+ * @author mengbo
+ */
+public class RootContainerPositionRule extends DefaultPositionRule {
+ public static final String[] HTML_ROOT_CONTAINERS = { "body" };
+
+ /**
+ * @param mediator
+ */
+ public RootContainerPositionRule(IPositionMediator mediator,
+ ActionData actionData) {
+ super(mediator, actionData);
+ }
+
+ /**
+ * 1. If anyone of the three containers exists, the target should be in the
+ * container. 2. If none of the containers exists, then target will be not
+ * restricted.
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#hasEditableArea(org.eclipse.gef.EditPart)
+ */
+ public boolean hasEditableArea(Target target) {
+ EditPart part = target.getPart();
+ if (part == null) {
+ return false;
+ }
+ Node node = target.getNode();
+ if (hasBasicContainers(EditModelQuery.getDocumentNode(node))) {
+ return true;// isWithinkBasicContainer(node);
+ }
+ return super.hasEditableArea(target);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.gef.EditPart)
+ */
+ public boolean isEditable(Target target) {
+ Node node = target.getNode();
+ if (hasBasicContainers(EditModelQuery.getDocumentNode(node))) {
+ boolean result = isWithinkBasicContainer(node);
+ return result;
+ }
+ return super.isEditable(target);
+ }
+
+ /**
+ * We need to see if body, view are there. and they should be at first or
+ * second level.
+ *
+ * @param document
+ * @return
+ */
+ public static boolean hasBasicContainers(Document document) {
+ return getBasicContainer(document) != null;
+
+ }
+
+ public static boolean isWithinkBasicContainer(Node node) {
+ return EditModelQuery.isChild(HTML_ROOT_CONTAINERS, node, true, false);
+ }
+
+ public static Node getBasicContainer(Document document) {
+ Node node = EditModelQuery.getChild(document, HTML_ROOT_CONTAINERS, 2,
+ false);
+ if (node == null) {
+ node = EditModelQuery.getChild(document, HTML_ROOT_CONTAINERS, 2,
+ true);
+ }
+ return node;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#canReference(org.eclipse.jst.pagedesigner.validation.caret.Target,
+ * boolean)
+ */
+ public boolean canReference(Target target, boolean atRight) {
+ Node node = target.getNode();
+ if (node.getLocalName() != null) {
+ if (Arrays.asList(HTML_ROOT_CONTAINERS).contains(
+ node.getLocalName().toLowerCase())) {
+ return EditModelQuery.isChild(
+ JSFRootContainerPositionRule.JSF_ROOT_CONTAINERS, node,
+ false, false);
+ }
+ }
+ return true;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/Target.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/Target.java
new file mode 100644
index 000000000..b65d26b09
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/Target.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class Target {
+ private EditPart _part;
+
+ private Node _node;
+
+ public Target(EditPart part) {
+ _part = part;
+ Assert.isTrue(part.getModel() instanceof Node);
+ _node = (Node) part.getModel();
+ }
+
+ public Target(Node node) {
+ _node = node;
+ Assert.isTrue(node instanceof INodeNotifier);
+ if (((INodeNotifier) node).getAdapterFor(EditPart.class) != null) {
+ _part = (EditPart) ((INodeNotifier) node)
+ .getAdapterFor(EditPart.class);
+ }
+ }
+
+ /**
+ * @return Returns the _node.
+ */
+ public Node getNode() {
+ return _node;
+ }
+
+ /**
+ * @return Returns the _part.
+ */
+ public EditPart getPart() {
+ return _part;
+ }
+
+ public static EditPart resolvePart(Node node) {
+ if (node instanceof INodeNotifier
+ && ((INodeNotifier) node).getAdapterFor(EditPart.class) != null) {
+ return (EditPart) ((INodeNotifier) node)
+ .getAdapterFor(EditPart.class);
+ }
+ return null;
+ }
+
+ public static Node resolveNode(EditPart part) {
+ return (Node) part.getModel();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/WhitespacePositionMoveRule.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/WhitespacePositionMoveRule.java
new file mode 100644
index 000000000..9c98f73c5
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/validation/caret/WhitespacePositionMoveRule.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.validation.caret;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
+import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
+import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
+import org.w3c.dom.Text;
+
+/**
+ * For whitespaces 1. If there is sibling can be reference, then we don't
+ * reference whitespace text. 2. Position can't be between whitespace text.
+ *
+ * @author mengbo
+ */
+public class WhitespacePositionMoveRule extends DefaultPositionRule implements
+ IMovementRule {
+
+ /**
+ * @param mediator
+ */
+ public WhitespacePositionMoveRule(IPositionMediator mediator,
+ ActionData actionData) {
+ super(mediator, actionData);
+ _actionData = actionData;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IMovementRule#canEnter(org.eclipse.gef.EditPart)
+ */
+ public boolean allowsMoveIn(Target target) {
+ if (EditModelQuery.isTransparentText(target.getNode())) {
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IMovementRule#canMoveOut(org.eclipse.gef.EditPart)
+ */
+ public boolean allowsMoveOut(Target target) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#canReference(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public boolean canReference(Target target, boolean atRight) {
+ boolean result = super.canReference(target, atRight);
+ if (EditModelQuery.isText(target.getNode())) {
+ if (((Text) target.getNode()).getData().length() == 0) {
+ result = false;
+ } else if (EditModelQuery.isTransparentText(target.getNode())) {
+ DesignPosition position = new DesignRefPosition(target
+ .getPart(), atRight);
+ if (EditPartPositionHelper.getConcretePart(position, atRight) != null) {
+ result = true;
+ } else {
+ EditPart part = EditPartPositionHelper.getNextConcretPart(
+ position, atRight);
+ EditPart oppPart = EditPartPositionHelper
+ .getNextConcretPart(position, !atRight);
+ if (part == null) {
+ if (oppPart == null) {
+ result = true;
+ }
+ }
+ result = false;
+ }
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#hasEditableArea(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public boolean hasEditableArea(Target target) {
+ if (EditModelQuery.isTransparentText(target.getNode())) {
+ return false;
+ }
+ return super.hasEditableArea(target);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.caret.IPositionRule#isEditable(org.eclipse.jst.pagedesigner.caret.Target)
+ */
+ public boolean isEditable(Target target) {
+ if (EditModelQuery.isTransparentText(target.getNode())) {
+ return false;
+ }
+ return super.isEditable(target);
+ }
+
+ // /*
+ // * (non-Javadoc)
+ // *
+ // * @see
+ // org.eclipse.jst.pagedesigner.caret.IPositionRule#isValidPosition(org.eclipse.jst.pagedesigner.dom.IDOMPosition)
+ // */
+ // public boolean isValidPosition(IDOMPosition position)
+ // {
+ // Node node = null;
+ // if (position instanceof DOMRefPosition)
+ // {
+ // node = ((DOMRefPosition)position).getReferenceNode();
+ // } else if (position.isText())
+ // {
+ // node = position.getContainerNode();
+ // } else {
+ // return super.isValidPosition(position);
+ // }
+ // if (EditModelQuery.isTransparentText(position.getContainerNode()))
+ // {
+ // if (node.getPreviousSibling() != null)
+ // {
+ // node = node.getPreviousSibling();
+ // return _mediator.canReference(new Target(node), true);
+ // }
+ // else if (node.getNextSibling() != null)
+ // {
+ // node = node.getNextSibling();
+ // return _mediator.canReference(new Target(node), false);
+ // }
+ // }
+ // return super.isValidPosition(position);
+ // }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretPositionResolver.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretPositionResolver.java
new file mode 100644
index 000000000..ca7a59c8f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretPositionResolver.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.util.List;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ * @version 1.5
+ */
+public class CaretPositionResolver {
+ private IPositionMediator _validator;
+
+ private Point _point;
+
+ private static CaretPositionResolver _instance;
+
+ public static CaretPositionResolver getInstance(
+ IPositionMediator validator, Point point) {
+ if (_instance == null) {
+ _instance = new CaretPositionResolver();
+ }
+ _instance.setPoint(point);
+ _instance.setValidator(validator);
+ return _instance;
+ }
+
+ /**
+ * @param _point
+ * The _point to set.
+ */
+ private void setPoint(Point _point) {
+ this._point = _point;
+ }
+
+ /**
+ * @param _validator
+ * The _validator to set.
+ */
+ private void setValidator(IPositionMediator _validator) {
+ this._validator = _validator;
+ }
+
+ /**
+ * Calculate the two part's distance to point, the shorter one will be
+ * return. Distance is calculated based on: if there is one box contains
+ * point.y, then calculate that box, or if there is no any such one box,
+ * then calculate the y distance.
+ *
+ * @param part1
+ * @param part2
+ * @param point
+ * @return
+ */
+ static LayoutPart getCloserPart(LayoutPart part1, LayoutPart part2,
+ Point _point) {
+ if (part1 == null
+ || EditModelQuery.isTransparentText(Target.resolveNode(part1
+ .getPart()))) {
+ return (LayoutPart) part2;
+ } else if (part2 == null
+ || EditModelQuery.isTransparentText(Target.resolveNode(part2
+ .getPart()))) {
+ return (LayoutPart) part1;
+ }
+ Rectangle rect1 = ((LayoutPart) part1).getAbsoluteBounds();
+ Rectangle rect2 = ((LayoutPart) part2).getAbsoluteBounds();
+ Node n1 = Target.resolveNode(((LayoutPart) part1).getPart());
+ Node n2 = Target.resolveNode(((LayoutPart) part2).getPart());
+ // Within same.
+ if (EditModelQuery.isChild(n1, n2)
+ && (CaretPositionResolver.getXDistance(rect2, _point) == 0)
+ && !part1.isCloseToEdgeFromOutSide()) {
+ return (LayoutPart) part2;
+ } else if (EditModelQuery.isChild(n2, n1)
+ && (CaretPositionResolver.getXDistance(rect1, _point) == 0 && !part2
+ .isCloseToEdgeFromOutSide())
+ && !part2.isCloseToEdgeFromOutSide()) {
+ return (LayoutPart) part1;
+ }
+ if (rect1.intersect(new Rectangle(rect1.x, rect2.y, rect1.width,
+ rect2.height)).height == 0) {
+ return heightFirst(part1, part2, _point);
+ } else {
+ return widthFirst(part1, part2, _point);
+ }
+ }
+
+ private static LayoutPart heightFirst(LayoutPart part1, LayoutPart part2,
+ Point _point) {
+ Rectangle rect1 = part1.getAbsoluteBounds();
+ Rectangle rect2 = part2.getAbsoluteBounds();
+ int offset1 = Math.abs(CaretPositionResolver
+ .getYDistance(rect1, _point));
+ int offset2 = Math.abs(CaretPositionResolver
+ .getYDistance(rect2, _point));
+ if (offset1 > offset2) {
+ return (LayoutPart) part2;
+ } else if (offset1 < offset2) {
+ return (LayoutPart) part1;
+ } else {
+ offset1 = Math.abs(CaretPositionResolver
+ .getXDistance(rect1, _point));
+ offset2 = Math.abs(CaretPositionResolver
+ .getXDistance(rect2, _point));
+ if (offset1 >= offset2) {
+ return (LayoutPart) part2;
+ } else {
+ return (LayoutPart) part1;
+ }
+ }
+ }
+
+ private static LayoutPart widthFirst(LayoutPart part1, LayoutPart part2,
+ Point _point) {
+ Rectangle rect1 = ((LayoutPart) part1).getAbsoluteBounds();
+ Rectangle rect2 = ((LayoutPart) part2).getAbsoluteBounds();
+ int offset1 = Math.abs(CaretPositionResolver
+ .getXDistance(rect1, _point));
+ int offset2 = Math.abs(CaretPositionResolver
+ .getXDistance(rect2, _point));
+ if (offset1 > offset2) {
+ return (LayoutPart) part2;
+ } else if (offset1 < offset2) {
+ return (LayoutPart) part1;
+ } else {
+ offset1 = Math.abs(CaretPositionResolver
+ .getYDistance(rect1, _point));
+ offset2 = Math.abs(CaretPositionResolver
+ .getYDistance(rect2, _point));
+ if (offset1 >= offset2) {
+ return (LayoutPart) part2;
+ } else {
+ return (LayoutPart) part1;
+ }
+ }
+ }
+
+ /**
+ * Return a descendent part under parent that is one of the closest part to
+ * point.
+ *
+ * @param parent
+ * @return
+ */
+ private LayoutPart getClosestChildPart(LayoutPart parent) {
+ LayoutPart result = null;
+ if (parent != null) {
+ List children = null;
+ if ((children = parent.getPart().getChildren()).size() > 0) // &&
+ // _validator.hasEditableArea(new
+ // Target(parent.getPart())))
+ {
+ // iterate its children, we know the part doesn't contain p. so
+ // we only see if its children can be
+ // referenced.
+ for (int i = 0, n = children.size(); i < n; i++) {
+ LayoutPart nextPart = new LayoutPart((EditPart) children
+ .get(i), _point);
+ Target target = new Target(nextPart.getPart());
+ if (_validator.isValidPosition(new DesignRefPosition(target
+ .getPart(), false))) {
+ result = getCloserPart(result, nextPart, _point);
+ } else if (_validator.hasEditableArea(target)) {
+ LayoutPart temp = getClosestChildPart(nextPart);
+ if (temp == null) {
+ temp = nextPart;
+ }
+ result = getCloserPart(result, temp, _point);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Use by vertical movement, we need to see whther the par
+ *
+ * @param closestPart
+ * @param target
+ * @return
+ */
+ LayoutPart resolveClosestPartFrom(LayoutPart closestPart) {
+ Target target = new Target(closestPart.getPart());
+ LayoutPart finalPart = null;
+ if (EditModelQuery.isInline(Target.resolveNode(closestPart.getPart()))) {
+
+ if (closestPart.isAfterPoint() || closestPart.isBeforePoint()) {
+ finalPart = closestPart;
+ } else {
+ if (_validator.hasEditableArea(target)
+ && (_validator instanceof IMovementMediator
+ && ((IMovementMediator) _validator)
+ .allowsMoveIn(target) || !(_validator instanceof IMovementMediator))) {
+ finalPart = getClosestChildPartOrPart(closestPart);
+ }
+ }
+ }
+ // block
+ else {
+ if (closestPart.contains(_point)) {
+ if (_validator.hasEditableArea(target) && //
+ (_validator instanceof IMovementMediator
+ && ((IMovementMediator) _validator)
+ .allowsMoveIn(target) || !(_validator instanceof IMovementMediator))) {
+ finalPart = getClosestChildPartOrPart(closestPart);
+ }
+ }
+ // outside of bounds
+ else {
+ if (_validator.hasEditableArea(target)
+ && !IHTMLConstants.TAG_TABLE.equalsIgnoreCase(target
+ .getNode().getNodeName())
+ && (_validator instanceof IMovementMediator
+ && ((IMovementMediator) _validator)
+ .allowsMoveIn(target) || !(_validator instanceof IMovementMediator))) {
+ if (closestPart.atSameRow(_point)) {
+ finalPart = getClosestChildPartOrPart(closestPart);
+ } else if (!_validator
+ .isValidPosition(new DesignRefPosition(target
+ .getPart(), true))) {
+ finalPart = getClosestChildPartOrPart(closestPart);
+ }
+ }
+ }
+ }
+ if (finalPart == null && //
+ (_validator.isValidPosition(new DesignRefPosition(target
+ .getPart(), true)) || //
+ _validator.isValidPosition(new DesignRefPosition(target
+ .getPart(), false)))) {
+ finalPart = closestPart;
+ }
+ return finalPart;
+ }
+
+ private LayoutPart getClosestChildPartOrPart(LayoutPart closestPart) {
+ LayoutPart result = getClosestChildPart(closestPart);
+ if (result != null) {
+ result = resolveClosestPartFrom(result);
+ } else {
+ if (closestPart.getConcretePart() == null) {
+ result = closestPart;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the distance from rect's edge to point.x.
+ *
+ * @param rect
+ * @param point
+ * @return
+ */
+ public static int getXDistance(Rectangle rect, Point point) {
+ if (rect.getRight().x <= point.x) {
+ return point.x - (rect.getRight().x);
+ } else if (rect.x >= point.x) {
+ return point.x - rect.x;
+ } else if (rect.x <= point.x && point.x <= rect.getRight().x) {
+ return 0;
+ }
+ return -1;
+ }
+
+ /**
+ * from point to middle's distance. If the result is nagative, point is at
+ * left part of rect, if it is positive, the point is at the right part.
+ *
+ * @param rect
+ * @param point
+ * @return
+ */
+ public static int toXMiddle(Rectangle rect, Point point) {
+ return (point.x - (rect.x + rect.getRight().x) / 2);
+ }
+
+ /**
+ * from point to middle's distance If the result is nagative, point is at
+ * upper part of rect, if it is positive, the point is at the lower part.
+ *
+ * @param rect
+ * @param point
+ * @return
+ */
+ public static int toYMiddle(Rectangle rect, Point point) {
+ return (point.y - (rect.y + rect.getBottom().y) / 2);
+ }
+
+ public static int getYDistance(Rectangle rect, Point point) {
+ if (rect.y + rect.height <= point.y) {
+ return point.y - (rect.y + rect.height);
+ } else if (rect.y >= point.y) {
+ return point.y - rect.y;
+ } else if (rect.y <= point.y && point.y <= rect.y + rect.height) {
+ return 0;
+ }
+ return -1;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretUpdater.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretUpdater.java
new file mode 100644
index 000000000..3fe1e6c25
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/CaretUpdater.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.draw2d.FigureListener;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.RangeModel;
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
+import org.eclipse.jst.pagedesigner.tools.ExposeHelper;
+import org.eclipse.swt.widgets.Caret;
+
+/**
+ * This class is responsible for update the caret location. At least the
+ * following changes may result in caret location change. <ll>
+ * <li>The selection mode change. For example, from/to text mode to/from object
+ * mode, we need to hide/display the caret
+ * <li>The caret location change in the model.
+ * <li>the figures moved. This may result in model change in somewhere else, or
+ * user resized the page designer.
+ * <li>The figure that containing the caret get recreated. </ll>
+ *
+ * @author mengbo
+ */
+public class CaretUpdater implements IHTMLGraphicalViewerListener,
+ FigureListener {
+ private static final Logger _log = PDPlugin.getLogger(CaretUpdater.class);
+
+ private IHTMLGraphicalViewer _viewer;
+
+ private boolean _viewerBatchChanging = false;
+
+ public static final int CARET_WIDTH = 2;
+
+ /**
+ * the figure the caret associate to, we need to track this figure's
+ * resizing, location change, etc.
+ */
+ private IFigure _trackFigure;
+
+ private Polyline _rangeStartCaret;
+
+ public CaretUpdater(IHTMLGraphicalViewer viewer) {
+ _viewer = viewer;
+ setup();
+ }
+
+ public void setup() {
+ _viewer.addSelectionChangedListener(this);
+ }
+
+ /**
+ * this method is called after the view is fully initialized.
+ */
+ public void connectViewer() {
+ Viewport viewport = _viewer.getViewport();
+ if (viewport != null) {
+ viewport.getHorizontalRangeModel().addPropertyChangeListener(
+ new PropertyChangeListener() {
+ public void propertyChange(
+ PropertyChangeEvent propertychangeevent) {
+ if ((propertychangeevent.getSource() instanceof RangeModel)
+ && (propertychangeevent.getPropertyName()
+ .equals(ICSSPropertyID.ATTR_VALUE) || propertychangeevent
+ .getPropertyName().equals("extent")))
+ updateCaret();
+ }
+
+ });
+ viewport.getVerticalRangeModel().addPropertyChangeListener(
+ new PropertyChangeListener() {
+
+ public void propertyChange(
+ PropertyChangeEvent propertychangeevent) {
+ if ((propertychangeevent.getSource() instanceof RangeModel)
+ && (propertychangeevent.getPropertyName()
+ .equals(ICSSPropertyID.ATTR_VALUE) || propertychangeevent
+ .getPropertyName().equals("extent")))
+ updateCaret();
+ }
+
+ });
+ }
+ }
+
+ public void dispose() {
+ _viewer.removeSelectionChangedListener(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void updateSelection() {
+ setCaretVisible(false);
+ updateRangeSelection();
+ updateCaret();
+ reveal();
+ }
+
+ private void setCaretVisible(boolean visible) {
+ Caret caret = _viewer.getCaret();
+ if (caret == null)
+ return;
+ if (caret.isDisposed()) {
+ return;
+ }
+ caret.setVisible(visible);
+ }
+
+ /**
+ *
+ */
+ private void updateRangeSelection() {
+ // FIXME: optimization needed here. Normally should not repaint the
+ // whole page.
+ DesignRange range = _viewer.getRangeSelection();
+ ((GraphicalEditPart) _viewer.getRootEditPart()).getFigure().repaint();
+ ((GraphicalEditPart) _viewer.getRootEditPart()).getFigure()
+ .getUpdateManager().performUpdate();
+ }
+
+ public void updateCaret() {
+ if (_trackFigure != null) {
+ _trackFigure.removeFigureListener(this);
+ _trackFigure = null;
+ }
+ Caret caret = _viewer.getCaret();
+ if (caret == null) {
+ return;
+ }
+ if (caret.isDisposed()) {
+ return;
+ }
+
+ Rectangle rect = null;
+
+ // try get the caret bounds.
+ if (_viewer.isInRangeMode()) {
+ DesignRange range = _viewer.getRangeSelection();
+ if (range != null) {
+ DesignPosition endPosition = range.getEndPosition();
+ if (endPosition != null && endPosition.isValid()) {
+ rect = EditPartPositionHelper
+ .convertToAbsoluteCaretRect(endPosition);
+ _trackFigure = ((GraphicalEditPart) endPosition
+ .getContainerPart()).getFigure();
+ _trackFigure.addFigureListener(this);
+ }
+ }
+ }
+
+ // set visible effect
+ if (rect == null) {
+ caret.setVisible(false);
+ } else {
+ caret.setVisible(false); // make sure it get removed from the
+ // screen.
+ // the caret width doesn't need to be calculated, the x pos should
+ // be adjusted more acurately.
+ caret.setBounds(rect.x, rect.y, CARET_WIDTH, rect.height);
+ caret.setVisible(true);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (_viewerBatchChanging) {
+ return;
+ }
+ updateSelection();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewerListener#selectionAboutToChange()
+ */
+ public void selectionAboutToChange() {
+ _viewerBatchChanging = true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewerListener#selectionChangeFinished()
+ */
+ public void selectionChangeFinished() {
+ _viewerBatchChanging = false;
+ updateSelection();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure)
+ */
+ public void figureMoved(IFigure source) {
+ updateCaret();
+ }
+
+ private void reveal() {
+ Caret caret = _viewer.getCaret();
+ if (caret != null && !caret.isDisposed() && _viewer.isInRangeMode()) {
+ org.eclipse.swt.graphics.Rectangle rect = caret.getBounds();
+ ExposeHelper helper = new ExposeHelper(_viewer);
+ helper.exposeArea(new Rectangle(rect.x, rect.y, rect.width,
+ rect.height));
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignPosition.java
new file mode 100644
index 000000000..f541b1390
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignPosition.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.util.List;
+
+import org.eclipse.gef.EditPart;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * @author mengbo
+ */
+public class DesignPosition {
+ public static final DesignPosition INVALID = new DesignPosition(null, -1);
+
+ private EditPart _containerPart;
+
+ int _offset;
+
+ private Node _containerNode;
+
+ /**
+ * @param part
+ * @param offset
+ */
+ public DesignPosition(EditPart part, int offset) {
+ _containerPart = part;
+ _offset = offset;
+
+ int[] a = new int[] { 0, 0 };
+ }
+
+ /**
+ * if _containerPart is null, means it is invalid
+ *
+ * @return
+ */
+ public EditPart getContainerPart() {
+ return _containerPart;
+ }
+
+ public Node getContainerNode() {
+ if (_containerPart != null) {
+ return (Node) _containerPart.getModel();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * if offset < 0, means it is invalid.
+ *
+ * @return
+ */
+ public int getOffset() {
+ return _offset;
+ }
+
+ public boolean isValid() {
+ return (_containerPart != null) && (_offset >= 0);
+ }
+
+ /**
+ * This method should not be called when is text node.
+ *
+ * @param forward
+ * @return
+ */
+ public EditPart getSiblingEditPart(boolean forward) {
+ if (!isValid()) {
+ return null;
+ }
+
+ int index = forward ? (_offset) : (_offset - 1);
+ List children = _containerPart.getChildren();
+
+ if ((index >= children.size()) || (index < 0)) {
+ return null;
+ }
+
+ return (EditPart) children.get(index);
+ }
+
+ /**
+ * factory method
+ *
+ * @param part
+ * @return
+ */
+ public static DesignPosition createPositionBeforePart(EditPart part) {
+ EditPart parent = part.getParent();
+
+ if (parent == null) {
+ return new DesignPosition(part, 0);
+ } else {
+ return new DesignPosition(parent, parent.getChildren()
+ .indexOf(part));
+ }
+ }
+
+ /**
+ * factory method
+ *
+ * @param part
+ * @return
+ */
+ public static DesignPosition createPositionAfterPart(EditPart part) {
+ EditPart parent = part.getParent();
+
+ if (parent == null) {
+ return new DesignPosition(part, part.getChildren().size());
+ } else {
+ return new DesignPosition(parent, parent.getChildren()
+ .indexOf(part) + 1);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof DesignPosition) {
+ DesignPosition p = (DesignPosition) obj;
+
+ return (p.getContainerPart() == this._containerPart)
+ && (p.getOffset() == this._offset);
+ }
+
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public StringBuffer debugDump(StringBuffer buffer) {
+ try {
+ buffer.append("DesignPosition: ").append(this._containerPart)
+ .append(": ").append(this._offset).append("\n");
+
+ if (this._containerPart.getModel() instanceof Text) {
+ // skip
+ } else {
+ if (this._offset > 0) {
+ buffer.append("after: ").append(
+ this._containerPart.getChildren().get(
+ this._offset - 1)).append("\n");
+ }
+
+ if (this._offset < (this._containerPart.getChildren().size() - 1)) {
+ buffer.append("before: ")
+ .append(
+ this._containerPart.getChildren().get(
+ this._offset)).append("\n");
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ return buffer;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ return debugDump(buffer).toString();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRange.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRange.java
new file mode 100644
index 000000000..468defadf
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRange.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * @author mengbo
+ */
+public class DesignRange implements ISelection {
+ public DesignPosition _start;
+
+ public DesignPosition _end;
+
+ public DesignRange(DesignPosition start, DesignPosition end) {
+ _start = start;
+ _end = end;
+ }
+
+ public DesignPosition getStartPosition() {
+ return _start;
+ }
+
+ public DesignPosition getEndPosition() {
+ return _end;
+ }
+
+ // public boolean isCollapsed()
+ // {
+ // }
+
+ // public boolean fullyContains(EditPart part)
+ // {
+ //
+ // }
+
+ public boolean isValid() {
+ return _start != null && _start.isValid() && _end != null
+ && _end.isValid();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.ISelection#isEmpty()
+ */
+ public boolean isEmpty() {
+ // FIXME: temp implementation, need revisit.
+ return !isValid() || _start.equals(_end);
+ }
+
+ public StringBuffer debugDump(StringBuffer buffer) {
+ if (_start != null) {
+ buffer.append("Start: ").append(_start);
+ } else {
+ buffer.append("Start: null");
+ }
+ if (_end != null) {
+ buffer.append("End: ").append(_end);
+ } else {
+ buffer.append("End: null");
+ }
+ return buffer;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ return debugDump(buffer).toString();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRefPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRefPosition.java
new file mode 100644
index 000000000..d02733fbb
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/DesignRefPosition.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import org.eclipse.gef.EditPart;
+
+/**
+ * @author mengbo
+ */
+public class DesignRefPosition extends DesignPosition {
+ private boolean _caretIsAtRight;
+
+ private EditPart _refPart;
+
+ /**
+ * @param part
+ * @param offset
+ */
+ public DesignRefPosition(EditPart part, boolean caretIsAfter) {
+ super(part.getParent(), 0);
+ int offset = part.getParent().getChildren().indexOf(part);
+ _offset = caretIsAfter ? offset + 1 : offset;
+ _refPart = part;
+ _caretIsAtRight = caretIsAfter;
+ }
+
+ public EditPart getRefPart() {
+ return _refPart;
+ }
+
+ /**
+ * @return Returns the _isAfter.
+ */
+ public boolean caretIsAtRight() {
+ return _caretIsAtRight;
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/EditPartPositionHelper.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/EditPartPositionHelper.java
new file mode 100644
index 000000000..9d61fe892
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/EditPartPositionHelper.java
@@ -0,0 +1,699 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.common.logging.Logger;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSTextFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowBox;
+import org.eclipse.jst.pagedesigner.dom.DOMPosition;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.utils.BodyHelper;
+import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class EditPartPositionHelper {
+ private final static Logger _log = PDPlugin
+ .getLogger(EditPartPositionHelper.class);
+
+ /**
+ * Add something to curent
+ *
+ * @param lineBox
+ * @param host
+ * @param point
+ * @param validator
+ */
+ private static void addToCurrentLine(FlowBoxLine lineBox, EditPart host,
+ Point point, IPositionMediator validator) {
+ Node node = Target.resolveNode(host);
+ if (!(node == null || EditModelQuery.isDocument(node))) {
+ // Either it is referencable or is editable.
+ if (validator.isValidPosition(new DOMRefPosition(node, true))
+ || //
+ validator
+ .isValidPosition((new DOMRefPosition(node, false)))
+ || //
+ validator.isValidPosition(new DOMPosition(node, 0))) {
+ lineBox.addLayoutPart(host, point);
+ }
+ }
+ }
+
+ /**
+ * @param endPosition
+ * @return null means failed to convert to rect.
+ */
+ public static Rectangle convertToAbsoluteCaretRect(DesignPosition position) {
+ Rectangle ret = null;
+ try {
+ final int CARET_OFFSET = 1;
+ if (position == null || !position.isValid()) {
+ return null;
+ }
+ EditPart containerEditPart = position.getContainerPart();
+ if (containerEditPart instanceof TextEditPart) {
+ CSSTextFigure figure = (CSSTextFigure) ((TextEditPart) containerEditPart)
+ .getFigure();
+ ret = figure.calculateCaretPosition(position.getOffset());
+ figure.translateToAbsolute(ret);
+ ret.width = CaretUpdater.CARET_WIDTH;
+ } else {
+ int offset = position.getOffset();
+ // there is no child
+ if (containerEditPart.getChildren().isEmpty()
+ || LayoutPart.getConcretePart(containerEditPart) == null) {
+ IFigure figure = ((GraphicalEditPart) containerEditPart)
+ .getFigure();
+ Rectangle bounds = figure.getBounds();
+ if (figure instanceof CSSFigure) {
+ List fragments = ((CSSFigure) figure)
+ .getFragmentsForRead();
+ if (fragments.size() > 0) {
+ FlowBox box = (FlowBox) fragments.get(fragments
+ .size() - 1);
+ bounds = LayoutPart.getBounds(box);
+ }
+ }
+
+ ret = new Rectangle(bounds.x + CARET_OFFSET, bounds.y,
+ CaretUpdater.CARET_WIDTH, bounds.height);
+
+ figure.translateToAbsolute(ret);
+ } else if (offset >= 0
+ && offset <= containerEditPart.getChildren().size()) {
+ ret = getRefRect(position);
+ }
+ }
+ } catch (Exception e) {
+ // This should never happen, we catch here for later analysis.
+ // _log.debug("Error in caret rect resolving", e);
+ ret = new Rectangle(0, 0, 0, 0);
+ }
+ if (ret == null) {
+ ret = new Rectangle(0, 0, 0, 0);
+ }
+ return ret;
+ }
+
+ /**
+ * This method will create FlowBoxLine to calculate the accurate parts.
+ *
+ * @param host
+ * @param p
+ * @return
+ */
+ public static DesignPosition findEditPartPosition(EditPart host, Point p,
+ IPositionMediator validator) {
+ try {
+ host = validator.getEditableContainer(new Target(host));
+ FlowBoxLine boxLine = new FlowBoxLine(
+ new Rectangle(p.x, p.y, 0, 0), validator, p);
+ DesignPosition position = innerFindEditPartPosition(host, host, p,
+ boxLine, validator);
+ if (position == null) {
+ position = innerFindEditPartPosition(host, host, p, boxLine,
+ validator);
+ if (position == null) {
+ EditPart part = boxLine.getClosestPart();
+ if (part != null) {
+ LayoutPart layoutPart = new LayoutPart(part, p);
+ position = layoutPart.resolvePosition(validator);
+ }
+ }
+ }
+ return position;
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+
+ /**
+ * This function find the position, if there is one which is widget or text
+ * and it contains p, or there is not such widget, then boxLine will returns
+ * the widget that are in a sameline which contains p;
+ *
+ * @param p
+ * @param result
+ * @param tagName
+ * @param skip
+ * @return
+ */
+ public static DesignPosition innerFindEditPartPosition(EditPart rootHost,
+ EditPart host, Point p, FlowBoxLine boxLine,
+ IPositionMediator validator) {
+ Target target = new Target(host);
+ LayoutPart lPart = new LayoutPart(host, p);
+ // text
+ if (host instanceof TextEditPart) {
+ if (lPart.contains(p)) {
+ DesignPosition position = null;
+ // see if the point is within string.
+ position = findTextEditPartPosition((TextEditPart) host, p);
+ if (position == null) {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ // found?!!
+ return position;
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ return null;
+ }
+ }
+ // widget
+ else if (isWidget(host)) {
+ if (lPart.contains(p)
+ && (validator.isValidPosition(new DOMRefPosition(target
+ .getNode(), true)) || //
+ validator.isValidPosition((new DOMRefPosition(target
+ .getNode(), false))))) {
+ if (IHTMLConstants.TAG_BR.equalsIgnoreCase(Target.resolveNode(
+ host).getNodeName())) {
+ return new DesignRefPosition(host, lPart.isBeforePoint(p));
+ } else {
+ return new DesignRefPosition(host, lPart.isBeforePoint(p)
+ || !lPart.atLeftPart(p));
+ }
+ // found!!!
+ // return new DesignRefPosition(host, lPart.isBeforePoint(p) ||
+ // !lPart.atLeftPart(p));
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ } else {
+ // root host. we always supporse it has editable area.
+ if (host == rootHost) {
+ if (host.getChildren().size() > 0) {
+ List children = host.getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ GraphicalEditPart child = (GraphicalEditPart) children
+ .get(i);
+ DesignPosition position = innerFindEditPartPosition(
+ rootHost, child, p, boxLine, validator);
+ if (position != null) {
+ return position;
+ }
+ }
+ }
+ if (boxLine.getPartsList().size() == 0) {
+ if (lPart.contains(p)) {
+ // found!!!
+ return new DesignPosition(host, 0);
+ }
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ // container
+ else {
+ // cann't edit it.
+ if (!validator.hasEditableArea(target)) {
+ if (lPart.contains(p) && //
+ (validator.isValidPosition(new DesignRefPosition(
+ target.getPart(), true)) || //
+ validator.isValidPosition(new DesignRefPosition(
+ target.getPart(), true)))) {
+ return new DesignRefPosition(host, lPart
+ .isBeforePoint(p)
+ || !lPart.atLeftPart(p));
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ // can edit
+ else {
+ // contains p
+ if (lPart.contains(p) || //
+ (!validator.isValidPosition(new DesignRefPosition(
+ target.getPart(), true)) && //
+ !validator.isValidPosition(new DesignRefPosition(
+ target.getPart(), true)))) {
+ if (host.getChildren().size() > 0) {
+ List children = host.getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ GraphicalEditPart child = (GraphicalEditPart) children
+ .get(i);
+ DesignPosition position = innerFindEditPartPosition(
+ rootHost, child, p, boxLine, validator);
+ if (position != null) {
+ return position;
+ }
+ }
+ } else {
+ // we put the container which is empty here.
+ if (lPart.contains(p)) {
+ // found!!!
+ return new DesignPosition(host, 0);
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ }
+ // not contains p
+ else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * similiar to findEditPartPositionConstrained, this method is used to
+ * vertically move caret.
+ *
+ * @param host
+ * @param p
+ * @return
+ */
+ public static DesignPosition findEditPartPositionConstrained(EditPart host,
+ Point p, IMovementMediator validator) {
+ try {
+ FlowBoxLine boxLine = new FlowBoxLine(
+ new Rectangle(p.x, p.y, 0, 0), validator, p);
+ DesignPosition position = innerFindEditPartPositionConstrained(
+ host, host, p, boxLine, validator);
+ if (position == null) {
+ position = innerFindEditPartPositionConstrained(host, host, p,
+ boxLine, validator);
+ if (position == null) {
+ EditPart part = boxLine.getClosestPart();
+ if (part != null) {
+ LayoutPart layoutPart = new LayoutPart(part, p);
+ position = layoutPart.resolvePosition(validator);
+ }
+ }
+ }
+ return position;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * This method is used for move up/down, except for using tactics to deal
+ * with container, this method is similiar to findEditPartPosition.
+ *
+ * @param p
+ * @param result
+ * @param tagName
+ * @param skip
+ * @return
+ */
+ public static DesignPosition innerFindEditPartPositionConstrained(
+ EditPart rootHost, EditPart host, Point p, FlowBoxLine boxLine,
+ IMovementMediator validator) {
+ Target target = new Target(host);
+ LayoutPart lPart = new LayoutPart(host, p);
+ // text
+ if (host instanceof TextEditPart) {
+ if (lPart.contains(p)) {
+ DesignPosition position = null;
+ // see if the point is within string.
+ position = findTextEditPartPosition((TextEditPart) host, p);
+ if (position == null) {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ // found?!!
+ return position;
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ return null;
+ }
+ }
+ // widget
+ else if (isWidget(host)) {
+ if (lPart.contains(p)) {
+ // found!!!
+ if (IHTMLConstants.TAG_BR.equalsIgnoreCase(Target.resolveNode(
+ host).getNodeName())) {
+ return new DesignRefPosition(host, lPart.isBeforePoint(p));
+ } else {
+ return new DesignRefPosition(host, lPart.isBeforePoint(p)
+ || !lPart.atLeftPart(p));
+ }
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ } else {
+ // root host. we always supporse it has editable area.
+ if (host == rootHost) {
+ if (host.getChildren().size() > 0) {
+ List children = host.getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ GraphicalEditPart child = (GraphicalEditPart) children
+ .get(i);
+ DesignPosition position = innerFindEditPartPositionConstrained(
+ rootHost, child, p, boxLine, validator);
+ if (position != null) {
+ return position;
+ }
+ }
+ } else {
+ if (lPart.contains(p)) {
+ // found!!!
+ return new DesignPosition(host, 0);
+ }
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ // container
+ else {
+ // cann't edit it.
+ if (!validator.hasEditableArea(target)
+ || !validator.allowsMoveIn(target)) {
+ if (validator.canReference(target, true)
+ || validator.canReference(target, false)) {
+ if (lPart.contains(p)) {
+ return new DesignRefPosition(host, lPart
+ .isBeforePoint(p)
+ || !lPart.atLeftPart(p));
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ }
+ // can edit
+ else {
+ // contains p
+ if (lPart.contains(p)) {
+ if (host.getChildren().size() > 0) {
+ List children = host.getChildren();
+ for (int i = 0, size = children.size(); i < size; i++) {
+ GraphicalEditPart child = (GraphicalEditPart) children
+ .get(i);
+ DesignPosition position = innerFindEditPartPositionConstrained(
+ rootHost, child, p, boxLine, validator);
+ if (position != null) {
+ return position;
+ }
+ }
+ } else {
+ // we put the container which is empty here.
+ if (lPart.contains(p)) {
+ // found!!!
+ return new DesignPosition(host, 0);
+ } else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ }
+ // not contains p
+ else {
+ addToCurrentLine(boxLine, host, p, validator);
+ }
+ }
+ }
+ }
+ return null;
+
+ }
+
+ // /**
+ // * @param host
+ // * @param p
+ // * @return
+ // */
+ // private static DesignPosition
+ // findTextEditPartPositionAdjacent(TextEditPart host, Point p)
+ // {
+ // if (host.getFigure() instanceof CSSTextFigure)
+ // {
+ // CSSTextFigure figure = (CSSTextFigure) host.getFigure();
+ // // make a copy to not destroy the original o
+ // p = p.getCopy();
+ // figure.translateToRelative(p);
+ // int offset = figure.getNewInsertionOffset(p);
+ // if (offset >= 0)
+ // {
+ // return new DesignPosition(host, offset);
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+ // else
+ // {
+ // // should not happen.
+ // return new DesignPosition(host, 0);
+ // }
+ // }
+
+ /**
+ * @param host
+ * @param p
+ * @return
+ */
+ private static DesignPosition findTextEditPartPosition(TextEditPart host,
+ Point p) {
+ if (host.getFigure() instanceof CSSTextFigure) {
+ CSSTextFigure figure = (CSSTextFigure) host.getFigure();
+ // make a copy to not destroy the original o
+ p = p.getCopy();
+ figure.translateToRelative(p);
+ int offset = figure.getInsertionOffset(p);
+ if (offset >= 0) {
+ return new DesignPosition(host, offset);
+ } else {
+ return null;
+ }
+ } else {
+ // should not happen.
+ return new DesignPosition(host, 0);
+ }
+ }
+
+ /**
+ * @param figure
+ * @param box
+ * @return
+ */
+ public static Rectangle getBoxBounds(IFigure figure, FlowBox box) {
+ Rectangle r = new Rectangle(box._x, box._y, box.getWidth(), box
+ .getHeight());
+ figure.translateToAbsolute(r);
+ return r;
+ }
+
+ /**
+ * @param child
+ * @return
+ */
+ public static Rectangle getAbsoluteBounds(EditPart child) {
+ if (child instanceof GraphicalEditPart) {
+ Rectangle bounds = ((GraphicalEditPart) child).getFigure()
+ .getBounds().getCopy();
+ ((GraphicalEditPart) child).getFigure().translateToAbsolute(bounds);
+ return bounds;
+ } else {
+ return new Rectangle(0, 0, 0, 0);
+ }
+ }
+
+ /**
+ * @param host
+ * @param tagName
+ * @return
+ */
+ private static boolean isWidget(EditPart host) {
+ if (host instanceof NodeEditPart) {
+ return ((NodeEditPart) host).isWidget();
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Is Caret at right?
+ *
+ * @param position
+ * @param caretRefResult
+ * @return
+ */
+ private static EditPart tryTwoWays(DesignPosition position,
+ List caretRefResult) {
+ EditPart result = null;
+ // Sibling first:
+ Node node = EditModelQuery.getInstance().getSibling(
+ DOMPositionHelper.toDOMPosition(position), true);
+ if (node != null && !EditModelQuery.isTransparentText(node)) {
+ result = Target.resolvePart(node);
+ caretRefResult.add(new Boolean(false));
+ } else {
+ node = EditModelQuery.getInstance().getSibling(
+ DOMPositionHelper.toDOMPosition(position), false);
+ if (node != null && !EditModelQuery.isTransparentText(node)) {
+ result = Target.resolvePart(node);
+ caretRefResult.add(new Boolean(true));
+ }
+ }
+ if (result == null) {
+ if (getConcretePart(position, false) != null) {
+ result = getConcretePart(position, false);
+ caretRefResult.add(new Boolean(true));
+ } else if (getConcretePart(position, true) != null) {
+ result = getConcretePart(position, true);
+ caretRefResult.add(new Boolean(false));
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Here we are doing something to avoid reference witespace tag. Since we
+ * still need to improve whitespace tags's layout furthure more.
+ */
+ private static EditPart getNextConcretPart(DesignPosition position,
+ List caretIsAtRightTest) {
+ EditPart result = null;
+ boolean caretIsAtRight = true;
+ if (position instanceof DesignRefPosition) {
+ caretIsAtRight = ((DesignRefPosition) position).caretIsAtRight();
+ result = ((DesignRefPosition) position).getRefPart();
+ caretIsAtRightTest.add(new Boolean(caretIsAtRight));
+ }
+ if (result == null
+ || EditModelQuery.isTransparentText(Target.resolveNode(result))) {
+ caretIsAtRightTest.clear();
+ result = tryTwoWays(position, caretIsAtRightTest);
+ }
+ return result;
+ }
+
+ /**
+ * Avoid whitespaces
+ *
+ * @param position
+ * @param forward
+ * @return
+ */
+ public static EditPart getConcretePart(DesignPosition position,
+ boolean forward) {
+ EditPart result = null;
+ Node node = EditModelQuery.getInstance().getSibling(
+ DOMPositionHelper.toDOMPosition(position), forward);
+ while (node != null && EditModelQuery.isTransparentText(node)) {
+ node = EditModelQuery.getInstance().getSibling(node, forward);
+ }
+ if (node != null) {
+ result = Target.resolvePart(node);
+ }
+ return result;
+ }
+
+ public static EditPart getNextConcretPart(DesignPosition position,
+ boolean forward) {
+ Node node;
+ EditPart result = null;
+ node = EditModelQuery.getInstance().getSibling(
+ DOMPositionHelper.toDOMPosition(position), forward);
+ if (node != null) {
+ if (forward) {
+ while (node != null) {
+ if (!EditModelQuery.isTransparentText(node)
+ && (result = Target.resolvePart(node)) != null) {
+ result = Target.resolvePart(node);
+ break;
+ }
+ node = node.getNextSibling();
+ }
+ } else {
+ while (node != null) {
+ if (!EditModelQuery.isTransparentText(node)
+ && (result = Target.resolvePart(node)) != null) {
+ result = Target.resolvePart(node);
+ break;
+ }
+ node = node.getPreviousSibling();
+ }
+ }
+ }
+ return result;
+ }
+
+ private static Rectangle getRefRect(DesignPosition position) {
+ List caretLocation = new ArrayList();
+ EditPart part = getNextConcretPart(position, caretLocation);
+ LayoutPart layoutPart;
+ Rectangle rect = null;
+ if (part != null) {
+ layoutPart = new LayoutPart(part, null);
+ boolean caretIsAtRight = ((Boolean) caretLocation.get(0))
+ .booleanValue();
+ final int CARET_OFFSET = 1;
+ Rectangle bounds = null;
+ IFigure figure = ((GraphicalEditPart) part).getFigure();
+ if (!caretIsAtRight) {
+ FlowBox box;
+ if ((box = layoutPart.getLine(0)) != null) {
+ bounds = LayoutPart.getBounds(box);
+ }
+ } else {
+ FlowBox box;
+ if ((box = layoutPart.getLastLine()) != null) {
+ bounds = LayoutPart.getBounds(box);
+ }
+ }
+ if (bounds == null) {
+ bounds = figure.getBounds();
+ }
+ if (!caretIsAtRight) {
+ rect = new Rectangle(bounds.x - CARET_OFFSET, bounds.y,
+ CaretUpdater.CARET_WIDTH, bounds.height);// new
+ } else {
+ rect = new Rectangle(bounds.getRight().x + CARET_OFFSET,
+ bounds.y, CaretUpdater.CARET_WIDTH, bounds.height);// new
+ }
+ figure.translateToAbsolute(rect);
+ } else {
+ System.out.println("No concrete part?");
+ }
+ return rect;
+ }
+
+ public static DesignPosition moveDesignPositionForInsert(
+ DesignPosition position, String uri, String tag) {
+ IDOMPosition domposition;
+ domposition = DOMPositionHelper.toDOMPosition(position);
+ if (domposition != null) {
+ domposition = BodyHelper
+ .adjustInsertPosition(uri, tag, domposition);
+ }
+ if (domposition != null) {
+ return DOMPositionHelper.toDesignPosition(domposition);
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/FlowBoxLine.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/FlowBoxLine.java
new file mode 100644
index 000000000..d6f9d1ad2
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/FlowBoxLine.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
+import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
+
+/**
+ * FlowBoxLine collects EditParts in a line that cover the x or y coordinate of
+ * design view caret. An EditPart may be a widget that can't contains children,
+ * a TextEditPart which contains a set of flowbox, or a widgets container which
+ * contains some other editparts. For container, there are two types: white box
+ * to visitor, that is the container * visitor should consider its content, like
+ * <A>, <B>. etc, or black box to visitor, like <TABLE>. Black box means the
+ * container will be considered as a whole from outside. For non-container
+ * widget we only see TextEditPart can be broken at line end. For black box,
+ * only start box or latest box are used for final reference, for white box, we
+ * will process its content for reference <@see
+ * EditPartPositionHelper.findEditPartPosition>. For Text, the char that is
+ * closest to caret will be referenced. In this line class, tree types of
+ * EditPart are collected: TextEditPart, Widget, BlackBox container.
+ *
+ * @author mengbo
+ */
+public class FlowBoxLine {
+ private int _x;
+
+ private int _y;
+
+ private int _height;
+
+ private int _width;
+
+ private HashMap _parts = new HashMap();
+
+ private IPositionMediator _validator;
+
+ private Point _point;
+
+ public FlowBoxLine(Rectangle rect, IPositionMediator validator, Point point) {
+ _x = rect.x;
+ _y = rect.y;
+ _width = rect.width;
+ _height = rect.height;
+ _validator = validator;
+ _point = point;
+ }
+
+ /**
+ * @return Returns the _height.
+ */
+ public int getHeight() {
+ return _height;
+ }
+
+ /**
+ * @return Returns the _width.
+ */
+ public int getWidth() {
+ return _width;
+ }
+
+ /**
+ * @return Returns the _x.
+ */
+ public int getX() {
+ return _x;
+ }
+
+ /**
+ * @return Returns the _y.
+ */
+ public int getY() {
+ return _y;
+ }
+
+ public HashMap getPartsList() {
+ return _parts;
+ }
+
+ public Point getRightBottom() {
+ return new Point(_x + _width, _y + _height);
+ }
+
+ public boolean addLayoutPart(EditPart part, Point point) {
+ Assert.isTrue(part != null && point != null);
+ Rectangle rect = null;
+ LayoutPart lPart = new LayoutPart(part, point);
+ if (_parts.size() == 0) {
+ resetBounds(lPart);
+ return true;
+ }
+ if (!interact(lPart)) {
+ if (closer(lPart)) {
+ resetBounds(lPart);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ rect = lPart.getAbsoluteBounds();
+ }
+ int xx = Math.min(rect.x, _x);
+ int width = Math.max(rect.getRight().x, getRightBottom().x) - xx;
+ int yy = Math.min(rect.y, _y);
+ int height = Math.max(rect.getBottom().y, getRightBottom().y) - yy;
+ _x = xx;
+ _y = yy;
+ _width = width;
+ _height = height;
+ _parts.put(part, lPart);
+ return true;
+ }
+
+ public boolean interact(LayoutPart lPart) {
+ Rectangle rect = lPart.getAbsoluteBounds();
+ return !(rect.getBottom().y <= _y || getRightBottom().y <= rect.y);
+ }
+
+ public boolean contains(EditPart part) {
+ return _parts.containsKey(part);
+ }
+
+ public boolean contains(LayoutPart part) {
+ return _parts.containsValue(part);
+ }
+
+ public LayoutPart getLayoutPart(EditPart part) {
+ return (LayoutPart) _parts.get(part);
+ }
+
+ // For vertical movement, we need to see if there is part cover p.x.
+ public EditPart getClosestPart() {
+ if (_parts.isEmpty()) {
+ return null;
+ }
+ Collection parts = _parts.values();
+ Iterator iterator = parts.iterator();
+ LayoutPart closestPart = (LayoutPart) iterator.next();
+ if (iterator.hasNext()) {
+ while (iterator.hasNext()) {
+ LayoutPart nextPart = (LayoutPart) iterator.next();
+ closestPart = CaretPositionResolver.getCloserPart(closestPart,
+ nextPart, _point);
+ }
+ }
+ // for children.
+ LayoutPart result = null;
+ if (_validator.getActionData().getActionType() == ActionData.KEYBOARD_NAVAGATION
+ || //
+ closestPart.isInline()) {
+ result = CaretPositionResolver.getInstance(_validator, _point)
+ .resolveClosestPartFrom(closestPart);
+ } else {
+ result = closestPart;
+ }
+ if (result != null) {
+ return result.getPart();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * See how close the part,box is closer to point, if it is closer than
+ * current FlowBoxLine. return true;
+ */
+ private boolean closer(LayoutPart lPart) {
+ int lineYOffset = Math.abs(CaretPositionResolver.getYDistance(
+ getBounds(), _point));
+ int partYOffset = Math.abs(CaretPositionResolver.getYDistance(lPart
+ .getAbsoluteBounds(), _point));
+ return lineYOffset > partYOffset;
+ }
+
+ public Rectangle getBounds() {
+ return new Rectangle(_x, _y, _width, _height);
+ }
+
+ private void resetBounds(Rectangle rect) {
+ _x = rect.x;
+ _y = rect.y;
+ _width = rect.width;
+ _height = rect.height;
+ }
+
+ private void resetBounds(LayoutPart lPart) {
+ EditPart part = lPart.getPart();
+ Rectangle rect = lPart.getAbsoluteBounds();
+ resetBounds(rect);
+ _parts.clear();
+ _parts.put(part, lPart);
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/HTMLGraphicalViewer.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/HTMLGraphicalViewer.java
new file mode 100644
index 000000000..06007a03c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/HTMLGraphicalViewer.java
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.util.List;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jst.pagedesigner.commands.nav.CaretPositionTracker;
+import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
+import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
+import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
+import org.eclipse.jst.pagedesigner.tools.ExposeHelper;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Node;
+
+/**
+ * For the GraphicalViewer selection management, we have two different selection
+ * mode: Range mode and object mode.
+ *
+ * Range mode is to support inline text editing, it selects a range. Object mode
+ * selects a list of edit parts.
+ *
+ * We let the super class of HTMLGraphicalViewer to handle object selection, and
+ * add range selection support in this class. Need to override certain selection
+ * related methods of super class to handle selection mode switching.
+ *
+ * @author mengbo
+ */
+public class HTMLGraphicalViewer extends ScrollingGraphicalViewer implements
+ IHTMLGraphicalViewer, CaretPositionTracker {
+ private IEditorPart _parentPart;
+
+ private Caret _caret;
+
+ // initially nothing selected, treat as object selectin mode.
+ private boolean _rangeMode = false;
+
+ private DesignRange _selectionRange = null;
+
+ private int _inBatch = 0;
+
+ private CaretUpdater _caretUpdater = null;
+
+ private int _xOffset;
+
+ // private ListenerList _postSelectionChangedListeners = new
+ // ListenerList(1);
+
+ /**
+ *
+ */
+ public HTMLGraphicalViewer(IEditorPart parent) {
+ _parentPart = parent;
+ // CaretUpdater is not fully initialized yet, since this time the
+ // viewport is not
+ // initialized yet, and we need add listener to range model change.
+ _caretUpdater = new CaretUpdater(this);
+ }
+
+ /**
+ * @return Returns the _caretUpdater.
+ */
+ public CaretUpdater getCaretUpdater() {
+ return _caretUpdater;
+ }
+
+ public Viewport getViewport() {
+ FigureCanvas canvas = this.getFigureCanvas();
+ if (canvas != null) {
+ return canvas.getViewport();
+ } else {
+ return null;
+ }
+ }
+
+ public IDOMModel getModel() {
+ // XXX: temp implementation.
+ EditPart part = this.getContents();
+ if (part != null) {
+ return ((IDOMNode) part.getModel()).getModel();
+ } else {
+ return null;
+ }
+ }
+
+ public IStatusLineManager getStatusLineManager() {
+ if (_parentPart == null) {
+ return null;
+ } else {
+ return _parentPart.getEditorSite().getActionBars()
+ .getStatusLineManager();
+ }
+ }
+
+ public Caret getCaret() {
+ if (_caret == null) {
+ Canvas parentCanvas = (Canvas) getControl();
+ if (parentCanvas == null || parentCanvas.isDisposed()) {
+ return null;
+ }
+
+ _caret = new Caret(parentCanvas, 0);
+ _caretUpdater.connectViewer();
+ }
+ return _caret;
+
+ }
+
+ /**
+ * this method normally should only be called when in object selection mode.
+ *
+ * @return
+ */
+ public EditPart getPrimarySelectedNode() {
+ List list = this.getSelectedEditParts();
+ if (list.isEmpty()) {
+ return null;
+ }
+ for (int i = 0, n = list.size(); i < n; i++) {
+ EditPart part = (EditPart) list.get(i);
+ if (part.getSelected() == EditPart.SELECTED_PRIMARY) {
+ return part;
+ }
+ }
+ return (EditPart) list.get(0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#ensureRangeSelectionMode()
+ */
+ public void ensureRangeSelectionMode() {
+ if (!_rangeMode) {
+ EditPart primary = getPrimarySelectedNode();
+ this.deselectAll();
+ DesignPosition begin = primary == null ? DesignPosition.INVALID
+ : DesignPosition.createPositionBeforePart(primary);
+ DesignPosition after = primary == null ? DesignPosition.INVALID
+ : DesignPosition.createPositionAfterPart(primary);
+ internalSetRange(begin, after);
+ fireSelectionChanged();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#ensureObjectSelectionMode()
+ */
+ public void ensureObjectSelectionMode() {
+ if (_rangeMode) {
+ // switch to object selection mode with no selection.
+ internalToObjectMode();
+ fireSelectionChanged();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#isInRangeMode()
+ */
+ public boolean isInRangeMode() {
+ return _rangeMode;
+ }
+
+ public ISelection getSelection() {
+ if (isInRangeMode()) {
+ return getRangeSelection();
+ } else {
+ return super.getSelection();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#startSelectionChange()
+ */
+ public void startSelectionChange() {
+ if (_inBatch == 0) {
+ fireSelectionAboutToChange();
+ }
+ _inBatch++;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#selectionChanged()
+ */
+ public void selectionChanged() {
+ if (--_inBatch == 0) {
+ fireSelectionChanged();
+ fireSelectionChangeFinished();
+ }
+ }
+
+ /**
+ *
+ */
+ private void fireSelectionAboutToChange() {
+ Object listeners[] = selectionListeners.toArray();
+ for (int i = 0, n = selectionListeners.size(); i < n; i++) {
+ if (listeners[i] instanceof IHTMLGraphicalViewerListener) {
+ IHTMLGraphicalViewerListener l = (IHTMLGraphicalViewerListener) listeners[i];
+ l.selectionAboutToChange();
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private void fireSelectionChangeFinished() {
+ Object listeners[] = selectionListeners.toArray();
+ for (int i = 0, n = selectionListeners.size(); i < n; i++) {
+ if (listeners[i] instanceof IHTMLGraphicalViewerListener) {
+ IHTMLGraphicalViewerListener l = (IHTMLGraphicalViewerListener) listeners[i];
+ l.selectionChangeFinished();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#fireSelectionChanged()
+ */
+ protected void fireSelectionChanged() {
+ if (_inBatch == 0)// && this.getControl().isFocusControl())
+ {
+ super.fireSelectionChanged();
+ // firePostSelectionChanged(new SelectionChangedEvent(this,
+ // getSelection()));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#setSelection(org.eclipse.jface.viewers.ISelection)
+ */
+ public void setSelection(ISelection newSelection) {
+ if (newSelection instanceof IStructuredSelection) {
+ internalToObjectMode();
+ ExposeHelper.expose(newSelection, this);
+ updateRangeSelection(newSelection);
+ super.setSelection(newSelection);
+ } else if (newSelection instanceof DesignRange) {
+ DesignRange range = (DesignRange) newSelection;
+ internalSetRange(range.getStartPosition(), range.getEndPosition());
+ fireSelectionChanged();
+ }
+ // else we don't support, ignore
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#setSelection(org.eclipse.jface.viewers.ISelection)
+ */
+ public void updateRangeSelection(ISelection newSelection) {
+ if (newSelection instanceof IStructuredSelection && //
+ !(((IStructuredSelection) newSelection).getFirstElement() instanceof DocumentEditPart)) {
+ Object element = ((IStructuredSelection) newSelection)
+ .getFirstElement();
+ if (element instanceof ElementEditPart) {
+ updateRangeSelection(new DesignRefPosition((EditPart) element,
+ false), new DesignRefPosition((EditPart) element, true));
+ } else if (element instanceof Node) {
+ IDOMPosition start = new DOMRefPosition((Node) element, false);
+ IDOMPosition end = new DOMRefPosition((Node) element, true);
+ updateRangeSelection(DOMPositionHelper.toDesignPosition(start),
+ DOMPositionHelper.toDesignPosition(end));
+ }
+ }
+ }
+
+ /**
+ * This method is used to synchronize range mode selection when node
+ * selection is changed.
+ *
+ * @param position
+ * @param position2
+ */
+ private void updateRangeSelection(DesignPosition position,
+ DesignPosition position2) {
+ // if only one position is invalid, we will make a collapsed range using
+ // the valid position
+ if (position == null) {
+ position = DesignPosition.INVALID;
+ }
+ if (position2 == null || !position2.isValid()) {
+ position2 = position;
+ }
+ if (!position.isValid()) {
+ position = position2;
+ }
+
+ _selectionRange = new DesignRange(position, position2);
+ }
+
+ // -------------------------------------------------------------------------------------------------
+ // override super class methods for selection handling.
+ // operations that handles object selection
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#appendSelection(org.eclipse.gef.EditPart)
+ */
+ public void appendSelection(EditPart editpart) {
+ internalToObjectMode();
+ super.appendSelection(editpart); // super will fireSelectionChanged.
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#deselectAll()
+ */
+ public void deselectAll() {
+ internalToObjectMode();
+ super.deselectAll(); // super.deselectAll() will fireSelectionChanged
+ }
+
+ /**
+ * Clear the selection to null. When the model is modified, the selection is
+ * invalid, so we need to clear the selection. We change the selection
+ * directly, it won't need to fire selectionchange event to other part.
+ *
+ */
+ public void clearSelectionRange() {
+ internalToObjectMode();
+ _selectionRange = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#deselect(org.eclipse.gef.EditPart)
+ */
+ public void deselect(EditPart editpart) {
+ if (!_rangeMode) {
+ super.deselect(editpart); // super will fireSelectionChanged.
+ }
+ // else just ignore.
+ }
+
+ // ---------------------------------------------------------------------------------------------
+ // range selection handling methods.
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#getRangeSelection()
+ */
+ public DesignRange getRangeSelection() {
+ return _selectionRange;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#setRange(org.eclipse.jst.pagedesigner.selection.EditPartPosition,
+ * org.eclipse.jst.pagedesigner.selection.EditPartPosition)
+ */
+ public void setRange(DesignPosition position, DesignPosition position2) {
+ internalSetRange(position, position2);
+ fireSelectionChanged();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.parts.IHTMLGraphicalViewer#setRangeEndPosition(org.eclipse.jst.pagedesigner.selection.EditPartPosition)
+ */
+ public void setRangeEndPosition(DesignPosition position) {
+ DesignRange range = getRangeSelection();
+ DesignPosition begin = null;
+ if (range != null) {
+ begin = range.getStartPosition();
+ }
+ internalSetRange(begin, position);
+ fireSelectionChanged();
+ }
+
+ // --------------------------------------------------------------------------------------
+ /**
+ * internall switch to object mode, no selection change event is fired. the
+ * caller must call some other methods that will result in selection change
+ * event after calling this method.
+ */
+ private void internalToObjectMode() {
+ _rangeMode = false;
+ }
+
+ /**
+ * this method will not fire selection changed event. caller should do that.
+ *
+ * @param position
+ * @param position2
+ */
+ private void internalSetRange(DesignPosition position,
+ DesignPosition position2) {
+ if (!_rangeMode) {
+ // XXX: deselectAll() will result in fireSelectionChange, so here is
+ // one unnecessary
+ // event fire. But should be ok.
+ deselectAll();
+ _rangeMode = true;
+ }
+ // if only one position is invalid, we will make a collapsed range using
+ // the valid position
+ if (position == null) {
+ position = DesignPosition.INVALID;
+ }
+ if (position2 == null || !position2.isValid()) {
+ position2 = position;
+ }
+ if (!position.isValid()) {
+ position = position2;
+ }
+
+ _selectionRange = new DesignRange(position, position2);
+ }
+
+ /**
+ * debug method, dump some debug information to the console
+ */
+ public void dumpStatus() {
+ if (isInRangeMode()) {
+ // System.out.println("Range start: " +
+ // this.getRangeSelection().getStartPosition());
+ // System.out.println("Range end: " +
+ // this.getRangeSelection().getEndPosition());
+ } else {
+ // System.out.println("Object selection mode");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.nav.CaretPositionTracker#getXoffset()
+ */
+ public int getXoffset() {
+ return _xOffset;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jst.pagedesigner.commands.nav.CaretPositionTracker#setXoffset(int)
+ */
+ public void setXoffset(int xoffset) {
+ this._xOffset = xoffset;
+ }
+
+ public void updateHorizontalPos() {
+ Caret caret = getCaret();
+ if (caret != null && !caret.isDisposed() && isInRangeMode()) {
+ org.eclipse.swt.graphics.Rectangle rect = caret.getBounds();
+ setXoffset(rect.x);
+ }
+ }
+
+ // public void addPostSelectionChangedListener(ISelectionChangedListener
+ // listener)
+ // {
+ // _postSelectionChangedListeners.add(listener);
+ //
+ // }
+ //
+ // public void removePostSelectionChangedListener(ISelectionChangedListener
+ // listener)
+ // {
+ // _postSelectionChangedListeners.remove(listener);
+ // }
+
+ /**
+ * Notifies any post selection listeners that a post selection event has
+ * been received. Only listeners registered at the time this method is
+ * called are notified.
+ *
+ * @param event
+ * a selection changed event
+ *
+ * @see #addPostSelectionChangedListener(ISelectionChangedListener)
+ */
+ // public void firePostSelectionChanged(final SelectionChangedEvent event)
+ // {
+ // Object[] listeners = _postSelectionChangedListeners.getListeners();
+ // for (int i = 0; i < listeners.length; ++i)
+ // {
+ // final ISelectionChangedListener l = (ISelectionChangedListener)
+ // listeners[i];
+ // SafeRunnable.run(new SafeRunnable()
+ // {
+ // public void run()
+ // {
+ // l.selectionChanged(event);
+ // }
+ // });
+ // }
+ // }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewer.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewer.java
new file mode 100644
index 000000000..44e845204
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewer.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+/**
+ * @author mengbo
+ */
+public interface IHTMLGraphicalViewer extends GraphicalViewer {
+ public IDOMModel getModel();
+
+ public void ensureRangeSelectionMode();
+
+ public void ensureObjectSelectionMode();
+
+ /**
+ * @return
+ */
+ public boolean isInRangeMode();
+
+ public DesignRange getRangeSelection();
+
+ /**
+ * @param position
+ * @param position2
+ */
+ public void setRange(DesignPosition position, DesignPosition position2);
+
+ /**
+ * @param position
+ */
+ public void setRangeEndPosition(DesignPosition position);
+
+ public Caret getCaret();
+
+ /**
+ * indicate a batch of operations is began, and may result in selection
+ * change. This viewer will only fire a single selection changed event when
+ * this batch of operations finish.
+ */
+ public void startSelectionChange();
+
+ /**
+ * batch operation that change the selection finished.
+ *
+ */
+ public void selectionChanged();
+
+ public Viewport getViewport();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewerListener.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewerListener.java
new file mode 100644
index 000000000..6d16c4757
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/IHTMLGraphicalViewerListener.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+
+/**
+ * @author mengbo
+ */
+public interface IHTMLGraphicalViewerListener extends ISelectionChangedListener {
+ public void selectionAboutToChange();
+
+ public void selectionChangeFinished();
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/LayoutPart.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/LayoutPart.java
new file mode 100644
index 000000000..fe9d23a3c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/LayoutPart.java
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jst.pagedesigner.IHTMLConstants;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.CSSTextFigure;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowBox;
+import org.eclipse.jst.pagedesigner.css2.layout.FlowUtilities;
+import org.eclipse.jst.pagedesigner.css2.layout.TextFragmentBox;
+import org.eclipse.jst.pagedesigner.css2.layout.TextLayoutSupport;
+import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
+import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
+import org.eclipse.jst.pagedesigner.parts.SubNodeEditPart;
+import org.eclipse.jst.pagedesigner.parts.TextEditPart;
+import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
+import org.eclipse.jst.pagedesigner.validation.caret.Target;
+import org.w3c.dom.Node;
+
+/**
+ * @author mengbo
+ */
+public class LayoutPart {
+ private final static int MAX_OFFSET_TO_EDGE = 10;
+
+ private EditPart _part;
+
+ private FlowBox _box;
+
+ private final Point EMPTY_POINT = new Point(0, 0);
+
+ private Point _point = EMPTY_POINT;
+
+ /**
+ * If caller didn't resolve FlowBox, call this.
+ *
+ * @param part
+ * @param point
+ */
+ public LayoutPart(EditPart part, Point point) {
+ Assert.isTrue(part != null);
+ _part = part;
+ _point = point;
+ }
+
+ /**
+ * @return Returns the _box, when it is null, generate box with part and
+ * point.
+ */
+ public FlowBox getBox() {
+ if (_box == null) {
+ _box = getClosestBox();
+ }
+ return _box;
+ }
+
+ /**
+ * @return Returns the _part.
+ */
+ public EditPart getPart() {
+ return _part;
+ }
+
+ /**
+ * Get closest box's bounds.
+ *
+ * @param point
+ * @return
+ */
+ private Rectangle getClosestBoxAbsoluteBounds() {
+ Rectangle rect = null;
+ if (getBox() != null) {
+ rect = getAbsoluteBounds(getBox());
+ }
+ return rect;
+ }
+
+ /**
+ * Try to get the closest flowbox absolute bounds.
+ *
+ * @param point
+ * @return
+ */
+ public Rectangle getAbsoluteBounds() {
+ Rectangle bounds = null;
+ if ((bounds = getClosestBoxAbsoluteBounds()) == null) {
+ // This should never happens.
+ bounds = EditPartPositionHelper.getAbsoluteBounds(_part);
+ }
+ return bounds;
+ }
+
+ /**
+ * Get box's absolute bounds.
+ *
+ * @param point
+ * @return
+ */
+ public Rectangle getAbsoluteBounds(FlowBox box) {
+ if (box != null) {
+ IFigure figure = ((GraphicalEditPart) _part).getFigure();
+ Rectangle rect = new Rectangle(box._x, box._y, box.getWidth(), box
+ .getHeight());
+ figure.translateToAbsolute(rect);
+ return rect;
+ }
+ return null;
+ }
+
+ /**
+ * Closest box is the part's FlowBox which y coordinate is closest to point,
+ * and then its x coordinate is more close to point than other boxs of the
+ * same line.
+ *
+ * @param part
+ * @param point
+ * @return
+ */
+ private FlowBox getClosestBox() {
+ FlowBox closestBox = null;
+ List fragments = getLines(_part);
+
+ // if there is one which are at the same line with relative,
+ // calculate that line first;
+ for (int i = 0; i < fragments.size(); i++) {
+ FlowBox box = (FlowBox) fragments.get(i);
+ Rectangle boxRect = getAbsoluteBounds(box);
+ if (boxRect.contains(_point.x, _point.y)) {
+ closestBox = box;
+ break;
+ } else {
+ if (closestBox == null) {
+ closestBox = box;
+ } else {
+ // compare y.
+ int offset1 = Math.abs(CaretPositionResolver.getYDistance(
+ boxRect, _point));
+ Rectangle closestRect = getAbsoluteBounds(closestBox);
+ int offset2 = Math.abs(CaretPositionResolver.getYDistance(
+ closestRect, _point));
+ if (offset1 < offset2) {
+ closestBox = box;
+ }
+ }
+ // at the same line
+ if (closestBox != box && boxRect.contains(boxRect.x, _point.y)) {
+ // compare x.
+ int offset1 = Math.abs(CaretPositionResolver.getXDistance(
+ boxRect, _point));
+ Rectangle closestRect = getAbsoluteBounds(closestBox);
+ int offset2 = Math.abs(CaretPositionResolver.getXDistance(
+ closestRect, _point));
+ if (offset1 < offset2) {
+ closestBox = box;
+ }
+ }
+ }
+ }
+ return closestBox;
+ }
+
+ /**
+ * The point is whitin the bounds of the figure.
+ *
+ * @param point
+ * @return
+ */
+ public boolean contains(Point point) {
+ return getAbsoluteBounds().contains(point);
+ }
+
+ public DesignPosition resolveTextPosition() {
+ DesignPosition result = null;
+ if (_part instanceof TextEditPart
+ && !EditModelQuery.isTransparentText(Target.resolveNode(_part))) {
+ FlowBox flowBox = getBox();
+ if (flowBox instanceof TextFragmentBox) {
+ TextFragmentBox box = (TextFragmentBox) flowBox;
+ if (((TextEditPart) _part).getFigure() instanceof CSSTextFigure) {
+ CSSTextFigure figure = (CSSTextFigure) ((TextEditPart) _part)
+ .getFigure();
+ Rectangle boxRect = getAbsoluteBounds(box);
+ int index = FlowUtilities.getTextInWidth(box.getTextData(),
+ figure.getCSSStyle().getCSSFont().getSwtFont(),
+ _point.x - boxRect.x, TextLayoutSupport
+ .getAverageCharWidth(box));
+ result = new DesignPosition(_part, box._offset + index);
+ }
+ }
+ }
+ return result;
+ }
+
+ public DesignPosition resolvePosition(IPositionMediator validator) {
+ DesignPosition result;
+ if ((result = resolveTextPosition()) == null) {
+ boolean atPointLeft = false;
+ boolean atPointRight = false;
+ atPointLeft = isBeforePoint(_point);
+ atPointRight = isAfterPoint(_point);
+ if (!(atPointLeft ^ atPointRight)) {
+
+ }
+ Target target = new Target(getPart());
+ if (validator.isValidPosition(new DOMRefPosition(target.getNode(),
+ atPointLeft))) {
+ result = new DesignRefPosition(_part, atPointLeft);
+ } else if (validator.isValidPosition(new DOMRefPosition(target
+ .getNode(), !atPointLeft))) {
+ result = new DesignRefPosition(_part, !atPointLeft);
+ } else if (validator.isEditable(target)) {
+ if (atPointLeft) {
+ result = new DesignPosition(_part, 0);
+ } else {
+ result = new DesignPosition(_part, _part.getChildren()
+ .size());
+ }
+ }
+ }
+ return result;
+ }
+
+ private IFigure getFigure() {
+ return ((GraphicalEditPart) _part).getFigure();
+ }
+
+ public boolean isAfterPoint(Point point) {
+ boolean result = false;
+ FlowBox flowBox = getLine(0);
+ if (IHTMLConstants.TAG_BR.equalsIgnoreCase(Target.resolveNode(_part)
+ .getNodeName())) {
+ if (flowBox != null) {
+ Rectangle boxRect = getAbsoluteBounds(flowBox);
+ result = CaretPositionResolver.getYDistance(boxRect, point) == 0;
+ }
+ } else {
+
+ if (flowBox != null) {
+ Rectangle boxRect = getAbsoluteBounds(flowBox);
+ if (CaretPositionResolver.getXDistance(boxRect, point) != 0) {
+ result = CaretPositionResolver.getXDistance(boxRect, point) < 0
+ && //
+ CaretPositionResolver.getYDistance(boxRect, point) == 0;
+ }
+ }
+ }
+ result |= isUnderCaret();
+ // if (isWidget() && flowBox != null)
+ // {
+ // result |= contains(point) &&
+ // CaretPositionResolver.toXMiddle(getAbsoluteBounds(flowBox), point) <
+ // 0;
+ // }
+ return result;
+
+ }
+
+ /**
+ * EditPart is at point's left
+ *
+ * @param part
+ * @param point
+ * @return
+ */
+ public boolean isBeforePoint(Point point) {
+ boolean result = false;
+ FlowBox flowBox = getLastLine();
+ if (flowBox != null) {
+ Rectangle boxRect = getAbsoluteBounds(flowBox);
+ if (IHTMLConstants.TAG_BR.equalsIgnoreCase(Target
+ .resolveNode(_part).getNodeName())) {
+ return CaretPositionResolver.getYDistance(boxRect, point) == 0;
+ } else if (CaretPositionResolver.getXDistance(boxRect, point) != 0) {
+ result = CaretPositionResolver.getXDistance(boxRect, point) > 0
+ && //
+ CaretPositionResolver.getYDistance(boxRect, point) == 0;
+ }
+ }
+ result |= isAboveCaret();
+ // if (isWidget() && flowBox != null)
+ // {
+ // result |= contains(point) &&
+ // CaretPositionResolver.toXMiddle(getAbsoluteBounds(flowBox), point) >
+ // 0;
+ // }
+ return result;
+ // return !isAfterPoint(point);
+ }
+
+ public boolean isBeforePoint() {
+ return isBeforePoint(_point);
+ }
+
+ public boolean atLeftPart(Point point) {
+ FlowBox flowBox = getBox();
+ if (flowBox != null) {
+ Rectangle boxRect = getAbsoluteBounds(flowBox);
+ return CaretPositionResolver.toXMiddle(boxRect, point) < 0;
+ }
+ return true;
+ }
+
+ public boolean isAfterPoint() {
+ return isAfterPoint(_point);
+ }
+
+ public boolean atSameLine(Point point) {
+ Rectangle bounds = getAbsoluteBounds();
+ return bounds.contains(bounds.getTop().x, point.y);
+ }
+
+ public boolean atSameRow(Point point) {
+ Rectangle bounds = getAbsoluteBounds();
+ return bounds.contains(point.x, bounds.getRight().y);
+ }
+
+ public static Rectangle getBounds(FlowBox box) {
+ return new Rectangle(box._x, box._y, box.getWidth(), box.getHeight());
+ }
+
+ /**
+ * @return Returns the _point.
+ */
+ public Point getPoint() {
+ return _point;
+ }
+
+ FlowBox getLine(int index) {
+ FlowBox result = null;
+ List lines = getLines(_part);
+ if (lines.size() > 0 && index >= 0 && index <= lines.size() - 1) {
+ result = (FlowBox) lines.get(index);
+ }
+ return result;
+ }
+
+ FlowBox getLastLine() {
+ FlowBox result = null;
+ List lines = getLines(_part);
+ if (lines.size() > 0) {
+ result = (FlowBox) lines.get(lines.size() - 1);
+ }
+ return result;
+ }
+
+ /**
+ * @param _part
+ * @return
+ */
+ List getLines(EditPart _part) {
+ List fragments = new ArrayList();
+ if (_part instanceof SubNodeEditPart) {
+ IFigure figure = ((GraphicalEditPart) _part).getFigure();
+
+ if (figure instanceof CSSTextFigure) {
+ fragments = ((CSSTextFigure) figure).getFragments();
+ ((CSSTextFigure) figure).getCSSStyle();
+ } else if (figure instanceof CSSFigure) {
+ fragments = ((CSSFigure) figure).getFragmentsForRead();
+ ((CSSFigure) figure).getCSSStyle();
+ }
+ }
+ return fragments;
+ }
+
+ /**
+ * To search for none empty string, this is not final.
+ *
+ * @param lineBox
+ * @param host
+ * @param rect
+ * @param validator
+ */
+ public static EditPart getConcretePart(EditPart part) {
+ if (part != null) {
+ Node node = Target.resolveNode(part);
+ Node child = node.getFirstChild();
+ EditPart result;
+ while (child != null) {
+ if (!EditModelQuery.isTransparentText(child)
+ && (result = Target.resolvePart(child)) != null) {
+ return result;
+ }
+ child = child.getNextSibling();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * To search for none empty string, this is not final.
+ *
+ * @param lineBox
+ * @param host
+ * @param rect
+ * @param validator
+ */
+ public EditPart getConcretePart() {
+ return getConcretePart(_part);
+ }
+
+ public static Node getConcreteNode(Node node) {
+ if (node != null) {
+ Node child = node.getFirstChild();
+ while (child != null) {
+ if (!EditModelQuery.isTransparentText(child)) {
+ return node;
+ }
+ child = child.getNextSibling();
+ }
+ }
+ return null;
+ }
+
+ public boolean isCloseToEdgeFromOutSide() {
+ boolean result = false;
+ if (EditModelQuery.isBlockNode(Target.resolveNode(_part))) {
+ result = Math.abs(getAbsoluteBounds().getLeft().x - _point.x) <= MAX_OFFSET_TO_EDGE;
+ if (!result) {
+ result = Math.abs(getAbsoluteBounds().getRight().x - _point.x) <= MAX_OFFSET_TO_EDGE;
+ }
+ }
+ return result;
+ }
+
+ private boolean isAboveCaret() {
+ return getAbsoluteBounds().getBottom().y <= _point.y;
+ }
+
+ private boolean isUnderCaret() {
+ return getAbsoluteBounds().getTop().y >= _point.y;
+ }
+
+ public boolean isInline() {
+ return EditModelQuery.isInline(Target.resolveNode(_part));
+ }
+
+ private boolean isWidget() {
+ return EditModelQuery.isWidget(_part);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("editPart:" + _part + ", --- box: " + getBox());
+ return sb.toString();
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/TextPosition.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/TextPosition.java
new file mode 100644
index 000000000..a88c86b34
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/viewer/TextPosition.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Sybase, Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner.viewer;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+
+/**
+ * This class used to identify a position in a text node. It's very similiar to
+ * EditPartPosition. Used instead of EditPartPosition when in cases we are in
+ * the middle of handling something without available EditPart created.
+ *
+ * offset has the same meaning as in EditPartPosition.
+ *
+ * @author mengbo
+ */
+public class TextPosition {
+ private IDOMText _containerNode;
+
+ private int _offset;
+
+ /**
+ * @param part
+ * @param offset
+ */
+ public TextPosition(IDOMText part, int offset) {
+ _containerNode = part;
+ _offset = offset;
+ }
+
+ /**
+ * if _containerPart is null, means it is invalid
+ *
+ * @return
+ */
+ public IDOMText getTextNode() {
+ return _containerNode;
+ }
+
+ /**
+ * if offset < 0, means it is invalid.
+ *
+ * @return
+ */
+ public int getOffset() {
+ return _offset;
+ }
+
+ public boolean isValid() {
+ return _containerNode != null && _offset >= 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof TextPosition) {
+ TextPosition p = (TextPosition) obj;
+ return p.getTextNode() == this._containerNode
+ && p.getOffset() == this._offset;
+ }
+ return false;
+ }
+}

Back to the top