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

History | View | Annotate | Download (38.2 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.Iterator;
31
import javax.swing.DefaultListCellRenderer;
32
import javax.swing.DefaultListModel;
33
import javax.swing.JButton;
34
import javax.swing.JLabel;
35
import javax.swing.JList;
36
import javax.swing.JOptionPane;
37
import javax.swing.JTable;
38
import javax.swing.ListSelectionModel;
39
import javax.swing.SwingUtilities;
40
import javax.swing.event.ChangeEvent;
41
import javax.swing.event.ListSelectionEvent;
42
import javax.swing.table.DefaultTableCellRenderer;
43
import javax.swing.table.DefaultTableModel;
44
import org.apache.commons.lang3.BooleanUtils;
45
import org.apache.commons.lang3.StringUtils;
46
import org.apache.commons.lang3.mutable.MutableLong;
47
import org.gvsig.featureform.swing.JFeatureForm;
48
import org.gvsig.fmap.dal.feature.Feature;
49
import org.gvsig.fmap.dal.feature.FeatureStore;
50
import org.gvsig.fmap.dal.feature.FeatureType;
51
import org.gvsig.fmap.dal.swing.DALSwingLocator;
52
import org.gvsig.fmap.dal.swing.DataSwingManager;
53
import org.gvsig.fmap.geom.Geometry;
54
import org.gvsig.json.Json;
55
import org.gvsig.tools.ToolsLocator;
56
import org.gvsig.tools.dispose.DisposeUtils;
57
import org.gvsig.tools.dynform.DynFormLocator;
58
import org.gvsig.tools.dynform.JDynForm;
59
import org.gvsig.tools.dynobject.DynObject;
60
import org.gvsig.tools.i18n.I18nManager;
61
import org.gvsig.tools.swing.api.ToolsSwingLocator;
62
import org.gvsig.tools.swing.api.ToolsSwingManager;
63
import org.gvsig.tools.swing.api.pickercontroller.PickerController;
64
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
65
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
66
import org.gvsig.tools.util.LabeledValue;
67
import org.gvsig.tools.util.LabeledValueImpl;
68
import org.gvsig.vcsgis.lib.VCSGisChange;
69
import org.gvsig.vcsgis.lib.VCSGisEntity;
70
import org.gvsig.vcsgis.lib.VCSGisLocator;
71
import org.gvsig.vcsgis.lib.VCSGisManager;
72
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_OK;
73
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_ADD_ENTITY;
74
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_DELETE;
75
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_UNKNOWN;
76
import org.gvsig.vcsgis.lib.VCSGisRuntimeException;
77
import org.gvsig.vcsgis.lib.repository.VCSGisRepositoryChange;
78
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspace;
79
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceChange;
80
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceChanges;
81
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceEntity;
82
import org.gvsig.vcsgis.swing.VCSGisSwingLocator;
83
import org.gvsig.vcsgis.swing.VCSGisSwingManager;
84
import org.gvsig.vcsgis.swing.VCSGisSwingServices;
85
import static org.gvsig.vcsgis.swing.VCSGisSwingServices.HIGHLIGHT_REPOSITORY;
86
import static org.gvsig.vcsgis.swing.VCSGisSwingServices.HIGHLIGHT_WORKSPACE;
87
import org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons;
88
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.cleanHighligthed;
89
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.notInSwingThreadInvokeLater;
90
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.refreshDocument;
91
import static org.gvsig.vcsgis.swing.impl.changes.VCSGisJChangesImpl.LOCAL_TAB_INDEX;
92
import org.slf4j.Logger;
93
import org.slf4j.LoggerFactory;
94
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.showAuthenticationErrors;
95
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.showAuthenticationErrors;
96
import static org.gvsig.vcsgis.swing.impl.VCSGisSwingCommons.showAuthenticationErrors;
97

    
98
/**
99
 *
100
 * @author gvSIG Team
101
 */
102
@SuppressWarnings("UseSpecificCatch")
103
public class RemoteChangesController {
104

    
105
    private static final Logger LOGGER = LoggerFactory.getLogger(RemoteChangesController.class);
106

    
107
    private final PickerController<VCSGisWorkspace> workspacePicker;
108
    private final JTable tblRemoteChanges;
109
    private final JButton btnRemoteShowForm;
110
    private final JButton btnRemoteUpdate;
111
    private final JButton btnRemoteMerge;
112
    private final JButton btnRemoteReloadChanges;
113
    private final JButton btnRemoteCheckAll;
114
    private final JButton btnRemoteUnCheckAll;
115
    private final JList lstRemoteTables;
116

    
117
    private VCSGisWorkspaceChanges<VCSGisRepositoryChange> changes;
118

    
119
    private final JButton btnRemoteTablesReload;
120
    private final JButton btnRemoteDownloadChanges;
121
    private final JButton btnRemoteCleanChanges;
122
    private final VCSGisJChangesImpl context;
123
    
124
    
125
    private final JButton btnRemoteZoom;
126
    private final JButton btnRemoteCenter;
127
    private final JButton btnRemoteCheckout;
128
    private final JButton btnRemoteCleanHighligthed;
129

    
130
    private final JLabel lblRemoteChangesCount;
131

    
132
    public RemoteChangesController(
133
            VCSGisJChangesImpl context,
134
            PickerController<VCSGisWorkspace> workspacePicker,
135
            JList lstRemoteTables,
136
            JButton btnRemoteTablesReload,
137
            JTable tblRemoteChanges,
138
            JButton btnRemoteCheckAll,
139
            JButton btnRemoteUnCheckAll,
140
            JButton btnRemoteDownloadChanges,
141
            JButton btnRemoteReloadChanges,
142
            JButton btnRemoteCleanChanges,
143
            JButton btnRemoteUpdate,
144
            JButton btnRemoteMerge,
145
            JButton btnRemoteShowForm,
146
            JButton btnRemoteZoom,
147
            JButton btnRemoteCenter,
148
            JButton btnRemoteCheckout,
149
            JButton btnRemoteCleanHighligthed,
150
            JLabel lblRemoteChangesCount
151
    ) {
152
        this.context = context;
153

    
154
        this.workspacePicker = workspacePicker;
155

    
156
        this.lstRemoteTables = lstRemoteTables;
157
        this.btnRemoteTablesReload = btnRemoteTablesReload;
158

    
159
        this.tblRemoteChanges = tblRemoteChanges;
160
        this.btnRemoteCheckAll = btnRemoteCheckAll;
161
        this.btnRemoteUnCheckAll = btnRemoteUnCheckAll;
162
        this.btnRemoteDownloadChanges = btnRemoteDownloadChanges;
163
        this.btnRemoteCleanChanges = btnRemoteCleanChanges;
164
        this.btnRemoteReloadChanges = btnRemoteReloadChanges;
165

    
166
        this.btnRemoteUpdate = btnRemoteUpdate;
167
        this.btnRemoteMerge = btnRemoteMerge;
168
        this.btnRemoteShowForm = btnRemoteShowForm;
169

    
170
        this.btnRemoteZoom = btnRemoteZoom;
171
        this.btnRemoteCenter = btnRemoteCenter;
172
        this.btnRemoteCheckout = btnRemoteCheckout;
173
        
174
        this.btnRemoteCleanHighligthed = btnRemoteCleanHighligthed;
175

    
176
        this.lblRemoteChangesCount= lblRemoteChangesCount;
177
        initComponents();
178
    }
179

    
180
    public void message(final String msg) {
181
        this.context.message(msg);
182
    }
183

    
184
    public void initComponents() {
185
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
186
        I18nManager i18n = ToolsLocator.getI18nManager();
187

    
188
        this.btnRemoteCheckAll.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
189
        this.btnRemoteCleanChanges.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
190
        this.btnRemoteDownloadChanges.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
191
        this.btnRemoteMerge.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
192
        this.btnRemoteReloadChanges.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
193
        this.btnRemoteShowForm.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
194
        this.btnRemoteTablesReload.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
195
        this.btnRemoteUnCheckAll.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
196
        this.btnRemoteUpdate.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
197
        this.btnRemoteZoom.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
198
        this.btnRemoteCenter.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
199
        this.btnRemoteCheckout.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
200
        this.btnRemoteCleanHighligthed.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
201

    
202
        translate();
203

    
204
        lstRemoteTables.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
205

    
206
        lstRemoteTables.setCellRenderer(new DefaultListCellRenderer() {
207
            @Override
208
            public java.awt.Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
209
                JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
210
                LabeledValue lvalue = (LabeledValue) value;
211
                VCSGisEntity entity = (VCSGisEntity) lvalue.getValue();
212
                String entityCode = entity.getEntityCode();
213
                VCSGisWorkspaceEntity lentity = getWorkspace().getWorkspaceEntity(entityCode);
214
                String s = VCSGisSwingCommons.getHTMLColorTag(
215
                        lentity == null ? VCSGisManager.STATE_REPOSITORY_NEW : lentity.getState(),
216
                        lvalue.getLabel()
217
                );
218
                label.setText(s);
219
                return label;
220
            }
221
        });
222

    
223
        this.lstRemoteTables.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
224
            doReloadChanges();
225
        });
