Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / extCAD / src / com / iver / cit / gvsig / gui / cad / CADToolAdapter.java @ 20100

History | View | Annotate | Download (45.3 KB)

1
package com.iver.cit.gvsig.gui.cad;
2

    
3
import java.awt.Color;
4
import java.awt.Cursor;
5
import java.awt.FontMetrics;
6
import java.awt.Graphics;
7
import java.awt.Graphics2D;
8
import java.awt.Image;
9
import java.awt.Point;
10
import java.awt.Toolkit;
11
import java.awt.event.InputEvent;
12
import java.awt.event.MouseEvent;
13
import java.awt.event.MouseWheelEvent;
14
import java.awt.geom.Point2D;
15
import java.awt.geom.Rectangle2D;
16
import java.awt.image.MemoryImageSource;
17
import java.io.IOException;
18
import java.text.NumberFormat;
19
import java.util.ArrayList;
20
import java.util.HashMap;
21
import java.util.Stack;
22
import java.util.prefs.Preferences;
23

    
24
import org.cresques.cts.IProjection;
25

    
26
import com.iver.andami.PluginServices;
27
import com.iver.andami.messages.NotificationManager;
28
import com.iver.andami.ui.mdiFrame.MainFrame;
29
import com.iver.andami.ui.mdiManager.IWindow;
30
import com.iver.cit.gvsig.CADExtension;
31
import com.iver.cit.gvsig.EditionManager;
32
import com.iver.cit.gvsig.fmap.DriverException;
33
import com.iver.cit.gvsig.fmap.MapContext;
34
import com.iver.cit.gvsig.fmap.MapControl;
35
import com.iver.cit.gvsig.fmap.ViewPort;
36
import com.iver.cit.gvsig.fmap.core.FShape;
37
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
38
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
39
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
40
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
41
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
42
import com.iver.cit.gvsig.fmap.edition.UtilFunctions;
43
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
44
import com.iver.cit.gvsig.fmap.layers.FBitSet;
45
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
46
import com.iver.cit.gvsig.fmap.layers.SpatialCache;
47
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
48
import com.iver.cit.gvsig.fmap.tools.Behavior.Behavior;
49
import com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener;
50
import com.iver.cit.gvsig.gui.cad.snapping.FinalPointSnapper;
51
import com.iver.cit.gvsig.gui.cad.snapping.ISnapper;
52
import com.iver.cit.gvsig.gui.cad.snapping.ISnapperRaster;
53
import com.iver.cit.gvsig.gui.cad.snapping.ISnapperVectorial;
54
import com.iver.cit.gvsig.gui.cad.snapping.NearestPointSnapper;
55
import com.iver.cit.gvsig.gui.cad.snapping.PixelSnapper;
56
import com.iver.cit.gvsig.gui.cad.snapping.SnappingVisitor;
57
import com.iver.cit.gvsig.gui.cad.tools.SelectionCADTool;
58
import com.iver.cit.gvsig.layers.ILayerEdited;
59
import com.iver.cit.gvsig.layers.VectorialLayerEdited;
60
import com.iver.cit.gvsig.project.documents.view.gui.View;
61
import com.iver.utiles.console.JConsole;
62
import com.vividsolutions.jts.geom.Envelope;
63

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

    
123
        /**
124
         * Reference to the object used to manage the edition of the layers of the associated <code>MapControl</code>.
125
         * 
126
         * @see EditionManager
127
         * @see #getEditionManager()
128
         */
129
        private EditionManager editionManager = new EditionManager();
130

    
131
        /**
132
         * Identifies that the data are absolute coordinates of the new point from the (0, 0) position.
133
         */
134
        public static final int ABSOLUTE = 0;
135

    
136
        /**
137
         * Equivalent to {@link CADToolAdapter#ABSOLUTE CADToolAdapter#ABSOLUTE}.
138
         */
139
        public static final int RELATIVE_SCP = 1;
140

    
141
        /**
142
         * Identifies that the data are relative distances of the new point from the previous introduced.
143
         */
144
        public static final int RELATIVE_SCU = 2;
145

    
146
        /**
147
         * Identifies that the data are relative polar distances (longitude of the line and angle given in degrees)
148
         *  of the new point from the previous introduced.
149
         */
150
        public static final int POLAR_SCP = 3;
151

    
152
        /**
153
         * Identifies that the data are relative polar distances (longitude of the line and angle given in radians)
154
         *  of the new point from the previous introduced.
155
         */
156
        public static final int POLAR_SCU = 4;
157

    
158
        /**
159
         * Stores the 2D map coordinates of the last point added.
160
         */
161
        private double[] previousPoint = null;
162

    
163
        /**
164
         * <i>Stack with CAD tools.</i>
165
         * 
166
         * <i>For each CAD tool we use, the last item added in this stack will
167
         *  display a different icon according to the current operation and its status.</i> 
168
         */
169
        private Stack cadToolStack = new Stack();
170

    
171
        /**
172
         * X coordinate of the last dragging or moving mouse event.
173
         */
174
        private int lastX;
175

    
176
        /**
177
         * Y coordinate of the last dragging or moving mouse event.
178
         */
179
        private int lastY;
180

    
181
        /**
182
         * Unused attribute.
183
         */
184
        private FSymbol symbol = new FSymbol(FConstant.SYMBOL_TYPE_POINT, Color.RED);
185

    
186
        /**
187
         * Represents the cursor's point selected in <i>map coordinates</i>.
188
         * 
189
         * @see MapControl#toMapPoint
190
         */
191
        private Point2D mapAdjustedPoint;
192

    
193
        /**
194
         * Kind of geometry drawn to identify the kind of control point selected by the cursor's mouse.
195
         */
196
        private ISnapper usedSnap = null;
197

    
198
        /**
199
         * Kind of geometry drawn to identify the kind of control point selected by the cursor's mouse.
200
         */
201
        private boolean questionAsked = false;
202

    
203
        /**
204
         * Represents the cursor's point selected in <i>screen coordinates</i>.
205
         *
206
         * @see ViewPort#fromMapPoint(Point2D)
207
         */
208
        private Point2D adjustedPoint;
209

    
210
        /**
211
         * Determines if the snap tools are enabled or disabled.
212
         * 
213
         * @see #isRefentEnabled()
214
         * @see #setRefentEnabled(boolean)
215
         */
216
        private boolean bRefent = true;
217

    
218
        /**
219
         * <p>Determines if the position of the snap of the mouse's cursor on the <code>MapControl</code>
220
         * is within the area around a control point of a geometry.</p>
221
         * 
222
         * <p>The area is calculated as a circle centered at the control point and with radius the pixels tolerance
223
         *  defined in the preferences.</p>
224
         */
225
        private boolean bForceCoord = false;
226

    
227
        /**
228
         * <p>Determines if the position of the snap of the mouse's cursor on the <code>MapControl</code>
229
         * is within the area around a control point of a geometry.</p>
230
         * 
231
         * <p>The area is calculated as a circle centered at the control point and with radius the pixels tolerance
232
         *  defined in the preferences.</p>
233
         */
