Statistics
| Revision:

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

History | View | Annotate | Download (14.9 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
import java.util.logging.Logger;
31

    
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.project.documents.view.gui.DefaultViewPanel;
39
import org.gvsig.editing.layers.FactoryLayerEdited;
40
import org.gvsig.editing.layers.ILayerEdited;
41
import org.gvsig.editing.layers.VectorialLayerEdited;
42
import org.gvsig.fmap.dal.exception.DataException;
43
import org.gvsig.fmap.dal.exception.DataRuntimeException;
44
import org.gvsig.fmap.dal.feature.AbstractFeatureRule;
45
import org.gvsig.fmap.dal.feature.EditableFeature;
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.FeatureRule;
49
import org.gvsig.fmap.dal.feature.FeatureRules;
50
import org.gvsig.fmap.dal.feature.FeatureStore;
51
import org.gvsig.fmap.dal.feature.FeatureType;
52
import org.gvsig.fmap.mapcontext.layers.CancelationException;
53
import org.gvsig.fmap.mapcontext.layers.FLayer;
54
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
55
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
56
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
57
import org.gvsig.fmap.mapcontext.layers.LayerListener;
58
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
59
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
60
import org.gvsig.fmap.mapcontrol.MapControl;
61
import org.gvsig.gui.beans.buttonspanel.ButtonsPanel;
62
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelEvent;
63
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelListener;
64
import org.gvsig.tools.service.ServiceException;
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

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

    
95
    private List<ILayerEdited> editedLayers = new ArrayList<ILayerEdited>();
96
    // private ArrayList activeLayerEdited = new ArrayList();
97
    private MapControl mapCtrl = null;
98
    private ILayerEdited ile = null;
99

    
100
    // private int idActiveLayer=0;
101

    
102
    /**
103
     * @param lyr
104
     * @return
105
     */
106
    public ILayerEdited getLayerEdited(FLayer lyr) {
107
        ILayerEdited aux = null;
108
        for (int i = 0; i < editedLayers.size(); i++) {
109
            aux = editedLayers.get(i);
110
            if (aux.getLayer() == lyr)
111
                return aux;
112
        }
113
        return null;
114
    }
115

    
116
    public void visibilityChanged(LayerEvent e) {
117
    }
118

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

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

    
147
    public void nameChanged(LayerEvent e) {
148
    }
149

    
150
    public void editionChanged(LayerEvent e) {
151
        Logger.global.info(e.toString());
152
        ILayerEdited lyrEdit = getLayerEdited(e.getSource());
153

    
154
        // Si no est? en la lista, comprobamos que est? en edici?n
155
        // y lo a?adimos
156
        if ((lyrEdit == null) && e.getSource().isEditing()) {
157
            lyrEdit =
158
                FactoryLayerEdited.createLayerEdited(e.getSource(), mapCtrl);
159
            editedLayers.add(lyrEdit);
160
            if (getMapControl() != null) {
161
                getMapControl().setTool("cadtooladapter");
162
                CADExtension.setCADTool("_selection", true);
163
            }
164
            PluginServices.getMainFrame().setSelectedTool("_selection");
165
            // idActiveLayer = editedLayers.size() - 1;
166
            ile = getLayerEdited(e.getSource());
167
            System.out.println("NUEVA CAPA EN EDICION: "
168
                + 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 (ServiceException e) {
342
            throw new FeatureRuleMandatoryAttributesException(e,
343
                store.getFullName());
344
        }
345
        final JPanel panel = new JPanel();
346

    
347
        ButtonsPanel buttonsPanel =
348
            new ButtonsPanel(ButtonsPanel.BUTTONS_ACCEPTCANCEL);
349
        buttonsPanel.addButtonPressedListener(new ButtonsPanelListener() {
350

    
351
            public void actionButtonPressed(ButtonsPanelEvent e) {
352
                if (e.getButton() == ButtonsPanel.BUTTON_ACCEPT) {
353
                    dynObjectComponent.saveStatus();
354
                    panel.setVisible(false);
355
                }
356
                if (e.getButton() == ButtonsPanel.BUTTON_CANCEL) {
357
                    panel.setVisible(false);
358
                    throw new FeatureRuleMandatoryAttributesException(store
359
                        .getFullName());
360
                }
361
            }
362

    
363
        });
364
        panel.setLayout(new BorderLayout());
365
        ScrollPane scrollPanel = new ScrollPane();
366
        scrollPanel.add(dynObjectComponent.asJComponent(), BorderLayout.CENTER);
367
        panel.add(scrollPanel);
368
        panel.add(buttonsPanel, BorderLayout.SOUTH);
369
        panel.setPreferredSize(new Dimension(800, 600));
370
        WindowManager wm = ToolsSwingLocator.getWindowManager();
371
        wm.showWindow(panel, "Fill mandatory fields", WindowManager.MODE.DIALOG);
372

    
373
    }
374

    
375
    private void addCheckRules(FLyrVect layer) {
376
        try {
377
            FeatureType featureType =
378
                layer.getFeatureStore().getDefaultFeatureType();
379
            FeatureRules featureRules = featureType.getRules();
380
            for (Iterator it = featureRules.iterator(); it.hasNext();) {
381
                FeatureRule rule = (FeatureRule) it.next();
382
                if (rule instanceof CheckMandatoryAttributtes) {
383
                    return;
384
                }
385
            }
386
            featureRules.add(new CheckMandatoryAttributtes());
387
        } catch (DataException e) {
388
            // TODO Auto-generated catch block
389
            e.printStackTrace();
390
        }
391
    }
392

    
393
    public class FeatureRuleMandatoryAttributesException extends
394
        DataRuntimeException {
395

    
396
        private static final long serialVersionUID = -7965533441336164612L;
397
        private final static String MESSAGE_FORMAT =
398
            "Can't apply rule in store %(store)s.";
399
        private final static String MESSAGE_KEY =
400
            "_FeatureRuleMandatoryAttributesException";
401

    
402
        public FeatureRuleMandatoryAttributesException(Throwable cause,
403
            String store) {
404
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
405
            this.setValue("store", store);
406
        }
407

    
408
        public FeatureRuleMandatoryAttributesException(String store) {
409
            super(MESSAGE_FORMAT, MESSAGE_KEY, serialVersionUID);
410
            this.setValue("store", store);
411
        }
412
    }
413

    
414
}