Statistics
| Revision:

gvsig-projects-pool / org.gvsig.vcsgis / trunk / org.gvsig.vcsgis / org.gvsig.vcsgis.swing / org.gvsig.vcsgis.swing.impl / src / main / java / org / gvsig / vcsgis / swing / impl / changes / RemoteChangesController.java @ 8892

History | View | Annotate | Download (57.6 KB)

1
/*
2
 * gvSIG. Desktop Geographic Information System.
3
 * 
4
 * Copyright (C) 2007-2020 gvSIG Association.
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 3
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, see <https://www.gnu.org/licenses/>. 
18
 * 
19
 * For any additional information, do not hesitate to contact us
20
 * at info AT gvsig.com, or visit our website www.gvsig.com.
21
 */
22
package org.gvsig.vcsgis.swing.impl.changes;
23

    
24
import java.awt.Component;
25
import java.awt.Cursor;
26
import java.awt.Dimension;
27
import java.awt.event.ActionEvent;
28
import java.awt.event.KeyAdapter;
29
import java.awt.event.KeyEvent;
30
import java.util.ArrayList;
31
import java.util.Collection;
32
import java.util.HashSet;
33
import java.util.Iterator;
34
import java.util.List;
35
import java.util.Set;
36
import javax.swing.JButton;
37
import javax.swing.JLabel;
38
import javax.swing.JOptionPane;
39
import javax.swing.JTable;
40
import javax.swing.JTree;
41
import javax.swing.ListSelectionModel;
42
import javax.swing.SwingUtilities;
43
import javax.swing.event.ChangeEvent;
44
import javax.swing.event.ListSelectionEvent;
45
import javax.swing.table.DefaultTableCellRenderer;
46
import javax.swing.table.DefaultTableModel;
47
import javax.swing.text.JTextComponent;
48
import org.apache.commons.collections.CollectionUtils;
49
import org.apache.commons.lang3.StringUtils;
50
import org.apache.commons.lang3.mutable.MutableLong;
51
import org.apache.commons.lang3.mutable.MutableObject;
52
import org.gvsig.featureform.swing.JFeatureForm;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.dal.feature.FeatureType;
56
import org.gvsig.fmap.dal.swing.DALSwingLocator;
57
import org.gvsig.fmap.dal.swing.DataSwingManager;
58
import org.gvsig.fmap.geom.Geometry;
59
import org.gvsig.fmap.geom.GeometryLocator;
60
import org.gvsig.fmap.geom.GeometryUtils;
61
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
62
import org.gvsig.json.Json;
63
import org.gvsig.tools.ToolsLocator;
64
import org.gvsig.tools.dispose.DisposeUtils;
65
import org.gvsig.tools.dispose.impl.AbstractDisposable;
66
import org.gvsig.tools.dynform.DynFormLocator;
67
import org.gvsig.tools.dynform.JDynForm;
68
import org.gvsig.tools.dynobject.DynObject;
69
import org.gvsig.tools.exception.BaseException;
70
import org.gvsig.tools.i18n.I18nManager;
71
import org.gvsig.tools.swing.api.ToolsSwingLocator;
72
import org.gvsig.tools.swing.api.ToolsSwingManager;
73
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
74
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
75
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
76
import org.gvsig.tools.task.SimpleTaskStatus;
77
import org.gvsig.vcsgis.lib.UserCancelledException;
78
import org.gvsig.vcsgis.lib.VCSGisChange;
79
import org.gvsig.vcsgis.lib.VCSGisEntity;
80
import org.gvsig.vcsgis.lib.VCSGisLocator;
81
import org.gvsig.vcsgis.lib.VCSGisManager;
82
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_OK;
83
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_ADD_ENTITY;
84
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_DELETE;
85
import org.gvsig.vcsgis.lib.VCSGisRuntimeException;
86
import org.gvsig.vcsgis.lib.repository.VCSGisRepositoryChange;
87
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspace;
88
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceChanges;
89
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceEntity;
90
import org.gvsig.vcsgis.swing.VCSGisEntitySelectorController;
91
import org.gvsig.vcsgis.swing.VCSGisSwingLocator;
92
import org.gvsig.vcsgis.swing.VCSGisSwingManager;
93
import org.gvsig.vcsgis.swing.VCSGisSwingServices;
94
import static org.gvsig.vcsgis.swing.VCSGisSwingServices.HIGHLIGHT_REPOSITORY;
95
import static org.gvsig.vcsgis.swing.VCSGisSwingServices.HIGHLIGHT_WORKSPACE;
96
import org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons;
97
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.cleanHighligthed;
98
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.notInSwingThreadInvokeLater;
99
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.refreshDocument;
100
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.showAuthenticationErrors;
101
import static org.gvsig.vcsgis.swing.impl.changes.VCSGisJChangesImpl.LOCAL_TAB_INDEX;
102
import org.slf4j.Logger;
103
import org.slf4j.LoggerFactory;
104

    
105
/**
106
 *
107
 * @author gvSIG Team
108
 */