234
        private CADGrid cadgrid = new CADGrid();
235

    
236
        /**
237
         * Determines is is enabled or not the <i>Orto</i> mode.
238
         */
239
        private boolean bOrtoMode;
240

    
241
        /**
242
         * A light yellow color for the tool tip text box associated to the point indicated by the mouse's cursor.
243
         */
244
        private Color theTipColor = new Color(255, 255, 155);
245

    
246
        /**
247
         * Maximum tolerance in the approximation of a curved line by a polyline.
248
         * 
249
         * @see #initializeFlatness()
250
         */
251
        private static boolean flatnessInitialized=false;
252

    
253
        /**
254
         * Edition preferences.
255
         */
256
        private static Preferences prefs = Preferences.userRoot().node( "cadtooladapter" );
257

    
258
        /**
259
         * <p>Draws the selected geometries to edit. And, if the <i>snapping</i> is enabled,
260
         *  draws also its effect over them.</p>
261
         *
262
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#paintComponent(java.awt.Graphics)
263
         */
264
        public void paintComponent(Graphics g) {
265
                super.paintComponent(g);
266
                if (CADExtension.getCADToolAdapter()!=this)
267
                        return;
268

    
269
                if (adjustedPoint != null) {
270
                        Point2D p = null;
271
                        if (mapAdjustedPoint != null) {
272
                                p = mapAdjustedPoint;
273
                        } else {
274
                                p = getMapControl().getViewPort().toMapPoint(adjustedPoint);
275
                        }
276

    
277
                        ((CADTool) cadToolStack.peek())
278
                                        .drawOperation(g, p.getX(), p.getY());
279
                }
280
                drawCursor(g);
281
                getGrid().drawGrid(g);
282
        }
283

    
284
        /**
285
         * Displays a popup with edition options clicking the third button of the mouse.
286
         * 
287
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseClicked(java.awt.event.MouseEvent)
288
         * @see CADExtension#showPopup(MouseEvent)
289
         */
290
        public void mouseClicked(MouseEvent e) throws BehaviorException {
291
                if (e.getButton() == MouseEvent.BUTTON3) {
292
                        CADExtension.showPopup(e);
293
                }
294
        }
295

    
296
        /*
297
         * (non-Javadoc)
298
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseEntered(java.awt.event.MouseEvent)
299
         */
300
        public void mouseEntered(MouseEvent e) throws BehaviorException {
301
                clearMouseImage();
302
        }
303

    
304
        /*
305
         * (non-Javadoc)
306
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseExited(java.awt.event.MouseEvent)
307
         */
308
        public void mouseExited(MouseEvent e) throws BehaviorException {
309
        }
310

    
311
        /**
312
         * Selects the vertex of a geometry at the point selected on the <code>MapControl</code> 
313
         * by pressing the first mouse's button.
314
         * 
315
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mousePressed(java.awt.event.MouseEvent)
316
         */
317
        public void mousePressed(MouseEvent e) throws BehaviorException {
318
                if (e.getButton() == MouseEvent.BUTTON1) {
319
                        ViewPort vp = getMapControl().getMapContext().getViewPort();
320
                        Point2D p;
321

    
322
                        if (mapAdjustedPoint != null) {
323
                                p = mapAdjustedPoint;
324
                        } else {
325
                                p = vp.toMapPoint(adjustedPoint);
326
                        }
327
                        transition(new double[] { p.getX(), p.getY() }, e, ABSOLUTE);
328
                }
329
        }
330

    
331
        /**
332
         * <p>Adjusts the <code>point</code> to the grid if its enabled, and 
333
         *  sets <code>mapHandlerAdjustedPoint</code> with that new value.</p>
334
         * 
335
         * <p>The value returned is the distance between those points: the original and
336
         *  the adjusted one.</p>
337
         *
338
         * @param point point to adjust
339
         * @param mapHandlerAdjustedPoint <code>point</code> adjusted
340
         *
341
         * @return distance from <code>point</code> to the adjusted one. If there is no
342
         *  adjustment, returns <code>Double.MAX_VALUE</code>.
343
         */
344
        private double adjustToHandler(Point2D point,
345
                        Point2D mapHandlerAdjustedPoint) {
346

    
347
                if (!isRefentEnabled())
348
                        return Double.MAX_VALUE;
349

    
350
                ILayerEdited aux = CADExtension.getEditionManager().getActiveLayerEdited();
351
                if (!(aux instanceof VectorialLayerEdited))
352
                        return Double.MAX_VALUE;
353
                VectorialLayerEdited vle = (VectorialLayerEdited) aux;
354

    
355
                ArrayList snappers = vle.getSnappers();
356
                ArrayList layersToSnap = vle.getLayersToSnap();
357

    
358

    
359
                ViewPort vp = getMapControl().getViewPort();
360

    
361
                // TODO: PROVISIONAL. PONER ALGO COMO ESTO EN UN CUADRO DE DIALOGO
362
                // DE CONFIGURACI?N DEL SNAPPING
363
                FinalPointSnapper defaultSnap = new FinalPointSnapper();
364
                NearestPointSnapper nearestSnap = new NearestPointSnapper();
365
                // PixelSnapper pixSnap = new PixelSnapper();
366
                snappers.clear();
367
                snappers.add(defaultSnap);
368
                snappers.add(nearestSnap);
369
                // snappers.add(pixSnap);
370

    
371
                double mapTolerance = vp.toMapDistance(SelectionCADTool.tolerance);
372
                double minDist = mapTolerance;
373
//                double rw = getMapControl().getViewPort().toMapDistance(5);
374
                Point2D mapPoint = point;
375
                Rectangle2D r = new Rectangle2D.Double(mapPoint.getX() - mapTolerance / 2,
376
                                mapPoint.getY() - mapTolerance / 2, mapTolerance, mapTolerance);
377

    
378
                Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
379

    
380
                usedSnap = null;
381
                Point2D lastPoint = null;
382
                if (previousPoint != null)
383
                {
384
                        lastPoint = new Point2D.Double(previousPoint[0], previousPoint[1]);
385
                }
386
                for (int j = 0; j < layersToSnap.size(); j++)
387
                {
388
                        FLyrVect lyrVect = (FLyrVect) layersToSnap.get(j);
389
                        SpatialCache cache = lyrVect.getSpatialCache();
390
                        if (lyrVect.isVisible())
391
                        {
392
                                // La lista de snappers est? siempre ordenada por prioridad. Los de mayor
393
                                // prioridad est?n primero.
394
                                for (int i = 0; i < snappers.size(); i++)
395
                                {
396
                                        ISnapper theSnapper = (ISnapper) snappers.get(i);
397

    
398
                                        if (usedSnap != null)
399
                                        {
400
                                                // Si ya tenemos un snap y es de alta prioridad, cogemos ese. (A no ser que en otra capa encontremos un snapper mejor)
401
                                                if (theSnapper.getPriority() < usedSnap.getPriority())
402
                                                        break;
403
                                        }
404
                                        SnappingVisitor snapVisitor = null;
405
                                        Point2D theSnappedPoint = null;
406
                                        if (theSnapper instanceof ISnapperVectorial)
407
                                        {
408
                                                snapVisitor = new SnappingVisitor((ISnapperVectorial) theSnapper, point, mapTolerance, lastPoint);
409
                                                // System.out.println("Cache size = " + cache.size());
410
                                                cache.query(e, snapVisitor);
411
                                                theSnappedPoint = snapVisitor.getSnapPoint();
412
                                        }
413
                                        if (theSnapper instanceof ISnapperRaster)
414
                                        {
415
                                                ISnapperRaster snapRaster = (ISnapperRaster) theSnapper;
416
                                                theSnappedPoint = snapRaster.getSnapPoint(getMapControl(), point, mapTolerance, lastPoint);
417
                                        }
418

    
419

    
420
                                        if (theSnappedPoint != null) {
421
                                                double distAux = theSnappedPoint.distance(point);
422
                                                if (minDist > distAux)
423
                                                {
424
                                                        minDist = distAux;
425
                                                        usedSnap = theSnapper;
426
                                                        mapHandlerAdjustedPoint.setLocation(theSnappedPoint);
427
                                                }
428
                                        }
429
                                }
430
                        } // visible
431
                }
432
                if (usedSnap != null)
433
                        return minDist;
434
                return Double.MAX_VALUE;
435

    
436
        }
