Statistics
| Revision:

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

History | View | Annotate | Download (49.5 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.View;
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.fmap.dal.feature.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.Converter;
41
import org.gvsig.fmap.geom.util.UtilFunctions;
42
import org.gvsig.fmap.mapcontext.MapContext;
43
import org.gvsig.fmap.mapcontext.ViewPort;
44
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
45
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
46
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbologyFactory;
47
import org.gvsig.fmap.mapcontrol.MapControl;
48
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
49
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
50
import org.gvsig.fmap.mapcontrol.tools.Listeners.ToolListener;
51
import org.gvsig.utils.console.JConsole;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

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

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

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

    
133
        /**
134
         * Reference to the object used to manage the edition of the layers of the
135
         * associated <code>MapControl</code>.
136
         *
137
         * @see EditionManager
138
         * @see #getEditionManager()
139
         */
140
        private EditionManager editionManager = new EditionManager();
141

    
142
        /**
143
         * Identifies that the data are absolute coordinates of the new point from
144
         * the (0, 0) position.
145
         */
146
        public static final int ABSOLUTE = 0;
147

    
148
        /**
149
         * Equivalent to {@link CADToolAdapter#ABSOLUTE CADToolAdapter#ABSOLUTE}.
150
         */
151
        public static final int RELATIVE_SCP = 1;
152

    
153
        /**
154
         * Identifies that the data are relative distances of the new point from the
155
         * previous introduced.
156
         */
157
        public static final int RELATIVE_SCU = 2;
158

    
159
        /**
160
         * Identifies that the data are relative polar distances (longitude of the
161
         * line and angle given in degrees) of the new point from the previous
162
         * introduced.
163
         */
164
        public static final int POLAR_SCP = 3;
165

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

    
173
        /**
174
         * Stores the 2D map coordinates of the last point added.
175
         */
176
        private double[] previousPoint = null;
177

    
178
        /**
179
         * <i>Stack with CAD tools.</i>
180
         *
181
         * <i>For each CAD tool we use, the last item added in this stack will
182
         * display a different icon according to the current operation and its
183
         * status.</i>
184
         */
185
        private Stack cadToolStack = new Stack();
186

    
187
        /**
188
         * X coordinate of the last dragging or moving mouse event.
189
         */
190
        private int lastX;
191

    
192
        /**
193
         * Y coordinate of the last dragging or moving mouse event.
194
         */
195
        private int lastY;
196

    
197
        /**
198
         * Unused attribute.
199
         */
200
        private ISymbol symbol = SymbologyFactory.createDefaultSymbolByShapeType(
201
                        Geometry.TYPES.POINT, Color.RED);
202

    
203
        /**
204
         * Represents the cursor's point selected in <i>map coordinates</i>.
205
         *
206
         * @see MapControl#toMapPoint
207
         */
208
        private Point2D mapAdjustedPoint;
209

    
210
        /**
211
         * Kind of geometry drawn to identify the kind of control point selected by
212
         * the cursor's mouse.
213
         */
214
        // private ISnapper usedSnap = null;
215
        /**
216
         * Determines if has displayed at the edition console, the question for the
217
         * operations that can do the user with the current CAD tool, in its current
218
         * state.
219
         */
220
        private boolean questionAsked = false;
221

    
222
        /**
223
         * Represents the cursor's point selected in <i>screen coordinates</i>.
224
         *
225
         * @see ViewPort#fromMapPoint(Point2D)
226
         */
227
        private Point2D adjustedPoint;
228

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

    
262
        /**
263
         * A light yellow color for the tool tip text box associated to the point
264
         * indicated by the mouse's cursor.
265
         */
266
        private Color theTipColor = new Color(255, 255, 155);
267

    
268
        /**
269
         * Last question asked to the user in the CAD console.
270
         */
271
        private Object lastQuestion;
272

    
273
        /**
274
         * Maximum tolerance in the approximation of a curved line by a polyline.
275
         *
276
         * @see #initializeFlatness()
277
         */
278
        private static boolean flatnessInitialized = false;
279

    
280
        /**
281
         * Edition preferences.
282
         */
283
        private static Preferences prefs = Preferences.userRoot().node(
284
                        "cadtooladapter");
285

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

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

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

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

    
356
        }