109
@SuppressWarnings("UseSpecificCatch")
110
public class RemoteChangesController extends AbstractDisposable {
111

    
112
    private static final Logger LOGGER = LoggerFactory.getLogger(RemoteChangesController.class);
113

    
114
    private final PickerController<VCSGisWorkspace> workspacePicker;
115
    private final JTable tblRemoteChanges;
116
    private final JButton btnRemoteShowForm;
117
    private final JButton btnRemoteUpdate;
118
    private final JButton btnRemoteMerge;
119
    private final JButton btnRemoteReloadChanges;
120
    private final JButton btnRemoteCheckAll;
121
    private final JButton btnRemoteUnCheckAll;
122
    private final JButton btnRemoteExpandAllEntities;
123
    private final JButton btnRemoteCollapseAllEntities;
124
    private final JTree treeRepositoryTables;
125
    private final JTextComponent txtRepositoryTablesFilter;
126
    private final JButton btnRepositoryTablesFilter;
127

    
128
    private VCSGisWorkspaceChanges<VCSGisRepositoryChange> changes;
129

    
130
    private final JButton btnRemoteTablesReload;
131
    private final JButton btnRemoteDownloadChanges;
132
    private final JButton btnRemoteCleanChanges;
133
    private final VCSGisJChangesImpl context;
134
    
135
    
136
    private final JButton btnRemoteZoom;
137
    private final JButton btnRemoteCenter;
138
    private final JButton btnRemoteHighlight;
139
    private final JButton btnRemoteCheckout;
140
    private final JButton btnRemoteCheckoutOverwrite;
141
    private final JButton btnRemoteCleanHighligthed;
142

    
143
    private final JLabel lblRemoteChangesCount;
144
    private VCSGisEntitySelectorController entitySelector;
145
    private final JButton btnRemoteCheckRecomendedEntities;
146
    private final JButton btnRemoteUnCheckAllEntities;
147

    
148
    public RemoteChangesController(
149
            VCSGisJChangesImpl context,
150
            PickerController<VCSGisWorkspace> workspacePicker,
151
            JTree treeRepositoryTables,
152
            JTextComponent txtRepositoryTablesFilter,
153
            JButton btnRepositoryTablesFilter,
154
            JButton btnRemoteTablesReload,
155
            JTable tblRemoteChanges,
156
            JButton btnRemoteCheckAll,
157
            JButton btnRemoteUnCheckAll,
158
            JButton btnRemoteExpandAllEntities,
159
            JButton btnRemoteCollapseAllEntities,
160
            JButton btnRemoteDownloadChanges,
161
            JButton btnRemoteReloadChanges,
162
            JButton btnRemoteCleanChanges,
163
            JButton btnRemoteUpdate,
164
            JButton btnRemoteMerge,
165
            JButton btnRemoteShowForm,
166
            JButton btnRemoteZoom,
167
            JButton btnRemoteCenter,
168
            JButton btnRemoteHighlight,
169
            JButton btnRemoteCheckout,
170
            JButton btnRemoteCheckoutOverwrite,
171
            JButton btnRemoteCleanHighligthed,
172
            JLabel lblRemoteChangesCount,
173
            JButton btnRemoteCheckRecomendedEntities,
174
            JButton btnRemoteUnCheckAllEntities
175
    ) {
176
        this.context = context;
177

    
178
        this.workspacePicker = workspacePicker;
179

    
180
        this.treeRepositoryTables = treeRepositoryTables;
181
        this.txtRepositoryTablesFilter = txtRepositoryTablesFilter;
182
        this.btnRepositoryTablesFilter = btnRepositoryTablesFilter;
183
        
184
        this.btnRemoteTablesReload = btnRemoteTablesReload;
185

    
186
        this.tblRemoteChanges = tblRemoteChanges;
187
        this.btnRemoteCheckAll = btnRemoteCheckAll;
188
        this.btnRemoteUnCheckAll = btnRemoteUnCheckAll;
189
        
190
        this.btnRemoteExpandAllEntities = btnRemoteExpandAllEntities;
191
        this.btnRemoteCollapseAllEntities = btnRemoteCollapseAllEntities;
192
        
193
        this.btnRemoteDownloadChanges = btnRemoteDownloadChanges;
194
        this.btnRemoteCleanChanges = btnRemoteCleanChanges;
195
        this.btnRemoteReloadChanges = btnRemoteReloadChanges;
196

    
197
        this.btnRemoteUpdate = btnRemoteUpdate;
198
        this.btnRemoteMerge = btnRemoteMerge;
199
        this.btnRemoteShowForm = btnRemoteShowForm;
200

    
201
        this.btnRemoteZoom = btnRemoteZoom;
202
        this.btnRemoteCenter = btnRemoteCenter;
203
        this.btnRemoteHighlight = btnRemoteHighlight;
204
        this.btnRemoteCheckout = btnRemoteCheckout;
205
        this.btnRemoteCheckoutOverwrite = btnRemoteCheckoutOverwrite;
206
        
207
        this.btnRemoteCleanHighligthed = btnRemoteCleanHighligthed;
208

    
209
        this.lblRemoteChangesCount= lblRemoteChangesCount;
210
        
211
        this.btnRemoteCheckRecomendedEntities = btnRemoteCheckRecomendedEntities;
212
        this.btnRemoteUnCheckAllEntities = btnRemoteUnCheckAllEntities;
213
        
214
        initComponents();
215
    }
216

    
217
    public void alert(final String msg) {
218
        this.context.alert(msg);
219
    }
220

    
221
    public void message(final String msg) {
222
        this.context.message(msg);
223
    }
224

    
225
    private void initComponents() {
226
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
227
        I18nManager i18n = ToolsLocator.getI18nManager();
228

    
229
        this.btnRemoteCheckAll.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
230
        this.btnRemoteCleanChanges.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
231
        this.btnRemoteDownloadChanges.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
232
        this.btnRemoteMerge.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
233
        this.btnRemoteReloadChanges.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
234
        this.btnRemoteShowForm.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
235
        this.btnRemoteTablesReload.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
236
        this.btnRemoteUnCheckAll.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
237
        this.btnRemoteUpdate.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
238
        this.btnRemoteZoom.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
239
        this.btnRemoteCenter.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
240
        this.btnRemoteHighlight.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
241
        this.btnRemoteCheckout.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
242
        this.btnRemoteCheckoutOverwrite.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
243
        this.btnRemoteCleanHighligthed.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
244

    
245
        translate();
246

    
247
        this.entitySelector = VCSGisSwingLocator.getVCSGisSwingManager().createEntitySelectorController(
248
                this.treeRepositoryTables, 
249
                this.txtRepositoryTablesFilter, 
250
                this.btnRepositoryTablesFilter
251
        );
252
        this.entitySelector.setViewFilter(VCSGisEntitySelectorController.ALL_ENTITIES);
253
        this.entitySelector.setFilter(VCSGisEntitySelectorController.ALL_ENTITIES);
254
        this.entitySelector.setChecksEnabled(true);
255
        this.entitySelector.addChangeListener((ChangeEvent e) -> {
256
            doReloadChanges();
257
        });
258
        this.entitySelector.addActionListener((ActionEvent e) -> {
259
            switch(e.getID()) {
260
                case VCSGisEntitySelectorController.ACTION_SELECT_ID:
261
                    doUpdateComponents();
262
                    break;
263
                case VCSGisEntitySelectorController.ACTION_CHECK_ID:
264
                    doReloadChanges();
265
                    doUpdateComponents();
266
                    break;
267
                case VCSGisEntitySelectorController.ACTION_RELOAD_ID:
268
                    doReloadChanges();
269
                    doUpdateComponents();
270
                    break;
271
            }
272
        });
273
        
274
        
275
//        lstRemoteTables.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
276
//
277
//        lstRemoteTables.setCellRenderer(new DefaultListCellRenderer() {
278
//            @Override
279
//            public java.awt.Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
280
//                JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
281
//                LabeledValue lvalue = (LabeledValue) value;
282
//                VCSGisEntity entity = (VCSGisEntity) lvalue.getValue();
283
//                String entityCode = entity.getEntityCode();
284
//                VCSGisWorkspaceEntity lentity = getUndisposableWorkspace().getWorkspaceEntity(entityCode);
285
//                String s = VCSGisSwingCommons.getHTMLColorTag(
286
//                        lentity == null ? VCSGisManager.STATE_REPOSITORY_NEW : lentity.getState(),
287
//                        lvalue.getLabel()
288
//                );
289
//                label.setText(s);
290
//                return label;
291
//            }
292
//        });
293
//
294
//        this.lstRemoteTables.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
295
//            doReloadChanges();
296
//        });
297

    
298
        this.btnRemoteTablesReload.addActionListener((ActionEvent e) -> {
299
            doReloadTables();
300
            doReloadChanges();
301
        });
302

    
303
        this.tblRemoteChanges.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
304

    
305
        this.tblRemoteChanges.addKeyListener(new KeyAdapter() {
306
            @Override
307
            public void keyPressed(KeyEvent e) {
308
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
309
                    doToggleSelection();
310
                }
311
            }
312
        });
313

    
314
        this.tblRemoteChanges.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
315
            context.doUpdateComponents();
316
        });
317

    
318
        this.btnRemoteCheckAll.addActionListener((ActionEvent e) -> {
319
            if (changes != null) {
320
                doCheckAll();
321
                doReloadChanges();
322
            }
323
        });
324

    
325
        this.btnRemoteUnCheckAll.addActionListener((ActionEvent e) -> {
326
            if (changes != null) {
327
                doUnCheckAll();
328
                doReloadChanges();
329
            }
330
        });