226

    
227
        this.btnRemoteTablesReload.addActionListener((ActionEvent e) -> {
228
            doReloadTables(true);
229
            doReloadChanges();
230
        });
231

    
232
        this.tblRemoteChanges.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
233

    
234
        this.tblRemoteChanges.addKeyListener(new KeyAdapter() {
235
            @Override
236
            public void keyPressed(KeyEvent e) {
237
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
238
                    doToggleSelection();
239
                }
240
            }
241
        });
242

    
243
        this.tblRemoteChanges.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
244
            context.doUpdateComponents();
245
        });
246

    
247
        this.btnRemoteCheckAll.addActionListener((ActionEvent e) -> {
248
            if (changes != null) {
249
                doCheckAll();
250
                doReloadChanges();
251
            }
252
        });
253

    
254
        this.btnRemoteUnCheckAll.addActionListener((ActionEvent e) -> {
255
            if (changes != null) {
256
                doUnCheckAll();
257
                doReloadChanges();
258
            }
259
        });
260

    
261
        this.btnRemoteDownloadChanges.addActionListener((ActionEvent e) -> {
262
            doDownloadChangesOfSelectedTable();
263
        });
264

    
265
        this.btnRemoteReloadChanges.addActionListener((ActionEvent e) -> {
266
            doDownloadChangesOfSelectedTable();
267
        });
