Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / gui / cad / CADToolAdapter.java @ 33205

History | View | Annotate | Download (49.9 KB)

1
package org.gvsig.editing.gui.cad;
2

    
3
import java.awt.Color;
4
import java.awt.Cursor;
5
import java.awt.Graphics;
6
import java.awt.Image;
7
import java.awt.Point;
8
import java.awt.Toolkit;
9
import java.awt.event.InputEvent;
10
import java.awt.event.MouseEvent;
11
import java.awt.event.MouseWheelEvent;
12
import java.awt.geom.Point2D;
13
import java.awt.image.BufferedImage;
14
import java.awt.image.MemoryImageSource;
15
import java.util.HashMap;
16
import java.util.Stack;
17
import java.util.prefs.Preferences;
18

    
19
import org.cresques.cts.IProjection;
20
import org.gvsig.andami.PluginServices;
21
import org.gvsig.andami.messages.NotificationManager;
22
import org.gvsig.andami.ui.mdiFrame.MainFrame;
23
import org.gvsig.andami.ui.mdiManager.IWindow;
24
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
25
import org.gvsig.app.project.documents.view.toolListeners.StatusBarListener;
26
import org.gvsig.editing.CADExtension;
27
import org.gvsig.editing.EditionManager;
28
import org.gvsig.editing.gui.cad.tools.SelectionCADTool;
29
import org.gvsig.editing.layers.ILayerEdited;
30
import org.gvsig.editing.layers.VectorialLayerEdited;
31
import org.gvsig.fmap.dal.exception.DataException;
32
import org.gvsig.fmap.dal.exception.ReadException;
33
import org.gvsig.tools.dispose.DisposableIterator;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureSelection;
36
import org.gvsig.fmap.dal.feature.FeatureSet;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
39
import org.gvsig.fmap.geom.Geometry;
40
import org.gvsig.fmap.geom.util.UtilFunctions;
41
import org.gvsig.fmap.mapcontext.MapContext;
42
import org.gvsig.fmap.mapcontext.MapContextLocator;
43
import org.gvsig.fmap.mapcontext.MapContextManager;
44
import org.gvsig.fmap.mapcontext.ViewPort;
45
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
46
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
47
import org.gvsig.fmap.mapcontrol.MapControl;
48
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
49
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
50
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
51
import org.gvsig.fmap.mapcontrol.tools.Listeners.ToolListener;
52
import org.gvsig.utils.console.JConsole;
53
import org.slf4j.Logger;
54
import org.slf4j.LoggerFactory;
55

    
56
/**
57
 * <p>
58
 * Allows user interact with different CAD tools, on a layer being edited.
59
 * </p>
60
 *
61
 * <p>
62
 * There are two ways of interacting:
63
 * <ul>
64
 * <li><b>With the mouse</b> : user selects any {@link CADTool CADTool} that
65
 * produces mouse events as consequence of the actions working with the layer
66
 * being edited. </li>
67
 * <li><b>Writing commands in the edition console</b> : most of the
68
 * {@link CADTool CADTool} mouse actions can also be called writing a command or
69
 * a command's parameter in the associated edition console, and pressing the key
70
 * <code>Enter</code>. If the command isn't valid, will notify it. </li>
71
 * </ul>
72
 * </p>
73
 *
74
 * <p>
75
 * The edition has been implemented as a <i>finite machine</i>, with three kind
76
 * of transitions between states according the parameters introduced:
77
 * <ul>
78
 * <li><i>First transition type: <b>Point</i></b>: if <code>text</code>
79
 * matches with any pattern of parameters needed for any kind of point
80
 * coordinates.<br>
81
 * There are eight ways of introducing point 2D coordinates:
82
 * <ul>
83
 * <li><i>X,Y</i> : absolute cardinal 2D coordinate from the center <i>(0,0)</i>
84
 * of the CCS <i>Current Coordinate System</i>.</li>
85
 * <li><i>@X,Y</i> : relative cardinal 2D distances from the last point added
86
 * of the CCS. If it's the first point of the geometry, works like <i>X,Y</i>.</li>
87
 * <li><i>length< angle</i> : absolute polar 2D coordinate from the center
88
 * <i>(0,0)</i> of the CCS <i>Current Coordinate System</i>, using <i>angle</i>
89
 * from the <i>X</i> axis of CCS, and <i>length</i> far away.</li>
90
 * <li><i>@length< angle</i> : relative polar 2D coordinate from the last
91
 * point added of the CCS <i>Current Coordinate System</i>, using <i>angle</i>
92
 * from the <i>X</i> axis of CCS, and <i>length</i> far away. If it's the
93
 * first point of the geometry, works like <i>length< angle</i>.</li>
94
 * <li><i>*X,Y</i> : like <i>X,Y</i> but using UCS <i>Universal Coordinate
95
 * System</i> as reference.</li>
96
 * <li><i>@*X,Y</i> : like <i>@X,Y</i> but using UCS <i>Universal Coordinate
97
 * System</i> as reference. If it's the first point of the geometry, works like
98
 * <i>*X,Y</i>.</li>
99
 * <li><i>*length< angle</i> : like <i>length< angle</i> but using UCS
100
 * <i>Universal Coordinate System</i> as reference.</li>
101
 * <li><i>@*length< angle</i> : like <i>@length< angle</i> but using UCS
102
 * <i>Universal Coordinate System</i> as reference. If it's the first point of
103
 * the geometry, works like <i>*length< angle</i>.</li>
104
 * </ul>
105
 * </li>
106
 * <li><i>Second transition type: <b>Value</i></b>: if recognizes it as a
107
 * single number.</li>
108
 * <li><i>Third transition type: <b>Option</i></b>: by default, if can't
109
 * classify the information as a single number neither as a point. This
110
 * information will be an <code>String</code> and dealt as an option of the
111
 * current tool state. Ultimately, if isn't valid, <code>text</code> will be
112
 * rewritten in the console notifying the user that isn't correct.</li>
113
 * </ul>
114
 * </p>
115
 *
116
 * @see Behavior
117
 * @see MapControl
118
 */