331

    
332
        this.btnRemoteCollapseAllEntities.addActionListener((ActionEvent e) -> {
333
            this.entitySelector.collapseAll();
334
        });
335
        this.btnRemoteExpandAllEntities.addActionListener((ActionEvent e) -> {
336
            this.entitySelector.expandAll();
337
        });
338
        
339
        this.btnRemoteDownloadChanges.addActionListener((ActionEvent e) -> {
340
            doDownloadChangesOfSelectedTable();
341
        });
342

    
343
        this.btnRemoteReloadChanges.addActionListener((ActionEvent e) -> {
344
//            doDownloadChangesOfSelectedTable();
345
            doReloadTables();
346
        });
347

    
348
        this.btnRemoteCleanChanges.addActionListener((ActionEvent e) -> {
349
            doCleanChanges();
350
            doReloadChanges();
351
        });
352

    
353
        this.btnRemoteUpdate.addActionListener((ActionEvent e) -> {
354
            doUpdate();
355
        });
356

    
357
        this.btnRemoteMerge.addActionListener((ActionEvent e) -> {
358
            doMerge();
359
        });
360

    
361
        this.btnRemoteShowForm.addActionListener((ActionEvent e) -> {
362
            doShowForm();
363
        });
364
        
365
        this.btnRemoteZoom.addActionListener((ActionEvent e) -> {
366
            doZoomToSelectedChange();
367
        });
368

    
369
        this.btnRemoteCenter.addActionListener((ActionEvent e) -> {
370
            doCenterToSelectedChange();
371
        });
372
        
373
        this.btnRemoteHighlight.addActionListener((ActionEvent e) -> {
374
            doHighLightSelectedChange();
375
        });
376
        
377
        this.btnRemoteCleanHighligthed.addActionListener((ActionEvent e) -> {
378
            cleanHighligthed();
379
        });
380

    
381
        this.btnRemoteCheckout.addActionListener((ActionEvent e) -> {
382
            doCheckout(false);
383
        });
384
        this.btnRemoteCheckoutOverwrite.addActionListener((ActionEvent e) -> {
385
            if( askUserOverwriteSelectedTables() ) {
386
                doCheckout(true);
387
            }
388
        });
389
        
390
        this.btnRemoteCheckRecomendedEntities.addActionListener((ActionEvent e) -> {
391
            doCheckRecomendedEntities();
392
        });
393
        this.btnRemoteUnCheckAllEntities.addActionListener((ActionEvent e) -> {
394
            this.entitySelector.clearChecks();
395
        });
396

    
397

    
398
        context.doUpdateComponents();
399

    
400
        SwingUtilities.invokeLater(() -> {
401
            message(i18n.getTranslation("_Ready"));
402
            this.lblRemoteChangesCount.setText("");
403
        });
404

    
405
    }
406
    
407
    private boolean askUserOverwriteSelectedTables() {
408
        I18nManager i18n = ToolsLocator.getI18nManager();
409
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
410
        int n = dialogs.confirmDialog(
411
                i18n.getTranslation("_Are_you_sure_you_want_to_overwrite_the_selected_tables"),
412
                i18n.getTranslation("_VCSGis_Checkout_overwrite"),
413
                JOptionPane.YES_NO_OPTION, 
414
                JOptionPane.QUESTION_MESSAGE
415
        );
416
        return n == JOptionPane.YES_OPTION;
417
    }
418
    
419
    public void doChangeWorkspace() {
420
        VCSGisWorkspace ws = this.context.getWorkspace();
421
        this.entitySelector.setWorkspace(ws);
422
        if( ws!=null ) {
423
            for (String tableName : this.context.getDefaultTablesSelection()) {
424
                VCSGisWorkspaceEntity entity = ws.getWorkspaceEntity(tableName);
425
                if( entity!=null ) {
426
                    this.entitySelector.check(entity);
427
                }
428
            }
429
        }
430
        doReloadChanges();
431
    }
432
    
433
    public void translate() {
434
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
435

    
436
        swingManager.translate(this.btnRemoteCheckAll);
437
        swingManager.translate(this.btnRemoteUpdate);
438
        swingManager.translate(this.btnRemoteCleanChanges);
439
        swingManager.translate(this.btnRemoteReloadChanges);
440
        swingManager.translate(this.btnRemoteMerge);
441
        swingManager.translate(this.btnRemoteShowForm);
442
        swingManager.translate(this.btnRemoteUnCheckAll);
443
        swingManager.translate(this.btnRemoteTablesReload);
444
        swingManager.translate(this.btnRemoteDownloadChanges);
445
        swingManager.translate(this.btnRemoteCenter);
446
        swingManager.translate(this.btnRemoteHighlight);
447
        swingManager.translate(this.btnRemoteZoom);
448
        swingManager.translate(this.btnRemoteCheckout);
449
        swingManager.translate(this.btnRemoteCheckoutOverwrite);
450
        swingManager.translate(this.btnRemoteCleanHighligthed);
451
        
452
        swingManager.translate(this.btnRemoteCheckRecomendedEntities);
453
        swingManager.translate(this.btnRemoteUnCheckAllEntities);
454

    
455
        swingManager.translate(this.btnRemoteCollapseAllEntities);
456
        swingManager.translate(this.btnRemoteExpandAllEntities);
457
    }
458

    
459
    private VCSGisWorkspace getUndisposableWorkspace() {
460
        VCSGisWorkspace ws = this.context.getWorkspace();
461
        DisposeUtils.disposeQuietly(ws);
462
//        LOGGER.info("ws.references = " + DisposeUtils.getReferences(ws));
463
        return ws;
464
    }