268

    
269
        this.btnRemoteCleanChanges.addActionListener((ActionEvent e) -> {
270
            doCleanChanges();
271
            doReloadChanges();
272
        });
273

    
274
        this.btnRemoteUpdate.addActionListener((ActionEvent e) -> {
275
            doUpdate();
276
        });
277

    
278
        this.btnRemoteMerge.addActionListener((ActionEvent e) -> {
279
            doMerge();
280
        });
281

    
282
        this.btnRemoteShowForm.addActionListener((ActionEvent e) -> {
283
            doShowForm();
284
        });
285
        
286
        this.btnRemoteZoom.addActionListener((ActionEvent e) -> {
287
            doZoomToSelectedChange();
288
        });
289

    
290
        this.btnRemoteCenter.addActionListener((ActionEvent e) -> {
291
            doCenterToSelectedChange();
292
        });
293
        
294
        this.btnRemoteCleanHighligthed.addActionListener((ActionEvent e) -> {
295
            cleanHighligthed();
296
        });
297

    
298
        this.btnRemoteCheckout.addActionListener((ActionEvent e) -> {
299
            doCheckout();
300
        });
301

    
302

    
303
        context.doUpdateComponents();
304

    
305
        SwingUtilities.invokeLater(() -> {
306
            message(i18n.getTranslation("_Ready"));
307
            this.lblRemoteChangesCount.setText("");
308
        });
309

    
310
    }
311
    
312
    public void doChangeWorkspace() {
313
        doReloadTables(false);
314
        doReloadChanges();
315
    }
316
    
317
    public void translate() {
318
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
319

    
320
        swingManager.translate(this.btnRemoteCheckAll);
321
        swingManager.translate(this.btnRemoteUpdate);
322
        swingManager.translate(this.btnRemoteCleanChanges);
323
        swingManager.translate(this.btnRemoteReloadChanges);
324
        swingManager.translate(this.btnRemoteMerge);
325
        swingManager.translate(this.btnRemoteShowForm);
326
        swingManager.translate(this.btnRemoteUnCheckAll);
327
        swingManager.translate(this.btnRemoteTablesReload);
328
        swingManager.translate(this.btnRemoteDownloadChanges);
329
        swingManager.translate(this.btnRemoteCenter);
330
        swingManager.translate(this.btnRemoteZoom);
331
        swingManager.translate(this.btnRemoteCheckout);
332
        swingManager.translate(this.btnRemoteCleanHighligthed);
333

    
334
    }
335

    
336
    public VCSGisWorkspace getWorkspace() {
337
        return this.context.getWorkspace();
338
    }
