Statistics
| Revision:

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

History | View | Annotate | Download (50 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.slf4j.Logger;
21
import org.slf4j.LoggerFactory;
22

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
360
        }
361

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

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

    
384
                        //If the stack is empty, return
385
                        if (cadToolStack.isEmpty()){
386
                            return;
387
                        }
388
                        
389
                        if (((CADTool) cadToolStack.peek()).getVLE() == null){
390
                                return;
391
                        }
392
                        
393
                        ((CADTool) cadToolStack.peek())
394
                                        .drawOperation(mapControlDrawer, p.getX(), p.getY());
395
                }
396
        }
397

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

    
424
                                if (mapAdjustedPoint != null) {
425
                                        p = mapAdjustedPoint;
426
                                } else {
427
                                        p = vp.toMapPoint(adjustedPoint);
428
                                }
429
                                ct.endTransition(p.getX(), p.getY(), e);
430
                                previousPoint = new double[] { p.getX(), p.getY() };
431
                        }
432
                }
433
        }
434

    
435
        /*
436
         * (non-Javadoc)
437
         *
438
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseEntered(java.awt.event.MouseEvent)
439
         */
440
        public void mouseEntered(MouseEvent e) throws BehaviorException {
441
                clearMouseImage();
442
        }
443

    
444
        /*
445
         * (non-Javadoc)
446
         *
447
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseExited(java.awt.event.MouseEvent)
448
         */
449
        public void mouseExited(MouseEvent e) throws BehaviorException {
450
        }
451

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

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

    
588
        /*
589
         * (non-Javadoc)
590
         *
591
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseReleased(java.awt.event.MouseEvent)
592
         */
593
        public void mouseReleased(MouseEvent e) throws BehaviorException {
594
                getMapControl().repaint();
595
        }
596

    
597
        /*
598
         * (non-Javadoc)
599
         *
600
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseDragged(java.awt.event.MouseEvent)
601
         */
602
        public void mouseDragged(MouseEvent e) throws BehaviorException {
603
                lastX = e.getX();
604
                lastY = e.getY();
605
                adjustedPoint = e.getPoint();
606
                // calculateSnapPoint(e.getPoint());
607
        }
608

    
609
        /*
610
         * (non-Javadoc)
611
         *
612
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseMoved(java.awt.event.MouseEvent)
613
         */
614
        public void mouseMoved(MouseEvent e) throws BehaviorException {
615

    
616
                lastX = e.getX();
617
                lastY = e.getY();
618
                adjustedPoint = e.getPoint();
619
//                 calculateSnapPoint(e.getPoint());
620

    
621
                showCoords(e.getPoint());
622

    
623
                getMapControl().repaint();
624
        }
625

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

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

    
664
                if (mF != null) {
665
                        mF.getStatusBar().setMessage(
666
                                        "units",
667
                                        PluginServices
668
                                                        .getText(this, MapContext.getDistanceNames()[vp
669
                                                                        .getDistanceUnits()]));
670
                        mF.getStatusBar().setControlValue("scale",
671
                                        String.valueOf(mapControl.getMapContext().getScaleView()));
672
                        mF.getStatusBar().setMessage("projection", iProj.getAbrev());
673

    
674
                        String[] coords = sbl.getCoords(p);
675
                        mF.getStatusBar().setMessage("x", axisText[0] + coords[0]);
676
                        mF.getStatusBar().setMessage("y", axisText[1] + coords[1]);
677
                }
678
        }
679

    
680
        /**
681
         * Hides the mouse's cursor.
682
         */
683
        private void clearMouseImage() {
684
                int[] pixels = new int[16 * 16];
685
                Image image = Toolkit.getDefaultToolkit().createImage(
686
                                new MemoryImageSource(16, 16, pixels, 0, 16));
687
                Cursor transparentCursor = Toolkit.getDefaultToolkit()
688
                                .createCustomCursor(image, new Point(0, 0), "invisiblecursor");
689

    
690
                getMapControl().setCursor(transparentCursor);
691
        }
692

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

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

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

    
935
                        double[] values = null;
936

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

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

    
968
                for (int i = 0; i < desc.length; i++) {
969
                        if (desc[i] != null) {
970
                                CADExtension
971
                                                .addMenuEntry(PluginServices.getText(this, desc[i]));// ,
972
                                // labels[i]);
973
                        }
974
                }
975

    
976
        }