465

    
466
    /* friend */ void doUpdateComponents() {
467
        if (notInSwingThreadInvokeLater(() -> {
468
            doUpdateComponents();
469
        })) {
470
            return;
471
        }
472
        VCSGisWorkspace ws;
473
        try {
474
            this.context.setVisibleStatus(context.processing);
475
            this.context.btnClose.setEnabled(!context.processing);
476
            ws = this.getUndisposableWorkspace();
477
            List<VCSGisEntity> checkedEntities = entitySelector.getCheckedEntities();
478

    
479
            boolean hasLocalTables = false;
480
            boolean hasRemoteTables = false;
481
            for (VCSGisEntity checkedEntity : checkedEntities) {
482
                if( ws.getWorkspaceEntityByName(checkedEntity.getEntityName())!=null ) {
483
                    hasLocalTables = true;
484
                } else {
485
                    hasRemoteTables = true;
486
                }
487
            }
488
            
489
            this.btnRemoteCheckAll.setEnabled(!context.processing && changes != null);
490
            this.btnRemoteUnCheckAll.setEnabled(!context.processing && changes != null);
491

    
492
            this.btnRemoteDownloadChanges.setEnabled(!context.processing && ws != null && hasLocalTables);
493
            this.btnRemoteCheckout.setEnabled(!context.processing && ws != null && (hasRemoteTables && !hasLocalTables));
494
            this.btnRemoteCheckoutOverwrite.setEnabled(!context.processing && ws != null && (hasRemoteTables||hasLocalTables));
495
            this.btnRemoteReloadChanges.setEnabled(!context.processing && ws != null && hasLocalTables);
496
            this.btnRemoteCleanChanges.setEnabled(!context.processing && ws != null && hasLocalTables);
497
                        
498
            this.btnRemoteTablesReload.setEnabled(!context.processing);
499

    
500
            this.btnRemoteTablesReload.setEnabled(!context.processing && ws != null);
501

    
502
            //Show form
503
            boolean enableShowForm = false;
504
            int row = this.tblRemoteChanges.getSelectedRow();
505
            if (row >= 0) {
506
                VCSGisRepositoryChange change = this.changes.get64(row);
507
                if (change.getOperation() != OP_ADD_ENTITY) {
508
                    enableShowForm = true;
509
                }
510
            }
511
            this.btnRemoteShowForm.setEnabled(!context.processing && enableShowForm);
512

    
513
            this.entitySelector.setEnabled(!context.processing);
514
            this.tblRemoteChanges.setEnabled(!context.processing);
515
            this.workspacePicker.setEnabled(!context.processing);
516

    
517
            if ( CollectionUtils.isEmpty(checkedEntities) ) {
518
                this.btnRemoteMerge.setEnabled(false);
519
                this.btnRemoteUpdate.setEnabled(false);
520
            } else {
521
                MutableObject<String> msg = new MutableObject<>();
522
                for (VCSGisEntity checkedEntity : checkedEntities) {
523
                    if( !ws.canUpdate(msg,checkedEntity.getEntityName())) {
524
                        break;
525
                    }
526
                }
527
                if( msg.getValue()!=null ) {
528
                    this.btnRemoteDownloadChanges.setEnabled(false);
529
                    this.btnRemoteCheckout.setEnabled(false);
530
                    this.btnRemoteCheckoutOverwrite.setEnabled(false);
531
                    this.btnRemoteMerge.setEnabled(false);
532
                    this.btnRemoteUpdate.setEnabled(false);
533
                    this.alert(msg.getValue());
534
                } else {
535
                    if( checkedEntities.size()==1 ) {
536
                        VCSGisEntity checkedEntity = checkedEntities.get(0);
537
                        if ( ws.updateNeedMerge(checkedEntity.getEntityName())) {
538
                            this.btnRemoteMerge.setEnabled(!context.processing);
539
                            this.btnRemoteUpdate.setEnabled(false);
540
                        } else {
541
                            this.btnRemoteMerge.setEnabled(false);
542
                            this.btnRemoteUpdate.setEnabled(!context.processing && changes != null && !this.changes.isSelectionEmpty());
543
                        }
544
                    } else {
545
                        this.btnRemoteMerge.setEnabled(false);
546
                        this.btnRemoteUpdate.setEnabled(!context.processing && changes != null && !this.changes.isSelectionEmpty());
547
                        for (VCSGisEntity checkedEntity : checkedEntities) {
548
                            if( ws.updateNeedMerge(checkedEntity.getEntityName())) {
549
                                this.btnRemoteMerge.setEnabled(!context.processing);
550
                                this.btnRemoteUpdate.setEnabled(false);
551
                                break;
552
                            }
553
                        }
554
                    }
555
                }
556
            }
557

    
558
            Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
559
            Geometry wsGeom = getWorkspaceGeometryOfSelectedChange();
560
            Geometry bbox = VCSGisSwingCommons.createBBox(repoGeom, wsGeom);
561
            this.btnRemoteZoom.setEnabled(!context.processing && bbox != null);
562
            this.btnRemoteCenter.setEnabled(!context.processing && bbox != null);
563
            this.btnRemoteHighlight.setEnabled(!context.processing && bbox != null);
564
            this.btnRemoteCleanHighligthed.setEnabled(!context.processing);
565
        } catch (VCSGisRuntimeException e1) {
566
            LOGGER.warn("Can't updating components.", e1);
567
            if (showAuthenticationErrors("_VCS_Changes", e1)) {
568
                this.workspacePicker.set(null);
569
                doChangeWorkspace();
570
            }
571
        } catch (Exception e2) {
572
            LOGGER.warn("Can't updating components.", e2);
573
        }
574

    
575
    }
576

    
577
    private void doToggleSelection() {
578
        Thread task = new Thread(() -> {
579
            try {
580
                context.processing = true;
581
                context.doUpdateComponents();
582
                Iterator<Long> rows = getChangesSelectionIterator();
583

    
584
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
585
                    change.setSelected(!change.isSelected());
586
                    return true;
587
                });
588
            } finally {
589
                context.processing = false;
590
                context.doUpdateComponents();
591
            }
592
        }, "VCSGisToggleSelectionRemoteChanges");
593
        task.start();
594
    }
595

    
596
    private Iterator<Long> getChangesSelectionIterator() {
597
        ListSelectionModel selection = this.tblRemoteChanges.getSelectionModel();
598
        return new Iterator<Long>() {
599
            long n = selection.getMinSelectionIndex();
600

    
601
            @Override
602
            public boolean hasNext() {
603
                while (n <= selection.getMaxSelectionIndex()) {
604
                    if (selection.isSelectedIndex((int) n)) {
605
                        return true;
606
                    }
607
                    n++;
608
                }
609
                return false;
610
            }
611

    
612
            @Override
613
            public Long next() {
614
                if (n > selection.getMaxSelectionIndex()) {
615
                    throw new IllegalStateException();
616
                }
617
                return n++;
618
            }
619
        };
620
    }
621

    
622
    private Iterator<Long> getRowsIterator() {
623
        long size = changes.size64();
624
        return new Iterator<Long>() {
625
            long n = 0;
626

    
627
            @Override
628
            public boolean hasNext() {
629
                return (n < size);
630
            }
631

    
632
            @Override
633
            public Long next() {
634
                return n++;
635
            }
636
        };
637
    }
638

    
639
    private void doCheckAll() {
640
        Thread task = new Thread(() -> {
641
            try {
642
                context.processing = true;
643
                context.doUpdateComponents();
644
                Iterator<Long> rows = getRowsIterator();
645

    
646
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
647
                    change.setSelected(true);
648
                    return true;
649
                });
650
            } finally {
651
                context.processing = false;
652
                context.doUpdateComponents();
653
            }
654
        }, "VCSGisCheckAllRemoteChanges");
655
        task.start();
656
    }
657

    
658
    private void doUnCheckAll() {
659
        Thread task = new Thread(() -> {
660
            try {
661
                context.processing = true;
662
                context.doUpdateComponents();
663
                Iterator<Long> rows = getRowsIterator();
664

    
665
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
666
                    change.setSelected(false);
667
                    return true;
668
                });
669
            } finally {
670
                context.processing = false;
671
                context.doUpdateComponents();
672
            }
673
        }, "VCSGisCheckAllRemoteChanges");
674
        task.start();
675
    }
676

    
677
    private void doUpdate() {
678
        VCSGisWorkspace ws = getUndisposableWorkspace();
679
        if (ws == null) {
680
            return;
681
        }
682
        List<VCSGisEntity> checkedEntities = entitySelector.getCheckedEntities();
683
        if ( CollectionUtils.isEmpty(checkedEntities) ) {
684
            return;
685
        }
686

    
687
        this.tblRemoteChanges.setModel(new RemoteChangesTableModel(ws));
688

    
689
        SimpleTaskStatus taskStatus = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("_Download_changes");
690
        Thread task = new Thread(() -> {
691
            try {
692
                taskStatus.setAutoremove(true);
693
                taskStatus.add();
694
                context.setTaskStatus(taskStatus);
695
                context.processing = true;
696
                context.doUpdateComponents();
697
                int r = ERR_OK;
698
                for (VCSGisEntity checkedEntity : checkedEntities) {
699
                    r = ws.update(checkedEntity.getEntityName(), taskStatus);
700
                    if( r!=ERR_OK ) {
701
                        break;
702
                    }
703
                }
704
                doPostUpdate(checkedEntities, r);
705
                taskStatus.terminate();
706
            } catch(UserCancelledException ex) {
707
                LOGGER.warn("User cancelled");
708
                taskStatus.cancel();
709
            } catch(Exception ex) {
710
                taskStatus.abort();
711
            } finally {
712
                context.processing = false;
713
                context.doUpdateComponents();
714
            }
715
        }, "VCSGisUpdate");
716
        context.processing = true;
717
        context.doUpdateComponents();
718
        task.start();
719
    }