339

    
340
    /* friend */ void doUpdateComponents() {
341
        if (notInSwingThreadInvokeLater(() -> {
342
            doUpdateComponents();
343
        })) {
344
            return;
345
        }
346
        try {
347
            this.context.setVisibleStatus(context.processing);
348
            VCSGisWorkspace ws = this.getWorkspace();
349

    
350
            this.btnRemoteCheckAll.setEnabled(!context.processing && changes != null);
351
            this.btnRemoteUnCheckAll.setEnabled(!context.processing && changes != null);
352

    
353
            this.btnRemoteDownloadChanges.setEnabled(!context.processing && ws != null && BooleanUtils.isTrue(this.isSelectedTableInWorkspace()));
354
            this.btnRemoteCheckout.setEnabled(!context.processing && ws != null && BooleanUtils.isFalse(this.isSelectedTableInWorkspace()));
355
            this.btnRemoteReloadChanges.setEnabled(!context.processing && ws != null && BooleanUtils.isTrue(this.isSelectedTableInWorkspace()));
356
            this.btnRemoteCleanChanges.setEnabled(!context.processing && ws != null && BooleanUtils.isTrue(this.isSelectedTableInWorkspace()));
357
            this.btnRemoteTablesReload.setEnabled(!context.processing);
358

    
359
            this.btnRemoteTablesReload.setEnabled(!context.processing && ws != null);
360

    
361
            //Show form
362
            boolean enableShowForm = false;
363
            int row = this.tblRemoteChanges.getSelectedRow();
364
            if (row >= 0) {
365
                VCSGisRepositoryChange change = this.changes.get64(row);
366
                if (change.getOperation() != OP_ADD_ENTITY) {
367
                    enableShowForm = true;
368
                }
369
            }
370
            this.btnRemoteShowForm.setEnabled(!context.processing && enableShowForm);
371

    
372
            this.lstRemoteTables.setEnabled(!context.processing);
373
            this.tblRemoteChanges.setEnabled(!context.processing);
374
            this.workspacePicker.setEnabled(!context.processing);
375

    
376
            LabeledValue selected = (LabeledValue) lstRemoteTables.getSelectedValue();
377
            if (selected == null) {
378
                this.btnRemoteMerge.setEnabled(false);
379
                this.btnRemoteUpdate.setEnabled(false);
380
                return;
381
            }
382

    
383
            VCSGisEntity entity = (VCSGisEntity) selected.getValue();
384
            if (this.getWorkspace().updateNeedMerge(entity.getEntityName())) {
385
                this.btnRemoteMerge.setEnabled(!context.processing);
386
                this.btnRemoteUpdate.setEnabled(false);
387
            } else {
388
                this.btnRemoteMerge.setEnabled(false);
389
                this.btnRemoteUpdate.setEnabled(!context.processing && changes != null && !this.changes.isSelectionEmpty());
390
            }
391

    
392
            Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
393
            Geometry wsGeom = getWorkspaceGeometryOfSelectedChange();
394
            Geometry bbox = VCSGisSwingCommons.createBBox(repoGeom, wsGeom);
395
            this.btnRemoteCenter.setEnabled(!context.processing && bbox != null);
396
            this.btnRemoteZoom.setEnabled(!context.processing && bbox != null);
397
            this.btnRemoteCleanHighligthed.setEnabled(!context.processing);
398
        } catch (VCSGisRuntimeException e1) {
399
            LOGGER.warn("Can't updating components.", e1);
400
            if (showAuthenticationErrors("_VCS_Changes", e1)) {
401
                this.workspacePicker.set(null);
402
                doChangeWorkspace();
403
            }
404
        } catch (Exception e2) {
405
            LOGGER.warn("Can't updating components.", e2);
406
        }
407

    
408
    }
409

    
410
    private void doToggleSelection() {
411
        Thread task = new Thread(() -> {
412
            try {
413
                context.processing = true;
414
                context.doUpdateComponents();
415
                Iterator<Long> rows = getChangesSelectionIterator();
416

    
417
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
418
                    change.setSelected(!change.isSelected());
419
                    return true;
420
                });
421
            } finally {
422
                context.processing = false;
423
                context.doUpdateComponents();
424
            }
425
        }, "VCSGisToggleSelectionRemoteChanges");
426
        task.start();
427
    }
428

    
429
    private Iterator<Long> getChangesSelectionIterator() {
430
        ListSelectionModel selection = this.tblRemoteChanges.getSelectionModel();
431
        return new Iterator<Long>() {
432
            long n = selection.getMinSelectionIndex();
433

    
434
            @Override
435
            public boolean hasNext() {
436
                while (n <= selection.getMaxSelectionIndex()) {
437
                    if (selection.isSelectedIndex((int) n)) {
438
                        return true;
439
                    }
440
                    n++;
441
                }
442
                return false;
443
            }
444

    
445
            @Override
446
            public Long next() {
447
                if (n > selection.getMaxSelectionIndex()) {
448
                    throw new IllegalStateException();
449
                }
450
                return n++;
451
            }
452
        };
453
    }
454

    
455
    private Iterator<Long> getRowsIterator() {
456
        long size = changes.size64();
457
        return new Iterator<Long>() {
458
            long n = 0;
459

    
460
            @Override
461
            public boolean hasNext() {
462
                return (n < size);
463
            }
464

    
465
            @Override
466
            public Long next() {
467
                return n++;
468
            }
469
        };
470
    }
471

    
472
    private void doCheckAll() {
473
        Thread task = new Thread(() -> {
474
            try {
475
                context.processing = true;
476
                context.doUpdateComponents();
477
                Iterator<Long> rows = getRowsIterator();
478

    
479
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
480
                    change.setSelected(true);
481
                    return true;
482
                });
483
            } finally {
484
                context.processing = false;
485
                context.doUpdateComponents();
486
            }
487
        }, "VCSGisCheckAllRemoteChanges");