119
public class CADToolAdapter extends Behavior {
120

    
121
        private static Logger logger = LoggerFactory
122
                        .getLogger(CADToolAdapter.class);
123

    
124
        /**
125
         * Stores the CAD tools to edit the layers of the associated
126
         * <code>MapControl</code>.
127
         *
128
         * @see #addCADTool(String, CADTool)
129
         * @see #getCadTool()
130
         * @see #getCADTool(String)
131
         */
132
        private static HashMap namesCadTools = new HashMap();
133

    
134
        /**
135
         * Reference to the object used to manage the edition of the layers of the
136
         * associated <code>MapControl</code>.
137
         *
138
         * @see EditionManager
139
         * @see #getEditionManager()
140
         */
141
        private EditionManager editionManager = new EditionManager();
142
        
143
        /**
144
         * Reference to the MapContext library manager, used to create symbols
145
         * and legends.
146
         */
147
        private MapContextManager mapContextManager = MapContextLocator
148
                        .getMapContextManager();
149

    
150
        /**
151
         * Identifies that the data are absolute coordinates of the new point from
152
         * the (0, 0) position.
153
         */
154
        public static final int ABSOLUTE = 0;
155

    
156
        /**
157
         * Equivalent to {@link CADToolAdapter#ABSOLUTE CADToolAdapter#ABSOLUTE}.
158
         */
159
        public static final int RELATIVE_SCP = 1;
160

    
161
        /**
162
         * Identifies that the data are relative distances of the new point from the
163
         * previous introduced.
164
         */
165
        public static final int RELATIVE_SCU = 2;
166

    
167
        /**
168
         * Identifies that the data are relative polar distances (longitude of the
169
         * line and angle given in degrees) of the new point from the previous
170
         * introduced.
171
         */
172
        public static final int POLAR_SCP = 3;
173

    
174
        /**
175
         * Identifies that the data are relative polar distances (longitude of the
176
         * line and angle given in radians) of the new point from the previous
177
         * introduced.
178
         */
179
        public static final int POLAR_SCU = 4;
180

    
181
        /**
182
         * Stores the 2D map coordinates of the last point added.
183
         */
184
        private double[] previousPoint = null;
185

    
186
        /**
187
         * <i>Stack with CAD tools.</i>
188
         *
189
         * <i>For each CAD tool we use, the last item added in this stack will
190
         * display a different icon according to the current operation and its
191
         * status.</i>
192
         */
193
        private Stack cadToolStack = new Stack();
194

    
195
        /**
196
         * X coordinate of the last dragging or moving mouse event.
197
         */
198
        private int lastX;
199

    
200
        /**
201
         * Y coordinate of the last dragging or moving mouse event.
202
         */
203
        private int lastY;
204

    
205
        /**
206
         * Unused attribute.
207
         */
208
        private ISymbol symbol =
209
                        mapContextManager.getSymbolManager().createSymbol(
210
                        Geometry.TYPES.POINT, Color.RED);
211

    
212
        /**
213
         * Represents the cursor's point selected in <i>map coordinates</i>.
214
         *
215
         * @see MapControl#toMapPoint
216
         */
217
        private Point2D mapAdjustedPoint;
218

    
219
        /**
220
         * Kind of geometry drawn to identify the kind of control point selected by
221
         * the cursor's mouse.
222
         */
223
        // private ISnapper usedSnap = null;
224
        /**
225
         * Determines if has displayed at the edition console, the question for the
226
         * operations that can do the user with the current CAD tool, in its current
227
         * state.
228
         */
229
        private boolean questionAsked = false;
230

    
231
        /**
232
         * Represents the cursor's point selected in <i>screen coordinates</i>.
233
         *
234
         * @see ViewPort#fromMapPoint(Point2D)
235
         */
236
        private Point2D adjustedPoint;
237

    
238
        /**
239
         * Determines if the snap tools are enabled or disabled.
240
         *
241
         * @see #isRefentEnabled()
242
         * @see #setRefentEnabled(boolean)
243
         */
244
        // private boolean bRefent = true;
245
        /**
246
         * <p>
247
         * Determines if the position of the snap of the mouse's cursor on the
248
         * <code>MapControl</code> is within the area around a control point of a
249
         * geometry.
250
         * </p>
251
         *
252
         * <p>
253
         * The area is calculated as a circle centered at the control point and with
254
         * radius the pixels tolerance defined in the preferences.
255
         * </p>
256
         */
257
        // private boolean bForceCoord = false;
258
        /**
259
         * Optional grid that could be applied on the <code>MapControl</code>'s
260
         * view port.
261
         *
262
         * @see #getGrid()
263
         * @see #setAdjustGrid(boolean)
264
         */
265
        // private CADGrid cadgrid = new CADGrid();
266
        /**
267
         * Determines is is enabled or not the <i>Orto</i> mode.
268
         */
269
        private boolean bOrtoMode;
270

    
271
        /**
272
         * A light yellow color for the tool tip text box associated to the point
273
         * indicated by the mouse's cursor.
274
         */
275
        private Color theTipColor = new Color(255, 255, 155);
276

    
277
        /**
278
         * Last question asked to the user in the CAD console.
279
         */
280
        private Object lastQuestion;
281

    
282
        /**
283
         * Maximum tolerance in the approximation of a curved line by a polyline.
284
         *
285
         * @see #initializeFlatness()
286
         */
287
        private static boolean flatnessInitialized = false;
288

    
289
        /**
290
         * Listener to display the coordinates in the current application's status
291
         * bar.
292
         */
293
        private StatusBarListener sbl = null;
294

    
295
        /*
296
         * (non-Javadoc)
297
         *
298
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#setMapControl(com.iver.cit.gvsig.fmap.MapControl)
299
         */
300
        public void setMapControl(MapControl mc) {
301
                super.setMapControl(mc);
302
                sbl = new StatusBarListener(getMapControl());
303
        }
304

    
305
        private static final Image imageCursor = new BufferedImage(32, 32,
306
                        BufferedImage.TYPE_INT_ARGB);
307
        static {
308
                Graphics g = imageCursor.getGraphics();
309
                int size1 = 15;
310
                int size2 = 3;
311
                int x = 16;
312
                int y = 16;
313
                g.setColor(Color.MAGENTA);
314
                g.drawLine((x - size1), (y), (x + size1), (y));
315
                g.drawLine((x), (y - size1), (x), (y + size1));
316
                // g.setColor(Color.MAGENTA);
317
                g.drawRect((x - 6), (y - 6), 12, 12);
318
                g.drawRect((x - 3), (y - 3), 6, 6);
319

    
320
                // // getMapControl().setToolTipText(null);
321
                // if (adjustedPoint != null) {
322
                // if (bForceCoord) {
323
                // /* g.setColor(Color.ORANGE);
324
                // g.drawRect((int) (adjustedPoint.getX() - 6),
325
                // (int) (adjustedPoint.getY() - 6), 12, 12);
326
                // g.drawRect((int) (adjustedPoint.getX() - 3),
327
                // (int) (adjustedPoint.getY() - 3), 6, 6);
328
                // g.setColor(Color.MAGENTA);
329
                // g.drawRect((int) (adjustedPoint.getX() - 4),
330
                // (int) (adjustedPoint.getY() - 4), 8, 8); */
331
                // if (usedSnap != null)
332
                // {
333
                // usedSnap.draw(g, adjustedPoint);
334
                //
335
                // Graphics2D g2 = (Graphics2D) g;
336
                // FontMetrics metrics = g2.getFontMetrics();
337
                // int w = metrics.stringWidth(usedSnap.getToolTipText()) + 5;
338
                // int h = metrics.getMaxAscent() + 5;
339
                // int x = (int)p.getX()+9;
340
                // int y = (int)p.getY()- 7;
341
                //
342
                // g2.setColor(theTipColor );
343
                // g2.fillRect(x, y-h, w, h);
344
                // g2.setColor(Color.BLACK);
345
                // g2.drawRect(x, y-h, w, h);
346
                // g2.drawString(usedSnap.getToolTipText(), x+3, y-3);
347
                //
348
                //
349
                // // getMapControl().setToolTipText(usedSnap.getToolTipText());
350
                // }
351
                //
352
                // bForceCoord = false;
353
                // } else {
354
                // g.drawRect((int) (p.getX() - size2), (int) (p.getY() - size2),
355
                // (int) (size2 * 2), (int) (size2 * 2));
356
                // }
357
                // }
358

    
359
        }
360

    
361
        /**
362
         * <p>
363
         * Draws the selected geometries to edit. And, if the <i>snapping</i> is
364
         * enabled, draws also its effect over them.
365
         * </p>
366
         *
367
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#paintComponent(java.awt.Graphics)
368
         */
369
        public void paintComponent(MapControlDrawer mapControlDrawer) {
370
                super.paintComponent(mapControlDrawer);
371
                if (CADExtension.getCADToolAdapter() != this) {
372
                        return;
373
                }
374

    
375
                if (adjustedPoint != null) {
376
                        Point2D p = null;
377
                        if (mapAdjustedPoint != null) {
378
                                p = mapAdjustedPoint;
379
                        } else {
380
                                p = getMapControl().getViewPort().toMapPoint(adjustedPoint);
381
                        }
382

    
383
                        if (((CADTool) cadToolStack.peek()).getVLE() == null){
384
                                return;
385
                        }
386
                        
387
                        ((CADTool) cadToolStack.peek())
388
                                        .drawOperation(mapControlDrawer, p.getX(), p.getY());
389
                }
390
        }
391

    
392
        /**
393
         * <p>
394
         * Responds two kind of mouse click events:
395
         * <ul>
396
         * <li><b><i>One click of the third mouse's button</i></b>: displays a
397
         * popup with edition options.</li>
398
         * <li><b><i>Two clicks of the first mouse's button</i></b>: ends the
399
         * last cad tool setting as end transition point the event's one.</li>
400
         * </ul>
401
         * </p>
402
         *
403
         *
404
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseClicked(java.awt.event.MouseEvent)
405
         * @see CADExtension#showPopup(MouseEvent)
406
         */
407
        public void mouseClicked(MouseEvent e) throws BehaviorException {
408
                if (e.getButton() == MouseEvent.BUTTON3) {
409
                        CADExtension.showPopup(e);
410
                } else if (e.getButton() == MouseEvent.BUTTON1
411
                                && e.getClickCount() == 2) {
412
                        questionAsked = true;
413
                        if (!cadToolStack.isEmpty()) {
414
                                CADTool ct = (CADTool) cadToolStack.peek();
415
                                ViewPort vp = getMapControl().getMapContext().getViewPort();
416
                                Point2D p;
417

    
418
                                if (mapAdjustedPoint != null) {
419
                                        p = mapAdjustedPoint;
420
                                } else {
421
                                        p = vp.toMapPoint(adjustedPoint);
422
                                }
423
                                ct.endTransition(p.getX(), p.getY(), e);
424
                                previousPoint = new double[] { p.getX(), p.getY() };
425
                        }
426
                }
427
        }
428

    
429
        /*
430
         * (non-Javadoc)
431
         *
432
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseEntered(java.awt.event.MouseEvent)
433
         */
434
        public void mouseEntered(MouseEvent e) throws BehaviorException {
435
                clearMouseImage();
436
        }
437

    
438
        /*
439
         * (non-Javadoc)
440
         *
441
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseExited(java.awt.event.MouseEvent)
442
         */
443
        public void mouseExited(MouseEvent e) throws BehaviorException {
444
        }
445

    
446
        /**
447
         * Selects the vertex of a geometry at the point selected on the
448
         * <code>MapControl</code> by pressing the first mouse's button.
449
         *
450
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mousePressed(java.awt.event.MouseEvent)
451
         */
452
        public void mousePressed(MouseEvent e) throws BehaviorException {
453
                if (e.getButton() == MouseEvent.BUTTON1) {
454
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
455
                        Point2D p;
456
                        mapAdjustedPoint = getMapControl().getMapAdjustedPoint();
457
                        if (mapAdjustedPoint != null) {
458
                                p = mapAdjustedPoint;
459
                        } else {
460
                                p = vp.toMapPoint(adjustedPoint);
461
                        }
462
                        transition(new double[] { p.getX(), p.getY() }, e, ABSOLUTE);
463
                }
464
        }
465

    
466
        // /**
467
        // * <p>Adjusts the <code>point</code> to the grid if its enabled, and
468
        // * sets <code>mapHandlerAdjustedPoint</code> with that new value.</p>
469
        // *
470
        // * <p>The value returned is the distance between those points: the
471
        // original and
472
        // * the adjusted one.</p>
473
        // *
474
        // * @param point point to adjust
475
        // * @param mapHandlerAdjustedPoint <code>point</code> adjusted
476
        // *
477
        // * @return distance from <code>point</code> to the adjusted one. If there
478
        // is no
479
        // * adjustment, returns <code>Double.MAX_VALUE</code>.
480
        // */
481
        // private double adjustToHandler(Point2D point,
482
        // Point2D mapHandlerAdjustedPoint) {
483
        //
484
        // if (!isRefentEnabled())
485
        // return Double.MAX_VALUE;
486
        //
487
        // ILayerEdited aux =
488
        // CADExtension.getEditionManager().getActiveLayerEdited();
489
        // if (!(aux instanceof VectorialLayerEdited))
490
        // return Double.MAX_VALUE;
491
        // VectorialLayerEdited vle = (VectorialLayerEdited) aux;
492
        //
493
        // ArrayList snappers = vle.getSnappers();
494
        // ArrayList layersToSnap = vle.getLayersToSnap();
495
        //
496
        //
497
        // ViewPort vp = getMapControl().getViewPort();
498
        //
499
        // snappers=SnapConfigPage.getActivesSnappers();
500
        //
501
        // double mapTolerance = vp.toMapDistance(SelectionCADTool.tolerance);
502
        // double minDist = mapTolerance;
503
        // // double rw = getMapControl().getViewPort().toMapDistance(5);
504
        // Point2D mapPoint = point;
505
        // double middleTol=mapTolerance * 0.5;
506
        // org.gvsig.fmap.geom.primitive.Envelope r = new
507
        // DefaultEnvelope(mapPoint.getX() - middleTol,
508
        // mapPoint.getY() - middleTol,
509
        // mapPoint.getX() + middleTol,
510
        // mapPoint.getY() + middleTol);
511
        //
512
        // Envelope e = Converter.convertEnvelopeToJTS(r);
513
        //
514
        // usedSnap = null;
515
        // Point2D lastPoint = null;
516
        // if (previousPoint != null)
517
        // {
518
        // lastPoint = new Point2D.Double(previousPoint[0], previousPoint[1]);
519
        // }
520
        // for (int j = 0; j < layersToSnap.size(); j++)
521
        // {
522
        // FLyrVect lyrVect = (FLyrVect) layersToSnap.get(j);
523
        // SpatialCache cache = lyrVect.getSpatialCache();
524
        // if (lyrVect.isVisible())
525
        // {
526
        // // La lista de snappers est� siempre ordenada por prioridad. Los de mayor
527
        // // prioridad est�n primero.
528
        // for (int i = 0; i < snappers.size(); i++)
529
        // {
530
        // ISnapper theSnapper = (ISnapper) snappers.get(i);
531
        //
532
        // if (usedSnap != null)
533
        // {
534
        // // Si ya tenemos un snap y es de alta prioridad, cogemos ese. (A no ser
535
        // que en otra capa encontremos un snapper mejor)
536
        // if (theSnapper.getPriority() < usedSnap.getPriority())
537
        // break;
538
        // }
539
        // SnappingVisitor snapVisitor = null;
540
        // Point2D theSnappedPoint = null;
541
        //
542
        // if (theSnapper instanceof ISnapperVectorial)
543
        // {
544
        // if (theSnapper instanceof ISnapperGeometriesVectorial) {
545
        // snapVisitor=new GeometriesSnappingVisitor((ISnapperGeometriesVectorial)
546
        // theSnapper,point,mapTolerance,lastPoint);
547
        // }else {
548
        // snapVisitor = new SnappingVisitor((ISnapperVectorial) theSnapper, point,
549
        // mapTolerance, lastPoint);
550
        // }
551
        // // System.out.println("Cache size = " + cache.size());
552
        // cache.query(e, snapVisitor);
553
        // theSnappedPoint = snapVisitor.getSnapPoint();
554
        //
555
        // }
556
        // if (theSnapper instanceof ISnapperRaster)
557
        // {
558
        // ISnapperRaster snapRaster = (ISnapperRaster) theSnapper;
559
        // theSnappedPoint = snapRaster.getSnapPoint(getMapControl(), point,
560
        // mapTolerance, lastPoint);
561
        // }
562
        //
563
        //
564
        // if (theSnappedPoint != null) {
565
        // double distAux = theSnappedPoint.distance(point);
566
        // if (minDist > distAux)
567
        // {
568
        // minDist = distAux;
569
        // usedSnap = theSnapper;
570
        // mapHandlerAdjustedPoint.setLocation(theSnappedPoint);
571
        // }
572
        // }
573
        // }
574
        // } // visible
575
        // }
576
        // if (usedSnap != null)
577
        // return minDist;
578
        // return Double.MAX_VALUE;
579
        //
580
        // }
581

    
582
        /*
583
         * (non-Javadoc)
584
         *
585
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseReleased(java.awt.event.MouseEvent)
586
         */
587
        public void mouseReleased(MouseEvent e) throws BehaviorException {
588
                getMapControl().repaint();
589
        }
590

    
591
        /*
592
         * (non-Javadoc)
593
         *
594
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseDragged(java.awt.event.MouseEvent)
595
         */
596
        public void mouseDragged(MouseEvent e) throws BehaviorException {
597
                lastX = e.getX();
598
                lastY = e.getY();
599
                adjustedPoint = e.getPoint();
600
                // calculateSnapPoint(e.getPoint());
601
        }
602

    
603
        /*
604
         * (non-Javadoc)
605
         *
606
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseMoved(java.awt.event.MouseEvent)
607
         */
608
        public void mouseMoved(MouseEvent e) throws BehaviorException {
609

    
610
                lastX = e.getX();
611
                lastY = e.getY();
612
                adjustedPoint = e.getPoint();
613
//                 calculateSnapPoint(e.getPoint());
614

    
615
                showCoords(e.getPoint());
616

    
617
                getMapControl().repaint();
618
        }
619

    
620
        /**
621
         * Displays the current coordinates of the mouse's cursor on the associated
622
         * <code>MapControl</code> object, at the status bar of the application's
623
         * main frame.
624
         *
625
         * @param pPix
626
         *            current 2D mouse's cursor coordinates on the
627
         *            <code>MapControl</code>
628
         */
629
        private void showCoords(Point2D pPix) {
630
                String[] axisText = new String[2];
631
                axisText[0] = "X = ";
632
                axisText[1] = "Y = ";
633
                // NumberFormat nf = NumberFormat.getInstance();
634
                MapControl mapControl = getMapControl();
635
                ViewPort vp = mapControl.getMapContext().getViewPort();
636
                IProjection iProj = vp.getProjection();
637

    
638
                // if (iProj.getAbrev().equals("EPSG:4326") ||
639
                // iProj.getAbrev().equals("EPSG:4230")) {
640
                // axisText[0] = "Lon = ";
641
                // axisText[1] = "Lat = ";
642
                // nf.setMaximumFractionDigits(8);
643
                // } else {
644
                // axisText[0] = "X = ";
645
                // axisText[1] = "Y = ";
646
                // nf.setMaximumFractionDigits(2);
647
                // }
648
                Point2D p;
649
                if (mapAdjustedPoint == null) {
650
                        p = vp.toMapPoint(pPix);
651
                } else {
652
                        p = mapAdjustedPoint;
653
                }
654
                sbl.setFractionDigits(p);
655
                axisText = sbl.setCoorDisplayText(axisText);
656
                MainFrame mF = PluginServices.getMainFrame();
657

    
658
                if (mF != null) {
659
                        mF.getStatusBar().setMessage(
660
                                        "units",
661
                                        PluginServices
662
                                                        .getText(this, MapContext.getDistanceNames()[vp
663
                                                                        .getDistanceUnits()]));
664
                        mF.getStatusBar().setControlValue("scale",
665
                                        String.valueOf(mapControl.getMapContext().getScaleView()));
666
                        mF.getStatusBar().setMessage("projection", iProj.getAbrev());
667

    
668
                        String[] coords = sbl.getCoords(p);
669
                        mF.getStatusBar().setMessage("x", axisText[0] + coords[0]);
670
                        mF.getStatusBar().setMessage("y", axisText[1] + coords[1]);
671
                }
672
        }
673

    
674
        /**
675
         * Hides the mouse's cursor.
676
         */
677
        private void clearMouseImage() {
678
                int[] pixels = new int[16 * 16];
679
                Image image = Toolkit.getDefaultToolkit().createImage(
680
                                new MemoryImageSource(16, 16, pixels, 0, 16));
681
                Cursor transparentCursor = Toolkit.getDefaultToolkit()
682
                                .createCustomCursor(image, new Point(0, 0), "invisiblecursor");
683

    
684
                getMapControl().setCursor(transparentCursor);
685
        }
686

    
687
        /**
688
         * <p>
689
         * Draws a 31x31 pixels cross round the mouse's cursor with an small
690
         * geometry centered:
691
         * <ul>
692
         * <li><i>an square centered</i>: if isn't over a <i>control point</i>.
693
         * <li><i>an small geometry centered according to the kind of control point</i>:
694
         * if it's over a control point. In this case, the small geometry is drawn
695
         * by a {@link ISnapper ISnapper} type object.<br>
696
         * On the other hand, a light-yellowed background tool tip text with the
697
         * type of <i>control point</i> will be displayed.</li>
698
         * </p>
699
         *
700
         * @param g
701
         *            <code>MapControl</code>'s graphics where the data will be
702
         *            drawn
703
         */
704
        // private void drawCursor(Graphics g) {
705
        // g.setColor(Color.black);
706
        // Point2D p = adjustedPoint;
707
        //
708
        // if (p == null) {
709
        // getGrid().setViewPort(getMapControl().getViewPort());
710
        //
711
        // return;
712
        // }
713
        //
714
        // int size1 = 15;
715
        // int size2 = 3;
716
        // g.drawLine((int) (p.getX() - size1), (int) (p.getY()),
717
        // (int) (p.getX() + size1), (int) (p.getY()));
718
        // g.drawLine((int) (p.getX()), (int) (p.getY() - size1),
719
        // (int) (p.getX()), (int) (p.getY() + size1));
720
        //
721
        // // getMapControl().setToolTipText(null);
722
        // if (adjustedPoint != null) {
723
        // if (bForceCoord) {
724
        // /* g.setColor(Color.ORANGE);
725
        // g.drawRect((int) (adjustedPoint.getX() - 6),
726
        // (int) (adjustedPoint.getY() - 6), 12, 12);
727
        // g.drawRect((int) (adjustedPoint.getX() - 3),
728
        // (int) (adjustedPoint.getY() - 3), 6, 6);
729
        // g.setColor(Color.MAGENTA);
730
        // g.drawRect((int) (adjustedPoint.getX() - 4),
731
        // (int) (adjustedPoint.getY() - 4), 8, 8); */
732
        // if (usedSnap != null)
733
        // {
734
        // usedSnap.draw(g, adjustedPoint);
735
        //
736
        // Graphics2D g2 = (Graphics2D) g;
737
        // FontMetrics metrics = g2.getFontMetrics();
738
        // int w = metrics.stringWidth(usedSnap.getToolTipText()) + 5;
739
        // int h = metrics.getMaxAscent() + 5;
740
        // int x = (int)p.getX()+9;
741
        // int y = (int)p.getY()- 7;
742
        //
743
        // g2.setColor(theTipColor );
744
        // g2.fillRect(x, y-h, w, h);
745
        // g2.setColor(Color.BLACK);
746
        // g2.drawRect(x, y-h, w, h);
747
        // g2.drawString(usedSnap.getToolTipText(), x+3, y-3);
748
        //
749
        //
750
        // // getMapControl().setToolTipText(usedSnap.getToolTipText());
751
        // }
752
        //
753
        // bForceCoord = false;
754
        // } else {
755
        // g.drawRect((int) (p.getX() - size2), (int) (p.getY() - size2),
756
        // (int) (size2 * 2), (int) (size2 * 2));
757
        // }
758
        // }
759
        // }
760
        /**
761
         * <p>
762
         * Tries to find the nearest geometry or grid control point by the position
763
         * of the current snap tool.
764
         * </p>
765
         *
766
         * <p>
767
         * Prioritizes the grid control points than the geometries ones.
768
         * </p>
769
         *
770
         * <p>
771
         * If finds any near, stores the <i>map</i> and <i>pixel</i> coordinates
772
         * for the snap, and enables the <code>bForceCoord</code> attribute for
773
         * the next draw of the mouse's cursor.
774
         * </p>
775
         *
776
         * @param point
777
         *            current mouse 2D position
778
         */
779
        // private void calculateSnapPoint(Point point) {
780
        // // Se comprueba el ajuste a rejilla
781
        //
782
        // Point2D gridAdjustedPoint = getMapControl().getViewPort().toMapPoint(
783
        // point);
784
        // double minDistance = Double.MAX_VALUE;
785
        // CADTool ct = (CADTool) cadToolStack.peek();
786
        // if (ct instanceof SelectionCADTool
787
        // && ((SelectionCADTool) ct).getStatus().equals(
788
        // "Selection.FirstPoint")) {
789
        // mapAdjustedPoint = gridAdjustedPoint;
790
        // adjustedPoint = (Point2D) point.clone();
791
        // } else {
792
        //
793
        // minDistance = getGrid().adjustToGrid(gridAdjustedPoint);
794
        // if (minDistance < Double.MAX_VALUE) {
795
        // adjustedPoint = getMapControl().getViewPort().fromMapPoint(
796
        // gridAdjustedPoint);
797
        // mapAdjustedPoint = gridAdjustedPoint;
798
        // } else {
799
        // mapAdjustedPoint = null;
800
        // }
801
        // }
802
        // Point2D handlerAdjustedPoint = null;
803
        //
804
        // // Se comprueba el ajuste a los handlers
805
        // if (mapAdjustedPoint != null) {
806
        // handlerAdjustedPoint = (Point2D) mapAdjustedPoint.clone(); //
807
        // getMapControl().getViewPort().toMapPoint(point);
808
        // } else {
809
        // handlerAdjustedPoint = getMapControl().getViewPort().toMapPoint(
810
        // point);
811
        // }
812
        //
813
        // Point2D mapPoint = new Point2D.Double();
814
        // double distance = adjustToHandler(handlerAdjustedPoint, mapPoint);
815
        //
816
        // if (distance < minDistance) {
817
        // bForceCoord = true;
818
        // adjustedPoint = getMapControl().getViewPort().fromMapPoint(mapPoint);
819
        // mapAdjustedPoint = mapPoint;
820
        // minDistance = distance;
821
        // }
822
        //
823
        // // Si no hay ajuste
824
        // if (minDistance == Double.MAX_VALUE) {
825
        // adjustedPoint = point;
826
        // mapAdjustedPoint = null;
827
        // }
828
        //
829
        // }
830
        /*
831
         * (non-Javadoc)
832
         *
833
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseWheelMoved(java.awt.event.MouseWheelEvent)
834
         */
835
        public void mouseWheelMoved(MouseWheelEvent e) throws BehaviorException {
836
        }
837

    
838
        /**
839
         * <p>
840
         * Process the information written by the user about the next point
841
         * coordinate, determining the kind of <i>transition</i> according the
842
         * parameters written.
843
         * </p>
844
         *
845
         * <p>
846
         * After, invokes one of the three possible <i>transition</i> methods of
847
         * the <i>finite machine</i> of edition:
848
         * <ul>
849
         * <li><i>First transition type: <b>Point</i></b>: if <code>text</code>
850
         * matches with any pattern of parameters needed for any kind of point
851
         * coordinates.<br>
852
         * There are eight ways of introducing point 2D coordinates:
853
         * <ul>
854
         * <li><i>X,Y</i> : absolute cardinal 2D coordinate from the center
855
         * <i>(0,0)</i> of the CCS <i>Current Coordinate System</i>.</li>
856
         * <li><i>@X,Y</i> : relative cardinal 2D distances from the last point
857
         * added of the CCS. If it's the first point of the geometry, works like
858
         * <i>X,Y</i>.</li>
859
         * <li><i>length< angle</i> : absolute polar 2D coordinate from the
860
         * center <i>(0,0)</i> of the CCS <i>Current Coordinate System</i>, using
861
         * <i>angle</i> from the <i>X</i> axis of CCS, and <i>length</i> far
862
         * away.</li>
863
         * <li><i>@length< angle</i> : relative polar 2D coordinate from the last
864
         * point added of the CCS <i>Current Coordinate System</i>, using <i>angle</i>
865
         * from the <i>X</i> axis of CCS, and <i>length</i> far away. If it's the
866
         * first point of the geometry, works like <i>length< angle</i>.</li>
867
         * <li><i>*X,Y</i> : like <i>X,Y</i> but using UCS <i>Universal
868
         * Coordinate System</i> as reference.</li>
869
         * <li><i>@*X,Y</i> : like <i>@X,Y</i> but using UCS <i>Universal
870
         * Coordinate System</i> as reference. If it's the first point of the
871
         * geometry, works like <i>*X,Y</i>.</li>
872
         * <li><i>*length< angle</i> : like <i>length< angle</i> but using UCS
873
         * <i>Universal Coordinate System</i> as reference.</li>
874
         * <li><i>@*length< angle</i> : like <i>@length< angle</i> but using
875
         * UCS <i>Universal Coordinate System</i> as reference. If it's the first
876
         * point of the geometry, works like <i>*length< angle</i>.</li>
877
         * </ul>
878
         * </li>
879
         * <li><i>Second transition type: <b>Value</i></b>: if recognizes it as a
880
         * single number.</li>
881
         * <li><i>Third transition type: <b>Option</i></b>: by default, if can't
882
         * classify the information as a single number neither as a point. This
883
         * information will be an <code>String</code> and dealt as an option of
884
         * the current tool state. Ultimately, if isn't valid, <code>text</code>
885
         * will be rewritten in the console notifying the user that isn't correct.</li>
886
         * </ul>
887
         * </p>
888
         *
889
         * @param text
890
         *            command written by user in the edition's console
891
         */
892
        public void textEntered(String text) {
893
                if (text == null) {
894
                        transition(PluginServices.getText(this, "cancel"));
895
                } else {
896
                        /*
897
                         * if ("".equals(text)) { transition("aceptar"); } else {
898
                         */
899
                        text = text.trim();
900
                        int type = ABSOLUTE;
901
                        String[] numbers = new String[1];
902
                        numbers[0] = text;
903
                        if (text.indexOf(",") != -1) {
904

    
905
                                numbers = text.split(",");
906
                                if (numbers[0].substring(0, 1).equals("@")) {
907
                                        numbers[0] = numbers[0].substring(1, numbers[0].length());
908
                                        type = RELATIVE_SCU;
909
                                        if (numbers[0].substring(0, 1).equals("*")) {
910
                                                type = RELATIVE_SCP;
911
                                                numbers[0] = numbers[0].substring(1, numbers[0]
912
                                                                .length());
913
                                        }
914
                                }
915
                        } else if (text.indexOf("<") != -1) {
916
                                type = POLAR_SCP;
917
                                numbers = text.split("<");
918
                                if (numbers[0].substring(0, 1).equals("@")) {
919
                                        numbers[0] = numbers[0].substring(1, numbers[0].length());
920
                                        type = POLAR_SCU;
921
                                        if (numbers[0].substring(0, 1).equals("*")) {
922
                                                type = POLAR_SCP;
923
                                                numbers[0] = numbers[0].substring(1, numbers[0]
924
                                                                .length());
925
                                        }
926
                                }
927
                        }
928

    
929
                        double[] values = null;
930

    
931
                        try {
932
                                if (numbers.length == 2) {
933
                                        // punto
934
                                        values = new double[] { Double.parseDouble(numbers[0]),
935
                                                        Double.parseDouble(numbers[1]) };
936
                                        transition(values, null, type);
937
                                } else if (numbers.length == 1) {
938
                                        // valor
939
                                        values = new double[] { Double.parseDouble(numbers[0]) };
940
                                        transition(values[0]);
941
                                }
942
                        } catch (NumberFormatException e) {
943
                                transition(text);
944
                        } catch (NullPointerException e) {
945
                                transition(text);
946
                        }
947
                        // }
948
                }
949
                getMapControl().repaint();
950
        }
951

    
952
        /**
953
         * If there are options related with the <code>CADTool</code> at the peek
954
         * of the CAD tool stack, displays them as a popup.
955
         */
956
        public void configureMenu() {
957
                String[] desc = ((CADTool) cadToolStack.peek()).getDescriptions();
958
                // String[] labels = ((CADTool)
959
                // cadToolStack.peek()).getCurrentTransitions();
960
                CADExtension.clearMenu();
961

    
962
                for (int i = 0; i < desc.length; i++) {
963
                        if (desc[i] != null) {
964
                                CADExtension
965
                                                .addMenuEntry(PluginServices.getText(this, desc[i]));// ,
966
                                // labels[i]);
967
                        }
968
                }
969

    
970
        }
971

    
972
        /**
973
         * <p>
974
         * One of the three kind of transaction methods of the <i>finite machine</i>
975
         * of edition.
976
         * </p>
977
         *
978
         * <p>
979
         * This one deals <code>values</code> as two numbers that, according
980
         * <code>type</code> calculate a new point 2D in the current layer edited
981
         * in the associated <code>MapControl</code>.
982
         * </p>
983
         *
984
         * <p>
985
         * There are different ways of calculating the new point 2D coordinates,
986
         * according the value of <code>type</code>, see
987
         * {@link #textEntered(String) #textEntered(String)}.
988
         * </p>
989
         *
990
         * <p>
991
         * After applying the changes, updates the controls available for managing
992
         * the current data.
993
         * </p>
994
         *
995
         * @param values
996
         *            numbers needed to calculate the new point coordinates
997
         *            according <code>type</code>
998
         * @param event
999
         *            event which generated this invocation (a
1000
         *            <code>MouseEvent</code> or a <code>KeyEvent</code>)
1001
         * @param type
1002
         *            kind of information that is <code>values</code>. According
1003
         *            this parameter, will calculate the new point in a different
1004
         *            way
1005
         *
1006
         * @see CADTool#transition(double, double, InputEvent)
1007
         * @see #transition(double)
1008
         * @see #transition(String)
1009
         */
1010
        private void transition(double[] values, InputEvent event, int type) {
1011
                questionAsked = true;
1012
                if (!cadToolStack.isEmpty()) {
1013
                        CADTool ct = (CADTool) cadToolStack.peek();
1014

    
1015
                        switch (type) {
1016
                        case ABSOLUTE:
1017
                                ct.transition(values[0], values[1], event);
1018
                                previousPoint = values;
1019
                                break;
1020
                        case RELATIVE_SCU:
1021
                                // Comprobar que tenemos almacenado el punto anterior
1022
                                // y crear nuevo con coordenadas relativas a �l.
1023
                                double[] auxSCU = values;
1024
                                if (previousPoint != null) {
1025
                                        auxSCU[0] = previousPoint[0] + values[0];
1026
                                        auxSCU[1] = previousPoint[1] + values[1];
1027
                                }
1028
                                ct.transition(auxSCU[0], auxSCU[1], event);
1029

    
1030
                                previousPoint = auxSCU;
1031
                                break;
1032
                        case RELATIVE_SCP:
1033
                                // TODO de momento no implementado.
1034
                                ct.transition(values[0], values[1], event);
1035
                                previousPoint = values;
1036
                                break;
1037
                        case POLAR_SCU:// Relativo
1038
                                // Comprobar que tenemos almacenado el punto anterior
1039
                                // y crear nuevo con coordenadas relativas a �l.
1040
                                double[] auxPolarSCU = values;
1041
                                if (previousPoint != null) {
1042
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
1043
                                                        previousPoint[0], previousPoint[1]), Math
1044
                                                        .toRadians(values[1]), values[0]);
1045
                                        auxPolarSCU[0] = point.getX();
1046
                                        auxPolarSCU[1] = point.getY();
1047
                                        ct.transition(auxPolarSCU[0], auxPolarSCU[1], event);
1048
                                } else {
1049
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
1050
                                                        0, 0), Math.toRadians(values[1]), values[0]);
1051
                                        auxPolarSCU[0] = point.getX();
1052
                                        auxPolarSCU[1] = point.getY();
1053
                                        ct.transition(auxPolarSCU[0], auxPolarSCU[1], event);
1054
                                }
