Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2060 / extensions / extEditing / src / org / gvsig / editing / EditionManager.java @ 39348

History | View | Annotate | Download (16.6 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.editing;
23

    
24
import java.awt.BorderLayout;
25
import java.awt.Dimension;
26
import java.awt.ScrollPane;
27
import java.util.ArrayList;
28
import java.util.Iterator;
29
import java.util.List;
30

    
31
import javax.swing.JOptionPane;
32
import javax.swing.JPanel;
33
import javax.swing.SwingUtilities;
34

    
35
import org.gvsig.andami.PluginServices;
36
import org.gvsig.andami.messages.NotificationManager;
37
import org.gvsig.andami.ui.mdiManager.IWindow;
38
import org.gvsig.app.ApplicationLocator;
39
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
40
import org.gvsig.editing.layers.FactoryLayerEdited;
41
import org.gvsig.editing.layers.ILayerEdited;
42
import org.gvsig.editing.layers.VectorialLayerEdited;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.DataRuntimeException;
45
import org.gvsig.fmap.dal.feature.AbstractFeatureRule;
46
import org.gvsig.fmap.dal.feature.EditableFeature;
47
import org.gvsig.fmap.dal.feature.Feature;
48
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
49
import org.gvsig.fmap.dal.feature.FeatureRule;
50
import org.gvsig.fmap.dal.feature.FeatureRules;
51
import org.gvsig.fmap.dal.feature.FeatureStore;
52
import org.gvsig.fmap.dal.feature.FeatureType;
53
import org.gvsig.fmap.mapcontext.layers.CancelationException;
54
import org.gvsig.fmap.mapcontext.layers.FLayer;
55
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
56
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
57
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
58
import org.gvsig.fmap.mapcontext.layers.LayerListener;
59
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
60
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
61
import org.gvsig.fmap.mapcontrol.MapControl;
62
import org.gvsig.gui.beans.buttonspanel.ButtonsPanel;
63
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelEvent;
64
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelListener;
65
import org.gvsig.tools.swing.api.ToolsSwingLocator;
66
import org.gvsig.tools.swing.api.dynobject.DynObjectSwingManager;
67
import org.gvsig.tools.swing.api.dynobject.JDynObjectComponent;
68
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
69
import org.slf4j.Logger;
70
import org.slf4j.LoggerFactory;
71

    
72
/**
73
 * 
74
 * El prop?sito de esta clase es centralizar el manejo de la
75
 * edici?n. Aqu? podemos encontrar una lista con todas
76
 * los temas en edici?n, y las propiedades que sean globales
77
 * e interesantes a la hora de ponerse a editar.
78
 * Por ejemplo, podemos poner aqu? el Grid que vamos a usar,
79
 * el MapControl que tenemos asociado, etc, etc.
80
 * Tambi?n ser? el responsable de mantener una lista de
81
 * listeners interesados en los eventos de edici?n, y
82
 * de lanzar los eventos que necesitemos.
83
 * Lo principal es una colecci?n de LayerEdited, y cada
84
 * LayerEdited es un wrapper alrededor de un tema que guarda
85
 * las propiedades de la edici?n.
86
 * 
87
 * Nuevo: Llevar aqu? el control de las tablas en edici?n tambi?n
88
 * y centralizar los listeners interesados en los eventos de edici?n.
89
 * 
90
 * TODO: Poner todo lo referente al EditionManager dentro de una vista.
91
 * para permitir tener varias vistas con temas en edici?n
92
 * 
93
 * @author fjp
94
 */
95
public class EditionManager implements LayerListener, LayerCollectionListener {
96

    
97
    private static final Logger LOG = LoggerFactory
98
        .getLogger(EditionManager.class);
99

    
100
    private List<ILayerEdited> editedLayers = new ArrayList<ILayerEdited>();
101
    private MapControl mapCtrl = null;
102
    private ILayerEdited ile = null;
103

    
104
    /**
105
     * @param lyr
106
     * @return
107
     */
108
    public ILayerEdited getLayerEdited(FLayer lyr) {
109
        ILayerEdited aux = null;
110
        for (int i = 0; i < editedLayers.size(); i++) {
111
            aux = editedLayers.get(i);
112
            if (aux.getLayer() == lyr)
113
                return aux;
114
        }
115
        return null;
116
    }
117
    
118
    public void editLayer(FLyrVect lv, DefaultViewPanel vista)
119
        throws DataException {
120

    
121
        CADExtension.initFocus();
122
        vista.showConsole();
123
        MapControl mapControl = vista.getMapControl();
124
        this.setMapControl(mapControl);
125

    
126
        lv.addLayerListener(this);
127

    
128
        // This line also enables the spatial cache for snapping:
129
        lv.getFeatureStore().edit();
130
        lv.getFeatureStore().addObserver(vista);
131

    
132
        ApplicationLocator.getManager().refreshMenusAndToolBars();
133

    
134
        lv.getFeatureStore().addObserver(mapControl);
135
        StartEditing.startCommandsApplicable(vista, lv);
136

    
137
        // vista.repaintMap();
138
        // ----------------------------
139
        // this forces a true repaint:
140
        lv.drawValueChanged(LayerEvent.createDrawValuesChangedEvent(lv, ""));
141

    
142
    }
143

    
144
    public void visibilityChanged(LayerEvent e) {
145
    }
146

    
147
    public void activationChanged(LayerEvent e) {
148
        if (e.getSource().isActive()) {
149
            ile = getLayerEdited(e.getSource());
150
        }
151
        if (ile == null || ile.getLayer().equals(e.getSource())) {
152

    
153
            if (ile != null && !ile.getLayer().isActive()) {
154
                VectorialLayerEdited lastVLE = (VectorialLayerEdited) ile;
155
                lastVLE.activationLost(e);
156
            }
157
            if (e.getSource() instanceof FLyrVect) {
158
                VectorialLayerEdited vle = null;
159
                vle = (VectorialLayerEdited) getLayerEdited(e.getSource());
160
                ile = vle;
161
                if (getMapControl() != null && vle != null
162
                    && vle.getLayer().isActive()) {
163
                    getMapControl().setTool("cadtooladapter");
164
                    vle.activationGained(e);
165
                    return;
166
                }
167
            }
168
            if (getMapControl() != null) {
169
                getMapControl().setTool("zoomIn");
170
                PluginServices.getMainFrame().setSelectedTool("ZOOM_IN");
171
            }
172
        }
173
    }
174

    
175
    public void nameChanged(LayerEvent e) {
176
    }
177

    
178
    public void editionChanged(LayerEvent e) {
179
        ILayerEdited lyrEdit = getLayerEdited(e.getSource());
180

    
181
        // Si no est? en la lista, comprobamos que est? en edici?n
182
        // y lo a?adimos
183
        if ((lyrEdit == null) && e.getSource().isEditing()) {
184
            lyrEdit =
185
                FactoryLayerEdited.createLayerEdited(e.getSource(), mapCtrl);
186
            editedLayers.add(lyrEdit);
187
            if (getMapControl() != null) {
188
                getMapControl().setTool("cadtooladapter");
189
                CADExtension.setCADTool("_selection", true);
190
            }
191
            PluginServices.getMainFrame().setSelectedTool("_selection");
192
            // idActiveLayer = editedLayers.size() - 1;
193
            ile = getLayerEdited(e.getSource());
194
            LOG.debug("NUEVA CAPA EN EDICION: {}", lyrEdit.getLayer().getName());
195

    
196
            // Ponemos el resto de temas desactivados
197
            if (mapCtrl != null)
198
                mapCtrl.getMapContext().getLayers().setActive(false);
199
            // y activamos el nuevo.
200
            e.getSource().setActive(true);
201

    
202
            if (e.getSource() instanceof FLyrVect) {
203
                FLyrVect fLyrVect = (FLyrVect) e.getSource();
204
                ((VectorialLayerEdited) lyrEdit)
205
                    .setEditionChangeManager(new EditionChangeManager(fLyrVect));
206

    
207
                addCheckRules(fLyrVect);
208
            }
209
        } else {
210
            for (int i = 0; i < editedLayers.size(); i++) {
211
                VectorialLayerEdited vle =
212
                    (VectorialLayerEdited) editedLayers.get(i);
213
                if (vle.equals(lyrEdit)) {
214
                    editedLayers.remove(i);
215
                    ile = null;
216
                    return;
217
                }
218
            }
219
        }
220

    
221
    }
222

    
223
    /**
224
     * @return Returns the activeLayerEdited. Null if there isn't any active AND
225
     *         edited
226
     */
227
    public ILayerEdited getActiveLayerEdited() {
228
        return ile;
229
    }
230

    
231
    /**
232
     * @return Returns the mapCtrl.
233
     */
234
    public MapControl getMapControl() {
235
        return mapCtrl;
236
    }
237

    
238
    /**
239
     * @param mapCtrl
240
     *            The mapCtrl to set.
241
     */
242
    public void setMapControl(MapControl mapCtrl) {
243
        if (mapCtrl != null) {
244
            this.mapCtrl = mapCtrl;
245
            mapCtrl.getMapContext().getLayers().addLayerListener(this);
246
            mapCtrl.getMapContext().getLayers()
247
                .addLayerCollectionListener(this);
248
        }
249
    }
250

    
251
    public void layerAdded(LayerCollectionEvent e) {
252
        // Nothing to do
253

    
254
    }
255

    
256
    public void layerMoved(LayerPositionEvent e) {
257
        // Nothing to do
258
    }
259

    
260
    public void layerRemoved(LayerCollectionEvent e) {
261
        VectorialLayerEdited vle =
262
            (VectorialLayerEdited) getActiveLayerEdited();
263
        if (vle != null && vle.getLayer().isActive()) {
264
            try {
265
                vle.clearSelection();
266
            } catch (DataException e1) {
267
                NotificationManager.addError(e1);
268
            }
269
            editedLayers.remove(vle);
270
            getMapControl().setTool("zoomIn");
271
            FLyrVect lv = (FLyrVect) vle.getLayer();
272
            if (e.getAffectedLayer().equals(lv)) {
273
                IWindow window =
274
                    PluginServices.getMDIManager().getActiveWindow();
275
                if (window instanceof DefaultViewPanel) {
276
                    DefaultViewPanel view = (DefaultViewPanel) window;
277
                    view.hideConsole();
278
                    view.validate();
279
                    view.repaint();
280
                }
281
            }
282
        }
283
        PluginServices.getMainFrame().enableControls();
284
    }
285

    
286
    public void layerAdding(LayerCollectionEvent e) throws CancelationException {
287
        // Nothing to do
288
    }
289

    
290
    public void layerMoving(LayerPositionEvent e) throws CancelationException {
291
        // Nothing to do
292
    }
293

    
294
    public void layerRemoving(LayerCollectionEvent e)
295
        throws CancelationException {
296
        // Nothing to do
297
    }
298

    
299
    public void activationChanged(LayerCollectionEvent e)
300
        throws CancelationException {
301
        // Nothing to do
302
    }
303

    
304
    public void visibilityChanged(LayerCollectionEvent e)
305
        throws CancelationException {
306
        // Nothing to do
307
    }
308

    
309
    public void drawValueChanged(LayerEvent e) {
310
        // Nothing to do
311
    }
312

    
313
    class CheckMandatoryAttributtes extends AbstractFeatureRule {
314

    
315
        protected CheckMandatoryAttributtes() {
316
            super("CheckMandatoryAttributtes", "CheckMandatoryAttributtes");
317
        }
318

    
319
        public void validate(Feature feature, FeatureStore featureStore)
320
            throws DataException {
321
            // Comprobar si hay campos obligatorios y presentar formulario
322
            FeatureType featureType = feature.getType();
323
            FeatureAttributeDescriptor[] attributeDescriptors =
324
                featureType.getAttributeDescriptors();
325
            boolean showForm = false;
326
            for (int i = 0; i < attributeDescriptors.length; i++) {
327
                FeatureAttributeDescriptor attrDesc = attributeDescriptors[i];
328
                if ((attrDesc.isPrimaryKey() || !attrDesc.allowNull())
329
                    && feature.get(attrDesc.getName()) == null) {
330
                    showForm = true;
331
                    break;
332
                }
333
            }
334
            if (showForm) {
335
                askRequiredAttributtes((EditableFeature) feature, featureStore);
336
            }
337
        }
338

    
339
    }
340

    
341
    private void askRequiredAttributtes(final EditableFeature feature,
342
        final FeatureStore store)
343
        throws FeatureRuleMandatoryAttributesException {
344

    
345
        // Comprobar que estamos en el thread de swing y si no excepcion
346
        if (!SwingUtilities.isEventDispatchThread()) {
347
            try {
348
                SwingUtilities.invokeAndWait(new Runnable() {
349

    
350
                    public void run() {
351
                        askRequiredAttributtes(feature, store);
352
                    }
353
                });
354
            } catch (Exception e1) {
355
                throw new FeatureRuleMandatoryAttributesException(e1,
356
                    store.getFullName());
357
            }
358
            return;
359
        }
360
        DynObjectSwingManager dynObjectSwinManager =
361
            ToolsSwingLocator.getDynObjectSwingManager();
362
        final JDynObjectComponent dynObjectComponent;
363
        try {
364
            dynObjectComponent =
365
                dynObjectSwinManager.createJDynObjectComponent(
366
                    feature.getAsDynObject(), true);
367
        } catch (Exception e) {
368
            
369
            // TODO This has to be improved
370
            // Instead of this warning, show dialog to
371
            // fill feature type 
372
            showBadValuesMessage(e.getMessage());
373
            return;
374
            
375
        }
376
        final JPanel panel = new JPanel();
377

    
378
        ButtonsPanel buttonsPanel =
379
            new ButtonsPanel(ButtonsPanel.BUTTONS_ACCEPTCANCEL);
380
        buttonsPanel.addButtonPressedListener(new ButtonsPanelListener() {
381

    
382
            public void actionButtonPressed(ButtonsPanelEvent e) {
383
                if (e.getButton() == ButtonsPanel.BUTTON_ACCEPT) {
384
                    dynObjectComponent.saveStatus();
385
                    panel.setVisible(false);
386
                }
387
                if (e.getButton() == ButtonsPanel.BUTTON_CANCEL) {
388
                    panel.setVisible(false);
389
                    throw new FeatureRuleMandatoryAttributesException(store
390
                        .getFullName());
391
                }
392
            }
393

    
394
        });
395
        panel.setLayout(new BorderLayout());
396
        ScrollPane scrollPanel = new ScrollPane();
397
        scrollPanel.add(dynObjectComponent.asJComponent(), BorderLayout.CENTER);
398
        panel.add(scrollPanel);
399
        panel.add(buttonsPanel, BorderLayout.SOUTH);
400
        panel.setPreferredSize(new Dimension(800, 600));
401
        WindowManager wm = ToolsSwingLocator.getWindowManager();
402
        wm.showWindow(panel, "Fill mandatory fields", WindowManager.MODE.DIALOG);
403

    
404
    }
405

    
406
    /**
407
     * @param message
408
     */
409
    private void showBadValuesMessage(String message) {
410
        
411
        ApplicationLocator.getManager().message(
412
            message,
413
            JOptionPane.WARNING_MESSAGE);
414
        
415
        /*
416
         * We cannot do this because window focus
417
         * causes exception in drawing
418
         * 
419
        IWindow iw = PluginServices.getMDIManager().getActiveWindow();
420
        Component pare = null;
421
        if (iw instanceof Component) {
422
            pare = (Component) iw;
423
        }
424
        
425
        String _tit = Messages.getText("editing");
426
        String _msg = Messages.getText("_Invalid_values_in_some_fields_must_be_edited_before_end_editing");
427
        _msg = _msg + "\n\n[" + message + "]";
428
        
429
        JOptionPane.showMessageDialog(
430
            pare,
431
            _msg, _tit,
432
            JOptionPane.WARNING_MESSAGE);
433
            */
434
    }
435

    
436
    private void addCheckRules(FLyrVect layer) {
437
        try {
438
            FeatureType featureType =
439
                layer.getFeatureStore().getDefaultFeatureType();
440
            FeatureRules featureRules = featureType.getRules();
441
            for (Iterator it = featureRules.iterator(); it.hasNext();) {
442
                FeatureRule rule = (FeatureRule) it.next();
443
                if (rule instanceof CheckMandatoryAttributtes) {
444
                    return;
445
                }
446
            }
447
            featureRules.add(new CheckMandatoryAttributtes());
448
        } catch (DataException e) {
449
            throw new RuntimeException(e);
450
        }
451
    }
452

    
453
    public class FeatureRuleMandatoryAttributesException extends
454
        DataRuntimeException {
455

    
456
        private static final long serialVersionUID = -7965533441336164612L;
457
        private final static String MESSAGE_FORMAT =
458
            "Can't apply rule in store %(store)s.";
459
        private final static String MESSAGE_KEY =
460
            "_FeatureRuleMandatoryAttributesException";
461

    
462
        public FeatureRuleMandatoryAttributesException(Throwable cause,
463
            String store) {
464
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
465
            this.setValue("store", store);
466
        }
467

    
468
        public FeatureRuleMandatoryAttributesException(String store) {
469
            super(MESSAGE_FORMAT, MESSAGE_KEY, serialVersionUID);
470
            this.setValue("store", store);
471
        }
472
    }
473

    
474
}