720

    
721
    private void doPostUpdate(List<VCSGisEntity> checkedEntities, int updateStatus) {
722
        if (notInSwingThreadInvokeLater(() -> {doPostUpdate(checkedEntities, updateStatus);})) {
723
            return;
724
        }
725
        if (updateStatus == ERR_OK) {
726
            context.setVisibleStatus(false);
727
        }
728
        VCSGisWorkspace ws = getUndisposableWorkspace();
729
        
730
        doReloadChanges();
731

    
732
        for (VCSGisEntity checkedEntity : checkedEntities) {
733
            FeatureStore store = ws.getFeatureStore(checkedEntity.getEntityName());
734
            refreshDocument(store);
735
        }
736
        
737
        context.doUpdateComponents();
738
        context.updateLocalChangesTable();
739
        cleanHighligthed();        
740
    }
741

    
742

    
743
    private void doMerge() {
744
        VCSGisWorkspace ws = getUndisposableWorkspace();
745
        if (ws == null) {
746
            return;
747
        }
748
        List<VCSGisEntity> checkedEntities = entitySelector.getCheckedEntities();
749
        if ( CollectionUtils.isEmpty(checkedEntities) ) {
750
            return;
751
        }
752
//        if( checkedEntities.size()!=1 ) {
753
//            ThreadSafeDialogsManager dialogsManager = ToolsSwingLocator.getThreadSafeDialogsManager();
754
//            I18nManager i18n = ToolsLocator.getI18nManager();
755
//            dialogsManager.messageDialog(
756
//                    i18n.getTranslation("_Cant_merge_with_more_a_table_selected"), 
757
//                    null, 
758
//                    i18n.getTranslation("_VCSGis_Merge"), 
759
//                    JOptionPane.WARNING_MESSAGE
760
//            );
761
//            return;
762
//        }
763
//        VCSGisEntity entity = checkedEntities.get(0);
764
//        String tableName = entity.getEntityName();
765

    
766
        this.tblRemoteChanges.setModel(new RemoteChangesTableModel(ws));
767

    
768
        Thread task = new Thread(() -> {
769
            try {
770
                context.processing = true;
771
                context.doUpdateComponents();
772
                MutableLong localChangesCreated = new MutableLong(0);
773
                List<VCSGisEntity> entitiesWithLocalChanges = new ArrayList<>();
774
                int r = ERR_OK;
775
                for (VCSGisEntity entity : checkedEntities) {
776
                    String tableName = entity.getEntityName();
777
                    Long lchanges = localChangesCreated.getValue();
778
                    r = getUndisposableWorkspace().merge(
779
                            tableName,
780
                            localChangesCreated,
781
                            this.context.getTaskStatusController().getSimpleTaskStatus()
782
                    );
783
                    if( r!=ERR_OK ) {
784
                        break;
785
                    }
786
                    if( lchanges!=localChangesCreated.getValue() ) {
787
                        entitiesWithLocalChanges.add(entity);
788
                    }
789
                }
790
                doPostMerge(checkedEntities, entitiesWithLocalChanges, r, localChangesCreated.getValue());
791
            } catch(UserCancelledException ex) {
792
                LOGGER.warn("User cancelled");
793
            } finally {
794
                context.processing = false;
795
                context.doUpdateComponents();
796
            }
797
        }, "VCSGisMerge");
798
        context.processing = true;
799
        context.doUpdateComponents();
800
        task.start();
801
    }
802

    
803
    private void doPostMerge(List<VCSGisEntity> checkedEntities, List<VCSGisEntity> entitiesWithLocalChanges, int mergeStatus, long localChangesCreated) {
804
        if (notInSwingThreadInvokeLater(() -> {doPostMerge(checkedEntities, entitiesWithLocalChanges, mergeStatus, localChangesCreated);})) {
805
            return;
806
        }
807
        if (mergeStatus == ERR_OK) {
808
            this.context.setVisibleStatus(false);
809
        }
810
        doReloadChanges();
811
        VCSGisWorkspace ws = getUndisposableWorkspace();
812
        for (VCSGisEntity entity : checkedEntities) {
813
            FeatureStore store = ws.getFeatureStore(entity.getEntityName());
814
            refreshDocument(store);
815
        }
816
//        FeatureStore store = getUndisposableWorkspace().getFeatureStore(entity.getEntityName());
817
//        refreshDocument(store);
818
        
819
        if(localChangesCreated>0){
820
            ThreadSafeDialogsManager dialogsManager = ToolsSwingLocator.getThreadSafeDialogsManager();
821
            I18nManager i18n = ToolsLocator.getI18nManager();
822
            dialogsManager.messageDialog(
823
                    i18n.getTranslation("_The_process_has_modified_local_changes_that_would_need_to_be_committed_to_the_repository"), 
824
                    null, 
825
                    i18n.getTranslation("_VCSGis_Merge"), 
826
                    JOptionPane.INFORMATION_MESSAGE, 
827
                    "VCSGIS_merge_need_commit");
828
            context.selectTab(LOCAL_TAB_INDEX);
829
            context.selectOnlyALocalEntity(entitiesWithLocalChanges);
830
        }
831
        context.doUpdateComponents();
832
        context.updateLocalChangesTable();
833
        cleanHighligthed();
834
    }
835

    
836
    private void doShowForm() {
837
        if (this.changes == null) {
838
            return;
839
        }
840
        int row = this.tblRemoteChanges.getSelectedRow();
841
        VCSGisRepositoryChange change = this.changes.get64(row);
842
        if (change.getOperation() == OP_DELETE) {
843
            return;
844
        }
845
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
846
        if (ws == null) {
847
            return;
848
        }
849
        VCSGisWorkspaceEntity entity = ws.getWorkspaceEntityByCode(change.getEntityCode());
850

    
851
        if (entity == null) {
852
            VCSGisEntity repoEntity = ws.getEntity(change.getEntityCode());
853
            FeatureType featureType = repoEntity.getFeatureType();
854
            JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(featureType);
855
            DynObject values = ToolsLocator.getDynObjectManager().createDynObject(featureType);
856
            Json.addAll(values, change.getRelatedFeatureDataAsJson());
857
            form.setValues(values);
858
            form.setReadOnly(true);
859
            WindowManager winManager = ToolsSwingLocator.getWindowManager();
860
            form.asJComponent().setPreferredSize(new Dimension(400, 200));
861
            winManager.showWindow(form.asJComponent(), "Remote change: " + change.getLabel(), WindowManager.MODE.WINDOW);
862
            return;
863
        }
864

    
865
        FeatureStore store = null;
866
        try {
867
            DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
868

    
869
            store = ws.openFeatureStore(entity.getEntityName(),false);
870
            Feature feature = store.createNewFeature(change.getRelatedFeatureDataAsJson());
871
            JFeatureForm form = dataSwingManager.createJFeatureForm(feature);
872
            form.getDynForm().setReadOnly(true);
873
            WindowManager winManager = ToolsSwingLocator.getWindowManager();
874
            form.asJComponent().setPreferredSize(new Dimension(400, 200));
875
            winManager.showWindow(form.asJComponent(), "Remote change: " + change.getLabel(), WindowManager.MODE.WINDOW);
876
        } catch (Exception ex) {
877
            LOGGER.warn("Can't show form for change '" + change.getCode() + "'.", ex);
878
        } finally {
879
            DisposeUtils.disposeQuietly(store);
880
        }
881

    
882
    }