1055
                                previousPoint = auxPolarSCU;
1056
                                break;
1057
                        case POLAR_SCP:// Absoluto
1058
                                double[] auxPolarSCP = values;
1059
                                if (previousPoint != null) {
1060
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
1061
                                                        0, 0), Math.toRadians(values[1]), values[0]);
1062
                                        auxPolarSCP[0] = point.getX();
1063
                                        auxPolarSCP[1] = point.getY();
1064
                                        ct.transition(auxPolarSCP[0], auxPolarSCP[1], event);
1065
                                } else {
1066
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
1067
                                                        0, 0), values[1], values[0]);
1068
                                        auxPolarSCP[0] = point.getX();
1069
                                        auxPolarSCP[1] = point.getY();
1070
                                        ct.transition(auxPolarSCP[0], auxPolarSCP[1], event);
1071
                                }
1072
                                previousPoint = auxPolarSCP;
1073
                                break;
1074
                        default:
1075
                                break;
1076
                        }
1077
                        askQuestion();
1078
                }
1079
                configureMenu();
1080
                PluginServices.getMainFrame().enableControls();
1081
        }
1082

    
1083
        /**
1084
         * <p>
1085
         * One of the three kind of transaction methods of the <i>finite machine</i>
1086
         * of edition.
1087
         * </p>
1088
         *
1089
         * <p>
1090
         * This one deals <code>value</code> as a single number used as a
1091
         * parameter for the current tool state. Ultimately, if isn't valid,
1092
         * <code>number</code> will be rewritten in the console notifying the user
1093
         * that isn't correct.
1094
         * </p>
1095
         *
1096
         * <p>
1097
         * After applying the changes, updates the controls available for managing
1098
         * the current data.
1099
         * </p>
1100
         *
1101
         * @param value
1102
         *            value for the current tool state
1103
         *
1104
         * @see CADTool#transition(double)
1105
         * @see #transition(double[], InputEvent, int)
1106
         * @see #transition(String)
1107
         */