357

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

    
372
                if (adjustedPoint != null) {
373
                        Point2D p = null;
374
                        if (mapAdjustedPoint != null) {
375
                                p = mapAdjustedPoint;
376
                        } else {
377
                                p = getMapControl().getViewPort().toMapPoint(adjustedPoint);
378
                        }
379

    
380
                        ((CADTool) cadToolStack.peek())
381
                                        .drawOperation(g, p.getX(), p.getY());
382
                }
383
                // drawCursor(g);
384
                // getGrid().drawGrid(g);
385
        }
386

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

    
413
                                if (mapAdjustedPoint != null) {
414
                                        p = mapAdjustedPoint;
415
                                } else {
416
                                        p = vp.toMapPoint(adjustedPoint);
417
                                }
418
                                ct.endTransition(p.getX(), p.getY(), e);
419
                                previousPoint = new double[] { p.getX(), p.getY() };
420
                        }
421
                }
422
        }
423

    
424
        /*
425
         * (non-Javadoc)
426
         *
427
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseEntered(java.awt.event.MouseEvent)
428
         */
429
        public void mouseEntered(MouseEvent e) throws BehaviorException {
430
                clearMouseImage();
431
        }
432

    
433
        /*
434
         * (non-Javadoc)
435
         *
436
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseExited(java.awt.event.MouseEvent)
437
         */
438
        public void mouseExited(MouseEvent e) throws BehaviorException {
439
        }
440

    
441
        /**
442
         * Selects the vertex of a geometry at the point selected on the
443
         * <code>MapControl</code> by pressing the first mouse's button.
444
         *
445
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mousePressed(java.awt.event.MouseEvent)
446
         */
447
        public void mousePressed(MouseEvent e) throws BehaviorException {
448
                if (e.getButton() == MouseEvent.BUTTON1) {
449
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
450
                        Point2D p;
451

    
452
                        if (mapAdjustedPoint != null) {
453
                                p = mapAdjustedPoint;
454
                        } else {
455
                                p = vp.toMapPoint(adjustedPoint);
456
                        }
457
                        transition(new double[] { p.getX(), p.getY() }, e, ABSOLUTE);
458
                }
459
        }
460

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

    
577
        /*
578
         * (non-Javadoc)
579
         *
580
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseReleased(java.awt.event.MouseEvent)
581
         */
582
        public void mouseReleased(MouseEvent e) throws BehaviorException {
583
                getMapControl().repaint();
584
        }
585

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

    
598
        /*
599
         * (non-Javadoc)
600
         *
601
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseMoved(java.awt.event.MouseEvent)
602
         */
603
        public void mouseMoved(MouseEvent e) throws BehaviorException {
604

    
605
                lastX = e.getX();
606
                lastY = e.getY();
607
                adjustedPoint = e.getPoint();
608
                // calculateSnapPoint(e.getPoint());
609

    
610
                showCoords(e.getPoint());
611

    
612
                getMapControl().repaint();
613
        }
614

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

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

    
653
                if (mF != null) {
654
                        mF.getStatusBar().setMessage(
655
                                        "units",
656
                                        PluginServices
657
                                                        .getText(this, MapContext.getDistanceNames()[vp
658
                                                                        .getDistanceUnits()]));
659
                        mF.getStatusBar().setControlValue("scale",
660
                                        String.valueOf(mapControl.getMapContext().getScaleView()));
661
                        mF.getStatusBar().setMessage("projection", iProj.getAbrev());
662

    
663
                        String[] coords = sbl.getCoords(p);
664
                        mF.getStatusBar().setMessage("x", axisText[0] + coords[0]);
665
                        mF.getStatusBar().setMessage("y", axisText[1] + coords[1]);
666
                }