488
        task.start();
489
    }
490

    
491
    private void doUnCheckAll() {
492
        Thread task = new Thread(() -> {
493
            try {
494
                context.processing = true;
495
                context.doUpdateComponents();
496
                Iterator<Long> rows = getRowsIterator();
497

    
498
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
499
                    change.setSelected(false);
500
                    return true;
501
                });
502
            } finally {
503
                context.processing = false;
504
                context.doUpdateComponents();
505
            }
506
        }, "VCSGisCheckAllRemoteChanges");
507
        task.start();
508
    }
509

    
510
    private void doUpdate() {
511
        VCSGisWorkspace ws = getWorkspace();
512
        if (ws == null) {
513
            return;
514
        }
515
        LabeledValue selectedTable = (LabeledValue) lstRemoteTables.getSelectedValue();
516
        if (selectedTable == null) {
517
            return;
518
        }
519
        VCSGisEntity entity = (VCSGisEntity) selectedTable.getValue();
520
        String tableName = entity.getEntityName();
521

    
522
        this.tblRemoteChanges.setModel(new ChangesTableModel(ws));
523

    
524
        Thread task = new Thread(() -> {
525
            try {
526
                context.processing = true;
527
                context.doUpdateComponents();
528
                int r = ws.update(tableName, null);
529
                doPostUpdate(r);
530
            } finally {
531
                context.processing = false;
532
                context.doUpdateComponents();
533
            }
534
        }, "VCSGisUpdate");
535
        context.processing = true;
536
        context.doUpdateComponents();
537
        task.start();
538
    }
539

    
540
    private void doPostUpdate(int updateStatus) {
541
        if (notInSwingThreadInvokeLater(() -> {doPostUpdate(updateStatus);})) {
542
            return;
543
        }
544
        if (updateStatus == ERR_OK) {
545
            context.setVisibleStatus(false);
546
        }
547
        doReloadChanges();
548

    
549
        VCSGisEntity selectedTable = getSelectedTable();
550
        FeatureStore store = getWorkspace().getFeatureStore(selectedTable.getEntityName());
551
        refreshDocument(store);
552
        
553
        context.doUpdateComponents();
554
        context.updateLocalChangesTable();
555
    }
556

    
557

    
558
    private void doMerge() {
559
        VCSGisWorkspace ws = getWorkspace();
560
        if (ws == null) {
561
            return;
562
        }
563
        LabeledValue selectedTable = (LabeledValue) lstRemoteTables.getSelectedValue();
564
        if (selectedTable == null) {
565
            return;
566
        }
567
        VCSGisEntity entity = (VCSGisEntity) selectedTable.getValue();
568
        String tableName = entity.getEntityName();
569

    
570
        this.tblRemoteChanges.setModel(new ChangesTableModel(ws));
571

    
572
        Thread task = new Thread(() -> {
573
            try {
574
                context.processing = true;
575
                context.doUpdateComponents();
576
                MutableLong localChangesCreated = new MutableLong(0);
577
                int r = getWorkspace().merge(
578
                        tableName,
579
                        localChangesCreated,
580
                        this.context.getTaskStatusController().getSimpleTaskStatus()
581
                );
582
                doPostMerge(r, localChangesCreated.getValue());
583
            } finally {
584
                context.processing = false;
585
                context.doUpdateComponents();
586
            }
587
        }, "VCSGisMerge");
588
        context.processing = true;
589
        context.doUpdateComponents();
590
        task.start();
591
    }
592

    
593
    private void doPostMerge(int mergeStatus, long localChangesCreated) {
594
        if (notInSwingThreadInvokeLater(() -> {doPostMerge(mergeStatus, localChangesCreated);})) {
595
            return;
596
        }
597
        if (mergeStatus == ERR_OK) {
598
            this.context.setVisibleStatus(false);
599
        }
600
        doReloadChanges();
601
        VCSGisEntity selectedTable = getSelectedTable();
602
        FeatureStore store = getWorkspace().getFeatureStore(selectedTable.getEntityName());
603
        refreshDocument(store);
604
        
605
        if(localChangesCreated>0){
606
            ThreadSafeDialogsManager dialogsManager = ToolsSwingLocator.getThreadSafeDialogsManager();
607
            I18nManager i18n = ToolsLocator.getI18nManager();
608
            dialogsManager.messageDialog(
609
                    i18n.getTranslation("_The_process_has_created_local_changes_that_would_need_to_be_committed_to_the_repository"), 
610
                    null, 
611
                    i18n.getTranslation("_VCSGis_Merge"), 
612
                    JOptionPane.INFORMATION_MESSAGE, 
613
                    "VCSGIS_merge_need_commit");
614
            context.selectTab(LOCAL_TAB_INDEX);
615
            context.selectOnlyALocalEntity(selectedTable);
616
        }
617
        context.doUpdateComponents();
618
        context.updateLocalChangesTable();
619
    }