1108
        private void transition(double value) {
1109
                questionAsked = true;
1110
                if (!cadToolStack.isEmpty()) {
1111
                        CADTool ct = (CADTool) cadToolStack.peek();
1112
                        ct.transition(value);
1113
                        askQuestion();
1114
                }
1115
                configureMenu();
1116
                PluginServices.getMainFrame().enableControls();
1117
        }
1118

    
1119
        /**
1120
         * <p>
1121
         * One of the three kind of transaction methods of the <i>finite machine</i>
1122
         * of edition.
1123
         * </p>
1124
         *
1125
         * <p>
1126
         * This one deals <code>option</code> as an option of the current tool
1127
         * state. Ultimately, if isn't valid, <code>option</code> will be
1128
         * rewritten in the console notifying the user that isn't correct.
1129
         * </p>
1130
         *
1131
         * @param option
1132
         *            option for the current tool state
1133
         *
1134
         * @see CADTool#transition(String)
1135
         * @see #transition(double[], InputEvent, int)
1136
         * @see #transition(double)
1137
         */
1138
        public void transition(String option) {
1139
                questionAsked = true;
1140
                if (!cadToolStack.isEmpty()) {
1141
                        CADTool ct = (CADTool) cadToolStack.peek();
1142
                        try {
1143
                                ct.transition(option);
1144
                        } catch (Exception e) {
1145
                                IWindow window = PluginServices.getMDIManager()
1146
                                                .getActiveWindow();
1147

    
1148
                                if (window instanceof DefaultViewPanel) {
1149
                                        ((DefaultViewPanel) window).getConsolePanel().addText(
1150
                                                        "\n"
1151
                                                                        + PluginServices.getText(this,
1152
                                                                                        "incorrect_option") + " : "
1153
                                                                        + option, JConsole.ERROR);
1154
                                }
1155
                        }
1156
                        askQuestion();
1157
                }
1158
                configureMenu();
1159
                PluginServices.getMainFrame().enableControls();
1160
        }
