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 @ 65

History | View | Annotate | Download (18.4 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.tools.ToolsLocator;
46
import org.gvsig.tools.i18n.I18nManager;
47
import org.gvsig.utils.console.JConsole;
48
import org.gvsig.utils.console.JDockPanel;
49
import org.gvsig.utils.console.ResponseListener;
50
import org.gvsig.utils.console.jedit.JEditTextArea;
51
import org.gvsig.vectorediting.lib.api.DrawingStatus;
52
import org.gvsig.vectorediting.lib.api.EditingLocator;
53
import org.gvsig.vectorediting.lib.api.EditingManager;
54
import org.gvsig.vectorediting.lib.api.EditingService;
55
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
56
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
57
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
58
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
59
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
60
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
61
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
62
import org.gvsig.vectorediting.swing.api.EditingBehavior;
63
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65

    
66
public class DefaultEditingBehavior extends Behavior implements EditingBehavior {
67

    
68
  private static final Logger logger = LoggerFactory
69
      .getLogger(DefaultEditingBehavior.class);
70

    
71
  private Map<FLyrVect, EditingService> serviceRegistration;
72

    
73
  private MapControl mapControl;
74

    
75
  private FLyrVect currentLayer;
76

    
77
  private EditingService activeService;
78

    
79
  private EditingServiceParameter currentParam;
80

    
81
  private Point adjustedPoint;
82

    
83
  private StatusBarListener sbl = null;
84

    
85
  private JConsole console;
86

    
87
  private JDockPanel dockConsole = null;
88

    
89
  private boolean isShowConsole;
90

    
91
  protected ResponseAdapter consoleResponseAdapter;
92

    
93
  private I18nManager i18nManager = ToolsLocator.getI18nManager();
94

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

    
109
  private LayerListener layerListener = new LayerListener() {
110

    
111
    public void activationChanged(LayerEvent e) {
112
      FLayer layer = e.getSource();
113
      if (layer instanceof FLyrVect) {
114

    
115
        if (layer.isActive() && layer.isEditing()) {
116
          showConsole();
117
          getMapControl().setTool("VectorEditing");
118
        }
119
        else if (!layer.isEditing() && layer.isActive()) {
120
          changeCurrentLayer((FLyrVect) layer);
121
          hideConsole();
122
          getMapControl().setTool("zoomIn");
123
        }
124
        changeCurrentLayer((FLyrVect) layer);
125

    
126
      }
127

    
128
    }
129

    
130
    public void drawValueChanged(LayerEvent e) {}
131

    
132
    public void editionChanged(LayerEvent e) {}
133

    
134
    public void nameChanged(LayerEvent e) {}
135

    
136
    public void visibilityChanged(LayerEvent e) {}
137
  };
138

    
139
  public void cleanBehavior() {
140
    activeService = null;
141
    currentParam = null;
142

    
143
    showConsoleMessage("\nSeleccione una herramienta\n");
144
    // MainFrame main = PluginServices.getMainFrame();
145
    // main.setSelectedTool(""); We can define a default tool. I.E Zoom in.
146
  }
147

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

    
162
    }
163
  }
164

    
165
  private void initConsolePanelListeners(JConsole jConsole) {
166
    consoleResponseAdapter = new ResponseAdapter();
167
    jConsole.addResponseListener(consoleResponseAdapter);
168
    addConsoleListener("ViewEditing", new ResponseListener() {
169

    
170
      public void acceptResponse(String response) {
171
        try {
172
          textEntered(response);
173
        }
174
        catch (VectorEditingException e) {
175
          showConsoleMessage(i18nManager.getTranslation("invalid_option"));
176
        }
177
        finally {
178
          if (activeService != null) {
179
            getNextParameter();
180
          }
181
        }
182
      }
183
    });
184

    
185
  }
186

    
187
  public void activateTool(String name) {
188

    
189
    EditingManager manager = EditingLocator.getManager();
190

    
191
    if (currentLayer != null) {
192
      EditingService service = serviceRegistration.get(currentLayer);
193
      if (service == null || !service.getName().equals(name)) {
194
        service = (EditingService) manager.getEditingService(name,
195
            currentLayer.getFeatureStore());
196
        serviceRegistration.put(currentLayer, service);
197
      }
198
      if (service != null) {
199
        this.activeService = service;
200
        try {
201
          service.start();
202
        }
203
        catch (StartServiceException e) {
204
          logger.error(
205
              String.format("Can't start the service %(s)", service.getName()),
206
              e);
207
        }
208
        getNextParameter();
209
      }
210
    }
211
  }
