Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / EditionManager.java @ 38564

History | View | Annotate | Download (15.8 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 visibilityChanged(LayerEvent e) {
119
    }
120

    
121
    public void activationChanged(LayerEvent e) {
122
        if (e.getSource().isActive()) {
123
            ile = getLayerEdited(e.getSource());
124
        }
125
        if (ile == null || ile.getLayer().equals(e.getSource())) {
126

    
127
            if (ile != null && !ile.getLayer().isActive()) {
128
                VectorialLayerEdited lastVLE = (VectorialLayerEdited) ile;
129
                lastVLE.activationLost(e);
130
            }
131
            if (e.getSource() instanceof FLyrVect) {
132
                VectorialLayerEdited vle = null;
133
                vle = (VectorialLayerEdited) getLayerEdited(e.getSource());
134
                ile = vle;
135
                if (getMapControl() != null && vle != null
136
                    && vle.getLayer().isActive()) {
137
                    getMapControl().setTool("cadtooladapter");
138
                    vle.activationGained(e);
139
                    return;
140
                }
141
            }
142
            if (getMapControl() != null) {
143
                getMapControl().setTool("zoomIn");
144
                PluginServices.getMainFrame().setSelectedTool("ZOOM_IN");
145
            }
146
        }
147
    }
148

    
149
    public void nameChanged(LayerEvent e) {
150
    }
151

    
152
    public void editionChanged(LayerEvent e) {
153
        ILayerEdited lyrEdit = getLayerEdited(e.getSource());
154

    
155
        // Si no est? en la lista, comprobamos que est? en edici?n
156
        // y lo a?adimos
157
        if ((lyrEdit == null) && e.getSource().isEditing()) {
158
            lyrEdit =
159
                FactoryLayerEdited.createLayerEdited(e.getSource(), mapCtrl);
160
            editedLayers.add(lyrEdit);
161
            if (getMapControl() != null) {
162
                getMapControl().setTool("cadtooladapter");
163
                CADExtension.setCADTool("_selection", true);
164
            }
165
            PluginServices.getMainFrame().setSelectedTool("_selection");
166
            // idActiveLayer = editedLayers.size() - 1;
167
            ile = getLayerEdited(e.getSource());
168
            LOG.debug("NUEVA CAPA EN EDICION: {}", lyrEdit.getLayer().getName());
169

    
170
            // Ponemos el resto de temas desactivados
171
            if (mapCtrl != null)
172
                mapCtrl.getMapContext().getLayers().setActive(false);
173
            // y activamos el nuevo.
174
            e.getSource().setActive(true);
175

    
176
            if (e.getSource() instanceof FLyrVect) {
177
                FLyrVect fLyrVect = (FLyrVect) e.getSource();
178
                ((VectorialLayerEdited) lyrEdit)
179
                    .setEditionChangeManager(new EditionChangeManager(fLyrVect));
180

    
181
                addCheckRules(fLyrVect);
182
            }
183
        } else {
184
            for (int i = 0; i < editedLayers.size(); i++) {
185
                VectorialLayerEdited vle =
186
                    (VectorialLayerEdited) editedLayers.get(i);
187
                if (vle.equals(lyrEdit)) {
188
                    editedLayers.remove(i);
189
                    ile = null;
190
                    return;
191
                }
192
            }
193
        }
194

    
195
    }
196

    
197
    /**
198
     * @return Returns the activeLayerEdited. Null if there isn't any active AND
199
     *         edited
200
     */
201
    public ILayerEdited getActiveLayerEdited() {
202
        return ile;
203
    }
204

    
205
    /**
206
     * @return Returns the mapCtrl.
207
     */
208
    public MapControl getMapControl() {
209
        return mapCtrl;
210
    }
211

    
212
    /**
213
     * @param mapCtrl
214
     *            The mapCtrl to set.
215
     */
216
    public void setMapControl(MapControl mapCtrl) {
217
        if (mapCtrl != null) {
218
            this.mapCtrl = mapCtrl;
219
            mapCtrl.getMapContext().getLayers().addLayerListener(this);
220
            mapCtrl.getMapContext().getLayers()
221
                .addLayerCollectionListener(this);
222
        }
223
    }
224

    
225
    public void layerAdded(LayerCollectionEvent e) {
226
        // Nothing to do
227

    
228
    }
229

    
230
    public void layerMoved(LayerPositionEvent e) {
231
        // Nothing to do
232
    }
233

    
234
    public void layerRemoved(LayerCollectionEvent e) {
235
        VectorialLayerEdited vle =
236
            (VectorialLayerEdited) getActiveLayerEdited();
237
        if (vle != null && vle.getLayer().isActive()) {
238
            try {
239
                vle.clearSelection();
240
            } catch (DataException e1) {
241
                NotificationManager.addError(e1);
242
            }
243
            editedLayers.remove(vle);
244
            getMapControl().setTool("zoomIn");
245
            FLyrVect lv = (FLyrVect) vle.getLayer();
246
            if (e.getAffectedLayer().equals(lv)) {
247
                IWindow window =
248
                    PluginServices.getMDIManager().getActiveWindow();
249
                if (window instanceof DefaultViewPanel) {
250
                    DefaultViewPanel view = (DefaultViewPanel) window;
251
                    view.hideConsole();
252
                    view.validate();
253
                    view.repaint();
254
                }
255
            }
256
        }
257
        PluginServices.getMainFrame().enableControls();
258
    }
259

    
260
    public void layerAdding(LayerCollectionEvent e) throws CancelationException {
261
        // Nothing to do
262
    }
263

    
264
    public void layerMoving(LayerPositionEvent e) throws CancelationException {
265
        // Nothing to do
266
    }
267

    
268
    public void layerRemoving(LayerCollectionEvent e)
269
        throws CancelationException {
270
        // Nothing to do
271
    }
272

    
273
    public void activationChanged(LayerCollectionEvent e)
274
        throws CancelationException {
275
        // Nothing to do
276
    }
277

    
278
    public void visibilityChanged(LayerCollectionEvent e)
279
        throws CancelationException {
280
        // Nothing to do
281
    }
282

    
283
    public void drawValueChanged(LayerEvent e) {
284
        // Nothing to do
285
    }
286

    
287
    class CheckMandatoryAttributtes extends AbstractFeatureRule {
288

    
289
        protected CheckMandatoryAttributtes() {
290
            super("CheckMandatoryAttributtes", "CheckMandatoryAttributtes");
291
        }
292

    
293
        public void validate(Feature feature, FeatureStore featureStore)
294
            throws DataException {
295
            // Comprobar si hay campos obligatorios y presentar formulario
296
            FeatureType featureType = feature.getType();
297
            FeatureAttributeDescriptor[] attributeDescriptors =
298
                featureType.getAttributeDescriptors();
299
            boolean showForm = false;
300
            for (int i = 0; i < attributeDescriptors.length; i++) {
301
                FeatureAttributeDescriptor attrDesc = attributeDescriptors[i];
302
                if ((attrDesc.isPrimaryKey() || !attrDesc.allowNull())
303
                    && feature.get(attrDesc.getName()) == null) {
304
                    showForm = true;
305
                    break;
306
                }
307
            }
308
            if (showForm) {
309
                askRequiredAttributtes((EditableFeature) feature, featureStore);
310
            }
311
        }
312

    
313
    }
314

    
315
    private void askRequiredAttributtes(final EditableFeature feature,
316
        final FeatureStore store)
317
        throws FeatureRuleMandatoryAttributesException {
318

    
319
        // Comprobar que estamos en el thread de swing y si no excepcion
320
        if (!SwingUtilities.isEventDispatchThread()) {
321
            try {
322
                SwingUtilities.invokeAndWait(new Runnable() {
323

    
324
                    public void run() {
325
                        askRequiredAttributtes(feature, store);
326
                    }
327
                });
328
            } catch (Exception e1) {
329
                throw new FeatureRuleMandatoryAttributesException(e1,
330
                    store.getFullName());
331
            }
332
            return;
333
        }
334
        DynObjectSwingManager dynObjectSwinManager =
335
            ToolsSwingLocator.getDynObjectSwingManager();
336
        final JDynObjectComponent dynObjectComponent;
337
        try {
338
            dynObjectComponent =
339
                dynObjectSwinManager.createJDynObjectComponent(
340
                    feature.getAsDynObject(), true);
341
        } catch (Exception e) {
342
            
343
            // TODO This has to be improved
344
            // Instead of this warning, show dialog to
345
            // fill feature type 
346
            showBadValuesMessage(e.getMessage());
347
            return;
348
            
349
        }
350
        final JPanel panel = new JPanel();
351

    
352
        ButtonsPanel buttonsPanel =
353
            new ButtonsPanel(ButtonsPanel.BUTTONS_ACCEPTCANCEL);
354
        buttonsPanel.addButtonPressedListener(new ButtonsPanelListener() {
355

    
356
            public void actionButtonPressed(ButtonsPanelEvent e) {
357
                if (e.getButton() == ButtonsPanel.BUTTON_ACCEPT) {
358
                    dynObjectComponent.saveStatus();
359
                    panel.setVisible(false);
360
                }
361
                if (e.getButton() == ButtonsPanel.BUTTON_CANCEL) {
362
                    panel.setVisible(false);
363
                    throw new FeatureRuleMandatoryAttributesException(store
364
                        .getFullName());
365
                }
366
            }
367

    
368
        });
369
        panel.setLayout(new BorderLayout());
370
        ScrollPane scrollPanel = new ScrollPane();
371
        scrollPanel.add(dynObjectComponent.asJComponent(), BorderLayout.CENTER);
372
        panel.add(scrollPanel);
373
        panel.add(buttonsPanel, BorderLayout.SOUTH);
374
        panel.setPreferredSize(new Dimension(800, 600));
375
        WindowManager wm = ToolsSwingLocator.getWindowManager();
376
        wm.showWindow(panel, "Fill mandatory fields", WindowManager.MODE.DIALOG);
377

    
378
    }
379

    
380
    /**
381
     * @param message
382
     */
383
    private void showBadValuesMessage(String message) {
384
        
385
        ApplicationLocator.getManager().message(
386
            message,
387
            JOptionPane.WARNING_MESSAGE);
388
        
389
        /*
390
         * We cannot do this because window focus
391
         * causes exception in drawing
392
         * 
393
        IWindow iw = PluginServices.getMDIManager().getActiveWindow();
394
        Component pare = null;
395
        if (iw instanceof Component) {
396
            pare = (Component) iw;
397
        }
398
        
399
        String _tit = Messages.getText("editing");
400
        String _msg = Messages.getText("_Invalid_values_in_some_fields_must_be_edited_before_end_editing");
401
        _msg = _msg + "\n\n[" + message + "]";
402
        
403
        JOptionPane.showMessageDialog(
404
            pare,
405
            _msg, _tit,
406
            JOptionPane.WARNING_MESSAGE);
407
            */
408
    }
409

    
410
    private void addCheckRules(FLyrVect layer) {
411
        try {
412
            FeatureType featureType =
413
                layer.getFeatureStore().getDefaultFeatureType();
414
            FeatureRules featureRules = featureType.getRules();
415
            for (Iterator it = featureRules.iterator(); it.hasNext();) {
416
                FeatureRule rule = (FeatureRule) it.next();
417
                if (rule instanceof CheckMandatoryAttributtes) {
418
                    return;
419
                }
420
            }
421
            featureRules.add(new CheckMandatoryAttributtes());
422
        } catch (DataException e) {
423
            throw new RuntimeException(e);
424
        }
425
    }
426

    
427
    public class FeatureRuleMandatoryAttributesException extends
428
        DataRuntimeException {
429

    
430
        private static final long serialVersionUID = -7965533441336164612L;
431
        private final static String MESSAGE_FORMAT =
432
            "Can't apply rule in store %(store)s.";
433
        private final static String MESSAGE_KEY =
434
            "_FeatureRuleMandatoryAttributesException";
435

    
436
        public FeatureRuleMandatoryAttributesException(Throwable cause,
437
            String store) {
438
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
439
            this.setValue("store", store);
440
        }
441

    
442
        public FeatureRuleMandatoryAttributesException(String store) {
443
            super(MESSAGE_FORMAT, MESSAGE_KEY, serialVersionUID);
444
            this.setValue("store", store);
445
        }
446
    }
447

    
448
}