1161

    
1162
        /**
1163
         * Shows or hides a grid on the <code>ViewPort</code> of the associated
1164
         * <code>MapControl</code>.
1165
         *
1166
         * @param value
1167
         *            <code>true</code> to make the grid visible;
1168
         *            <code>false</code> to make it invisible
1169
         */
1170
        // public void setGridVisibility(boolean value) {
1171
        // getGrid().setShowGrid(value);
1172
        // getGrid().setViewPort(getMapControl().getViewPort());
1173
        // getMapControl().repaint();
1174
        // }
1175
        // /**
1176
        // * Sets the snap tools enabled or disabled.
1177
        // *
1178
        // * @param activated <code>true</code> to enable the snap tools;
1179
        // <code>false</code> to disable them
1180
        // *
1181
        // * @see #isRefentEnabled()
1182
        // */
1183
        // public void setRefentEnabled(boolean activated) {
1184
        // bRefent = activated;
1185
        // }
1186
        //
1187
        // /**
1188
        // * Determines if snap tools are enabled or disabled.
1189
        // *
1190
        // * @return <code>true</code> to enable the snap tools; <code>false</code>
1191
        // to disable them
1192
        // *
1193
        // * @see #setRefentEnabled(boolean)
1194
        // */
1195
        // public boolean isRefentEnabled()
