Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.swing / org.gvsig.vectorediting.swing.impl / src / main / java / org / gvsig / vectorediting / swing / impl / DefaultEditingBehavior.java @ 62

History | View | Annotate | Download (17.7 KB)

1
/*
2
 * Copyright 2014 DiSiD Technologies S.L.L. All rights reserved.
3
 *
4
 * Project  : DiSiD org.gvsig.vectorediting.lib.impl
5
 * SVN Id   : $Id$
6
 */
7
package org.gvsig.vectorediting.swing.impl;
8

    
9
import java.awt.BorderLayout;
10
import java.awt.Color;
11
import java.awt.Graphics;
12
import java.awt.Image;
13
import java.awt.event.MouseEvent;
14
import java.awt.geom.Point2D;
15
import java.awt.image.BufferedImage;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Map;
20

    
21
import org.cresques.cts.IProjection;
22
import org.gvsig.andami.PluginServices;
23
import org.gvsig.andami.ui.mdiFrame.MainFrame;
24
import org.gvsig.app.extension.CheckSOAndArquitectureExtension.ShowMessageControler;
25
import org.gvsig.app.project.documents.view.toolListeners.StatusBarListener;
26
import org.gvsig.fmap.geom.Geometry;
27
import org.gvsig.fmap.geom.primitive.Point;
28
import org.gvsig.fmap.mapcontext.MapContext;
29
import org.gvsig.fmap.mapcontext.ViewPort;
30
import org.gvsig.fmap.mapcontext.layers.CancelationException;
31
import org.gvsig.fmap.mapcontext.layers.FLayer;
32
import org.gvsig.fmap.mapcontext.layers.FLayers;
33
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
34
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
35
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
36
import org.gvsig.fmap.mapcontext.layers.LayerListener;
37
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
38
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
39
import org.gvsig.fmap.mapcontrol.MapControl;
40
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
41
import org.gvsig.fmap.mapcontrol.MapControlLocator;
42
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
43
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
44
import org.gvsig.fmap.mapcontrol.tools.Listeners.ToolListener;
45
import org.gvsig.utils.console.JConsole;
46
import org.gvsig.utils.console.JDockPanel;
47
import org.gvsig.utils.console.ResponseListener;
48
import org.gvsig.utils.console.jedit.JEditTextArea;
49
import org.gvsig.vectorediting.lib.api.DrawingStatus;
50
import org.gvsig.vectorediting.lib.api.EditingLocator;
51
import org.gvsig.vectorediting.lib.api.EditingManager;
52
import org.gvsig.vectorediting.lib.api.EditingService;
53
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
54
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
55
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
56
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
57
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
58
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
59
import org.gvsig.vectorediting.swing.api.EditingBehavior;
60
import org.slf4j.Logger;
61
import org.slf4j.LoggerFactory;
62

    
63
public class DefaultEditingBehavior extends Behavior implements EditingBehavior {
64

    
65
  private static final Logger logger = LoggerFactory
66
      .getLogger(DefaultEditingBehavior.class);
67

    
68
  private Map<FLyrVect, EditingService> serviceRegistration;
69

    
70
  private MapControl mapControl;
71

    
72
  private FLyrVect currentLayer;
73

    
74
  private EditingService activeService;
75

    
76
  private EditingServiceParameter currentParam;
77

    
78
  private Point adjustedPoint;
79

    
80
  private StatusBarListener sbl = null;
81

    
82
  private JConsole console;
83

    
84
  private JDockPanel dockConsole = null;
85

    
86
  private boolean isShowConsole;
87

    
88
  protected ResponseAdapter consoleResponseAdapter;
89

    
90
  private static final Image imageCursor = new BufferedImage(32, 32,
91
      BufferedImage.TYPE_INT_ARGB);
92
  static {
93
    Graphics g = imageCursor.getGraphics();
94
    int size1 = 15;
95
    int x = 16;
96
    int y = 16;
97
    g.setColor(Color.MAGENTA);
98
    g.drawLine((x - size1), (y), (x + size1), (y));
99
    g.drawLine((x), (y - size1), (x), (y + size1));
100
    g.drawRect((x - 6), (y - 6), 12, 12);
101
    g.drawRect((x - 3), (y - 3), 6, 6);
102
  }
103

    
104
  private LayerListener layerListener = new LayerListener() {
105

    
106
    public void activationChanged(LayerEvent e) {
107
      FLayer layer = e.getSource();
108
      if (layer instanceof FLyrVect) {
109

    
110
        if (layer.isActive() && layer.isEditing()) {
111
          showConsole();
112
          getMapControl().setTool("VectorEditing");
113
        }
114
        else if (!layer.isEditing() && layer.isActive()) {
115
          changeCurrentLayer((FLyrVect) layer);
116
          hideConsole();
117
          getMapControl().setTool("zoomIn");
118
        }
119
        changeCurrentLayer((FLyrVect) layer);
120

    
121
      }
122

    
123
    }
124

    
125
    public void drawValueChanged(LayerEvent e) {}
126

    
127
    public void editionChanged(LayerEvent e) {}
128

    
129
    public void nameChanged(LayerEvent e) {}
130

    
131
    public void visibilityChanged(LayerEvent e) {}
132
  };
133

    
134
  public void cleanBehavior() {
135
    activeService = null;
136
    currentParam = null;
137

    
138
    showConsoleMessage("\nSeleccione una herramienta\n");
139
    // MainFrame main = PluginServices.getMainFrame();
140
    // main.setSelectedTool(""); We can define a default tool. I.E Zoom in.
141
  }
142

    
143
  public DefaultEditingBehavior(MapControl mapControl) {
144
    if (mapControl != null) {
145
      this.mapControl = mapControl;
146
      serviceRegistration = new HashMap<FLyrVect, EditingService>();
147
      sbl = new StatusBarListener(mapControl);
148
      initMapControlListeners(mapControl);
149
      initConsolePanelListeners(getConsolePanel());
150
      FLayers layers = mapControl.getMapContext().getLayers();
151
      for (int i = 0; i < layers.getLayersCount(); i++) {
152
        if (layers.getLayer(i) instanceof FLyrVect
153
            && layers.getLayer(i).isActive())
154
          changeCurrentLayer((FLyrVect) layers.getLayer(i));
155
      }
156

    
157
    }
158
  }
159

    
160
  private void initConsolePanelListeners(JConsole jConsole) {
161
    consoleResponseAdapter = new ResponseAdapter();
162
    jConsole.addResponseListener(consoleResponseAdapter);
163
    addConsoleListener("ViewEditing", new ResponseListener() {
164

    
165
      public void acceptResponse(String response) {
166
        try{
167
          textEntered(response);
168
        } catch( VectorEditingException e){
169
          showConsoleMessage(e.getMessage());
170
        } finally{
171
          getNextParameter();
172
        }
173
      }
174
    });
175

    
176
  }
177

    
178
  public void activateTool(String name) {
179

    
180
    EditingManager manager = EditingLocator.getManager();
181

    
182
    if (currentLayer != null) {
183
      EditingService service = serviceRegistration.get(currentLayer);
184
      if (service == null || !service.getName().equals(name)) {
185
        service = (EditingService) manager.getEditingService(name,
186
            currentLayer.getFeatureStore());
187
        serviceRegistration.put(currentLayer, service);
188
      }
189
      if (service != null) {
190
        this.activeService = service;
191
        service.start();
192
        getNextParameter();
193
      }
194
    }
195
  }
196

    
197
  private void askQuestion(EditingServiceParameter param) {
198
    if (getConsolePanel() != null) {
199
      showConsoleMessage("\n#" + param.getDescription() + " > ");
200
    }
201
  }
202

    
203
  private void showConsoleMessage(String text) {
204
    getConsolePanel().addText(text, JConsole.MESSAGE);
205
  }
206

    
207
  @Override
208
  public ToolListener getListener() {
209
    return new ToolListener() {
210

    
211
      /**
212
       *
213
       */
214
      public boolean cancelDrawing() {
215
        return false;
216
      }
217

    
218
      /**
219
       *
220
       */
221
      public Image getImageCursor() {
222
        return imageCursor;
223
      }
224
    };
225
  }
226

    
227
  private void getNextParameter() {
228
    currentParam = activeService.next();
229
    if (currentParam == null) {
230
      finishAndStartService();
231
      getNextParameter();
232
    }
233
    else {
234
      askQuestion(currentParam);
235
      setCaretPosition();
236
    }
237

    
238
  }
239

    
240
  private void finishAndStartService() {
241
    try {
242
      activeService.finish();
243
    }
244
    catch (VectorEditingException e) {
245
      logger.error("An error ocurred when try to finish service", e);
246
    }
247
    mapControl.rePaintDirtyLayers();
248
    activeService.start();
249
  }
250

    
251
  private void initMapControlListeners(MapControl mapControl) {
252

    
253
    MapContext context = mapControl.getMapContext();
254
    FLayers layers = context.getLayers();
255
    layers.addLayerListener(layerListener);
256

    
257
    layers.addLayerCollectionListener(new LayerCollectionListener() {
258

    
259
      public void layerAdded(LayerCollectionEvent e) {
260
        FLayers layers2 = e.getLayers();
261
        for (int i = 0; i < layers2.getLayersCount(); i++) {
262
          FLayer layer = layers2.getLayer(i);
263
          if (layer instanceof FLyrVect) {
264
            ((FLyrVect) layer).addLayerListener(layerListener);
265
          }
266
        }
267
      }
268

    
269
      public void layerAdding(LayerCollectionEvent e)
270
          throws CancelationException {}
271

    
272
      public void layerMoved(LayerPositionEvent e) {}
273

    
274
      public void layerMoving(LayerPositionEvent e) throws CancelationException {}
275

    
276
      public void layerRemoved(LayerCollectionEvent e) {
277
        FLayers layers2 = e.getLayers();
278
        for (int i = 0; i < layers2.getLayersCount(); i++) {
279
          FLayer layer = layers2.getLayer(i);
280
          if (layer instanceof FLyrVect) {
281
            ((FLyrVect) layer).removeLayerListener(layerListener);
282
          }
283
        }
284
      }
285

    
286
      public void layerRemoving(LayerCollectionEvent e)
287
          throws CancelationException {}
288

    
289
      public void visibilityChanged(LayerCollectionEvent e)
290
          throws CancelationException {}
291
    });
292
  }
293

    
294
  public void mouseClicked(MouseEvent e) {
295
    ViewPort vp = mapControl.getViewPort();
296
    if (activeService != null) {
297
      if (currentParam != null) {
298
        List<TYPE> typesOfParam = currentParam.getTypes();
299
        if (typesOfParam.contains(TYPE.LIST_POSITIONS)) {
300
          if (e.getClickCount() == 2) {
301
            finishAndStartService();
302
            return;
303
          }
304
          Point point;
305
          point = vp.convertToMapPoint(e.getX(), e.getY());
306
          try {
307
            this.activeService.value(point);
308
          }
309
          catch (VectorEditingException ex) {
310
            logger.error("Invalid value %s", new Object[] { point });
311
          }
312
        }
313
        if (typesOfParam.contains(TYPE.POSITION)) {
314
          Point point;
315
          point = vp.convertToMapPoint(e.getX(), e.getY());
316
          try {
317
            this.activeService.value(point);
318
          }
319
          catch (VectorEditingException ex) {
320
            logger.error("Invalid value %s", new Object[] { point });
321
          }
322
          // TODO: Comprobar el resto de casos:
323
          // TYPE.VALUE,
324
          // TYPE.OPTION, TYPE.SELECTION,
325
          // TYPE.GEOMETRY:
326
        }
327
        getNextParameter();
328
      }
329
    }
330
  }
331

    
332
  public void mouseEntered(MouseEvent e) throws BehaviorException {
333
    // TODO Auto-generated method stub
334
  }
335

    
336
  public void mouseMoved(MouseEvent e) throws BehaviorException {
337
    ViewPort vp = mapControl.getViewPort();
338
    adjustedPoint = vp.convertToMapPoint(e.getX(), e.getY());
339
    showCoords(e.getPoint());
340

    
341
    getMapControl().repaint();
342
  }
343

    
344
  public void mousePressed(MouseEvent e) throws BehaviorException {
345
    // TODO Auto-generated method stub
346
  }
347

    
348
  public void mouseReleased(MouseEvent e) throws BehaviorException {
349
    // TODO Auto-generated method stub
350
  }
351

    
352
  public void paintComponent(MapControlDrawer mapControlDrawer) {
353
    super.paintComponent(mapControlDrawer);
354
    if (activeService == null || adjustedPoint == null) {
355
      return;
356
    }
357

    
358
    DrawingStatus helperGeo = null;
359
    try {
360
      helperGeo = activeService.draw(adjustedPoint);
361
    }
362
    catch (VectorEditingException e) {
363
      logger.error("An error ocurred when draw service geometries", e);
364
    }
365
    if (helperGeo != null) {
366
      for (Iterator iterator = helperGeo.getGeometries().iterator(); iterator
367
          .hasNext();) {
368
        Geometry geometry = (Geometry) iterator.next();
369
        mapControl.getMapControlDrawer().draw(geometry,
370
            MapControlLocator.getMapControlManager().getAxisReferenceSymbol());
371
      }
372
    }
373
  }
374

    
375
  private void setCaretPosition() {
376

    
377
    JEditTextArea jeta = getConsolePanel().getTxt();
378
    jeta.requestFocusInWindow();
379
    jeta.setCaretPosition(jeta.getText().length());
380

    
381
  }
382

    
383
  private void changeCurrentLayer(FLyrVect layer) {
384
    this.currentLayer = layer;
385
    this.activeService = serviceRegistration.get(layer);
386
    if (activeService != null) {
387
      getNextParameter();
388
      MainFrame main = PluginServices.getMainFrame();
389
      main.setSelectedTool(activeService.getName());
390
    }
391
  }
392

    
393
  private void showCoords(Point2D point) {
394
    String[] axisText = new String[2];
395
    axisText[0] = "X = ";
396
    axisText[1] = "Y = ";
397

    
398
    ViewPort vp = mapControl.getMapContext().getViewPort();
399
    IProjection iProj = vp.getProjection();
400
    Point p = vp.convertToMapPoint(point);
401
    Point2D p2D = new Point2D.Double(p.getX(), p.getY());
402

    
403
    sbl.setFractionDigits(p2D);
404
    axisText = sbl.setCoorDisplayText(axisText);
405
    MainFrame mF = PluginServices.getMainFrame();
406

    
407
    if (mF != null) {
408
      mF.getStatusBar().setMessage(
409
          "units",
410
          PluginServices.getText(this,
411
              MapContext.getDistanceNames()[vp.getDistanceUnits()]));
412
      mF.getStatusBar().setControlValue("scale",
413
          String.valueOf(mapControl.getMapContext().getScaleView()));
414
      mF.getStatusBar().setMessage("projection", iProj.getAbrev());
415

    
416
      String[] coords = sbl.getCoords(p2D);
417
      mF.getStatusBar().setMessage("x", axisText[0] + coords[0]);
418
      mF.getStatusBar().setMessage("y", axisText[1] + coords[1]);
419
    }
420

    
421
  }
422

    
423
  private void textEntered(String response) throws InvalidEntryException{
424
    if (response == null) {
425
      this.activeService.stop();
426
      cleanBehavior();
427
    }
428
    else {
429
      List<TYPE> types = currentParam.getTypes();
430
      Point point = null;
431
      Double value = null;
432

    
433
      boolean insertedValue = false;
434
      if (!insertedValue && types.contains(TYPE.POSITION)
435
          || types.contains(TYPE.LIST_POSITIONS)) {
436
        try {
437
          point = parsePoint(response);
438
          if (point != null) {
439
            this.activeService.value(point);
440
            insertedValue = true;
441
          }
442
        }
443
        catch (VectorEditingException e) {
444
          // Do nothing
445
        }
446
      }
447
      if (!insertedValue && types.contains(TYPE.VALUE)) {
448
        try {
449
          value = parseValue(response);
450
          if (value != null) {
451
            this.activeService.value(value);
452
            insertedValue = true;
453
          }
454
        }
455
        catch (VectorEditingException e) {
456
          // Do nothing
457
        }
458

    
459
      }
460
      if (!insertedValue && types.contains(TYPE.OPTION)) {
461
        try {
462
          response = response.replace("\n", "");
463
          if (response != null) {
464
            this.activeService.value(response);
465
            insertedValue = true;
466
          }
467
        }
468
        catch (VectorEditingException e) {
469
          // Do nothing
470
        }
471
      }
472
      // TODO: contemplar el resto de casos
473
      // TYPE.OPTION,
474
      // TYPE.SELECTION,
475
      // TYPE.GEOMETRY
476
      if (!insertedValue) {
477
        throw new InvalidEntryException(null);
478
      }
479
    }
480
  }
481

    
482
   
483

    
484
  private Double parseValue(String response) throws ParseValueException {
485
    try {
486
      return Double.valueOf(response);
487
    }
488
    catch (Exception e) {
489
      throw new ParseValueException(e);
490
    }
491

    
492
  }
493

    
494
  private Point parsePoint(String response) throws ParsePointException {
495
    String[] numbers = new String[1];
496
    numbers[0] = response;
497
    numbers = response.split(",");
498
    if (numbers.length == 2) {
499
      if (numbers[0].startsWith("(") && numbers[1].endsWith(")\n")) { // CCS
500
        numbers[0] = numbers[0].replace("(", "");
501
        numbers[1] = numbers[1].replace(")\n", "");
502
      }
503
      double[] values;
504
      try {
505
        values = new double[] { Double.parseDouble(numbers[0]),
506
            Double.parseDouble(numbers[1]) };
507
      }
508
      catch (Exception e) {
509
        throw new ParsePointException(e);
510
      }
511

    
512
      Point point;
513
      try {
514
        point = geomManager.createPoint(values[0], values[1], currentLayer
515
            .getFeatureStore().getDefaultFeatureType()
516
            .getDefaultGeometryAttribute().getGeomType().getSubType());
517
        // TODO: Maybe do util class to get type and subtype of a featureStore
518
        // or a method in manager
519
      }
520
      catch (Exception e) {
521
        throw new ParsePointException(e);
522
      }
523
      return point;
524
    }
525
    else {
526
      throw new ParsePointException(null);
527
    }
528
  }
529

    
530
  private JDockPanel getDockConsole() {
531
    if (dockConsole == null) {
532
      dockConsole = new JDockPanel(getConsolePanel());
533
    }
534
    return dockConsole;
535
  }
536

    
537
  public void showConsole() {
538
    if (isShowConsole) {
539
      return;
540
    }
541
    isShowConsole = true;
542
    getMapControl().remove(getDockConsole());
543
    getMapControl().setLayout(new BorderLayout());
544
    getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
545
    getDockConsole().setVisible(true);
546
    setCaretPosition();
547
  }
548

    
549
  public void hideConsole() {
550
    isShowConsole = false;
551
    getDockConsole().setVisible(false);
552

    
553
  }
554

    
555
  private JConsole getConsolePanel() {
556
    if (console == null) {
557
      console = new JConsole(true);
558
      // Para distinguir cuando se est? escribiendo sobre la consola y
559
      // cuando no.
560
      console.setJTextName("VectorEditingConsole");
561
    }
562
    return console;
563
  }
564

    
565
  private void addConsoleListener(String prefix, ResponseListener listener) {
566
    consoleResponseAdapter.putSpaceListener(prefix, listener);
567

    
568
  }
569

    
570
  static class ResponseAdapter implements ResponseListener {
571

    
572
    private HashMap<String, ResponseListener> spaceListener = new HashMap<String, ResponseListener>();
573

    
574
    public void putSpaceListener(String namespace, ResponseListener listener) {
575
      spaceListener.put(namespace, listener);
576
    }
577

    
578
    public void acceptResponse(String response) {
579
      boolean nameSpace = false;
580
      int n = -1;
581
      if (response != null) {
582
        if ((n = response.indexOf(':')) != -1) {
583
          nameSpace = true;
584
        }
585
      }
586

    
587
      if (nameSpace) {
588
        ResponseListener listener = spaceListener.get(response.substring(0, n));
589
        if (listener != null) {
590
          listener.acceptResponse(response.substring(n + 1));
591
        }
592
      }
593
      else {
594
        Iterator<ResponseListener> i = spaceListener.values().iterator();
595
        while (i.hasNext()) {
596
          ResponseListener listener = i.next();
597
          listener.acceptResponse(response);
598
        }
599
      }
600
    }
601
  }
602
}