437

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

    
446
        /*
447
         * (non-Javadoc)
448
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseDragged(java.awt.event.MouseEvent)
449
         */
450
        public void mouseDragged(MouseEvent e) throws BehaviorException {
451
                lastX = e.getX();
452
                lastY = e.getY();
453

    
454
                calculateSnapPoint(e.getPoint());
455
        }
456

    
457
        /*
458
         * (non-Javadoc)
459
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseMoved(java.awt.event.MouseEvent)
460
         */
461
        public void mouseMoved(MouseEvent e) throws BehaviorException {
462

    
463
                lastX = e.getX();
464
                lastY = e.getY();
465

    
466
                calculateSnapPoint(e.getPoint());
467

    
468
                showCoords(e.getPoint());
469

    
470
                getMapControl().repaint();
471
        }
472

    
473
        /**
474
         * Displays the current coordinates of the mouse's cursor on the associated <code>MapControl</code>
475
         *  object, at the status bar of the application's main frame.
476
         * 
477
         * @param pPix current 2D mouse's cursor coordinates on the <code>MapControl</code>
478
         */
479
        private void showCoords(Point2D pPix)
480
        {
481
                String[] axisText = new String[2];
482
                NumberFormat nf = NumberFormat.getInstance();
483
                MapControl mapControl = getMapControl();
484
                ViewPort vp = mapControl.getMapContext().getViewPort();
485
                IProjection iProj = vp.getProjection();
486
                if (iProj.getAbrev().equals("EPSG:4326") || iProj.getAbrev().equals("EPSG:4230")) {
487
                        axisText[0] = "Lon = ";
488
                        axisText[1] = "Lat = ";
489
                        nf.setMaximumFractionDigits(8);
490
                } else {
491
                        axisText[0] = "X = ";
492
                        axisText[1] = "Y = ";
493
                        nf.setMaximumFractionDigits(2);
494
                }
495
                Point2D p;
496
                if (mapAdjustedPoint == null)
497
                {
498
                        p = vp.toMapPoint(pPix);
499
                }
500
                else
501
                {
502
                        p = mapAdjustedPoint;
503
                }
504
                MainFrame mF = PluginServices.getMainFrame();
505

    
506
                if (mF != null)
507
                {
508
            mF.getStatusBar().setMessage("units",
509
                            PluginServices.getText(this, FConstant.NAMES[vp.getDistanceUnits()]));
510
            mF.getStatusBar().setControlValue("scale",String.valueOf(mapControl.getMapContext().getScaleView()));
511
                        mF.getStatusBar().setMessage("projection", iProj.getAbrev());
512

    
513
                        mF.getStatusBar().setMessage("x",
514
                                        axisText[0] + String.valueOf(nf.format(p.getX()/MapContext.CHANGEM[vp.getDistanceUnits()])));
515
                        mF.getStatusBar().setMessage("y",
516
                                        axisText[1] + String.valueOf(nf.format(p.getY()/MapContext.CHANGEM[vp.getDistanceUnits()])));
517
                }
518
        }
519

    
520
        /**
521
         * Hides the mouse's cursor.
522
         */
523
        private void clearMouseImage() {
524
                int[] pixels = new int[16 * 16];
525
                Image image = Toolkit.getDefaultToolkit().createImage(
526
                                new MemoryImageSource(16, 16, pixels, 0, 16));
527
                Cursor transparentCursor = Toolkit.getDefaultToolkit()
528
                                .createCustomCursor(image, new Point(0, 0), "invisiblecursor");
529

    
530
                getMapControl().setCursor(transparentCursor);
531
        }
532

    
533
        /**
534
         * <p>Draws a 31x31 pixels cross round the mouse's cursor with an small geometry centered:
535
         *  <ul>
536
         *   <li><i>an square centered</i>: if isn't over a <i>control point</i>.
537
         *   <li><i>an small geometry centered according to the kind of control point</i>: if it's over a control
538
         *    point. In this case, the small geometry is drawn by a {@link ISnapper ISnapper} type object.<br>
539
         *    On the other hand, a light-yellowed background tool tip text with the type of <i>control point</i> will
540
         *     be displayed.</li>
541
         * </p> 
542
         *
543
         * @param g <code>MapControl</code>'s graphics where the data will be drawn
544
         */
545
        private void drawCursor(Graphics g) {
546
                Point2D p = adjustedPoint;
547
                g.setColor(Color.black);
548
                if (p == null) {
549
                        getGrid().setViewPort(getMapControl().getViewPort());
550

    
551
                        return;
552
                }
553

    
554
                int size1 = 15;
555
                int size2 = 3;
556
                g.drawLine((int) (p.getX() - size1), (int) (p.getY()),
557
                                (int) (p.getX() + size1), (int) (p.getY()));
558
                g.drawLine((int) (p.getX()), (int) (p.getY() - size1),
559
                                (int) (p.getX()), (int) (p.getY() + size1));
560

    
561
                // getMapControl().setToolTipText(null);
562
                if (adjustedPoint != null) {
563
                        if (bForceCoord) {
564
                                /* g.setColor(Color.ORANGE);
565
                                g.drawRect((int) (adjustedPoint.getX() - 6),
566
                                                (int) (adjustedPoint.getY() - 6), 12, 12);
567
                                g.drawRect((int) (adjustedPoint.getX() - 3),
568
                                                (int) (adjustedPoint.getY() - 3), 6, 6);
569
                                g.setColor(Color.MAGENTA);
570
                                g.drawRect((int) (adjustedPoint.getX() - 4),
571
                                                (int) (adjustedPoint.getY() - 4), 8, 8); */
572
                                if (usedSnap != null)
573
                                {
574
                                        usedSnap.draw(g, adjustedPoint);
575

    
576
                                        Graphics2D g2 = (Graphics2D) g;
577
                                FontMetrics metrics = g2.getFontMetrics();
578
                                int w = metrics.stringWidth(usedSnap.getToolTipText()) + 5;
579
                                int h = metrics.getMaxAscent() + 5;
580
                                int x = (int)p.getX()+9;
581
                                int y = (int)p.getY()- 7;
582

    
583
                                g2.setColor(theTipColor );
584
                                g2.fillRect(x, y-h, w, h);
585
                                g2.setColor(Color.BLACK);
586
                                g2.drawRect(x, y-h, w, h);
587
                                        g2.drawString(usedSnap.getToolTipText(), x+3, y-3);
588

    
589

    
590
                                        // getMapControl().setToolTipText(usedSnap.getToolTipText());
591
                                }
592

    
593
                                bForceCoord = false;
594
                        } else {
595
                                g.drawRect((int) (p.getX() - size2), (int) (p.getY() - size2),
596
                                                (int) (size2 * 2), (int) (size2 * 2));
597
                        }
598
                }
599
        }