883

    
884
    private void doReloadChanges() {
885
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
886
        if (ws == null) {
887
            return;
888
        }
889
        if (this.changes != null) {
890
            this.changes.removeAllChangeListener();
891
        }
892
        List<VCSGisEntity> checkedEntities = entitySelector.getCheckedEntities();
893
        if ( CollectionUtils.isEmpty(checkedEntities) ) {
894
            this.changes = null;
895
            this.tblRemoteChanges.setModel(new DefaultTableModel());
896
            this.lblRemoteChangesCount.setText("0");
897
            return;
898
        }
899
        I18nManager i18n = ToolsLocator.getI18nManager();
900
        message("Reloading list of remote changes...");
901
        this.changes = ws.getRemoteChangesByEntity(
902
                checkedEntities.stream()
903
                    .map((t) -> {return t.getEntityName();})
904
                    .toArray((n) -> { return new String[n];})
905
        );
906
        this.changes.addChangeListener((ChangeEvent e) -> {
907
            context.doUpdateComponents();
908
        });
909
        RemoteChangesTableModel changesModel = new RemoteChangesTableModel(changes, ws);
910
        this.tblRemoteChanges.setModel(changesModel);
911

    
912
        int columns = this.tblRemoteChanges.getColumnModel().getColumnCount();
913
        for (int i = 1; i < columns; i++) {
914
            this.tblRemoteChanges.getColumnModel().getColumn(i).setCellRenderer(new DefaultTableCellRenderer() {
915
                @Override
916
                public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
917
                    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
918
                    VCSGisChange changeRow = changes.get64(row);
919
                    VCSGisSwingCommons.setColorCompoment(c, changeRow.getStatus());
920
                    return c;
921
                }
922
            });
923
        }
924

    
925
        context.doUpdateComponents();
926
        context.message(i18n.getTranslation(
927
                "_Repository_changes_list_updated", 
928
                new String[] { String.valueOf(changes.size64()) }
929
            )
930
        );
931
        this.lblRemoteChangesCount.setText(String.valueOf(changes.size64()));
932
    }
933

    
934
    private List<VCSGisEntity>  getWorkspaceCheckedEntities() {
935
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
936
        if (ws == null) {
937
            return null;
938
        }
939
        List<VCSGisEntity> checkedEntities = entitySelector.getCheckedEntities();
940
        if ( CollectionUtils.isEmpty(checkedEntities) ) {
941
            return null;
942
        }
943
        List<VCSGisEntity> workspaceCheckedEntities = new ArrayList<>();
944
        for (VCSGisEntity entity : checkedEntities) {
945
            if( ws.getWorkspaceEntityByCode(entity.getEntityCode())!=null ) {
946
                workspaceCheckedEntities.add(entity);
947
            }
948
        }
949
        if ( CollectionUtils.isEmpty(workspaceCheckedEntities) ) {
950
            return null;
951
        }
952
        return workspaceCheckedEntities;
953
    }
954
    
955
    private List<VCSGisEntity>  getRepositoryCheckedEntities() {
956
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
957
        if (ws == null) {
958
            return null;
959
        }
960
        List<VCSGisEntity> checkedEntities = entitySelector.getCheckedEntities();
961
        if ( CollectionUtils.isEmpty(checkedEntities) ) {
962
            return null;
963
        }
964
        List<VCSGisEntity> workspaceCheckedEntities = new ArrayList<>();
965
        for (VCSGisEntity entity : checkedEntities) {
966
            if( ws.getWorkspaceEntityByCode(entity.getEntityCode())==null ) {
967
                workspaceCheckedEntities.add(entity);
968
            }
969
        }
970
        if ( CollectionUtils.isEmpty(workspaceCheckedEntities) ) {
971
            return null;
972
        }
973
        return workspaceCheckedEntities;
974
    }
975

    
976
    private void doCleanChanges() {
977
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
978
        if (ws == null) {
979
            return;
980
        }
981
        List<VCSGisEntity> entitiesToCleanChanges = this.getWorkspaceCheckedEntities();
982
        if ( CollectionUtils.isEmpty(entitiesToCleanChanges) ) {
983
            return;
984
        }
985
        Thread task = new Thread(() -> {
986
            try {
987
                context.processing = true;
988
                context.doUpdateComponents();
989
                for (VCSGisEntity checkedEntity : entitiesToCleanChanges) {
990
                    message("Removing list of remote changes from selected tables" + checkedEntity.getEntityName() + "...");
991
                    ws.updateClean(checkedEntity.getEntityName());
992
                }
993
                message("Ready.");
994
            } finally {
995
                context.processing = false;
996
                context.doUpdateComponents();
997
            }
998
        }, "VCSGisUpdateClean");
999
        task.start();
1000
    }
1001

    
1002
    private void doDownloadChangesOfSelectedTable() {
1003
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
1004
        if (ws == null) {
1005
            return;
1006
        }
1007
        List<VCSGisEntity> entitiesToUpdate = this.getWorkspaceCheckedEntities();
1008
        if ( CollectionUtils.isEmpty(entitiesToUpdate) ) {
1009
            return;
1010
        }
1011
        
1012
        SimpleTaskStatus taskStatus = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Download changes");
1013
        Thread task = new Thread(() -> {
1014
                try {
1015
                    taskStatus.setAutoremove(true);
1016
                    taskStatus.add();
1017
                    taskStatus.setRangeOfValues(0, entitiesToUpdate.size());
1018
                    taskStatus.setCurValue(0);
1019
                    context.setTaskStatus(taskStatus);
1020
                    context.processing = true;
1021
                    context.doUpdateComponents();
1022
                    for (VCSGisEntity entity : entitiesToUpdate) {
1023
                        taskStatus.setTitle("Download changes" + " - " + entity.getLabel());
1024
                        message("Removing list of remote changes of " + entity.getEntityName() + "...");
1025
                        ws.updateClean(entity.getEntityName());
1026
                        message("Downloading list of remote changes of " + entity.getEntityName() + "...");
1027
                        ws.updatePrepare(entity.getEntityName(), taskStatus);
1028
                        taskStatus.incrementCurrentValue();
1029
                    }
1030
                    message("Updating metadata information");
1031
                    ws.clearRepositoryEntitiesCached();
1032
                    ws.updateEntitiesFromRepository();
1033
                    context.updateLocalChangesTable();
1034
                    taskStatus.terminate();
1035
                } catch(UserCancelledException ex) {
1036
                    LOGGER.warn("User cancelled");
1037
                    taskStatus.cancel();
1038
                } catch(Exception ex) {
1039
                    taskStatus.abort();
1040
                } finally {
1041
                    context.processing = false;
1042
                    context.doUpdateComponents();
1043
                    doReloadChanges();
1044
                }
1045
            }, "VCSGisUpdatePrepare"
1046
        );
1047
        context.processing = true;
1048
        context.doUpdateComponents();
1049
        task.start();
1050
        message("_Ready");
1051
    }