1196
        // {
1197
        // return bRefent;
1198
        // }
1199
        /*
1200
         * (non-Javadoc)
1201
         *
1202
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#getListener()
1203
         */
1204
        public ToolListener getListener() {
1205
                return new ToolListener() {
1206
                        /**
1207
                         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#getCursor()
1208
                         */
1209
                        public Image getImageCursor() {
1210
                                return imageCursor;
1211
                        }
1212

    
1213
                        /**
1214
                         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#cancelDrawing()
1215
                         */
1216
                        public boolean cancelDrawing() {
1217
                                return false;
1218
                        }
1219
                };
1220
        }
1221

    
1222
        /**
1223
         * Returns the {@link CADTool CADTool} at the top of the stack without
1224
         * removing it from the CAD tool stack.
1225
         *
1226
         * @return the {@link CADTool CADTool} at the top of the stack
1227
         *
1228
         * @see #pushCadTool(CADTool)
1229
         * @see #popCadTool()
1230
         * @see #setCadTool(CADTool)
1231
         */
1232
        public CADTool getCadTool() {
1233
                return (CADTool) cadToolStack.peek();
1234
        }
1235

    
1236
        /**
1237
         * <p>
1238
         * Pushes a {@link CADTool CADTool} onto the top of the CAD tool stack, and
1239
         * sets it as current.
1240
         * </p>
1241
         *
1242
         * @param cadTool
1243
         *            CAD tool to enable as current
1244
         *
1245
         * @see #getCadTool()
1246
         * @see #popCadTool()
1247
         * @see #setCadTool(CADTool)
1248
         */