600

    
601
        /**
602
         * <p>Tries to find the nearest geometry or grid control point by the position of the current snap tool.</p>
603
         * 
604
         * <p>Prioritizes the grid control points than the geometries ones.</p>
605
         * 
606
         * <p>If finds any near, stores the <i>map</i> and <i>pixel</i> coordinates for the snap, and enables
607
         *  the <code>bForceCoord</code> attribute for the next draw of the mouse's cursor.</p>
608
         *
609
         * @param point current mouse 2D position
610
         */
611
        private void calculateSnapPoint(Point point) {
612
                // Se comprueba el ajuste a rejilla
613

    
614
                Point2D gridAdjustedPoint = getMapControl().getViewPort().toMapPoint(
615
                                point);
616
                double minDistance = Double.MAX_VALUE;
617
                CADTool ct = (CADTool) cadToolStack.peek();
618
                if (ct instanceof SelectionCADTool
619
                                && ((SelectionCADTool) ct).getStatus().equals(
620
                                                "Selection.FirstPoint")) {
621
                        mapAdjustedPoint = gridAdjustedPoint;
622
                        adjustedPoint = (Point2D) point.clone();
623
                } else {
624

    
625
                        minDistance = getGrid().adjustToGrid(gridAdjustedPoint);
626
                        if (minDistance < Double.MAX_VALUE) {
627
                                adjustedPoint = getMapControl().getViewPort().fromMapPoint(
628
                                                gridAdjustedPoint);
629
                                mapAdjustedPoint = gridAdjustedPoint;
630
                        } else {
631
                                mapAdjustedPoint = null;
632
                        }
633
                }
634
                Point2D handlerAdjustedPoint = null;
635

    
636
                // Se comprueba el ajuste a los handlers
637
                if (mapAdjustedPoint != null) {
638
                        handlerAdjustedPoint = (Point2D) mapAdjustedPoint.clone(); // getMapControl().getViewPort().toMapPoint(point);
639
                } else {
640
                        handlerAdjustedPoint = getMapControl().getViewPort().toMapPoint(
641
                                        point);
642
                }
643

    
644
                Point2D mapPoint = new Point2D.Double();
645
                double distance = adjustToHandler(handlerAdjustedPoint, mapPoint);
646

    
647
                if (distance < minDistance) {
648
                        bForceCoord = true;
649
                        adjustedPoint = getMapControl().getViewPort().fromMapPoint(mapPoint);
650
                        mapAdjustedPoint = mapPoint;
651
                        minDistance = distance;
652
                }
653

    
654
                // Si no hay ajuste
655
                if (minDistance == Double.MAX_VALUE) {
656
                        adjustedPoint = point;
657
                        mapAdjustedPoint = null;
658
                }
659

    
660
        }
661

    
662
        /*
663
         * (non-Javadoc)
664
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#mouseWheelMoved(java.awt.event.MouseWheelEvent)
665
         */
666
        public void mouseWheelMoved(MouseWheelEvent e) throws BehaviorException {
667
        }
668

    
669
        /**
670
         * <p>Process the information written by the user about the next point coordinate, determining
671
         *  the kind of <i>transition</i> according the parameters written.</p>
672
         * 
673
         * <p>After, invokes one of the three possible <i>transition</i> methods of the <i>finite machine</i> of
674
         *  edition:
675
         *  <ul>
676
         *   <li><i>First transition type: <b>Point</i></b>: if <code>text</code> matches with any pattern of
677
         *    parameters needed for any kind of point coordinates.<br>
678
         *    There are eight ways of introducing point 2D coordinates:
679
         *    <ul>
680
         *    <li><i>X,Y</i> : absolute cardinal 2D coordinate from the center <i>(0,0)</i> of the CCS <i>Current Coordinate System</i>.</li>
681
         *    <li><i>@X,Y</i> : relative cardinal 2D distances from the last point added of the CCS. If it's the first point of the geometry,
682
         *     works like <i>X,Y</i>.</li>
683
         *    <li><i>length< angle</i> : absolute polar 2D coordinate from the center <i>(0,0)</i> of the CCS <i>Current Coordinate System</i>, using
684
         *     <i>angle</i> from the <i>X</i> axis of CCS, and <i>length</i> far away.</li>
685
         *    <li><i>@length< angle</i> : relative polar 2D coordinate from the last point added of the CCS <i>Current Coordinate System</i>, using
686
         *     <i>angle</i> from the <i>X</i> axis of CCS, and <i>length</i> far away. If it's the first point of the geometry,
687
         *     works like <i>length< angle</i>.</li>
688
         *    <li><i>*X,Y</i> : like <i>X,Y</i> but using UCS <i>Universal Coordinate System</i> as reference.</li>
689
         *    <li><i>@*X,Y</i> : like <i>@X,Y</i> but using UCS <i>Universal Coordinate System</i> as reference.
690
         *      If it's the first point of the geometry, works like <i>*X,Y</i>.</li>
691
         *    <li><i>*length< angle</i> : like <i>length< angle</i> but using UCS <i>Universal Coordinate System</i> as reference.</li>
692
         *    <li><i>@*length< angle</i> : like <i>@length< angle</i> but using UCS <i>Universal Coordinate System</i> as reference.
693
         *      If it's the first point of the geometry, works like <i>*length< angle</i>.</li>
694
         *    </ul>
695
         *   </li>
696
         *   <li><i>Second transition type: <b>Value</i></b>: if recognizes it as a single number.</li>
697
         *   <li><i>Third transition type: <b>Option</i></b>: by default, if can't classify the information as a single number
698
         *    neither as a point. This information will be an <code>String</code> and dealt as an option of the current
699
         *    tool state. Ultimately, if isn't valid, <code>text</code> will be rewritten in the console notifying the user
700
         *    that isn't correct.</li>
701
         *  </ul>
702
         * </p>
703
         *
704
         * @param text command written by user in the edition's console
705
         */