212

    
213
  private void askQuestion(EditingServiceParameter param) {
214
    if (getConsolePanel() != null) {
215
      showConsoleMessage("\n#" + param.getDescription() + " > ");
216
    }
217
  }
218

    
219
  private void showConsoleMessage(String text) {
220
    getConsolePanel().addText(text, JConsole.MESSAGE);
221
  }
222

    
223
  @Override
224
  public ToolListener getListener() {
225
    return new ToolListener() {
226

    
227
      /**
228
       *
229
       */
230
      public boolean cancelDrawing() {
231
        return false;
232
      }
233

    
234
      /**
235
       *
236
       */
237
      public Image getImageCursor() {
238
        return imageCursor;
239
      }
240
    };
241
  }
242

    
243
  private void getNextParameter() {
244
    currentParam = activeService.next();
245
    if (currentParam == null) {
246
      finishAndStartService();
247
    }
248
    else {
249
      askQuestion(currentParam);
250
      setCaretPosition();
251
    }
252

    
253
  }
254

    
255
  private void finishAndStartService() {
256
    try {
257
      activeService.finish();
258
    }
259
    catch (VectorEditingException e) {
260
      logger.error("An error ocurred when try to finish service", e);
261
    }
262
    mapControl.rePaintDirtyLayers();
263
    try {
264
      activeService.start();
265
    }
266
    catch (StartServiceException e) {
267
      logger.error(String.format("Can't start the service %(s)",
268
          activeService.getName()), e);
269
    }
270
    getNextParameter();
271
  }
272

    
273
  private void initMapControlListeners(MapControl mapControl) {
274

    
275
    MapContext context = mapControl.getMapContext();
276
    FLayers layers = context.getLayers();
277
    layers.addLayerListener(layerListener);
278

    
279
    layers.addLayerCollectionListener(new LayerCollectionListener() {
280

    
281
      public void layerAdded(LayerCollectionEvent e) {
282
        FLayers layers2 = e.getLayers();
283
        for (int i = 0; i < layers2.getLayersCount(); i++) {
284
          FLayer layer = layers2.getLayer(i);
285
          if (layer instanceof FLyrVect) {
286
            ((FLyrVect) layer).addLayerListener(layerListener);
287
          }
288
        }
289
      }
290

    
291
      public void layerAdding(LayerCollectionEvent e)
292
          throws CancelationException {}
293

    
294
      public void layerMoved(LayerPositionEvent e) {}
295

    
296
      public void layerMoving(LayerPositionEvent e) throws CancelationException {}
297

    
298
      public void layerRemoved(LayerCollectionEvent e) {
299
        FLayers layers2 = e.getLayers();
300
        for (int i = 0; i < layers2.getLayersCount(); i++) {
301
          FLayer layer = layers2.getLayer(i);
302
          if (layer instanceof FLyrVect) {
303
            ((FLyrVect) layer).removeLayerListener(layerListener);
304
          }
305
        }
306
      }
307

    
308
      public void layerRemoving(LayerCollectionEvent e)
309
          throws CancelationException {}
310

    
311
      public void visibilityChanged(LayerCollectionEvent e)
312
          throws CancelationException {}
313
    });
314
  }
315

    
316
  public void mouseClicked(MouseEvent e) {
317
    ViewPort vp = mapControl.getViewPort();
318
    if (activeService != null) {
319
      if (currentParam != null) {
320
        List<TYPE> typesOfParam = currentParam.getTypes();
321
        if (typesOfParam.contains(TYPE.LIST_POSITIONS)) {
322
          if (e.getClickCount() == 2) {
323
            finishAndStartService();
324
            return;
325
          }
326
          Point point;
327
          point = vp.convertToMapPoint(e.getX(), e.getY());
328
          try {
329
            this.activeService.value(point);
330
          }
331
          catch (VectorEditingException ex) {
332
            logger.error("Invalid value %s", new Object[] { point });
333
          }
334
        }
335
        if (typesOfParam.contains(TYPE.POSITION)) {
336
          Point point;
337
          point = vp.convertToMapPoint(e.getX(), e.getY());
338
          try {
339
            this.activeService.value(point);
340
          }
341
          catch (VectorEditingException ex) {
342
            logger.error("Invalid value %s", new Object[] { point });
343
          }
344
          // TODO: Comprobar el resto de casos:
345
          // TYPE.VALUE,
346
          // TYPE.OPTION, TYPE.SELECTION,
347
          // TYPE.GEOMETRY:
348
        }
349
        getNextParameter();
350
      }
351
    }
352
  }