620

    
621
    private void doShowForm() {
622
        if (this.changes == null) {
623
            return;
624
        }
625
        int row = this.tblRemoteChanges.getSelectedRow();
626
        VCSGisRepositoryChange change = this.changes.get64(row);
627
        if (change.getOperation() == OP_DELETE) {
628
            return;
629
        }
630
        VCSGisWorkspace ws = this.getWorkspace();
631
        if (ws == null) {
632
            return;
633
        }
634
        VCSGisWorkspaceEntity entity = ws.getWorkspaceEntityByCode(change.getEntityCode());
635

    
636
        if (entity == null) {
637
            VCSGisEntity repoEntity = ws.getEntity(change.getEntityCode());
638
            FeatureType featureType = repoEntity.getFeatureType();
639
            JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(featureType);
640
            DynObject values = ToolsLocator.getDynObjectManager().createDynObject(featureType);
641
            Json.addAll(values, change.getRelatedFeatureDataAsJson());
642
            form.setValues(values);
643
            form.setReadOnly(true);
644
            WindowManager winManager = ToolsSwingLocator.getWindowManager();
645
            form.asJComponent().setPreferredSize(new Dimension(400, 200));
646
            winManager.showWindow(form.asJComponent(), "Remote change: " + change.getLabel(), WindowManager.MODE.WINDOW);
647
            return;
648
        }
649

    
650
        FeatureStore store = null;
651
        try {
652
            DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
653

    
654
            store = ws.getFeatureStore(entity.getEntityName());
655
            Feature feature = store.createNewFeature(change.getRelatedFeatureDataAsJson());
656
            JFeatureForm form = dataSwingManager.createJFeatureForm(feature);
657
            form.getDynForm().setReadOnly(true);
658
            WindowManager winManager = ToolsSwingLocator.getWindowManager();
659
            form.asJComponent().setPreferredSize(new Dimension(400, 200));
660
            winManager.showWindow(form.asJComponent(), "Remote change: " + change.getLabel(), WindowManager.MODE.WINDOW);
661
        } catch (Exception ex) {
662
            LOGGER.warn("Can't show form for change '" + change.getCode() + "'.", ex);
663
        } finally {
664
            DisposeUtils.disposeQuietly(store);
665
        }
666

    
667
    }
668

    
669
    private void doReloadChanges() {
670
        VCSGisWorkspace ws = this.getWorkspace();
671
        if (ws == null) {
672
            return;
673
        }
674
        if (this.changes != null) {
675
            this.changes.removeAllChangeListener();
676
        }
677
        LabeledValue selected = (LabeledValue) lstRemoteTables.getSelectedValue();
678
        if (selected != null) {
679
            I18nManager i18n = ToolsLocator.getI18nManager();
680
            VCSGisEntity entity = (VCSGisEntity) selected.getValue();
681
            message("Reloading list of remote changes...");
682
            this.changes = ws.getRemoteChangesByEntity(entity.getEntityName());
683
            this.changes.addChangeListener((ChangeEvent e) -> {
684
                context.doUpdateComponents();
685
            });
686
            ChangesTableModel changesModel = new ChangesTableModel(changes, ws);
687
            this.tblRemoteChanges.setModel(changesModel);
688

    
689
            int columns = this.tblRemoteChanges.getColumnModel().getColumnCount();
690
            for (int i = 1; i < columns; i++) {
691
                this.tblRemoteChanges.getColumnModel().getColumn(i).setCellRenderer(new DefaultTableCellRenderer() {
692
                    @Override
693
                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
694
                        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
695
                        VCSGisChange changeRow = changes.get64(row);
696
                        VCSGisSwingCommons.setColorCompoment(c, changeRow.getStatus());
697
                        return c;
698
                    }
699
                });
700
            }
701

    
702
            context.doUpdateComponents();
703
            context.message(i18n.getTranslation(
704
                    "_Repository_changes_list_updated", 
705
                    new String[] { String.valueOf(changes.size64()) }
706
                )
707
            );
708
            this.lblRemoteChangesCount.setText(String.valueOf(changes.size64()));
709
        } else {
710
            this.changes = null;
711
            this.tblRemoteChanges.setModel(new DefaultTableModel());
712
            this.lblRemoteChangesCount.setText("0");
713
        }
714

    
715
    }
