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

History | View | Annotate | Download (15.1 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.Color;
10
import java.awt.Graphics;
11
import java.awt.Image;
12
import java.awt.event.MouseEvent;
13
import java.awt.image.BufferedImage;
14
import java.util.HashMap;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Stack;
19

    
20
import org.gvsig.fmap.dal.feature.FeatureStore;
21
import org.gvsig.fmap.geom.Geometry;
22
import org.gvsig.fmap.geom.primitive.Point;
23
import org.gvsig.fmap.mapcontext.ViewPort;
24
import org.gvsig.fmap.mapcontext.layers.FLayers;
25
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
26
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
27
import org.gvsig.fmap.mapcontrol.MapControlLocator;
28
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
29
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
30
import org.gvsig.fmap.mapcontrol.tools.Listeners.ToolListener;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.i18n.I18nManager;
33
import org.gvsig.vectorediting.lib.api.DrawingStatus;
34
import org.gvsig.vectorediting.lib.api.EditingLocator;
35
import org.gvsig.vectorediting.lib.api.EditingManager;
36
import org.gvsig.vectorediting.lib.api.EditingService;
37
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
38
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
39
import org.gvsig.vectorediting.lib.api.exceptions.CreateEditingBehaviorException;
40
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
41
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
42
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
43
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
44
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
45
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
46
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
47
import org.gvsig.vectorediting.swing.api.EditingBehavior;
48
import org.gvsig.vectorediting.swing.api.EditingContext;
49
import org.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51

    
52
public class DefaultEditingBehavior extends Behavior implements EditingBehavior {
53

    
54
  private static final Logger logger = LoggerFactory
55
      .getLogger(DefaultEditingBehavior.class);
56

    
57
  private Map<FLyrVect, EditingService> serviceRegistration;
58

    
59
  private Stack<EditingService> serviceStack;
60

    
61
  private EditingContext editingContext;
62

    
63
  private FLyrVect currentLayer;
64

    
65
  private EditingServiceParameter currentParam;
66

    
67
  private FeatureStore featureStore;
68

    
69
  private Point adjustedPoint;
70

    
71
  private I18nManager i18nManager = ToolsLocator.getI18nManager();
72

    
73
  private static final Image imageCursor = new BufferedImage(32, 32,
74
      BufferedImage.TYPE_INT_ARGB);
75
  static {
76
    Graphics g = imageCursor.getGraphics();
77
    int size1 = 15;
78
    int x = 16;
79
    int y = 16;
80
    g.setColor(Color.MAGENTA);
81
    g.drawLine((x - size1), (y), (x + size1), (y));
82
    g.drawLine((x), (y - size1), (x), (y + size1));
83
    g.drawRect((x - 6), (y - 6), 12, 12);
84
    g.drawRect((x - 3), (y - 3), 6, 6);
85
  }
86

    
87
  public DefaultEditingBehavior(EditingContext editingContext) throws CreateEditingBehaviorException {
88
    if (editingContext.getMapControl() != null) {
89
      this.editingContext = editingContext;
90
      serviceRegistration = new HashMap<FLyrVect, EditingService>();
91
      serviceStack = new Stack<EditingService>();
92

    
93
      FLayers layers = editingContext.getMapControl().getMapContext().getLayers();
94
      for (int i = 0; i < layers.getLayersCount(); i++) {
95
        if (layers.getLayer(i) instanceof FLyrVect
96
            && layers.getLayer(i).isActive())
97
          changeCurrentLayer((FLyrVect) layers.getLayer(i));
98
      }
99
    }
100
  }
101

    
102
  public void activateService(String name) {
103

    
104
    EditingManager manager = EditingLocator.getManager();
105

    
106
    if (currentLayer != null) {
107
      EditingService service = serviceRegistration.get(currentLayer);
108
      if (service == null || !service.getName().equals(name)) {
109
        service = (EditingService) manager.getEditingService(name,
110
            currentLayer.getFeatureStore());
111
        serviceRegistration.put(currentLayer, service);
112
      }
113
      if (service != null) {
114
        this.enableSelection(false);
115
        try {
116
          service.start();
117
        }
118
        catch (StartServiceException e) {
119
          logger.error(
120
              String.format("Can't start the service %(s)", service.getName()),
121
              e);
122
        }
123
        if (serviceStack.isEmpty()
124
            || getActiveService().next().getTypes()
125
                .contains(EditingServiceParameter.TYPE.GEOMETRY)) {
126
          setActiveService(service);
127
        }
128
        else {
129
          serviceStack.clear();
130
          setActiveService(service);
131
        }
132
        getNextParameter();
133
      }
134
    }
135
  }
136

    
137
  /**
138
   * Shows description of parameter on console.
139
   */
140
  private void askQuestion(EditingServiceParameter param) {
141
    showConsoleMessage("\n#" + param.getDescription() + " > ");
142
  }
143

    
144
  public void cleanBehavior() {
145
    serviceStack.clear();
146
    currentParam = null;
147
    this.enableSelection(false);
148

    
149
    showConsoleMessage("\n" + i18nManager.getTranslation("select_new_tool")
150
        + "\n");
151
  }
152

    
153
  private void showConsoleMessage(String text) {
154
    editingContext.showConsoleMessage(text);
155
  }
156

    
157
  @Override
158
  public ToolListener getListener() {
159
    return new ToolListener() {
160

    
161
      /**
162
       *
163
       */
164
      public boolean cancelDrawing() {
165
        return false;
166
      }
167

    
168
      /**
169
       *
170
       */
171
      public Image getImageCursor() {
172
        return imageCursor;
173
      }
174
    };
175
  }
176

    
177
  /**
178
   * Gets next parameter of {@link #activateService(String)} and sets
179
   * {@link #currentParam}. If currentParam is null means all service parameters
180
   * have value and service doesn't need more values.
181
   */
182
  private void getNextParameter() {
183
    currentParam = getActiveService().next();
184
    if (currentParam == null) {
185
      finishService();
186
    }
187
    else {
188
      askQuestion(currentParam);
189
      if (currentParam.getTypes().contains(
190
          EditingServiceParameter.TYPE.SELECTION)) {
191
        enableSelection(true);
192
      }
193
      // setCaretPosition();
194
    }
195

    
196
  }
197

    
198
  private EditingService getActiveService() {
199
    if (!serviceStack.isEmpty()) {
200
      return serviceStack.peek();
201
    }
202
    return null;
203
  }
204

    
205
  private void setActiveService(EditingService service) {
206
    serviceStack.add(service);
207
  }
208

    
209
  private void finishService() {
210
    EditingService lastService = serviceStack.pop();
211
    try {
212
      if (serviceStack.isEmpty() || !getActiveService().next().getTypes()
213
              .contains(EditingServiceParameter.TYPE.GEOMETRY)) {
214
        lastService.finishAndStore();
215
        editingContext.getMapControl().rePaintDirtyLayers();
216
        setActiveService(lastService);
217
      }
218
      else if (!serviceStack.isEmpty() && getActiveService().next().getTypes()
219
              .contains(EditingServiceParameter.TYPE.GEOMETRY)) {
220
        Geometry geometry = lastService.finish();
221
        if (geometry != null) {
222
          getActiveService().setValue(geometry);
223
        } else {
224
          lastService.finishAndStore();
225
          editingContext.getMapControl().rePaintDirtyLayers();
226
          setActiveService(lastService);
227
        }
228
      }
229
      lastService.stop();
230
      lastService.start();
231
    }
232
    catch (InvalidEntryException ex) {
233
      showConsoleMessage(i18nManager.getTranslation("invalid_option"));
234
    }
235
    catch (FinishServiceException ex) {
236
      logger.error("Can't finish " + lastService.getName(), ex);
237
    }
238
    catch (StopServiceException ex) {
239
      logger.error("Can't stop " + lastService.getName(), ex);
240
    }
241
    catch (StartServiceException ex) {
242
      logger.error("Can't start " + lastService.getName(), ex);
243
    }
244
    getNextParameter();
245
  }
246

    
247
  public void mouseClicked(MouseEvent e) {
248
    ViewPort vp = editingContext.getMapControl().getViewPort();
249
    if (getActiveService() != null) {
250
      if (currentParam != null) {
251
        List<TYPE> typesOfParam = currentParam.getTypes();
252
        if (typesOfParam.contains(TYPE.LIST_POSITIONS) || typesOfParam.contains(TYPE.POSITION)) {
253
          if(typesOfParam.contains(TYPE.LIST_POSITIONS)){
254
            if (e.getClickCount() == 2) {
255
              finishService();
256
              return;
257
            }
258
          }
259
          Point point;
260
          point = vp.convertToMapPoint(e.getX(), e.getY());
261
          try {
262
            getActiveService().setValue(point);
263
          }
264
          catch (VectorEditingException ex) {
265
            logger.error("Invalid value %s", new Object[] { point });
266
          }
267
        }
268
        if (typesOfParam.contains(TYPE.SELECTION)) {
269
          // Do nothing
270
        }
271
        getNextParameter();
272
      }
273
    }
274
  }
275
  
276
  public void mouseEntered(MouseEvent e) throws BehaviorException {}
277

    
278
  public void mouseMoved(MouseEvent e) throws BehaviorException {
279
    ViewPort vp = editingContext.getMapControl().getViewPort();
280
    adjustedPoint = vp.convertToMapPoint(e.getX(), e.getY());
281
    getMapControl().repaint();
282
  }
283

    
284
  public void mousePressed(MouseEvent e) throws BehaviorException {}
285

    
286
  public void mouseReleased(MouseEvent e) throws BehaviorException {}
287

    
288
  public void paintComponent(MapControlDrawer mapControlDrawer) {
289
    super.paintComponent(mapControlDrawer);
290
    if (getActiveService() == null || adjustedPoint == null) {
291
      return;
292
    }
293

    
294
    DrawingStatus helperGeo = null;
295
    try {
296
      helperGeo = getActiveService().draw(adjustedPoint);
297
    }
298
    catch (VectorEditingException e) {
299
      logger.error("An error ocurred when draw service geometries", e);
300
    }
301
    if (helperGeo != null) {
302
      for (@SuppressWarnings("rawtypes")
303
      Iterator iterator = helperGeo.getGeometries().iterator(); iterator
304
          .hasNext();) {
305
        Geometry geometry = (Geometry) iterator.next();
306
        editingContext.getMapControl().getMapControlDrawer().draw(geometry,
307
            MapControlLocator.getMapControlManager().getAxisReferenceSymbol());
308
      }
309
    }
310
  }
311

    
312
  /**
313
   * Sets the layer received as parameter as {@link #currentLayer}
314
   * 
315
   * @param layer
316
   */
317
  public void changeCurrentLayer(FLyrVect layer) {
318
    this.currentLayer = layer;
319
    if (currentLayer != null) {
320
      this.featureStore = (FeatureStore) currentLayer.getFeatureStore();
321
    }
322

    
323
    serviceStack.clear();
324
    if (serviceRegistration.get(layer) != null) {
325
      setActiveService(serviceRegistration.get(layer));
326
    }
327
    if (getActiveService() != null && layer.isActive()) {
328
      getNextParameter();
329
    }
330
  }
331

    
332
  /**
333
   * Processes console entries from console. Tries to process entry in each type
334
   * of {@link #currentParam}. If there is some error, It will continue
335
   * checking. If entry has been processed, It will set value in
336
   * {@link #activeService}.
337
   * 
338
   * @param response Console entry.
339
   * @throws InvalidEntryException If console entries has not been able to
340
   *           process, it will throw an exception to indicate that entry is not
341
   *           valid.
342
   * @throws StopServiceException If there are some errors stopping service.
343
   */
344
  public void textEntered(String response) {
345
    if (response == null) {
346
      if (getActiveService() != null) {
347
        try {
348
          getActiveService().stop();
349
        }
350
        catch (StopServiceException e) {
351
          logger.error("Can't stop " + getActiveService().getName(), e);
352
        }
353
        cleanBehavior();
354
      }
355
    }
356
    else {
357
      List<TYPE> types = currentParam.getTypes();
358
      Point point = null;
359
      Double value = null;
360

    
361
      boolean insertedValue = false;
362
      if (!insertedValue && types.contains(TYPE.POSITION)
363
          || types.contains(TYPE.LIST_POSITIONS)) {
364
        try {
365
          point = parsePoint(response);
366
          if (point != null) {
367
            getActiveService().setValue(point);
368
            insertedValue = true;
369
          }
370
        }
371
        catch (VectorEditingException e) {
372
          // Do nothing to try other types
373
        }
374
      }
375
      if (!insertedValue && types.contains(TYPE.VALUE)) {
376
        try {
377
          value = parseValue(response);
378
          if (value != null) {
379
            getActiveService().setValue(value);
380
            insertedValue = true;
381
          }
382
        }
383
        catch (VectorEditingException e) {
384
          // Do nothing to try other types
385
        }
386

    
387
      }
388
      if (!insertedValue && types.contains(TYPE.OPTION)) {
389
        try {
390
          response = response.replace("\n", "");
391
          if (response != null) {
392
            getActiveService().setValue(response);
393
            insertedValue = true;
394
          }
395
        }
396
        catch (VectorEditingException e) {
397
          // Do nothing to try other types
398
        }
399
      }
400
      if (!insertedValue && types.contains(TYPE.SELECTION)) {
401
        if (response.equalsIgnoreCase("\n")){
402
          enableSelection(false);
403
          insertedValue = true;
404
          try {
405
            getActiveService()
406
                .setValue(featureStore.getFeatureSelection().clone());
407
          }
408
          catch (InvalidEntryException e) {
409
            showConsoleMessage(i18nManager.getTranslation("invalid_option"));
410
          }
411
          catch (Exception e) {
412
            cleanBehavior();
413
            logger.error("Can't access to selecction.", e);
414
          }
415
        }
416
      }
417
      if (!insertedValue) {
418
        showConsoleMessage(i18nManager.getTranslation("invalid_option"));
419
      }
420
      getNextParameter();
421
    }
422
  }
423

    
424
  /**
425
   * Parse String to value.
426
   * 
427
   * @param response String to be parsed.
428
   * @return Values of string.
429
   * @throws ParseValueException If there is error trying to parse
430
   *           <code>String</code>.
431
   */
432
  private Double parseValue(String response) throws ParseValueException {
433
    try {
434
      return Double.valueOf(response);
435
    }
436
    catch (Exception e) {
437
      throw new ParseValueException(e);
438
    }
439

    
440
  }
441

    
442
  /**
443
   * Parse String to point. Formats accepted: (x,y) and x,y.
444
   * 
445
   * @param response String to be parsed.
446
   * @return Point of string.
447
   * @throws ParsePointException If there is error trying to parse
448
   *           <code>String</code>.
449
   */
450
  private Point parsePoint(String response) throws ParsePointException {
451
    String[] numbers = new String[1];
452
    numbers[0] = response;
453
    numbers = response.split(",");
454
    if (numbers.length == 2) {
455
      if (numbers[0].startsWith("(") && numbers[1].endsWith(")\n")) { // CCS
456
        numbers[0] = numbers[0].replace("(", "");
457
        numbers[1] = numbers[1].replace(")\n", "");
458
      }
459
      double[] values;
460
      try {
461
        values = new double[] { Double.parseDouble(numbers[0]),
462
            Double.parseDouble(numbers[1]) };
463
      }
464
      catch (Exception e) {
465
        throw new ParsePointException(e);
466
      }
467

    
468
      Point point;
469
      try {
470
        point = geomManager.createPoint(values[0], values[1], currentLayer
471
            .getFeatureStore().getDefaultFeatureType()
472
            .getDefaultGeometryAttribute().getGeomType().getSubType());
473
        // TODO: Maybe do util class to get type and subtype of a featureStore
474
        // or a method in manager
475
      }
476
      catch (Exception e) {
477
        throw new ParsePointException(e);
478
      }
479
      return point;
480
    }
481
    else {
482
      throw new ParsePointException(null);
483
    }
484
  }
485

    
486
  private void enableSelection(boolean enableSelection) {
487
     editingContext.enableSelection(enableSelection);
488
  }
489
}