667
        }
668

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

    
679
                getMapControl().setCursor(transparentCursor);
680
        }
681

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

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

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

    
924
                        double[] values = null;
925

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

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

    
957
                for (int i = 0; i < desc.length; i++) {
958
                        if (desc[i] != null) {
959
                                CADExtension
960
                                                .addMenuEntry(PluginServices.getText(this, desc[i]));// ,
961
                                // labels[i]);
962
                        }
963
                }
964

    
965
        }
966

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

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

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

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

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

    
1143
                                if (window instanceof View) {
1144
                                        ((View) window).getConsolePanel().addText(
1145
                                                        "\n"
1146
                                                                        + PluginServices.getText(this,
1147
                                                                                        "incorrect_option") + " : "
1148
                                                                        + option, JConsole.ERROR);
1149
                                }
1150
                        }
1151
                        askQuestion();
1152
                }
1153
                configureMenu();
1154
                PluginServices.getMainFrame().enableControls();
1155
        }
1156

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

    
1208
                        /**
1209
                         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#cancelDrawing()
1210
                         */
1211
                        public boolean cancelDrawing() {
1212
                                return false;
1213
                        }
1214
                };
1215
        }
1216

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

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

    
1267
        /**
1268
         * Removes the peek of the CAD tool stack.
1269
         *
1270
         * @see #pushCadTool(CADTool)
1271
         * @see #getCadTool()
1272
         * @see #setCadTool(CADTool)
1273
         */
1274
        public void popCadTool() {
1275
                cadToolStack.pop();
1276
        }
1277

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

    
1313
        }
1314

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

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

    
1354
                        FeatureSelection selection = featureStore.createFeatureSelection();
1355
                        selection.select((FeatureSet) featureStore.getSelection());
1356
                        iterator = selection.iterator();
1357
                        while (iterator.hasNext()) {
1358
                                Feature feature = (Feature) iterator.next();
1359
                                featureStore.delete(feature);
1360
                        }
1361

    
1362
                        // int[] indexesToDel = new int[selection.cardinality()];
1363
                        // int j = 0;
1364
                        // for (int i = selection.nextSetBit(0); i >= 0; i = selection
1365
                        // .nextSetBit(i + 1)) {
1366
                        // indexesToDel[j++] = i;
1367
                        // // /vea.removeRow(i);
1368
                        // }
1369

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

    
1399
                /*
1400
                 * if (getCadTool() instanceof SelectionCADTool) { SelectionCADTool
1401
                 * selTool = (SelectionCADTool) getCadTool(); selTool.clearSelection(); }
1402
                 */
1403
                refreshEditedLayer();
1404
        }
1405

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

    
1462
                                pushCadTool(selCad);
1463
                                // getVectorialAdapter().getSelection().clear();
1464

    
1465
                                refreshEditedLayer();
1466

    
1467
                                PluginServices.getMainFrame().setSelectedTool("_selection");
1468
                                // askQuestion();
1469
                        } else {
1470
                                getMapControl().setPrevTool();
1471
                        }
1472
                }
1473

    
1474
                PluginServices.getMainFrame().enableControls();
1475

    
1476
        }
1477

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

    
1497
        }
1498

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

    
1523
        /**
1524
         * Enables / disables the <i>orto</i> mode.
1525
         *
1526
         * @param b
1527
         *            the desired value
1528
         *
1529
         * @see #isOrtoMode()
1530
         */
1531
        public void setOrtoMode(boolean b) {
1532
                bOrtoMode = b;
1533
        }
1534

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

    
1550
        }
1551

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

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

    
1581
        /**
1582
         * Gets the object used to manage the edition of the layers of the
1583
         * associated <code>MapControl</code>.
1584
         *
1585
         * @see EditionManager
1586
         *
1587
         * @return object used to manage the edition of the layers
1588
         */
1589
        public EditionManager getEditionManager() {
1590
                return editionManager;
1591
        }
1592

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

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

    
1675
}