706
        public void textEntered(String text) {
707
                if (text == null) {
708
                        transition(PluginServices.getText(this,"cancel"));
709
                } else {
710
                        /*
711
                         * if ("".equals(text)) { transition("aceptar"); } else {
712
                         */
713
                        text = text.trim();
714
                        int type = ABSOLUTE;
715
                        String[] numbers = new String[1];
716
                        numbers[0] = text;
717
                        if (text.indexOf(",") != -1) {
718

    
719
                                numbers = text.split(",");
720
                                if (numbers[0].substring(0, 1).equals("@")) {
721
                                        numbers[0] = numbers[0].substring(1, numbers[0].length());
722
                                        type = RELATIVE_SCU;
723
                                        if (numbers[0].substring(0, 1).equals("*")) {
724
                                                type = RELATIVE_SCP;
725
                                                numbers[0] = numbers[0].substring(1, numbers[0]
726
                                                                .length());
727
                                        }
728
                                }
729
                        } else if (text.indexOf("<") != -1) {
730
                                type = POLAR_SCP;
731
                                numbers = text.split("<");
732
                                if (numbers[0].substring(0, 1).equals("@")) {
733
                                        numbers[0] = numbers[0].substring(1, numbers[0].length());
734
                                        type = POLAR_SCU;
735
                                        if (numbers[0].substring(0, 1).equals("*")) {
736
                                                type = POLAR_SCP;
737
                                                numbers[0] = numbers[0].substring(1, numbers[0]
738
                                                                .length());
739
                                        }
740
                                }
741
                        }
742

    
743
                        double[] values = null;
744

    
745
                        try {
746
                                if (numbers.length == 2) {
747
                                        // punto
748
                                        values = new double[] { Double.parseDouble(numbers[0]),
749
                                                        Double.parseDouble(numbers[1]) };
750
                                        transition(values, null, type);
751
                                } else if (numbers.length == 1) {
752
                                        // valor
753
                                        values = new double[] { Double.parseDouble(numbers[0]) };
754
                                        transition(values[0]);
755
                                }
756
                        } catch (NumberFormatException e) {
757
                                transition(text);
758
                        } catch (NullPointerException e) {
759
                                transition(text);
760
                        }
761
                        // }
762
                }
763
                getMapControl().repaint();
764
        }
765

    
766
        /**
767
         * If there are options related with the <code>CADTool</code> at the peek of the CAD tool stack,
768
         *  displays them as a popup.
769
         */
770
        public void configureMenu() {
771
                String[] desc = ((CADTool) cadToolStack.peek()).getDescriptions();
772
                // String[] labels = ((CADTool)
773
                // cadToolStack.peek()).getCurrentTransitions();
774
                CADExtension.clearMenu();
775

    
776
                for (int i = 0; i < desc.length; i++) {
777
                        if (desc[i] != null) {
778
                                CADExtension
779
                                                .addMenuEntry(PluginServices.getText(this, desc[i]));// ,
780
                                // labels[i]);
781
                        }
782
                }
783

    
784
        }
785

    
786
        /**
787
         * <p>One of the three kind of transaction methods of the <i>finite machine</i> of
788
         *  edition.</p>
789
         * 
790
         * <p>This one deals <code>values</code> as two numbers that, according <code>type</code>
791
         *  calculate a new point 2D in the current layer edited in the associated <code>MapControl</code>.</p>
792
         *
793
         * <p>There are different ways of calculating the new point 2D coordinates, according the value of <code>type</code>, see 
794
         *  {@link #textEntered(String) #textEntered(String)}.</p>
795
         *    
796
         * <p>After applying the changes, updates the controls available for managing the current data.</p>
797
         * 
798
         * @param values numbers needed to calculate the new point coordinates according <code>type</code>
799
         * @param event event which generated this invocation (a <code>MouseEvent</code> or a <code>KeyEvent</code>)
800
         * @param type kind of information that is <code>values</code>. According this parameter, will calculate the
801
         *  new point in a different way
802
         * 
803
         * @see CADTool#transition(double, double, InputEvent)
804
         * @see #transition(double)
805
         * @see #transition(String)
806
         */
807
        private void transition(double[] values, InputEvent event, int type) {
808
                questionAsked = true;
809
                if (!cadToolStack.isEmpty()) {
810
                        CADTool ct = (CADTool) cadToolStack.peek();
811

    
812
                        switch (type) {
813
                        case ABSOLUTE:
814
                                ct.transition(values[0], values[1], event);
815
                                previousPoint = values;
816
                                break;
817
                        case RELATIVE_SCU:
818
                                // Comprobar que tenemos almacenado el punto anterior
819
                                // y crear nuevo con coordenadas relativas a ?l.
820
                                double[] auxSCU = values;
821
                                if (previousPoint != null) {
822
                                        auxSCU[0] = previousPoint[0] + values[0];
823
                                        auxSCU[1] = previousPoint[1] + values[1];
824
                                }
825
                                ct.transition(auxSCU[0], auxSCU[1], event);
826

    
827
                                previousPoint = auxSCU;
828
                                break;
829
                        case RELATIVE_SCP:
830
                                // TODO de momento no implementado.
831
                                ct.transition(values[0], values[1], event);
832
                                previousPoint = values;
833
                                break;
834
                        case POLAR_SCU://Relativo
835
                                // Comprobar que tenemos almacenado el punto anterior
836
                                // y crear nuevo con coordenadas relativas a ?l.
837
                                double[] auxPolarSCU = values;
838
                                if (previousPoint != null) {
839
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
840
                                                        previousPoint[0], previousPoint[1]), Math
841
                                                        .toRadians(values[1]), values[0]);
842
                                        auxPolarSCU[0] = point.getX();
843
                                        auxPolarSCU[1] = point.getY();
844
                                        ct.transition(auxPolarSCU[0], auxPolarSCU[1], event);
845
                                } else {
846
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
847
                                                        0, 0), Math.toRadians(values[1]), values[0]);
848
                                        auxPolarSCU[0] = point.getX();
849
                                        auxPolarSCU[1] = point.getY();
850
                                        ct.transition(auxPolarSCU[0], auxPolarSCU[1], event);
851
                                }
852
                                previousPoint = auxPolarSCU;
853
                                break;
854
                        case POLAR_SCP://Absoluto
855
                                double[] auxPolarSCP = values;
856
                                if (previousPoint != null) {
857
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
858
                                                        0, 0),  Math
859
                                                        .toRadians(values[1]), values[0]);
860
                                        auxPolarSCP[0] = point.getX();
861
                                        auxPolarSCP[1] = point.getY();
862
                                        ct.transition(auxPolarSCP[0], auxPolarSCP[1], event);
863
                                } else {
864
                                        Point2D point = UtilFunctions.getPoint(new Point2D.Double(
865
                                                        0, 0), values[1], values[0]);
866
                                        auxPolarSCP[0] = point.getX();
867
                                        auxPolarSCP[1] = point.getY();
868
                                        ct.transition(auxPolarSCP[0], auxPolarSCP[1], event);
869
                                }