1052

    
1053
    private void doReloadTables() {
1054
        VCSGisWorkspace ws = this.getUndisposableWorkspace();
1055
        if (ws == null) {
1056
            this.entitySelector.setWorkspace(null);
1057
            return;
1058
        }
1059
        this.entitySelector.reloadEntities();
1060
//        context.doUpdateComponents();
1061
    }
1062

    
1063
    public boolean isProcessing() {
1064
        return context.processing;
1065
    }
1066
    
1067
    private Geometry getRepositoryGeometryOfSelectedChange() {
1068
        Geometry geom = null;
1069
        try {
1070
            if( this.tblRemoteChanges.getSelectedRowCount()>1 && this.tblRemoteChanges.getSelectedRowCount()<200 ) {
1071
                for (int selectedRow : this.tblRemoteChanges.getSelectedRows()) {
1072
                    VCSGisRepositoryChange change = changes.get64(selectedRow);
1073
                    Geometry currentGeom = change.getGeometry();
1074
                    if( currentGeom!=null ) {
1075
                        if( geom == null ) {
1076
                            int type = currentGeom.getType();
1077
                            if( GeometryUtils.isSubtype(Geometry.TYPES.POINT, type) || GeometryUtils.isSubtype(Geometry.TYPES.MULTIPOINT, type)) {
1078
                                    geom = GeometryLocator.getGeometryManager().createMultiPoint(currentGeom.getGeometryType().getSubType());
1079
                            } else if( GeometryUtils.isSubtype(Geometry.TYPES.LINE, type) || GeometryUtils.isSubtype(Geometry.TYPES.MULTILINE, type)) {
1080
                                geom = GeometryLocator.getGeometryManager().createMultiCurve(currentGeom.getGeometryType().getSubType());
1081
                            } else if( GeometryUtils.isSubtype(Geometry.TYPES.SURFACE, type) || GeometryUtils.isSubtype(Geometry.TYPES.MULTISURFACE, type)) {
1082
                                geom = GeometryLocator.getGeometryManager().createMultiSurface(currentGeom.getGeometryType().getSubType());
1083
                            } else {
1084
                                return geom;
1085
                            }
1086
                        }
1087
                        ((MultiPrimitive)geom).addPrimitives(currentGeom);
1088
                    }
1089
                }
1090
            } else {
1091
                int selected = this.tblRemoteChanges.getSelectedRow();
1092
                if(selected >= 0){
1093
                    VCSGisRepositoryChange change = changes.get64(selected);
1094
                    geom = change.getGeometry();
1095
                }
1096
            }
1097
            return geom;
1098
        } catch (Exception ex) {
1099
            return geom;
1100
        }
1101
    }
1102
    
1103
    private Geometry getWorkspaceGeometryOfSelectedChange() {
1104
        Geometry geom = null;
1105
        try {
1106
            VCSGisWorkspace ws = getUndisposableWorkspace();
1107
            if( this.tblRemoteChanges.getSelectedRowCount()>1 && this.tblRemoteChanges.getSelectedRowCount()<200 ) {
1108
                for (int selectedRow : this.tblRemoteChanges.getSelectedRows()) {
1109
                    VCSGisRepositoryChange change = changes.get64(selectedRow);
1110
                    Feature f = ws.getRelatedFeature(change);
1111
                    if(f!= null){
1112
                        Geometry currentGeom = f.getDefaultGeometry();
1113
                        if( currentGeom!=null ) {
1114
                            if( geom == null ) {
1115
                                int type = currentGeom.getType();
1116
                                if( GeometryUtils.isSubtype(Geometry.TYPES.POINT, type) || GeometryUtils.isSubtype(Geometry.TYPES.MULTIPOINT, type)) {
1117
                                        geom = GeometryLocator.getGeometryManager().createMultiPoint(currentGeom.getGeometryType().getSubType());
1118
                                } else if( GeometryUtils.isSubtype(Geometry.TYPES.LINE, type) || GeometryUtils.isSubtype(Geometry.TYPES.MULTILINE, type)) {
1119
                                    geom = GeometryLocator.getGeometryManager().createMultiCurve(currentGeom.getGeometryType().getSubType());
1120
                                } else if( GeometryUtils.isSubtype(Geometry.TYPES.SURFACE, type) || GeometryUtils.isSubtype(Geometry.TYPES.MULTISURFACE, type)) {
1121
                                    geom = GeometryLocator.getGeometryManager().createMultiSurface(currentGeom.getGeometryType().getSubType());
1122
                                } else {
1123
                                    return geom;
1124
                                }
1125
                            }
1126
                            ((MultiPrimitive)geom).addPrimitives(currentGeom);
1127
                        }
1128
                    }
1129
                }
1130
            } else {
1131
                int selected = this.tblRemoteChanges.getSelectedRow();
1132
                if(selected >= 0){
1133
                    VCSGisRepositoryChange change = changes.get64(selected);
1134
                    Feature f = ws.getRelatedFeature(change);
1135
                    if(f!= null){
1136
                        geom = f.getDefaultGeometry();
1137
                    }
1138
                }
1139
            }
1140
            return geom;
1141
        } catch (Exception ex) {
1142
            return geom;
1143
        }
1144
    }
1145
    
1146
    private FeatureStore getWorkspaceStoreOfSelectedChange() {
1147
        FeatureStore store = null;
1148
        int selected = this.tblRemoteChanges.getSelectedRow();
1149
        if(selected >= 0){
1150
            VCSGisRepositoryChange change = changes.get64(selected);
1151
            
1152
            VCSGisWorkspace ws = getUndisposableWorkspace();
1153
            VCSGisWorkspaceEntity entity = ws.getWorkspaceEntityByCode(change.getEntityCode());
1154
            store = ws.openFeatureStore(entity.getEntityName(),false);
1155
        }
1156
        return store;
1157
    }
1158
    
1159
    private void doZoomToSelectedChange() {
1160
        cleanHighligthed();
1161
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
1162
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
1163
        VCSGisSwingServices services = swingManager.getDefaultServices();
1164
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
1165
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
1166
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
1167
        services.zoomViewsHavingAStoreToGeometry(store, VCSGisSwingCommons.createBBox(repoGeom, geom));
1168
        if(repoGeom != null){
1169
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
1170
        }
1171
        if(geom != null){
1172
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
1173
        }
1174
    }
1175

    
1176
    private void doCenterToSelectedChange() {
1177
        cleanHighligthed();
1178
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
1179
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
1180
        VCSGisSwingServices services = swingManager.getDefaultServices();
1181
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
1182
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
1183
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
1184
        services.centerViewsHavingAStoreToGeometry(store, VCSGisSwingCommons.createBBox(repoGeom, geom));
1185
        if(repoGeom != null){
1186
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
1187
        }
1188
        if(geom != null){
1189
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
1190
        }
1191
    }