1249
        public void pushCadTool(CADTool cadTool) {
1250
                cadToolStack.push(cadTool);
1251
                cadTool.setCadToolAdapter(this);
1252
                // cadTool.initializeStatus();
1253
                // cadTool.setVectorialAdapter(vea);
1254
                /*
1255
                 * int ret = cadTool.transition(null, editableFeatureSource, selection,
1256
                 * new double[0]);
1257
                 *
1258
                 * if ((ret & Automaton.AUTOMATON_FINISHED) ==
1259
                 * Automaton.AUTOMATON_FINISHED) { popCadTool();
1260
                 *
1261
                 * if (cadToolStack.isEmpty()) { pushCadTool(new
1262
                 * com.iver.cit.gvsig.gui.cad.smc.gen.CADTool());//new
1263
                 * SelectionCadTool());
1264
                 * PluginServices.getMainFrame().setSelectedTool("selection"); }
1265
                 *
1266
                 * askQuestion();
1267
                 *
1268
                 * getMapControl().drawMap(false); }
1269
                 */
1270
        }
1271

    
1272
        /**
1273
         * Removes the peek of the CAD tool stack.
1274
         *
1275
         * @see #pushCadTool(CADTool)
1276
         * @see #getCadTool()
1277
         * @see #setCadTool(CADTool)
1278
         */
1279
        public void popCadTool() {
1280
                cadToolStack.pop();
1281
        }
1282

    
1283
        /**
1284
         * <p>
1285
         * Displays at the console associated to the current active view that's
1286
         * being edited, the question of the following operation that user can do
1287
         * with the current <code>CADTool</code>, only if it hasn't just
1288
         * answered.
1289
         * </p>
1290
         *
1291
         * <p>
1292
         * The format of the question will be according the following pattern:<br>
1293
         * "\n#"<i>{cadtool at CAD tool stack peek}</i>.getQuestion()">"
1294
         * </p>
1295
         */
1296
        public void askQuestion() {
1297
                CADTool cadtool = (CADTool) cadToolStack.peek();
1298
                /*
1299
                 * if (cadtool..getStatus()==0){
1300
                 * PluginServices.getMainFrame().addTextToConsole("\n"
1301
                 * +cadtool.getName()); }
1302
                 */
1303
                if (PluginServices.getMDIManager().getActiveWindow() instanceof DefaultViewPanel) {
1304
                        DefaultViewPanel vista = (DefaultViewPanel) PluginServices.getMDIManager()
1305
                                        .getActiveWindow();
1306
                        String question = cadtool.getQuestion();
1307
                        if (lastQuestion == null || !(lastQuestion.equals(question))
1308
                                        || questionAsked) {
1309
                                vista.getConsolePanel().addText("\n" + "#" + question + " > ",
1310
                                                JConsole.MESSAGE);
1311
                                // ***PluginServices.getMainFrame().addTextToConsole("\n" +
1312
                                // cadtool.getQuestion());
1313
                                questionAsked = false;
1314
                        }
1315
                        lastQuestion = question;
1316
                }
1317

    
1318
        }
1319

    
1320
        /**
1321
         * Empties the CAD tools stack and pushes <code>cadTool</code> in it.
1322
         *
1323
         * @param cadTool
1324
         *            CAD tool to set at the peek of the stack
1325
         *
1326
         * @see #pushCadTool(CADTool)
1327
         * @see #popCadTool()
1328
         * @see #getCadTool()
1329
         */
1330
        public void setCadTool(CADTool cadTool) {
1331
                cadToolStack.clear();
1332
                pushCadTool(cadTool);
1333
                // askQuestion();
1334
        }
1335

    
1336
        /**
1337
         * <p>
1338
         * Removes all geometries selected in the associated <code>MapControl</code>.
1339
         */
1340
        public void delete() {
1341
                ILayerEdited aux = CADExtension.getEditionManager()
1342
                                .getActiveLayerEdited();
1343
                if (!(aux instanceof VectorialLayerEdited)) {
1344
                        return;
1345
                }
1346
                VectorialLayerEdited vle = (VectorialLayerEdited) aux;
1347
                FeatureStore featureStore = null;
1348
//                try {
1349
                        featureStore = ((FLyrVect) vle.getLayer()).getFeatureStore();
1350
//                } catch (ReadException e1) {
1351
//                        // TODO Auto-generated catch block
1352
//                        e1.printStackTrace();
1353
//                }
1354
                String description = PluginServices.getText(this, "remove_geometry");
1355
                DisposableIterator iterator = null;
1356
                try {
1357
                        featureStore.beginEditingGroup(description);
1358

    
1359
                        FeatureSelection selection = featureStore.createFeatureSelection();
1360
                        selection.select((FeatureSet) featureStore.getSelection());
1361
                        iterator = selection.iterator();
1362
                        while (iterator.hasNext()) {
1363
                                Feature feature = (Feature) iterator.next();
1364
                                featureStore.delete(feature);
1365
                        }
1366

    
1367
                        // int[] indexesToDel = new int[selection.cardinality()];
1368
                        // int j = 0;
1369
                        // for (int i = selection.nextSetBit(0); i >= 0; i = selection
1370
                        // .nextSetBit(i + 1)) {
1371
                        // indexesToDel[j++] = i;
1372
                        // // /vea.removeRow(i);
1373
                        // }
1374

    
1375
                        // ArrayList selectedRow = vle.getSelectedRow();
1376
                        //
1377
                        // int[] indexesToDel = new int[selectedRow.size()];
1378
                        // for (int i = 0;i < selectedRow.size(); i++) {
1379
                        // IRowEdited edRow = (IRowEdited) selectedRow.get(i);
1380
                        // indexesToDel[i] = vea.getInversedIndex(edRow.getIndex());
1381
                        // }
1382
                        //
1383
                        // for (int i = indexesToDel.length - 1; i >= 0; i--) {
1384
                        // vea.removeRow(indexesToDel[i], PluginServices.getText(this,
1385
                        // "deleted_feature"),EditionEvent.GRAPHIC);
1386
                        // }
1387
                        System.out.println("clear Selection");
1388
                        vle.clearSelection();
1389
                } catch (ReadException e) {
1390
                        NotificationManager.addError(e.getMessage(), e);
1391
                } catch (DataException e) {
1392
                        NotificationManager.addError(e.getMessage(), e);
1393
                } finally {
1394
                        if (iterator != null) {
1395
                                iterator.dispose();
1396
                        }
1397
                        try {
1398
                                featureStore.endEditingGroup();
1399
                        } catch (NeedEditingModeException e) {
1400
                                logger.error("Exception endEditingGroup", e);
1401
                        }
1402
                }
1403

    
1404
                /*
1405
                 * if (getCadTool() instanceof SelectionCADTool) { SelectionCADTool
1406
                 * selTool = (SelectionCADTool) getCadTool(); selTool.clearSelection(); }
1407
                 */
1408
                refreshEditedLayer();
1409
        }
1410

    
1411
        /**
1412
         * @see CADGrid#setAdjustGrid(boolean)
1413
         */
1414
        // public void setAdjustGrid(boolean b) {
1415
        // getGrid().setAdjustGrid(b);
1416
        // }
1417
        /**
1418
         * <p>
1419
         * Responds to actions of writing common key commands for all kind of CAD
1420
         * operations, enabling/disabling after the controls to manage the available
1421
         * information according the tool selected:
1422
         * <ul>
1423
         * <li><i>eliminar</i>: removes the geometries that are now selected.</li>
1424
         * <li><i>escape</i>: executes different actions according to the current
1425
         * CAD tool of the associated <code>MapControl</code>:
1426
         * <ul>
1427
         * <li>If the tool enabled is identified by <i>cadtooladapter</i>: empties
1428
         * the CAD tools stack, changing the current tool by a
1429
         * {@link SelectionCADTool SelectionCADTool}, which is identified by
1430
         * <i>_selection</i> and allows select features of the active vector layer
1431
         * of the associated <code>MapControl</code> instance. </li>
1432
         * <li>Otherwise, that means current associated <code>MapControl</code>
1433
         * instance isn't identified by "<i>cadtooladapter</i>", changes the
1434
         * enabled tool by the previous.</li>
1435
         * </ul>
1436
         * </li>
1437
         * </ul>
1438
         * </p>
1439
         *
1440
         * @param actionCommand
1441
         *            identifier of the key action command executed by the user
1442
         *
1443
         * @see SelectionCADTool
1444
         * @see MapControl#setPrevTool()
1445
         */