870
                                previousPoint = auxPolarSCP;
871
                                break;
872
                        default:
873
                                break;
874
                        }
875
                        askQuestion();
876
                }
877
                configureMenu();
878
                PluginServices.getMainFrame().enableControls();
879
        }
880

    
881
        /**
882
         * <p>One of the three kind of transaction methods of the <i>finite machine</i> of
883
         *  edition.</p>
884
         * 
885
         * <p>This one deals <code>value</code> as a single number used as a parameter for the current
886
         *    tool state. Ultimately, if isn't valid, <code>number</code> will be rewritten in the
887
         *    console notifying the user that isn't correct.</p>
888
         *    
889
         * <p>After applying the changes, updates the controls available for managing the current data.</p>
890
         * 
891
         * @param value value for the current tool state
892
         * 
893
         * @see CADTool#transition(double)
894
         * @see #transition(double[], InputEvent, int)
895
         * @see #transition(String)
896
         */
897
        private void transition(double value) {
898
                questionAsked = true;
899
                if (!cadToolStack.isEmpty()) {
900
                        CADTool ct = (CADTool) cadToolStack.peek();
901
                        ct.transition(value);
902
                        askQuestion();
903
                }
904
                configureMenu();
905
                PluginServices.getMainFrame().enableControls();
906
        }
907

    
908
        /**
909
         * <p>One of the three kind of transaction methods of the <i>finite machine</i> of
910
         *  edition.</p>
911
         * 
912
         * <p>This one deals <code>option</code> as an option of the current
913
         *    tool state. Ultimately, if isn't valid, <code>option</code> will be rewritten in the
914
         *    console notifying the user that isn't correct.</p>
915
         * 
916
         * @param option option for the current tool state
917
         * 
918
         * @see CADTool#transition(String)
919
         * @see #transition(double[], InputEvent, int)
920
         * @see #transition(double)
921
         */
922
        public void transition(String option) {
923
                questionAsked = true;
924
                if (!cadToolStack.isEmpty()) {
925
                        CADTool ct = (CADTool) cadToolStack.peek();
926
                        try {
927
                                ct.transition(option);
928
                        } catch (Exception e) {
929
                                IWindow window = (IWindow) PluginServices.getMDIManager()
930
                                                .getActiveWindow();
931

    
932
                                if (window instanceof View) {
933
                                        ((View)window).getConsolePanel().addText(
934
                                                "\n" + PluginServices.getText(this, "incorrect_option")
935
                                                                + " : " + option, JConsole.ERROR);
936
                                }
937
                        }
938
                        askQuestion();
939
                }
940
                configureMenu();
941
                PluginServices.getMainFrame().enableControls();
942
        }
943

    
944
        /**
945
         * Shows or hides a grid on the <code>ViewPort</code> of the associated <code>MapControl</code>.
946
         *
947
         * @param value <code>true</code> to make the grid visible; <code>false</code> to make it invisible
948
         */
949
        public void setGridVisibility(boolean value) {
950
                getGrid().setShowGrid(value);
951
                getGrid().setViewPort(getMapControl().getViewPort());
952
                getMapControl().repaint();
953
        }
954

    
955
        /**
956
         * Sets the snap tools enabled or disabled.
957
         * 
958
         * @param activated <code>true</code> to enable the snap tools; <code>false</code> to disable them
959
         * 
960
         * @see #isRefentEnabled()
961
         */
962
        public void setRefentEnabled(boolean activated) {
963
                bRefent = activated;
964
        }
965

    
966
        /**
967
         * Determines if snap tools are enabled or disabled.
968
         * 
969
         * @return <code>true</code> to enable the snap tools; <code>false</code> to disable them
970
         * 
971
         * @see #setRefentEnabled(boolean)
972
         */
973
        public boolean isRefentEnabled()
974
        {
975
                return bRefent;
976
        }
977

    
978
        /*
979
         * (non-Javadoc)
980
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#getListener()
981
         */
982
        public ToolListener getListener() {
983
                return new ToolListener() {
984
                        /**
985
                         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#getCursor()
986
                         */
987
                        public Cursor getCursor() {
988
                                return null;
989
                        }
990

    
991
                        /**
992
                         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#cancelDrawing()
993
                         */
994
                        public boolean cancelDrawing() {
995
                                return false;
996
                        }
997
                };
998
        }
999

    
1000
        /**
1001
         * Returns the {@link CADTool CADTool} at the top of the stack without removing it from the CAD tool stack.
1002
         * 
1003
         * @return the {@link CADTool CADTool} at the top of the stack
1004
         * 
1005
         * @see #pushCadTool(CADTool)
1006
         * @see #popCadTool()
1007
         * @see #setCadTool(CADTool)
1008
         */
1009
        public CADTool getCadTool() {
1010
                return (CADTool) cadToolStack.peek();
1011
        }
1012

    
1013
        /**
1014
         * <p>Pushes a {@link CADTool CADTool} onto the top of the CAD tool stack, and sets it as current.</p>
1015
         * 
1016
         * @param cadTool CAD tool to enable as current
1017
         *            
1018
         * @see #getCadTool()
1019
         * @see #popCadTool()
1020
         * @see #setCadTool(CADTool)
1021
         */
1022
        public void pushCadTool(CADTool cadTool) {
1023
                cadToolStack.push(cadTool);
1024
                cadTool.setCadToolAdapter(this);
1025
                // cadTool.initializeStatus();
1026
                // cadTool.setVectorialAdapter(vea);
1027
                /*
1028
                 * int ret = cadTool.transition(null, editableFeatureSource, selection,
1029
                 * new double[0]);
1030
                 *
1031
                 * if ((ret & Automaton.AUTOMATON_FINISHED) ==
1032
                 * Automaton.AUTOMATON_FINISHED) { popCadTool();
1033
                 *
1034
                 * if (cadToolStack.isEmpty()) { pushCadTool(new
1035
                 * com.iver.cit.gvsig.gui.cad.smc.gen.CADTool());//new
1036
                 * SelectionCadTool());
1037
                 * PluginServices.getMainFrame().setSelectedTool("selection"); }
1038
                 *
1039
                 * askQuestion();
1040
                 *
1041
                 * getMapControl().drawMap(false); }
1042
                 */
1043
        }
1044

    
1045
        /**
1046
         * Removes the peek of the CAD tool stack.
1047
         * 
1048
         * @see #pushCadTool(CADTool)
1049
         * @see #getCadTool()
1050
         * @see #setCadTool(CADTool)
1051
         */
1052
        public void popCadTool() {
1053
                cadToolStack.pop();
1054
        }
1055

    
1056
        /**
1057
         * <p>Displays at the console associated to the current active view that's being edited, the question of the following
1058
         *  operation that user can do with the current <code>CADTool</code>.</p>
1059
         * 
1060
         * <p>The format of the question will be according the following pattern:<br>
1061
         *   "\n#"<i>{cadtool at CAD tool stack peek}</i>.getQuestion()">"
1062
         * </p>
1063
         */
