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.test.umllib;
043:
044: import com.tomsawyer.drawing.geometry.TSConstPoint;//look in tsalleditor601dev.jar
045: import java.awt.AWTException;
046: import java.awt.Color; //import com.tomsawyer.util.TSConstPoint; changed with buzz3
047: import java.awt.Point;
048: import java.awt.Robot;
049: import java.awt.event.KeyEvent;
050: import java.util.ArrayList;
051: import java.util.Iterator;
052: import org.netbeans.jellytools.MainWindowOperator;
053: import org.netbeans.jemmy.EventTool;
054: import org.netbeans.jemmy.Timeout;
055: import org.netbeans.jemmy.drivers.DriverManager;
056: import org.netbeans.jemmy.drivers.input.KeyRobotDriver;
057: import org.netbeans.jemmy.drivers.input.MouseRobotDriver;
058: import org.netbeans.jemmy.operators.ComponentOperator;
059: import org.netbeans.jemmy.operators.JPopupMenuOperator;
060: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPresentationElement;
061: import org.netbeans.modules.uml.core.support.umlsupport.ETRect;
062: import org.netbeans.modules.uml.core.support.umlsupport.IETPoint;
063: import org.netbeans.modules.uml.core.support.umlsupport.IETRect;
064: import org.netbeans.modules.uml.core.support.umlutils.ETList;
065: import org.netbeans.modules.uml.ui.support.applicationmanager.LabelPresentation;
066: import org.netbeans.modules.uml.ui.support.applicationmanager.NodePresentation;
067: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETGraphObject;
068: import org.netbeans.modules.uml.ui.support.viewfactorysupport.PointConversions;
069: import org.netbeans.modules.uml.ui.swing.drawingarea.ADGraphWindow;
070: import org.netbeans.modules.uml.ui.swing.drawingarea.IDrawingAreaControl;
071: import org.netbeans.test.umllib.actions.Actionable;
072: import org.netbeans.test.umllib.exceptions.UMLCommonException;
073: import org.netbeans.test.umllib.util.JPopupByPointChooser;
074:
075: /**
076: * This is operator for diagram drawing area.
077: * (Drawing area is the area under toolbar where
078: * diagram elements and links are located ).
079: * This operator extends ComponentOperator
080: * so look carefully on inherited methods
081: */
082: public class DrawingAreaOperator extends ComponentOperator implements
083: Actionable {
084: private final int WIDTH_BORDER = 100;
085: private final int HEIGHT_BORDER = 100;
086:
087: static {
088: DriverManager.setDriver(DriverManager.MOUSE_DRIVER_ID,
089: new MouseRobotDriver(new Timeout("", 10)),
090: DrawingAreaOperator.class);
091: DriverManager.setKeyDriver(new KeyRobotDriver(new Timeout(
092: "autoDelay", 50)));
093: }
094:
095: /**
096: * Constructs new DrawingAreaOperator using instance of
097: * ADGraphWindow.
098: * @param area instance of ADGraphWindow.
099: */
100: public DrawingAreaOperator(ADGraphWindow area) {
101: super (area);
102: }
103:
104: /**
105: * Returns underlying ADGraphWindow
106: * @return underlying ADGraphWindow
107: */
108: public ADGraphWindow getArea() {
109: return (ADGraphWindow) getSource();
110: }
111:
112: /**
113: * Returns underlying ADGraphWindow ZoomLevel
114: * @return double
115: */
116: public double getZoomLevel() {
117: return getArea().getZoomLevel();
118: }
119:
120: /**
121: * Return free point. You may use such point
122: * to place an element or invoke popup menu
123: * @return free point
124: */
125: public Point getFreePoint() {
126: return getFreePoint(10);
127: }
128:
129: /**
130: * Return free point. the nearest element would be not closer than
131: * <CODE>span</CODE> points.
132: * You may use such point to place an element or invoke popup menu
133: * @param span Minimal distance to the nearest element
134: * @return free point
135: */
136: public Point getFreePoint(int span) {
137: //
138: try {
139: Thread.sleep(100);
140: } catch (Exception ex) {
141: }
142: //
143: int width = getSource().getWidth();
144: int height = getSource().getHeight();
145: IDrawingAreaControl daControl = getArea().getDrawingArea();
146: //searching for elements matching elemenFinder criteria
147: ETList<IETGraphObject> allGraphs = daControl.getAllItems6();
148: Iterator<IETGraphObject> tsIt = allGraphs.iterator();
149: ArrayList<IETRect> elementBounds = new ArrayList<IETRect>();
150: while (tsIt.hasNext()) {
151: IETGraphObject graphObject = tsIt.next();
152: IPresentationElement presElement = graphObject
153: .getPresentationElement();
154: if (presElement == null) {
155: continue;
156: }
157: if (!(presElement instanceof NodePresentation)) { //We are looking only for nodes here
158: continue;
159: }
160: IETRect rect = graphObject.getEngine()
161: .getLogicalBoundingRect(true);
162: rect.inflate(10 + span);
163: elementBounds.add(rect);
164: }
165:
166: IETPoint p = null;
167: for (int w = WIDTH_BORDER; w < width - WIDTH_BORDER; w += 10) {
168: for (int h = HEIGHT_BORDER; h < height - HEIGHT_BORDER; h += 10) {
169: p = daControl.deviceToLogicalPoint(w, h);
170: boolean pointIsFree = true;
171: for (int i = 0; i < elementBounds.size(); i++) {
172: if (elementBounds.get(i).contains(p)) {
173: pointIsFree = false;
174: break;
175: }
176: }
177: if (pointIsFree) {
178: //add small links check
179: ETList<IPresentationElement> tmp1 = daControl
180: .getAllEdgesViaRect(new ETRect(p.getX(), p
181: .getY(), 0, 0), true);
182: ETList<IPresentationElement> tmp2 = daControl
183: .getAllEdgesViaRect(new ETRect(p.getX(), p
184: .getY(), 1, 1), true);
185: ETList<IPresentationElement> tmp3 = daControl
186: .getAllEdgesViaRect(new ETRect(
187: p.getX() - 1, p.getY() - 1, 2, 2),
188: true);
189: ETList<IPresentationElement> tmp4 = daControl
190: .getAllEdgesViaRect(new ETRect(
191: p.getX() - 2, p.getY() - 2, 3, 3),
192: true);
193: ETList<IPresentationElement> tmp5 = daControl
194: .getAllEdgesViaRect(new ETRect(
195: p.getX() - 2, p.getY() - 2, 4, 4),
196: true);
197: if (tmp1 == null && tmp2 == null && tmp3 == null
198: && tmp4 == null && tmp5 == null)
199: return daControl.logicalToDevicePoint(p)
200: .asPoint();
201: }
202: }
203: }
204:
205: return centerAtPoint(new Point(width + 50, height / 2));
206: }
207:
208: /**
209: *
210: * @param point
211: * @return
212: */
213: boolean isFreePoint(Point point) {
214: IDrawingAreaControl daControl = getArea().getDrawingArea();
215:
216: //searching for elements
217: ETList<IETGraphObject> allGraphs = daControl.getAllItems6();
218: Iterator<IETGraphObject> tsIt = allGraphs.iterator();
219: ArrayList<IETRect> elementBounds = new ArrayList<IETRect>();
220: while (tsIt.hasNext()) {
221: IETGraphObject graphObject = tsIt.next();
222: IPresentationElement presElement = graphObject
223: .getPresentationElement();
224: if (presElement == null) {
225: continue;
226: }
227: if (!(presElement instanceof NodePresentation || presElement instanceof LabelPresentation)) { //We are looking only for nodes here
228: continue;
229: }
230: IETRect rect = graphObject.getEngine()
231: .getLogicalBoundingRect(true);
232: rect.inflate(5);
233: elementBounds.add(rect);
234: }
235:
236: IETPoint p = null;
237: p = daControl.deviceToLogicalPoint(point.x, point.y);
238: for (int i = 0; i < elementBounds.size(); i++) {
239: if (elementBounds.get(i).contains(p)) {
240: return false;
241: }
242: }
243: return true;
244: }
245:
246: /**
247: * centers at the device point specified and returns the new device coordinates of the point specified
248: * @param point device point to center at
249: * @return the new device coordinates of the point specified
250: */
251: public Point centerAtPoint(Point point) {
252: IDrawingAreaControl daControl = getArea().getDrawingArea();
253: IETPoint etPoint = daControl.deviceToLogicalPoint(point.x,
254: point.y);
255: TSConstPoint tsPoint = PointConversions
256: .ETPointToTSPoint(etPoint);
257: getArea().centerPointInWindow(tsPoint, true);
258: new EventTool().waitNoEvent(500);
259: return daControl.logicalToDevicePoint(
260: PointConversions.newETPoint(tsPoint)).asPoint();
261: }
262:
263: public void select() {
264: getOutput().printTrace("Diagram is not a selectable object.");
265: }
266:
267: public void addToSelection() {
268: getOutput().printTrace("Diagram is not a selectable object.");
269: }
270:
271: /**
272: * Invokes popup menu
273: * @return popup menu operator
274: */
275: public JPopupMenuOperator getPopup() {
276: Point clickPoint = getFreePoint(20);
277: //workarround for Issue 79519
278: if (System.getProperty("os.name").toLowerCase().indexOf(
279: "windows") == -1) {
280: clickMouse(clickPoint.x, clickPoint.y, 1);
281: try {
282: Thread.sleep(100);
283: } catch (Exception ex) {
284: }
285: }
286: clickForPopup(clickPoint.x, clickPoint.y);
287: JPopupMenuOperator ret = new JPopupMenuOperator(
288: JPopupMenuOperator.waitJPopupMenu(
289: (java.awt.Container) (MainWindowOperator
290: .getDefault().getSource()),
291: new JPopupByPointChooser(clickPoint,
292: getSource(), 0)));
293: //
294: return ret;
295: }
296:
297: /**
298: * click in empty space somewhere
299: **/
300: public void clickMouse() {
301: Point fr = getFreePoint(25);
302: super .clickMouse(fr.x, fr.y, 1);
303: }
304:
305: //
306: /**
307: *
308: * @param x
309: * @param y
310: * @param count
311: * @param movetovisible
312: */
313: public void clickMouse(int x, int y, int count,
314: boolean movetovisible) {
315: ComponentOperator o = (ComponentOperator) this ;
316: int oldCX = o.getX();
317: int oldCY = o.getY();
318: java.awt.Rectangle rel_bnds = o.getBounds();
319: if (!rel_bnds.contains(x, y) && movetovisible) {
320: Point tmp = centerAtPoint(new Point(x, y));
321: x = tmp.x;
322: y = tmp.y;
323: }
324: super .clickMouse(x, y, count);
325: }
326:
327: /**
328: *
329: * @param p
330: * @return
331: */
332: public Point relativeToScreenPoint(Point p) {
333: return new Point(p.x + getLocationOnScreen().x, p.y
334: + getLocationOnScreen().y);
335: }
336:
337: //native - not api functions
338: /**
339: * helps to find lines/points on diagram differs from surrounding area
340: * works only for visible area
341: * @param startPoint
342: * @param step_x
343: * @param step_y
344: * @param edgeClr should be null for auto
345: * @return
346: */
347: public Point getSolidEdge(Point startPoint, int step_x, int step_y,
348: Color edgeClr) {
349: Point ret = null;
350: //
351: ComponentOperator o = (ComponentOperator) this ;
352: //colors usually have no gradients on x axe
353: int big_color_shift = Math.min(2 * Math.abs(step_x) + 10
354: * Math.abs(step_y), 127);
355: //
356: int oldX = startPoint.x;
357: int oldY = startPoint.y;
358: java.awt.Robot rbt = null;
359: try {
360: rbt = new java.awt.Robot();
361: } catch (AWTException ex) {
362: ex.printStackTrace();
363: }
364: Color oldClr = rbt.getPixelColor(
365: oldX + getLocationOnScreen().x, oldY
366: + getLocationOnScreen().y);
367: Color prevClr = oldClr;
368: int oldR = oldClr.getRed();
369: int oldG = oldClr.getGreen();
370: int oldB = oldClr.getBlue();
371: int prevR = prevClr.getRed();
372: int prevG = prevClr.getGreen();
373: int prevB = prevClr.getBlue();
374: for (int x = oldX, y = oldY; x < (getBounds().x + getBounds().width)
375: && x > getBounds().x
376: && y < (getBounds().y + getBounds().height)
377: && y > getBounds().y; x += step_x, y += step_y) {
378: Color clr = rbt.getPixelColor(x + getLocationOnScreen().x,
379: y + getLocationOnScreen().y);
380: rbt.mouseMove(x + getLocationOnScreen().x, y
381: + getLocationOnScreen().y);
382: //new Timeout("",50).sleep();
383: if (edgeClr != null) {
384: if (clr.equals(edgeClr))
385: return new Point(x, y);
386: } else {
387: int r = clr.getRed();
388: int g = clr.getGreen();
389: int b = clr.getBlue();
390: //check difference, try to take into account gradients
391: if (Math.abs(prevR - r) > big_color_shift
392: || Math.abs(prevG - g) > big_color_shift
393: || Math.abs(prevB - b) > big_color_shift) {
394: //if(true)throw new UMLCommonException(Math.abs(prevR-r)+":"+Math.abs(prevG-g)+":"+Math.abs(prevB-b));
395: return new Point(x, y);
396: }
397: //
398: }
399: prevClr = clr;
400: prevR = prevClr.getRed();
401: prevG = prevClr.getGreen();
402: prevB = prevClr.getBlue();
403: }
404: return ret;
405: }
406:
407: }
|