353

    
354
  public void mouseEntered(MouseEvent e) throws BehaviorException {
355
    // TODO Auto-generated method stub
356
  }
357

    
358
  public void mouseMoved(MouseEvent e) throws BehaviorException {
359
    ViewPort vp = mapControl.getViewPort();
360
    adjustedPoint = vp.convertToMapPoint(e.getX(), e.getY());
361
    showCoords(e.getPoint());
362

    
363
    getMapControl().repaint();
364
  }
365

    
366
  public void mousePressed(MouseEvent e) throws BehaviorException {
367
    // TODO Auto-generated method stub
368
  }
369

    
370
  public void mouseReleased(MouseEvent e) throws BehaviorException {
371
    // TODO Auto-generated method stub
372
  }
373

    
374
  public void paintComponent(MapControlDrawer mapControlDrawer) {
375
    super.paintComponent(mapControlDrawer);
376
    if (activeService == null || adjustedPoint == null) {
377
      return;
378
    }
379

    
380
    DrawingStatus helperGeo = null;
381
    try {
382
      helperGeo = activeService.draw(adjustedPoint);
383
    }
384
    catch (VectorEditingException e) {
385
      logger.error("An error ocurred when draw service geometries", e);
386
    }
387
    if (helperGeo != null) {
388
      for (Iterator iterator = helperGeo.getGeometries().iterator(); iterator
389
          .hasNext();) {
390
        Geometry geometry = (Geometry) iterator.next();
391
        mapControl.getMapControlDrawer().draw(geometry,
392
            MapControlLocator.getMapControlManager().getAxisReferenceSymbol());
393
      }
394
    }
395
  }
396

    
397
  private void setCaretPosition() {
398

    
399
    JEditTextArea jeta = getConsolePanel().getTxt();
400
    jeta.requestFocusInWindow();
401
    jeta.setCaretPosition(jeta.getText().length());
402

    
403
  }
404

    
405
  private void changeCurrentLayer(FLyrVect layer) {
406
    this.currentLayer = layer;
407
    this.activeService = serviceRegistration.get(layer);
408
    if (activeService != null) {
409
      getNextParameter();
410
      MainFrame main = PluginServices.getMainFrame();
411
      main.setSelectedTool(activeService.getName());
412
    }
413
  }
414

    
415
  private void showCoords(Point2D point) {
416
    String[] axisText = new String[2];
417
    axisText[0] = "X = ";
418
    axisText[1] = "Y = ";
419

    
420
    ViewPort vp = mapControl.getMapContext().getViewPort();
421
    IProjection iProj = vp.getProjection();
422
    Point p = vp.convertToMapPoint(point);
423
    Point2D p2D = new Point2D.Double(p.getX(), p.getY());
424

    
425
    sbl.setFractionDigits(p2D);
426
    axisText = sbl.setCoorDisplayText(axisText);
427
    MainFrame mF = PluginServices.getMainFrame();
428

    
429
    if (mF != null) {
430
      mF.getStatusBar().setMessage(
431
          "units",
432
          PluginServices.getText(this,
433
              MapContext.getDistanceNames()[vp.getDistanceUnits()]));
434
      mF.getStatusBar().setControlValue("scale",
435
          String.valueOf(mapControl.getMapContext().getScaleView()));
436
      mF.getStatusBar().setMessage("projection", iProj.getAbrev());
437

    
438
      String[] coords = sbl.getCoords(p2D);
439
      mF.getStatusBar().setMessage("x", axisText[0] + coords[0]);
440
      mF.getStatusBar().setMessage("y", axisText[1] + coords[1]);
441
    }
442

    
443
  }
444

    
445
  private void textEntered(String response) throws InvalidEntryException {
446
    if (response == null) {
447
      if(activeService != null){
448
        this.activeService.stop();
449
        cleanBehavior();
450
      }
451
    }
452
    else {
453
      List<TYPE> types = currentParam.getTypes();
454
      Point point = null;
455
      Double value = null;
456

    
457
      boolean insertedValue = false;
458
      if (!insertedValue && types.contains(TYPE.POSITION)
459
          || types.contains(TYPE.LIST_POSITIONS)) {
460
        try {
461
          point = parsePoint(response);
462
          if (point != null) {
463
            this.activeService.value(point);
464
            insertedValue = true;
465
          }
466
        }
467
        catch (VectorEditingException e) {
468
          // Do nothing
469
        }
470
      }
471
      if (!insertedValue && types.contains(TYPE.VALUE)) {
472
        try {
473
          value = parseValue(response);
474
          if (value != null) {
475
            this.activeService.value(value);
476
            insertedValue = true;
477
          }
478
        }
479
        catch (VectorEditingException e) {
480
          // Do nothing
481
        }
482

    
483
      }
484
      if (!insertedValue && types.contains(TYPE.OPTION)) {
485
        try {
486
          response = response.replace("\n", "");
487
          if (response != null) {
488
            this.activeService.value(response);
489
            insertedValue = true;
490
          }
491
        }
492
        catch (VectorEditingException e) {
493
          // Do nothing
494
        }
495
      }
496
      // TODO: contemplar el resto de casos
497
      // TYPE.OPTION,
498
      // TYPE.SELECTION,
499
      // TYPE.GEOMETRY
500
      if (!insertedValue) {
501
        throw new InvalidEntryException(null);
502
      }
503
    }
504
  }