1064
        public void askQuestion() {
1065
                CADTool cadtool = (CADTool) cadToolStack.peek();
1066
                /*
1067
                 * if (cadtool..getStatus()==0){
1068
                 * PluginServices.getMainFrame().addTextToConsole("\n"
1069
                 * +cadtool.getName()); }
1070
                 */
1071
                if (PluginServices.getMDIManager().getActiveWindow() instanceof View)
1072
                {
1073
                        View vista = (View) PluginServices.getMDIManager().getActiveWindow();
1074
                        vista.getConsolePanel().addText(
1075
                                        "\n" + "#" + cadtool.getQuestion() + " > ", JConsole.MESSAGE);
1076
                        // ***PluginServices.getMainFrame().addTextToConsole("\n" +
1077
                        // cadtool.getQuestion());
1078
                        questionAsked = true;
1079
                }
1080

    
1081
        }
1082

    
1083
        /**
1084
         * Empties the CAD tools stack and pushes <code>cadTool</code> in it.
1085
         * 
1086
         * @param cadTool CAD tool to set at the peek of the stack
1087
         * 
1088
         * @see #pushCadTool(CADTool)
1089
         * @see #popCadTool()
1090
         * @see #getCadTool()
1091
         */
1092
        public void setCadTool(CADTool cadTool) {
1093
                cadToolStack.clear();
1094
                pushCadTool(cadTool);
1095
                // askQuestion();
1096
        }
1097

    
1098
        /**
1099
         * <p>Removes all geometries selected in the associated <code>MapControl</code>.
1100
         */
1101
        public void delete() {
1102
                ILayerEdited aux = CADExtension.getEditionManager().getActiveLayerEdited();
1103
                if (!(aux instanceof VectorialLayerEdited))
1104
                        return;
1105
                VectorialLayerEdited vle = (VectorialLayerEdited) aux;
1106
                VectorialEditableAdapter vea = vle.getVEA();
1107

    
1108
                vea.startComplexRow();
1109
                FBitSet selection = vea.getSelection();
1110
                try {
1111
                        int[] indexesToDel = new int[selection.cardinality()];
1112
                        int j = 0;
1113
                        for (int i = selection.nextSetBit(0); i >= 0; i = selection
1114
                                        .nextSetBit(i + 1)) {
1115
                                indexesToDel[j++] = i;
1116
                                // /vea.removeRow(i);
1117
                        }
1118

    
1119
//                          ArrayList selectedRow = vle.getSelectedRow();
1120
//
1121
//                          int[] indexesToDel = new int[selectedRow.size()];
1122
//                          for (int i = 0;i < selectedRow.size(); i++) {
1123
//                                  IRowEdited edRow = (IRowEdited) selectedRow.get(i);
1124
//                                  indexesToDel[i] = vea.getInversedIndex(edRow.getIndex());
1125
//                                  }
1126
//
1127
                        for (int i = indexesToDel.length - 1; i >= 0; i--) {
1128
                                vea.removeRow(indexesToDel[i], PluginServices.getText(this,
1129
                                                "deleted_feature"),EditionEvent.GRAPHIC);
1130
                        }
1131
                } catch (DriverIOException e) {
1132
                        NotificationManager.addError(e.getMessage(), e);
1133
                } catch (IOException e) {
1134
                        NotificationManager.addError(e.getMessage(), e);
1135
                } finally {
1136
                        try {
1137
                                String description=PluginServices.getText(this,"remove_geometry");
1138
                                vea.endComplexRow(description);
1139
                        } catch (IOException e1) {
1140
                                NotificationManager.addError(e1.getMessage(), e1);
1141
                        } catch (DriverIOException e1) {
1142
                                NotificationManager.addError(e1.getMessage(), e1);
1143
                        }
1144
                }
1145
                System.out.println("clear Selection");
1146
                selection.clear();
1147
                vle.clearSelection();
1148
                /*
1149
                 * if (getCadTool() instanceof SelectionCADTool) { SelectionCADTool
1150
                 * selTool = (SelectionCADTool) getCadTool(); selTool.clearSelection(); }
1151
                 */
1152
                refreshEditedLayer();
1153
        }
1154

    
1155
        /**
1156
         * @see CADGrid#setAdjustGrid(boolean)
1157
         */
1158
        public void setAdjustGrid(boolean b) {
1159
                getGrid().setAdjustGrid(b);
1160
        }
1161

    
1162
        /**
1163
         * <p>Responds to actions of writing common key commands for all kind of CAD operations, enabling/disabling after
1164
         *  the controls to manage the available information according the tool selected:
1165
         *  <ul>
1166
         *   <li><i>eliminar</i>: removes the geometries that are now selected.</li>
1167
         *   <li><i>escape</i>: executes different actions according to the current CAD tool of the associated <code>MapControl</code>:
1168
         *    <ul>
1169
         *     <li>If the tool enabled is identified by <i>cadtooladapter</i>: empties the CAD tools stack, changing the current tool by
1170
         *      a {@link SelectionCADTool SelectionCADTool}, which is identified by <i>_selection</i> and allows select features of the
1171
         *      active vector layer of the associated <code>MapControl</code> instance. </li>
1172
         *     <li>Otherwise, that means current associated <code>MapControl</code> instance isn't identified by "<i>cadtooladapter</i>",
1173
         *      changes the enabled tool by the previous.</li>
1174
         *    </ul>
1175
         *   </li>
1176
         *  </ul>
1177
         * </p>
1178
         *
1179
         * @param actionCommand identifier of the key action command executed by the user
1180
         * 
1181
         * @see SelectionCADTool
1182
         * @see MapControl#setPrevTool()
1183
         */
1184
        public void keyPressed(String actionCommand) {
1185
                if (CADExtension.getEditionManager().getActiveLayerEdited()== null) {
1186
                        return;
1187
                }
1188
                if (actionCommand.equals("eliminar")) {
1189
                        delete();
1190
                } else if (actionCommand.equals("escape")) {
1191
                        if (getMapControl().getCurrentTool().equals("cadtooladapter")) {
1192
                                CADTool ct = (CADTool) cadToolStack.peek();
1193
                                ct.end();
1194
                                cadToolStack.clear();
1195
                                SelectionCADTool selCad = new SelectionCADTool();
1196
                                selCad.init();
1197
                                VectorialLayerEdited vle = (VectorialLayerEdited) CADExtension
1198
                                                .getEditionManager().getActiveLayerEdited();
1199
                                vle.clearSelection();
1200

    
1201
                                pushCadTool(selCad);
1202
                                // getVectorialAdapter().getSelection().clear();
1203

    
1204
                                refreshEditedLayer();
1205

    
1206

    
1207
                                PluginServices.getMainFrame().setSelectedTool("_selection");
1208
                                // askQuestion();
1209
                        } else {
1210
                                getMapControl().setPrevTool();
1211
                        }
1212
                }
1213

    
1214
                PluginServices.getMainFrame().enableControls();
1215

    
1216
        }