1192

    
1193
    private void doHighLightSelectedChange() {
1194
        cleanHighligthed();
1195
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
1196
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
1197
        VCSGisSwingServices services = swingManager.getDefaultServices();
1198
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
1199
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
1200
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
1201
        if(repoGeom != null){
1202
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
1203
        }
1204
        if(geom != null){
1205
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
1206
        }
1207
    }
1208

    
1209
    private void doCheckout(boolean overwrite) {
1210
        I18nManager i18n = ToolsLocator.getI18nManager();
1211
        
1212
        final VCSGisWorkspace workspace = this.getUndisposableWorkspace();
1213
        if( workspace==null ) {
1214
            return;
1215
        }
1216
        List<VCSGisEntity> entitiesToCheckout;
1217
        if( overwrite ) {
1218
            entitiesToCheckout = this.entitySelector.getCheckedEntities();
1219
        } else {
1220
            entitiesToCheckout = this.getRepositoryCheckedEntities();
1221
        }
1222
        if ( CollectionUtils.isEmpty(entitiesToCheckout) ) {
1223
            return;
1224
        }
1225

    
1226

    
1227
        Thread task = new Thread(() -> {
1228
            try {
1229
                context.processing = true;
1230
                context.doUpdateComponents();
1231
                int r = ERR_OK;
1232
                for (VCSGisEntity entity : entitiesToCheckout) {
1233
                    if(overwrite){
1234
                        r = workspace.removeEntity(entity);
1235
                        if( r!=ERR_OK) {
1236
                            this.message(i18n.getTranslation("_Cant_overwrite")+" "+ entity.getEntityName());
1237
                            break;
1238
                        }
1239
                    }                   
1240
                    r = workspace.checkout(entity.getEntityName());
1241
                    if (r != ERR_OK) {
1242
                        this.message(i18n.getTranslation("_Cant_checkout")+" "+ entity.getEntityName());
1243
                        break;
1244
                    }
1245
                }
1246
                postCheckout(r, entitiesToCheckout);
1247
            } catch(UserCancelledException ex) {
1248
                LOGGER.warn("User cancelled");
1249
            } finally {
1250
                context.processing = false;
1251
                context.doUpdateComponents();
1252
                context.updateLocalChangesTable();
1253
            }
1254
        }, "VCSGisCheckout");
1255

    
1256
        this.context.processing = true;
1257
        doUpdateComponents();
1258
        task.start();
1259
    }
1260
    
1261
    private void postCheckout(int checkoutStatus, List<VCSGisEntity> entities) {
1262
        if (notInSwingThreadInvokeLater(() -> {
1263
            postCheckout(checkoutStatus, entities);
1264
        })) {
1265
            return;
1266
        }
1267
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
1268
        VCSGisSwingServices services = swingManager.getDefaultServices();
1269
        I18nManager i18n = ToolsLocator.getI18nManager();
1270

    
1271
        final VCSGisWorkspace workspace = this.getUndisposableWorkspace();
1272

    
1273
        if (checkoutStatus == ERR_OK) {
1274
            this.context.setVisibleStatus(false);
1275

    
1276
            int tablesWithGeometry = 0;
1277
            for (VCSGisEntity entity : entities) {
1278
                if (StringUtils.isNotBlank(entity.getGeometryFieldName()) )  {
1279
                    tablesWithGeometry++;
1280
                }
1281
            }
1282
            
1283
            if (tablesWithGeometry>0 && services.isThereAnyActiveView()) {
1284
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1285
                int n = dialogs.confirmDialog(i18n.getTranslation("_Do_you_want_add_layer_to_active_view"),
1286
                        i18n.getTranslation("_VCS_Checkout"),
1287
                        JOptionPane.YES_NO_OPTION,
1288
                        JOptionPane.QUESTION_MESSAGE,
1289
                        "VCSGis_Checkout_add_layer_to_view"
1290
                );
1291
                if( n == JOptionPane.YES_OPTION ) {
1292
                    for (VCSGisEntity entity : entities) {
1293
                        if (StringUtils.isNotBlank(entity.getGeometryFieldName()) )  {
1294
                            FeatureStore store = workspace.openFeatureStore(entity.getEntityName(),false);
1295
                            services.addLayerToView(
1296
                                    store, 
1297
                                    null, // Active view
1298
                                    entity.getFirstCategory(), 
1299
                                    entity.getLabel(), 
1300
                                    false
1301
                            );
1302
                        }
1303
                    }
1304
                }
1305
            } 
1306
            if( entities.size() - tablesWithGeometry > 0 ) {
1307
                // Hay tablas sin geometrias
1308
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1309
                int res = dialogs.confirmDialog(i18n.getTranslation("_Do_you_want_add_table_to_project"),
1310
                        i18n.getTranslation("_VCS_Checkout"),
1311
                        JOptionPane.YES_NO_OPTION,
1312
                        JOptionPane.QUESTION_MESSAGE,
1313
                        "VCSGis_Checkout_add_table_to_project"
1314
                );
1315

    
1316
                if (res == JOptionPane.YES_OPTION) {
1317
                    for (VCSGisEntity entity : entities) {
1318
                        if (!services.isThereAnyActiveView() || StringUtils.isBlank(entity.getGeometryFieldName()) )  {
1319
                            FeatureStore store = workspace.openFeatureStore(entity.getEntityName(), false);
1320
                            services.addTableToProject(workspace, store);
1321
                        }
1322
                    }
1323
                }
1324
            }
1325
        }
1326

    
1327
        doReloadChanges();
1328
        for (VCSGisEntity entity : entities) {
1329
            FeatureStore store = getUndisposableWorkspace().getFeatureStore(entity.getEntityName());
1330
            refreshDocument(store);
1331
        }
1332
    }
1333

    
1334
    
1335

    
1336
    @Override
1337
    protected void doDispose() throws BaseException {
1338
        //TODO: Dispose what is needed
1339
//        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1340
//        DisposeUtils.disposeQuietly(entitySelector);
1341
    }
1342

    
1343
    private void doCheckRecomendedEntities() {
1344
        final VCSGisWorkspace workspace = this.getUndisposableWorkspace();
1345
        if( workspace==null ) {
1346
            return;
1347
        }
1348
        Set<String> updateEntities = new HashSet<>();
1349
        Collection<VCSGisEntity> entities = this.entitySelector.getEntities();
1350
        for (VCSGisEntity entity : entities) {
1351
            if (workspace.existsInWorkspace(entity)) {
1352
                VCSGisWorkspaceEntity lentity = workspace.getWorkspaceEntityByCode(entity.getEntityCode());
1353
                switch (lentity.getState()) {
1354
                    case VCSGisManager.STATE_LOCAL_MODIFIED:
1355
                    case VCSGisManager.STATE_LOCAL_NEW:
1356
                    case VCSGisManager.STATE_LOCAL_UNMODIFIED:
1357
                    case VCSGisManager.STATE_REPOSITORY_NEW:
1358
                    default:
1359
                        break;
1360
                    case VCSGisManager.STATE_CONFLICT:
1361
                    case VCSGisManager.STATE_LOCAL_OUTDATED:
1362
                    case VCSGisManager.STATE_LOCAL_OUTDATED_AND_MODIFIED:
1363
                        updateEntities.add(entity.getEntityCode());
1364
                        break;
1365
                }
1366
            }
1367
        }
1368
        this.entitySelector.setCheck(updateEntities, true);
1369
    }
1370

    
1371
}