977

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

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

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

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

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

    
1154
                                if (window instanceof DefaultViewPanel) {
1155
                                        ((DefaultViewPanel) window).getConsolePanel().addText(
1156
                                                        "\n"
1157
                                                                        + PluginServices.getText(this,
1158
                                                                                        "incorrect_option") + " : "
1159
                                                                        + option, JConsole.ERROR);
1160
                                }
1161
                        }
1162
                        askQuestion();
1163
                }
1164
                configureMenu();
1165
                PluginServices.getMainFrame().enableControls();
1166
        }
1167

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

    
1219
                        /**
1220
                         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#cancelDrawing()
1221
                         */
1222
                        public boolean cancelDrawing() {
1223
                                return false;
1224
                        }
1225
                };
1226
        }
1227

    
1228
        /**
1229
         * Returns the {@link CADTool CADTool} at the top of the stack without
1230
         * removing it from the CAD tool stack.
1231
         *
1232
         * @return the {@link CADTool CADTool} at the top of the stack
1233
         *
1234
         * @see #pushCadTool(CADTool)
1235
         * @see #popCadTool()
1236
         * @see #setCadTool(CADTool)
1237
         */
1238
        public CADTool getCadTool() {
1239
                return (CADTool) cadToolStack.peek();
1240
        }
1241

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

    
1278
        /**
1279
         * Removes the peek of the CAD tool stack.
1280
         *
1281
         * @see #pushCadTool(CADTool)
1282
         * @see #getCadTool()
1283
         * @see #setCadTool(CADTool)
1284
         */
1285
        public void popCadTool() {
1286
                cadToolStack.pop();
1287
        }
1288

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

    
1324
        }
1325

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

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

    
1365
                        FeatureSelection selection = featureStore.createFeatureSelection();
1366
                        selection.select((FeatureSet) featureStore.getSelection());
1367
                        iterator = selection.iterator();
1368
                        while (iterator.hasNext()) {
1369
                                Feature feature = (Feature) iterator.next();
1370
                                featureStore.delete(feature);
1371
                        }
1372

    
1373
                        // int[] indexesToDel = new int[selection.cardinality()];
1374
                        // int j = 0;
1375
                        // for (int i = selection.nextSetBit(0); i >= 0; i = selection
1376
                        // .nextSetBit(i + 1)) {
1377
                        // indexesToDel[j++] = i;
1378
                        // // /vea.removeRow(i);
1379
                        // }
1380

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

    
1410
                /*
1411
                 * if (getCadTool() instanceof SelectionCADTool) { SelectionCADTool
1412
                 * selTool = (SelectionCADTool) getCadTool(); selTool.clearSelection(); }
1413
                 */
1414
                refreshEditedLayer();
1415
        }
1416

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

    
1473
                                pushCadTool(selCad);
1474
                                // getVectorialAdapter().getSelection().clear();
1475

    
1476
                                refreshEditedLayer();
1477

    
1478
                                PluginServices.getMainFrame().setSelectedTool("_selection");
1479
                                // askQuestion();
1480
                        } else {
1481
                                getMapControl().setPrevTool();
1482
                        }
1483
                }
1484

    
1485
                PluginServices.getMainFrame().enableControls();
1486

    
1487
        }
1488

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

    
1508
        }
1509

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

    
1534
        /**
1535
         * Enables / disables the <i>orto</i> mode.
1536
         *
1537
         * @param b
1538
         *            the desired value
1539
         *
1540
         * @see #isOrtoMode()
1541
         */
1542
        public void setOrtoMode(boolean b) {
1543
                bOrtoMode = b;
1544
        }
1545

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

    
1561
        }
1562

    
1563
        /**
1564
         * Gets all CAD tools available to edit layers with this tool listener.
1565
         *
1566
         * @return CAD tools available to edit layers with this tool listener
1567
         *
1568
         * @see #addCADTool(String, CADTool)
1569
         * @see #getCADTool(String)
1570
         */
1571
        public static CADTool[] getCADTools() {
1572
                return (CADTool[]) CADToolAdapter.namesCadTools.values().toArray(
1573
                                new CADTool[0]);
1574
        }
1575

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

    
1592
        /**
1593
         * Gets the object used to manage the edition of the layers of the
1594
         * associated <code>MapControl</code>.
1595
         *
1596
         * @see EditionManager
1597
         *
1598
         * @return object used to manage the edition of the layers
1599
         */
1600
        public EditionManager getEditionManager() {
1601
                return editionManager;
1602
        }
1603

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

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

    
1686
}