716

    
717
    private void doCleanChanges() {
718
        VCSGisWorkspace ws = this.getWorkspace();
719
        if (ws == null) {
720
            return;
721
        }
722
        LabeledValue tableSelected = (LabeledValue) lstRemoteTables.getSelectedValue();
723
        if (tableSelected != null) {
724
            final VCSGisEntity entity = (VCSGisEntity) tableSelected.getValue();
725
            Thread task = new Thread(() -> {
726
                try {
727
                    context.processing = true;
728
                    context.doUpdateComponents();
729
                    message("Removing list of remote changes from " + entity.getEntityName() + "...");
730
                    ws.updateClean(entity.getEntityCode());
731
                    message("Ready.");
732
                } finally {
733
                    context.processing = false;
734
                    context.doUpdateComponents();
735
                }
736
            }, "VCSGisUpdateClean");
737
            task.start();
738
        }
739

    
740
    }
741

    
742
    private void doDownloadChangesOfSelectedTable() {
743
        VCSGisWorkspace ws = this.getWorkspace();
744
        if (ws == null) {
745
            return;
746
        }
747
        LabeledValue selected = (LabeledValue) lstRemoteTables.getSelectedValue();
748
        if (selected == null) {
749
            return;
750
        }
751
        Thread task = new Thread(() -> {
752
                try {
753
                    context.processing = true;
754
                    context.doUpdateComponents();
755
                    VCSGisEntity entity = (VCSGisEntity) selected.getValue();
756
                    message("Removing list of remote changes of " + entity.getEntityName() + "...");
757
                    ws.updateClean(entity.getEntityName());
758
                    message("Downloading list of remote changes of " + entity.getEntityName() + "...");
759
                    ws.updatePrepare(entity.getEntityName());
760
                    context.updateLocalChangesTable();
761
                } finally {
762
                    context.processing = false;
763
                    context.doUpdateComponents();
764
                    doReloadChanges();
765
                }
766
            }, "VCSGisUpdatePrepare"
767
        );
768
        context.processing = true;
769
        context.doUpdateComponents();
770
        task.start();
771
        message("_Ready");
772
    }
773

    
774
    private void doReloadTables(boolean forceUpdateEntities) {
775
        DefaultListModel model = new DefaultListModel();
776
        VCSGisWorkspace ws = this.getWorkspace();
777
        if (ws == null) {
778
            this.lstRemoteTables.setModel(model);
779
            return;
780
        }
781
        message("Updating list of tables from remote repository...");// "+ws.getRepository().getLabel()+")...");
782
        this.context.updateEntitiesFromRepository(forceUpdateEntities);
783
        message("Loading list of tables...");
784

    
785
        for (VCSGisEntity entity : ws.getRepositoryEntities()) {
786
            model.addElement(new LabeledValueImpl<>(entity.getEntityName(), entity));
787
        }
788
        this.lstRemoteTables.setModel(model);
789
        context.doUpdateComponents();
790
        message("Ready.");
791
    }
792

    
793
    public boolean isProcessing() {
794
        return context.processing;
795
    }
796
    
797
    private Geometry getRepositoryGeometryOfSelectedChange() {
798
        Geometry geom = null;
799
        int selected = this.tblRemoteChanges.getSelectedRow();
800
        if(selected >= 0){
801
            VCSGisRepositoryChange change = changes.get64(selected);
802
            geom = change.getGeometry();
803
        }
804
        return geom;
805
    }
806
    
807
    private Geometry getWorkspaceGeometryOfSelectedChange() {
808
        Geometry geom = null;
809
        int selected = this.tblRemoteChanges.getSelectedRow();
810
        if(selected >= 0){
811
            VCSGisRepositoryChange change = changes.get64(selected);
812
            
813
            Feature f = getWorkspace().getRelatedFeature(change);
814
            if(f!= null){
815
                geom = f.getDefaultGeometry();
816
            }
817
        }
818
        return geom;
819
    }
820
    
821
    private FeatureStore getWorkspaceStoreOfSelectedChange() {
822
        FeatureStore store = null;
823
        int selected = this.tblRemoteChanges.getSelectedRow();
824
        if(selected >= 0){
825
            VCSGisRepositoryChange change = changes.get64(selected);
826
            
827
            VCSGisWorkspace ws = getWorkspace();
828
            VCSGisWorkspaceEntity entity = ws.getWorkspaceEntityByCode(change.getEntityCode());
829
            store = ws.openFeatureStore(entity.getEntityName());
830
        }
831
        return store;
832
    }
833
    
834
    private void doZoomToSelectedChange() {
835
        cleanHighligthed();
836
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
837
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
838
        VCSGisSwingServices services = swingManager.getDefaultServices();
839
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
840
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
841
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
842
//        services.zoomActiveViewToGeometry(VCSGisSwingCommons.createBBox(repoGeom, geom));
843
        services.zoomViewsHavingAStoreToGeometry(store, VCSGisSwingCommons.createBBox(repoGeom, geom));
844
        if(repoGeom != null){
845
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
846
        }
847
        if(geom != null){
848
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
849
        }
850
    }