1217

    
1218
        /**
1219
         * <p>Applies a lightweight repaint of the active layer being edited.</p>
1220
         * 
1221
         * <p>All layers under it won't be drawn, only the upper one and whose are over that layer in the TOC.</p>
1222
         * 
1223
         * @see MapControl#rePaintDirtyLayers()
1224
         */
1225
        public void refreshEditedLayer()
1226
        {
1227
                ILayerEdited edLayer = CADExtension.getEditionManager().getActiveLayerEdited();
1228
                if (edLayer != null)
1229
                {
1230
                        edLayer.getLayer().setDirty(true);
1231
                        getMapControl().rePaintDirtyLayers();
1232
                }
1233

    
1234
        }
1235

    
1236
        /**
1237
         * Gets the {@link CADGrid CADGrid} that can be drawn on the <code>ViewPort</code> of the associated <code>MapControl</code>.
1238
         * 
1239
         * @return reference to the <i>grid</i> that can be applied on the <code>ViewPort</code>
1240
         * 
1241
         * @see #setGridVisibility(boolean)
1242
         */
1243
        public CADGrid getGrid() {
1244
                return cadgrid;
1245
        }
1246

    
1247
        /**
1248
         * Determines if is enabled or not the <i>orto</i> mode.
1249
         * 
1250
         * @return <code>true</code> if is enabled the <i>orto</i> mode; otherwise <code>false</code> 
1251
         * 
1252
         * @see #setOrtoMode(boolean)
1253
         */
1254
        public boolean isOrtoMode() {
1255
                return bOrtoMode;
1256
        }
1257

    
1258
        /**
1259
         * Enables / disables the <i>orto</i> mode.
1260
         * 
1261
         * @param b the desired value
1262
         * 
1263
         * @see #isOrtoMode()
1264
         */
1265
        public void setOrtoMode(boolean b) {
1266
                bOrtoMode = b;
1267
        }
1268

    
1269
        /**
1270
         * Associates and stores the specified name with the specified {@link CADTool CADTool}.
1271
         * 
1272
         * @param name name of the tool
1273
         * @param c CAD tool to interactuate editing the layers
1274
         * 
1275
         * @see #getCADTools()
1276
         * @see #getCADTool(String)
1277
         */
1278
        public static void addCADTool(String name, CADTool c) {
1279
                namesCadTools.put(name, c);
1280

    
1281
        }
1282

    
1283
        /**
1284
         * Gets all CAD tools available to edit layers with this tool listener.
1285
         * 
1286
         * @return CAD tools available to edit layers with this tool listener
1287
         *
1288
         * @see #addCADTool(String, CADTool)
1289
         * @see #getCADTool(String)
1290
         */
1291
        public static CADTool[] getCADTools() {
1292
                return (CADTool[]) CADToolAdapter.namesCadTools.values().toArray(new CADTool[0]);
1293
        }
1294

    
1295
        /**
1296
         * Returns the {@link CADTool CADTool} to which the specified name is mapped.
1297
         * 
1298
         * @param text name of the tool
1299
         * @return the CAD tool whose associated name is to be returned
1300
         * 
1301
         * @see #addCADTool(String, CADTool)
1302
         * @see #getCADTools()
1303
         */
1304
        public CADTool getCADTool(String text) {
1305
                CADTool ct = (CADTool) namesCadTools.get(text);
1306
                return ct;
1307
        }
1308

    
1309
        /**
1310
         * Gets the object used to manage the edition of the layers of the associated <code>MapControl</code>.
1311
         * 
1312
         * @see EditionManager
1313
         * 
1314
         * @return object used to manage the edition of the layers
1315
         */
1316
        public EditionManager getEditionManager() {
1317
                return editionManager;
1318
        }
1319

    
1320
        /**
1321
         * <p>Initializes the <i>flatness</i> with the defined in preferences.</p>
1322
         *
1323
         * <p>The <i>flatness</i> is the maximum tolerance used to approximate curved lines in a <i>shape</i> by polylines.</p>
1324
         * <p>The shapes doesn't support primitive like arcs neither other curved lines to draw their geometries, then for drawing any
1325
         *  kind of this geometries the curved lines are drawn approximately by a polyline. And for doing more realistic that curves,
1326
         *  is used the <i>flatness</i> parameter, that indicates that the difference between each arc and the straight segment that
1327
         *  approximates it must be in the worse case, like the <i>flatness</i>.</p>
1328
         *  
1329
         * @see FConverter#FLATNESS
1330
         */
1331
        public void initializeFlatness() {
1332
                if (!flatnessInitialized){
1333
                        flatnessInitialized=true;
1334
                        Preferences prefs = Preferences.userRoot().node( "cadtooladapter" );
1335
                        double flatness = prefs.getDouble("flatness",FConverter.FLATNESS);
1336
                        FConverter.FLATNESS=flatness;
1337
                }
1338
        }
1339

    
1340
        /**
1341
         * <p>Updates the grid on the <code>ViewPort</code> of the associated <code>MapControl</code>
1342
         *  object according the values in the {@link com.iver.cit.gvsig.gui.cad.CADToolAdapter.prefs.Preferences com.iver.cit.gvsig.gui.cad.CADToolAdapter.prefs.Preferences}.</p>
1343
         * 
1344
         * <p>The preferences are:
1345
         *  <ul>
1346
         *   <li>Show/hide the grid.</li>
1347
         *   <li>Adjust or not the grid.</li>
1348
         *   <li>Horizontal ( X ) line separation.</li>
1349
         *   <li>Vertical ( Y ) line separation.</li>
1350
         *  </ul>
1351
         * </p>
1352
         */
1353
        public void initializeGrid(){
1354
                boolean showGrid = prefs.getBoolean("grid.showgrid",getGrid().isShowGrid());
1355
                boolean adjustGrid = prefs.getBoolean("grid.adjustgrid",getGrid().isAdjustGrid());
1356

    
1357
                double dx = prefs.getDouble("grid.distancex",getGrid().getGridSizeX());
1358
                double dy = prefs.getDouble("grid.distancey",getGrid().getGridSizeY());
1359

    
1360
                setGridVisibility(showGrid);
1361
                setAdjustGrid(adjustGrid);
1362
                getGrid().setGridSizeX(dx);
1363
                getGrid().setGridSizeY(dy);
1364
        }
1365

    
1366
        /**
1367
         * <p>Returns the type of the shape that's the current active and vector layer being edited.</p>
1368
         * 
1369
         * @see FLyrVect#getShapeType()
1370
         * 
1371
         * @return type of the shape that's the current active and vector layer being edited
1372
         */
1373
        public int getActiveLayerType() {
1374
                int type=FShape.MULTI;
1375
                try {
1376
                        type=((FLyrVect)CADExtension.getEditionManager().getActiveLayerEdited().getLayer()).getShapeType();
1377
                } catch (DriverException e) {
1378
                        NotificationManager.addError(e);
1379
                }
1380
                return type;
1381
        }
1382
}