001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.visualweb.designer.jsf.ui;
043:
044: import com.sun.rave.designtime.Result;
045: import com.sun.rave.designtime.markup.MarkupMouseRegion;
046: import java.awt.Component;
047: import java.awt.Point;
048: import java.util.ArrayList;
049: import java.util.List;
050: import javax.swing.SwingUtilities;
051: import org.netbeans.modules.visualweb.api.designer.Designer;
052: import org.netbeans.modules.visualweb.api.designer.Designer.Box;
053: import org.netbeans.modules.visualweb.api.designer.Designer.DesignerClickEvent;
054: import org.netbeans.modules.visualweb.api.designer.Designer.DesignerEvent;
055: import org.netbeans.modules.visualweb.api.designer.Designer.DesignerListener;
056: import org.netbeans.modules.visualweb.api.designer.Designer.DesignerPopupEvent;
057: import org.netbeans.modules.visualweb.api.designer.Designer.ExternalBox;
058: import org.netbeans.modules.visualweb.designer.html.HtmlTag;
059: import org.netbeans.modules.visualweb.designer.jsf.JsfForm;
060: import org.netbeans.modules.visualweb.designer.jsf.JsfSupportUtilities;
061: import org.netbeans.modules.visualweb.insync.faces.FacesPageUnit;
062: import org.openide.cookies.OpenCookie;
063: import org.openide.loaders.DataObject;
064: import org.openide.nodes.Node;
065: import org.w3c.dom.Element;
066:
067: /**
068: *
069: * @author Peter Zavadsky
070: */
071: class JsfDesignerListener implements DesignerListener {
072:
073: private final JsfTopComponent jsfTopComponent;
074:
075: public JsfDesignerListener(JsfTopComponent jsfTopComponent) {
076: this .jsfTopComponent = jsfTopComponent;
077: }
078:
079: /** The user double clicked on the component during -initial- inline editing
080: * (e.g. we entered inline editing as part of the first click in a double
081: * click) so cancel inline editing and process the double click in the normal
082: * way: as a request to open the default event handler. However if there is
083: * no default event handler, stay in inline edit mode. */
084: public void userActionPerformed(DesignerEvent evt) {
085: // if (webform.getActions().handleDoubleClick(true)) {
086: // if (handleDoubleClick(true)) {
087: // if (handleDoubleClick()) {
088: // finishInlineEditing(true);
089: // }
090: if (handleUserAction()) {
091: jsfTopComponent.getDesigner().finishInlineEditing(true);
092: }
093: }
094:
095: // XXX Moved from DesignerActions.
096: /** Perform the equivalent of a double click on the first item
097: * in the selection (if any).
098: * @param selOnly If true, only do something if the selection is nonempty
099: * @todo Rename to handleDefaultAction
100: * @return True iff the double click resulted in opening an event handler
101: */
102: // public boolean handleDoubleClick(/*boolean selOnly*/) {
103: private boolean handleUserAction() {
104: // CssBox box = null;
105: Box box = null;
106:
107: // SelectionManager sm = webform.getSelection();
108: // if (!sm.isSelectionEmpty()) {
109: if (jsfTopComponent.getDesigner().getSelectedCount() > 0) {
110: // Iterator it = sm.iterator();
111: //
112: // while (it.hasNext()) {
113: // DesignBean bean = (DesignBean)it.next();
114: // for (Element componentRootElement : sm.getSelectedComponentRootElements()) {
115: for (Element componentRootElement : jsfTopComponent
116: .getDesigner().getSelectedComponents()) {
117: // DesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
118: // if (bean != null) {
119: if (componentRootElement != null) {
120: // box = webform.getMapper().findBox(bean);
121: // box = ModelViewMapper.findBoxForComponentRootElement(webform.getPane().getPageBox(), componentRootElement);
122: box = jsfTopComponent.getDesigner()
123: .findBoxForComponentRootElement(
124: componentRootElement);
125: if (box != null) {
126: break;
127: }
128: }
129: }
130: // } else if (selOnly) {
131: }
132: // else {
133: // return false;
134: // }
135:
136: // return handleDoubleClick(box);
137: return handleUserAction(box);
138: }
139:
140: // XXX Moved from DesignerActions.
141: /** Handle double clicks with the given box as the target.
142: * @todo Rename to handleDefaultAction
143: * @return Return true iff the double click resulted in opening an event handler
144: */
145: // private boolean handleDoubleClick(CssBox box) {
146: private boolean handleUserAction(Box box) {
147: // if (box instanceof ExternalDocumentBox) {
148: // ((ExternalDocumentBox)box).open();
149: if (box instanceof ExternalBox) {
150: // ((ExternalDocumentBox)box).open();
151: openExternalBox((ExternalBox) box);
152: return false;
153: // } else if ((box != null) && (box.getTag() == HtmlTag.DIV) && (box.getBoxCount() == 1) &&
154: // box.getBox(0) instanceof ExternalDocumentBox) {
155: // XXX This is a hack.
156: } else if ((box != null) && (box.getTag() == HtmlTag.DIV)) {
157: Box[] children = box.getChildren();
158: if (children.length == 1
159: && children[0] instanceof ExternalBox) {
160: // IF user has clicked on a large div containing only a
161: // jsp include, treat this as an attempt to open the page
162: // fragment child.
163: // ((ExternalDocumentBox)box.getBox(0)).open();
164: openExternalBox((ExternalBox) children[0]);
165: return false;
166: }
167: }
168:
169: return editEventHandler();
170: }
171:
172: // XXX Copied from DesignerActions.
173: /** Return true iff an event handler was found and created/opened */
174: private boolean editEventHandler() {
175: // SelectionManager sm = webform.getSelection();
176: //
177: // if (sm.isSelectionEmpty()) {
178: // webform.getModel().openDefaultHandler();
179: //
180: // return false;
181: // }
182: //
183: // // TODO - get the component under the mouse, not the
184: // // whole selection!
185: // DesignBean component = getDefaultSelectionBean();
186: //
187: // if (component != null) {
188: // // See if it's an XHTML element; if so just show it in
189: // // the JSP source
190: //// if (FacesSupport.isXhtmlComponent(component)) {
191: // if (isXhtmlComponent(component)) {
192: //// MarkupBean mb = FacesSupport.getMarkupBean(component);
193: // MarkupBean mb = Util.getMarkupBean(component);
194: //
195: // MarkupUnit unit = webform.getMarkup();
196: // // <markup_separation>
197: //// Util.show(null, unit.getFileObject(),
198: //// unit.computeLine((RaveElement)mb.getElement()), 0, true);
199: // // ====
200: //// MarkupService.show(unit.getFileObject(), unit.computeLine((RaveElement)mb.getElement()), 0, true);
201: // showLineAt(unit.getFileObject(), unit.computeLine(mb.getElement()), 0);
202: // // </markup_separation>
203: // } else {
204: // webform.getModel().openDefaultHandler(component);
205: // }
206: //
207: // return true;
208: // }
209: //
210: // return false;
211: // SelectionManager sm = webform.getSelection();
212: //// DesignBean component;
213: Element componentRootElement;
214: // if (sm.isSelectionEmpty()) {
215: if (jsfTopComponent.getDesigner().getSelectedCount() == 0) {
216: // webform.getModel().openDefaultHandler();
217: //
218: // return false;
219: // component = null;
220: componentRootElement = null;
221: } else {
222: // component = getDefaultSelectionBean();
223: // Element componentRootElement = getDefaultSelectionComponentRootElement();
224: // component = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
225: componentRootElement = getDefaultSelectionComponentRootElement();
226: }
227:
228: // return webform.editEventHandlerForDesignBean(component);
229: // return webform.editEventHandlerForComponent(componentRootElement);
230: return jsfTopComponent.getJsfForm()
231: .editEventHandlerForComponent(componentRootElement);
232: }
233:
234: // XXX Copy also in designer/../InteractionManager
235: // private DesignBean getDefaultSelectionBean() {
236: private Element getDefaultSelectionComponentRootElement() {
237: // // TODO - should this be a checkbox instead?
238: // SelectionManager sm = webform.getSelection();
239: //// DesignBean bean = sm.getPrimary();
240: ////
241: //// if ((bean == null) && !sm.isSelectionEmpty()) {
242: // Element primaryComponentRootElement = sm.getPrimary();
243: Element primaryComponentRootElement = jsfTopComponent
244: .getDesigner().getPrimarySelection();
245: // DesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(primaryComponentRootElement);
246: // if (primaryComponentRootElement == null && !sm.isSelectionEmpty()) {
247: if (primaryComponentRootElement == null
248: && jsfTopComponent.getDesigner().getSelectedCount() > 0) {
249: // TODO - get the component under the mouse, not the
250: // whole selection!
251: // Iterator it = sm.iterator();
252: //
253: // while (it.hasNext()) {
254: // bean = (DesignBean)it.next();
255: // for (Element componentRootElement : sm.getSelectedComponentRootElements()) {
256: for (Element componentRootElement : jsfTopComponent
257: .getDesigner().getSelectedComponents()) {
258: // bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
259: primaryComponentRootElement = componentRootElement;
260: // if (bean != null) {
261: if (primaryComponentRootElement != null) {
262: break;
263: }
264: }
265: }
266:
267: // return bean;
268: return primaryComponentRootElement;
269: }
270:
271: private static void openExternalBox(ExternalBox externalBox) {
272: JsfForm externalJsfForm = JsfForm
273: .findJsfFormForDomProvider(externalBox
274: .getExternalDomProvider());
275: // if (frameForm == null) {
276: if (externalJsfForm == null) {
277: java.awt.Toolkit.getDefaultToolkit().beep();
278:
279: return;
280: }
281:
282: // DataObject dobj = frameForm.getDataObject();
283: DataObject dobj = externalJsfForm.getJspDataObject();
284: if (dobj == null) {
285: // #107543 The data object is missing. Notify user?
286: return;
287: }
288:
289: OpenCookie oc = (OpenCookie) dobj.getCookie(OpenCookie.class);
290:
291: if (oc != null) {
292: oc.open();
293: }
294: }
295:
296: public void selectionChanged(DesignerEvent evt) {
297: Designer designer = evt.getDesigner();
298: Element[] selectedComponents = designer.getSelectedComponents();
299:
300: Node[] nds;
301: if (selectedComponents.length > 0) {
302: List<Node> nodes = new ArrayList<Node>(
303: selectedComponents.length);
304: for (Element selectedComponent : selectedComponents) {
305: Node n = JsfSupportUtilities
306: .getNodeRepresentation(selectedComponent);
307: nodes.add(n);
308: }
309:
310: nds = nodes.toArray(new Node[nodes.size()]);
311: } else {
312: Node rootNode = jsfTopComponent.getJsfForm()
313: .getRootBeanNode();
314: nds = rootNode == null ? new Node[0]
315: : new Node[] { rootNode };
316: }
317:
318: jsfTopComponent.setActivatedNodes(nds);
319: // XXX #94718 To update the paste according the selection.
320: jsfTopComponent.updatePasteAction();
321: }
322:
323: public void userPopupActionPerformed(DesignerPopupEvent evt) {
324: Component component = evt.getComponent();
325: int x = evt.getX();
326: int y = evt.getY();
327: Point point = SwingUtilities.convertPoint(component, x, y,
328: jsfTopComponent);
329: jsfTopComponent.showPopup(evt.getActions(), evt.getContext(),
330: point.x, point.y);
331: }
332:
333: public void userElementClicked(DesignerClickEvent evt) {
334: MarkupMouseRegion region = findRegion(evt.getBox().getElement());
335:
336: if ((region != null) && region.isClickable()) {
337: Result r = region.regionClicked(evt.getClickCount());
338: // ResultHandler.handleResult(r, getFacesModel());
339: jsfTopComponent.getJsfForm().handleResult(r);
340: // #6353410 If there was performed click on the region
341: // then do not perform other actions on the same click.
342: // return true;
343: evt.consume();
344: }
345: // return false;
346: }
347:
348: /** Locate the closest mouse region to the given element */
349: private static MarkupMouseRegion findRegion(Element element) {
350: while (element != null) {
351: // if (element.getMarkupMouseRegion() != null) {
352: // return element.getMarkupMouseRegion();
353: // }
354: // MarkupMouseRegion region = InSyncService.getProvider().getMarkupMouseRegionForElement(element);
355: MarkupMouseRegion region = FacesPageUnit
356: .getMarkupMouseRegionForElement(element);
357: if (region != null) {
358: return region;
359: }
360:
361: if (element.getParentNode() instanceof Element) {
362: element = (Element) element.getParentNode();
363: } else {
364: break;
365: }
366: }
367:
368: return null;
369: }
370:
371: }
|