851

    
852
    private void doCenterToSelectedChange() {
853
        cleanHighligthed();
854
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
855
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
856
        VCSGisSwingServices services = swingManager.getDefaultServices();
857
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
858
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
859
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
860
//        services.centerActiveViewToGeometry(VCSGisSwingCommons.createBBox(repoGeom, geom));
861
        services.centerViewsHavingAStoreToGeometry(store, VCSGisSwingCommons.createBBox(repoGeom, geom));
862
        if(repoGeom != null){
863
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
864
        }
865
        if(geom != null){
866
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
867
        }
868
    }
869

    
870
    private void doCheckout() {
871
        I18nManager i18n = ToolsLocator.getI18nManager();
872
        
873
        final VCSGisWorkspace workspace = this.getWorkspace();
874
        VCSGisEntity entity = getSelectedTable();
875

    
876
        if (workspace != null && entity != null) {
877
            Thread task = new Thread(() -> {
878
                try {
879
                    context.processing = true;
880
                    context.doUpdateComponents();
881
                    int r = workspace.checkout(entity.getEntityName());
882
                    if (r != ERR_OK) {
883
                        this.message(i18n.getTranslation("_Cant_checkout"));
884
                    } else {
885
                        postCheckout(r, entity);
886
                    }
887
                } finally {
888
                    context.processing = false;
889
                    context.doUpdateComponents();
890
                    context.updateLocalChangesTable();
891
                }
892
            }, "VCSGisCheckout");
893

    
894
            this.context.processing = true;
895
            doUpdateComponents();
896
            task.start();
897

    
898
        }
899
    }
900
    
901
    private void postCheckout(int checkoutStatus, VCSGisEntity entity) {
902
        if (notInSwingThreadInvokeLater(() -> {
903
            postCheckout(checkoutStatus, entity);
904
        })) {
905
            return;
906
        }
907
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
908
        VCSGisSwingServices services = swingManager.getDefaultServices();
909
        I18nManager i18n = ToolsLocator.getI18nManager();
910

    
911
        final VCSGisWorkspace workspace = this.getWorkspace();
912

    
913
        if (checkoutStatus == ERR_OK) {
914
            this.context.setVisibleStatus(false);
915

    
916
            if (StringUtils.isNotBlank(entity.getGeometryFieldName()) && services.isThereAnyActiveView()) {
917
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
918
                dialogs.confirmDialog(i18n.getTranslation("_Do_you_want_add_layer_to_active_view"),
919
                        i18n.getTranslation("_VCS_Checkout"),
920
                        JOptionPane.YES_NO_OPTION,
921
                        JOptionPane.QUESTION_MESSAGE,
922
                        "VCSGis_Checkout_add_layer_to_view"
923
                );
924

    
925
                FeatureStore store = workspace.getFeatureStore(entity.getEntityName());
926
                String layerName = workspace.getLabel() + " - " + store.getName();
927
                services.addLayerToActiveView(store, layerName);
928
            } else {
929
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
930
                int res = dialogs.confirmDialog(i18n.getTranslation("_Do_you_want_add_table_to_project"),
931
                        i18n.getTranslation("_VCS_Checkout"),
932
                        JOptionPane.YES_NO_OPTION,
933
                        JOptionPane.QUESTION_MESSAGE,
934
                        "VCSGis_Checkout_add_table_to_project"
935
                );
936

    
937
                if (res == JOptionPane.YES_OPTION) {
938
                    FeatureStore store = workspace.getFeatureStore(entity.getEntityName());
939
                    services.addTableToProject(workspace, store);
940
                }
941
            }
942
        }
943

    
944
        doReloadChanges();
945
        VCSGisEntity selectedTable = getSelectedTable();
946
        FeatureStore store = getWorkspace().getFeatureStore(selectedTable.getEntityName());
947
        refreshDocument(store);
948
    }
949

    
950
    
951
    private VCSGisEntity getSelectedTable() {
952
        LabeledValue<VCSGisEntity> lValue = (LabeledValue<VCSGisEntity>) lstRemoteTables.getSelectedValue();
953
        if(lValue == null){
954
            return null;
955
        }
956
        return lValue.getValue();
957
    }
958
    
959
    private Boolean isSelectedTableInWorkspace() {
960
        VCSGisEntity entity = getSelectedTable();
961
        if(entity == null){
962
            return null;
963
        }
964
        VCSGisWorkspace ws = getWorkspace();
965
        if(ws == null){
966
            return null;
967
        }
968
        return ws.getWorkspaceEntity(entity.getEntityCode())!=null;
969
    }
970
    
971
}