1446
        public void keyPressed(String actionCommand) {
1447
                if (CADExtension.getEditionManager().getActiveLayerEdited() == null) {
1448
                        return;
1449
                }
1450
                if (actionCommand.equals("eliminar")) {
1451
                        delete();
1452
                } else if (actionCommand.equals("escape")) {
1453
                        if (getMapControl().getCurrentTool().equals("cadtooladapter")) {
1454
                                CADTool ct = (CADTool) cadToolStack.peek();
1455
                                ct.end();
1456
                                cadToolStack.clear();
1457
                                SelectionCADTool selCad = new SelectionCADTool();
1458
                                selCad.init();
1459
                                VectorialLayerEdited vle = (VectorialLayerEdited) CADExtension
1460
                                                .getEditionManager().getActiveLayerEdited();
1461
                                try {
1462
                                        vle.clearSelection();
1463
                                } catch (DataException e) {
1464
                                        NotificationManager.addError(e.getMessage(), e);
1465
                                }
1466

    
1467
                                pushCadTool(selCad);
1468
                                // getVectorialAdapter().getSelection().clear();
1469

    
1470
                                refreshEditedLayer();
1471

    
1472
                                PluginServices.getMainFrame().setSelectedTool("_selection");
1473
                                // askQuestion();
1474
                        } else {
1475
                                getMapControl().setPrevTool();
1476
                        }
1477
                }
1478

    
1479
                PluginServices.getMainFrame().enableControls();
1480

    
1481
        }
1482

    
1483
        /**
1484
         * <p>
1485
         * Applies a lightweight repaint of the active layer being edited.
1486
         * </p>
1487
         *
1488
         * <p>
1489
         * All layers under it won't be drawn, only the upper one and whose are over
1490
         * that layer in the TOC.
1491
         * </p>
1492
         *
1493
         * @see MapControl#rePaintDirtyLayers()
1494
         */
1495
        public void refreshEditedLayer() {
1496
                ILayerEdited edLayer = CADExtension.getEditionManager()
1497
                                .getActiveLayerEdited();
1498
                if (edLayer != null) {
1499
                        getMapControl().rePaintDirtyLayers();
1500
                }
1501

    
1502
        }
1503

    
1504
        /**
1505
         * Gets the {@link CADGrid CADGrid} that can be drawn on the
1506
         * <code>ViewPort</code> of the associated <code>MapControl</code>.
1507
         *
1508
         * @return reference to the <i>grid</i> that can be applied on the
1509
         *         <code>ViewPort</code>
1510
         *
1511
         * @see #setGridVisibility(boolean)
1512
         */
1513
        // public CADGrid getGrid() {
1514
        // return cadgrid;
1515
        // }
1516
        /**
1517
         * Determines if is enabled or not the <i>orto</i> mode.
1518
         *
1519
         * @return <code>true</code> if is enabled the <i>orto</i> mode;
1520
         *         otherwise <code>false</code>
1521
         *
1522
         * @see #setOrtoMode(boolean)
1523
         */
1524
        public boolean isOrtoMode() {
1525
                return bOrtoMode;
1526
        }
1527

    
1528
        /**
1529
         * Enables / disables the <i>orto</i> mode.
1530
         *
1531
         * @param b
1532
         *            the desired value
1533
         *
1534
         * @see #isOrtoMode()
1535
         */
1536
        public void setOrtoMode(boolean b) {
1537
                bOrtoMode = b;
1538
        }
1539

    
1540
        /**
1541
         * Associates and stores the specified name with the specified
1542
         * {@link CADTool CADTool}.
1543
         *
1544
         * @param name
1545
         *            name of the tool
1546
         * @param c
1547
         *            CAD tool to interactuate editing the layers
1548
         *
1549
         * @see #getCADTools()
1550
         * @see #getCADTool(String)
1551
         */
1552
        public static void addCADTool(String name, CADTool c) {
1553
                namesCadTools.put(name, c);
1554

    
1555
        }
1556

    
1557
        /**
1558
         * Gets all CAD tools available to edit layers with this tool listener.
1559
         *
1560
         * @return CAD tools available to edit layers with this tool listener
1561
         *
1562
         * @see #addCADTool(String, CADTool)
1563
         * @see #getCADTool(String)
1564
         */
1565
        public static CADTool[] getCADTools() {
1566
                return (CADTool[]) CADToolAdapter.namesCadTools.values().toArray(
1567
                                new CADTool[0]);
1568
        }
1569

    
1570
        /**
1571
         * Returns the {@link CADTool CADTool} to which the specified name is
1572
         * mapped.
1573
         *
1574
         * @param text
1575
         *            name of the tool
1576
         * @return the CAD tool whose associated name is to be returned
1577
         *
1578
         * @see #addCADTool(String, CADTool)
1579
         * @see #getCADTools()
1580
         */
1581
        public CADTool getCADTool(String text) {
1582
                CADTool ct = (CADTool) namesCadTools.get(text);
1583
                return ct;
1584
        }
1585

    
1586
        /**
1587
         * Gets the object used to manage the edition of the layers of the
1588
         * associated <code>MapControl</code>.
1589
         *
1590
         * @see EditionManager
1591
         *
1592
         * @return object used to manage the edition of the layers
1593
         */
1594
        public EditionManager getEditionManager() {
1595
                return editionManager;
1596
        }
1597

    
1598
        /**
1599
         * <p>
1600
         * Initializes the <i>flatness</i> with the defined in preferences.
1601
         * </p>
1602
         *
1603
         * <p>
1604
         * The <i>flatness</i> is the maximum tolerance used to approximate curved
1605
         * lines in a <i>shape</i> by polylines.
1606
         * </p>
1607
         * <p>
1608
         * The shapes doesn't support primitive like arcs neither other curved lines
1609
         * to draw their geometries, then for drawing any kind of this geometries
1610
         * the curved lines are drawn approximately by a polyline. And for doing
1611
         * more realistic that curves, is used the <i>flatness</i> parameter, that
1612
         * indicates that the difference between each arc and the straight segment
1613
         * that approximates it must be in the worse case, like the <i>flatness</i>.
1614
         * </p>
1615
         *
1616
         * @see FConverter#FLATNESS
1617
         */
1618
        public void initializeFlatness() {
1619
                if (!flatnessInitialized) {
1620
                        flatnessInitialized = true;
1621
                        Preferences prefs = Preferences.userRoot().node("cadtooladapter");
1622
                        double flatness = prefs.getDouble("flatness", geomManager.getFlatness());
1623
                        geomManager.setFlatness(flatness);
1624
                }
1625
        }
1626

    
1627
        /**
1628
         * <p>
1629
         * Updates the grid on the <code>ViewPort</code> of the associated
1630
         * <code>MapControl</code> object according the values in the
1631
         * {@link com.iver.cit.gvsig.gui.cad.CADToolAdapter.prefs.Preferences com.iver.cit.gvsig.gui.cad.CADToolAdapter.prefs.Preferences}.
1632
         * </p>
1633
         *
1634
         * <p>
1635
         * The preferences are:
1636
         * <ul>
1637
         * <li>Show/hide the grid.</li>
1638
         * <li>Adjust or not the grid.</li>
1639
         * <li>Horizontal ( X ) line separation.</li>
1640
         * <li>Vertical ( Y ) line separation.</li>
1641
         * </ul>
1642
         * </p>
1643
         */
1644
        // public void initializeGrid(){
1645
        // boolean showGrid =
1646
        // prefs.getBoolean("grid.showgrid",getGrid().isShowGrid());
1647
        // boolean adjustGrid =
1648
        // prefs.getBoolean("grid.adjustgrid",getGrid().isAdjustGrid());
1649
        //
1650
        // double dx = prefs.getDouble("grid.distancex",getGrid().getGridSizeX());
1651
        // double dy = prefs.getDouble("grid.distancey",getGrid().getGridSizeY());
1652
        //
1653
        // setGridVisibility(showGrid);
1654
        // setAdjustGrid(adjustGrid);
1655
        // getGrid().setGridSizeX(dx);
1656
        // getGrid().setGridSizeY(dy);
1657
        // }
1658
        /**
1659
         * <p>
1660
         * Returns the type of the shape that's the current active and vector layer
1661
         * being edited.
1662
         * </p>
1663
         *
1664
         * @see FLyrVect#getShapeType()
1665
         *
1666
         * @return type of the shape that's the current active and vector layer
1667
         *         being edited
1668
         */
1669
        public int getActiveLayerType() {
1670
                int type = Geometry.TYPES.GEOMETRY;
1671
                try {
1672
                        type = ((FLyrVect) CADExtension.getEditionManager()
1673
                                        .getActiveLayerEdited().getLayer()).getShapeType();
1674
                } catch (ReadException e) {
1675
                        NotificationManager.addError(e);
1676
                }
1677
                return type;
1678
        }
1679

    
1680
}