505

    
506
  private Double parseValue(String response) throws ParseValueException {
507
    try {
508
      return Double.valueOf(response);
509
    }
510
    catch (Exception e) {
511
      throw new ParseValueException(e);
512
    }
513

    
514
  }
515

    
516
  private Point parsePoint(String response) throws ParsePointException {
517
    String[] numbers = new String[1];
518
    numbers[0] = response;
519
    numbers = response.split(",");
520
    if (numbers.length == 2) {
521
      if (numbers[0].startsWith("(") && numbers[1].endsWith(")\n")) { // CCS
522
        numbers[0] = numbers[0].replace("(", "");
523
        numbers[1] = numbers[1].replace(")\n", "");
524
      }
525
      double[] values;
526
      try {
527
        values = new double[] { Double.parseDouble(numbers[0]),
528
            Double.parseDouble(numbers[1]) };
529
      }
530
      catch (Exception e) {
531
        throw new ParsePointException(e);
532
      }
533

    
534
      Point point;
535
      try {
536
        point = geomManager.createPoint(values[0], values[1], currentLayer
537
            .getFeatureStore().getDefaultFeatureType()
538
            .getDefaultGeometryAttribute().getGeomType().getSubType());
539
        // TODO: Maybe do util class to get type and subtype of a featureStore
540
        // or a method in manager
541
      }
542
      catch (Exception e) {
543
        throw new ParsePointException(e);
544
      }
545
      return point;
546
    }
547
    else {
548
      throw new ParsePointException(null);
549
    }
550
  }
551

    
552
  private JDockPanel getDockConsole() {
553
    if (dockConsole == null) {
554
      dockConsole = new JDockPanel(getConsolePanel());
555
    }
556
    return dockConsole;
557
  }
558

    
559
  public void showConsole() {
560
    if (isShowConsole) {
561
      return;
562
    }
563
    isShowConsole = true;
564
    getMapControl().remove(getDockConsole());
565
    getMapControl().setLayout(new BorderLayout());
566
    getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
567
    getDockConsole().setVisible(true);
568
    setCaretPosition();
569
  }
570

    
571
  public void hideConsole() {
572
    isShowConsole = false;
573
    getDockConsole().setVisible(false);
574

    
575
  }
576

    
577
  private JConsole getConsolePanel() {
578
    if (console == null) {
579
      console = new JConsole(true);
580
      // Para distinguir cuando se est? escribiendo sobre la consola y
581
      // cuando no.
582
      console.setJTextName("VectorEditingConsole");
583
    }
584
    return console;
585
  }
586

    
587
  private void addConsoleListener(String prefix, ResponseListener listener) {
588
    consoleResponseAdapter.putSpaceListener(prefix, listener);
589

    
590
  }
591

    
592
  static class ResponseAdapter implements ResponseListener {
593

    
594
    private HashMap<String, ResponseListener> spaceListener = new HashMap<String, ResponseListener>();
595

    
596
    public void putSpaceListener(String namespace, ResponseListener listener) {
597
      spaceListener.put(namespace, listener);
598
    }
599

    
600
    public void acceptResponse(String response) {
601
      boolean nameSpace = false;
602
      int n = -1;
603
      if (response != null) {
604
        if ((n = response.indexOf(':')) != -1) {
605
          nameSpace = true;
606
        }
607
      }
608

    
609
      if (nameSpace) {
610
        ResponseListener listener = spaceListener.get(response.substring(0, n));
611
        if (listener != null) {
612
          listener.acceptResponse(response.substring(n + 1));
613
        }
614
      }
615
      else {
616
        Iterator<ResponseListener> i = spaceListener.values().iterator();
617
        while (i.hasNext()) {
618
          ResponseListener listener = i.next();
619
          listener.acceptResponse(response);
620
        }
621
      }
622
    }
623
  }
624
}