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

History | View | Annotate | Download (38.4 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.VCSGisSwingCommons.showAuthenticationsErrors;
92
import static org.gvsig.vcsgis.swing.impl.changes.VCSGisJChangesImpl.LOCAL_TAB_INDEX;
93
import org.slf4j.Logger;
94
import org.slf4j.LoggerFactory;
95

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

    
103
    private static final Logger LOGGER = LoggerFactory.getLogger(RemoteChangesController.class);
104

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

    
115
    private VCSGisWorkspaceChanges<VCSGisRepositoryChange> changes;
116

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

    
128
    private final JLabel lblRemoteChangesCount;
129

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

    
152
        this.workspacePicker = workspacePicker;
153

    
154
        this.lstRemoteTables = lstRemoteTables;
155
        this.btnRemoteTablesReload = btnRemoteTablesReload;
156

    
157
        this.tblRemoteChanges = tblRemoteChanges;
158
        this.btnRemoteCheckAll = btnRemoteCheckAll;
159
        this.btnRemoteUnCheckAll = btnRemoteUnCheckAll;
160
        this.btnRemoteDownloadChanges = btnRemoteDownloadChanges;
161
        this.btnRemoteCleanChanges = btnRemoteCleanChanges;
162
        this.btnRemoteReloadChanges = btnRemoteReloadChanges;
163

    
164
        this.btnRemoteUpdate = btnRemoteUpdate;
165
        this.btnRemoteMerge = btnRemoteMerge;
166
        this.btnRemoteShowForm = btnRemoteShowForm;
167

    
168
        this.btnRemoteZoom = btnRemoteZoom;
169
        this.btnRemoteCenter = btnRemoteCenter;
170
        this.btnRemoteCheckout = btnRemoteCheckout;
171
        
172
        this.btnRemoteCleanHighligthed = btnRemoteCleanHighligthed;
173

    
174
        this.lblRemoteChangesCount= lblRemoteChangesCount;
175
        initComponents();
176
    }
177

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

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

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

    
200
        translate();
201

    
202
        lstRemoteTables.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
203

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

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

    
225
        this.workspacePicker.addChangeListener((ChangeEvent e) -> {
226
            doChangeWorkspace();
227
        });
228

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

    
234
        this.tblRemoteChanges.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
235

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

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

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

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

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

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

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

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

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

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

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

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

    
304

    
305
        context.doUpdateComponents();
306

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

    
312
    }
313
    
314
    private void doChangeWorkspace() {
315
        try {
316
            doReloadTables(false);
317
            doReloadChanges();
318
        } catch (VCSGisRuntimeException e1) {
319
            LOGGER.warn("Can't set workspace.", e1);
320
            if (showAuthenticationsErrors("_VCS_Changes", e1)) {
321
                this.workspacePicker.set(null);
322
                doChangeWorkspace();
323
            }
324
        } catch (Exception e2) {
325
            LOGGER.warn("Can't set workspace.", e2);
326
        }
327
        
328
    }
329
    
330
    public void translate() {
331
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
332

    
333
        swingManager.translate(this.btnRemoteCheckAll);
334
        swingManager.translate(this.btnRemoteUpdate);
335
        swingManager.translate(this.btnRemoteCleanChanges);
336
        swingManager.translate(this.btnRemoteReloadChanges);
337
        swingManager.translate(this.btnRemoteMerge);
338
        swingManager.translate(this.btnRemoteShowForm);
339
        swingManager.translate(this.btnRemoteUnCheckAll);
340
        swingManager.translate(this.btnRemoteTablesReload);
341
        swingManager.translate(this.btnRemoteDownloadChanges);
342
        swingManager.translate(this.btnRemoteCenter);
343
        swingManager.translate(this.btnRemoteZoom);
344
        swingManager.translate(this.btnRemoteCheckout);
345
        swingManager.translate(this.btnRemoteCleanHighligthed);
346

    
347
    }
348

    
349
    public VCSGisWorkspace getWorkspace() {
350
        return this.context.getWorkspace();
351
    }
352

    
353
    /* friend */ void doUpdateComponents() {
354
        if (notInSwingThreadInvokeLater(() -> {
355
            doUpdateComponents();
356
        })) {
357
            return;
358
        }
359
        try {
360
            this.context.setVisibleStatus(context.processing);
361
            VCSGisWorkspace ws = this.getWorkspace();
362

    
363
            this.btnRemoteCheckAll.setEnabled(!context.processing && changes != null);
364
            this.btnRemoteUnCheckAll.setEnabled(!context.processing && changes != null);
365

    
366
            this.btnRemoteDownloadChanges.setEnabled(!context.processing && ws != null && BooleanUtils.isTrue(this.isSelectedTableInWorkspace()));
367
            this.btnRemoteCheckout.setEnabled(!context.processing && ws != null && BooleanUtils.isFalse(this.isSelectedTableInWorkspace()));
368
            this.btnRemoteReloadChanges.setEnabled(!context.processing && ws != null && BooleanUtils.isTrue(this.isSelectedTableInWorkspace()));
369
            this.btnRemoteCleanChanges.setEnabled(!context.processing && ws != null && BooleanUtils.isTrue(this.isSelectedTableInWorkspace()));
370
            this.btnRemoteTablesReload.setEnabled(!context.processing);
371

    
372
            this.btnRemoteTablesReload.setEnabled(!context.processing && ws != null);
373

    
374
            //Show form
375
            boolean enableShowForm = false;
376
            int row = this.tblRemoteChanges.getSelectedRow();
377
            if (row >= 0) {
378
                VCSGisRepositoryChange change = this.changes.get64(row);
379
                if (change.getOperation() != OP_ADD_ENTITY) {
380
                    enableShowForm = true;
381
                }
382
            }
383
            this.btnRemoteShowForm.setEnabled(!context.processing && enableShowForm);
384

    
385
            this.lstRemoteTables.setEnabled(!context.processing);
386
            this.tblRemoteChanges.setEnabled(!context.processing);
387
            this.workspacePicker.setEnabled(!context.processing);
388

    
389
            LabeledValue selected = (LabeledValue) lstRemoteTables.getSelectedValue();
390
            if (selected == null) {
391
                this.btnRemoteMerge.setEnabled(false);
392
                this.btnRemoteUpdate.setEnabled(false);
393
                return;
394
            }
395

    
396
            VCSGisEntity entity = (VCSGisEntity) selected.getValue();
397
            if (this.getWorkspace().updateNeedMerge(entity.getEntityName())) {
398
                this.btnRemoteMerge.setEnabled(!context.processing);
399
                this.btnRemoteUpdate.setEnabled(false);
400
            } else {
401
                this.btnRemoteMerge.setEnabled(false);
402
                this.btnRemoteUpdate.setEnabled(!context.processing && changes != null && !this.changes.isSelectionEmpty());
403
            }
404

    
405
            Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
406
            Geometry wsGeom = getWorkspaceGeometryOfSelectedChange();
407
            Geometry bbox = VCSGisSwingCommons.createBBox(repoGeom, wsGeom);
408
            this.btnRemoteCenter.setEnabled(!context.processing && bbox != null);
409
            this.btnRemoteZoom.setEnabled(!context.processing && bbox != null);
410
            this.btnRemoteCleanHighligthed.setEnabled(!context.processing);
411
        } catch (VCSGisRuntimeException e1) {
412
            LOGGER.warn("Can't updating components.", e1);
413
            if (showAuthenticationsErrors("_VCS_Changes", e1)) {
414
                this.workspacePicker.set(null);
415
                doChangeWorkspace();
416
            }
417
        } catch (Exception e2) {
418
            LOGGER.warn("Can't updating components.", e2);
419
        }
420

    
421
    }
422

    
423
    private void doToggleSelection() {
424
        Thread task = new Thread(() -> {
425
            try {
426
                context.processing = true;
427
                context.doUpdateComponents();
428
                Iterator<Long> rows = getChangesSelectionIterator();
429

    
430
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
431
                    change.setSelected(!change.isSelected());
432
                    return true;
433
                });
434
            } finally {
435
                context.processing = false;
436
                context.doUpdateComponents();
437
            }
438
        }, "VCSGisToggleSelectionRemoteChanges");
439
        task.start();
440
    }
441

    
442
    private Iterator<Long> getChangesSelectionIterator() {
443
        ListSelectionModel selection = this.tblRemoteChanges.getSelectionModel();
444
        return new Iterator<Long>() {
445
            long n = selection.getMinSelectionIndex();
446

    
447
            @Override
448
            public boolean hasNext() {
449
                while (n <= selection.getMaxSelectionIndex()) {
450
                    if (selection.isSelectedIndex((int) n)) {
451
                        return true;
452
                    }
453
                    n++;
454
                }
455
                return false;
456
            }
457

    
458
            @Override
459
            public Long next() {
460
                if (n > selection.getMaxSelectionIndex()) {
461
                    throw new IllegalStateException();
462
                }
463
                return n++;
464
            }
465
        };
466
    }
467

    
468
    private Iterator<Long> getRowsIterator() {
469
        long size = changes.size64();
470
        return new Iterator<Long>() {
471
            long n = 0;
472

    
473
            @Override
474
            public boolean hasNext() {
475
                return (n < size);
476
            }
477

    
478
            @Override
479
            public Long next() {
480
                return n++;
481
            }
482
        };
483
    }
484

    
485
    private void doCheckAll() {
486
        Thread task = new Thread(() -> {
487
            try {
488
                context.processing = true;
489
                context.doUpdateComponents();
490
                Iterator<Long> rows = getRowsIterator();
491

    
492
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
493
                    change.setSelected(true);
494
                    return true;
495
                });
496
            } finally {
497
                context.processing = false;
498
                context.doUpdateComponents();
499
            }
500
        }, "VCSGisCheckAllRemoteChanges");
501
        task.start();
502
    }
503

    
504
    private void doUnCheckAll() {
505
        Thread task = new Thread(() -> {
506
            try {
507
                context.processing = true;
508
                context.doUpdateComponents();
509
                Iterator<Long> rows = getRowsIterator();
510

    
511
                this.changes.process(rows, (VCSGisRepositoryChange change) -> {
512
                    change.setSelected(false);
513
                    return true;
514
                });
515
            } finally {
516
                context.processing = false;
517
                context.doUpdateComponents();
518
            }
519
        }, "VCSGisCheckAllRemoteChanges");
520
        task.start();
521
    }
522

    
523
    private void doUpdate() {
524
        VCSGisWorkspace ws = getWorkspace();
525
        if (ws == null) {
526
            return;
527
        }
528
        LabeledValue selectedTable = (LabeledValue) lstRemoteTables.getSelectedValue();
529
        if (selectedTable == null) {
530
            return;
531
        }
532
        VCSGisEntity entity = (VCSGisEntity) selectedTable.getValue();
533
        String tableName = entity.getEntityName();
534

    
535
        this.tblRemoteChanges.setModel(new ChangesTableModel(ws));
536

    
537
        Thread task = new Thread(() -> {
538
            try {
539
                context.processing = true;
540
                context.doUpdateComponents();
541
                int r = ws.update(tableName, null);
542
                doPostUpdate(r);
543
            } finally {
544
                context.processing = false;
545
                context.doUpdateComponents();
546
            }
547
        }, "VCSGisUpdate");
548
        context.processing = true;
549
        context.doUpdateComponents();
550
        task.start();
551
    }
552

    
553
    private void doPostUpdate(int updateStatus) {
554
        if (notInSwingThreadInvokeLater(() -> {doPostUpdate(updateStatus);})) {
555
            return;
556
        }
557
        if (updateStatus == ERR_OK) {
558
            context.setVisibleStatus(false);
559
        }
560
        doReloadChanges();
561

    
562
        VCSGisEntity selectedTable = getSelectedTable();
563
        FeatureStore store = getWorkspace().getFeatureStore(selectedTable.getEntityName());
564
        refreshDocument(store);
565
        
566
        context.doUpdateComponents();
567
        context.updateLocalChangesTable();
568
    }
569

    
570

    
571
    private void doMerge() {
572
        VCSGisWorkspace ws = getWorkspace();
573
        if (ws == null) {
574
            return;
575
        }
576
        LabeledValue selectedTable = (LabeledValue) lstRemoteTables.getSelectedValue();
577
        if (selectedTable == null) {
578
            return;
579
        }
580
        VCSGisEntity entity = (VCSGisEntity) selectedTable.getValue();
581
        String tableName = entity.getEntityName();
582

    
583
        this.tblRemoteChanges.setModel(new ChangesTableModel(ws));
584

    
585
        Thread task = new Thread(() -> {
586
            try {
587
                context.processing = true;
588
                context.doUpdateComponents();
589
                MutableLong localChangesCreated = new MutableLong(0);
590
                int r = getWorkspace().merge(
591
                        tableName,
592
                        localChangesCreated,
593
                        this.context.getTaskStatusController().getSimpleTaskStatus()
594
                );
595
                doPostMerge(r, localChangesCreated.getValue());
596
            } finally {
597
                context.processing = false;
598
                context.doUpdateComponents();
599
            }
600
        }, "VCSGisMerge");
601
        context.processing = true;
602
        context.doUpdateComponents();
603
        task.start();
604
    }
605

    
606
    private void doPostMerge(int mergeStatus, long localChangesCreated) {
607
        if (notInSwingThreadInvokeLater(() -> {doPostMerge(mergeStatus, localChangesCreated);})) {
608
            return;
609
        }
610
        if (mergeStatus == ERR_OK) {
611
            this.context.setVisibleStatus(false);
612
        }
613
        doReloadChanges();
614
        VCSGisEntity selectedTable = getSelectedTable();
615
        FeatureStore store = getWorkspace().getFeatureStore(selectedTable.getEntityName());
616
        refreshDocument(store);
617
        
618
        if(localChangesCreated>0){
619
            ThreadSafeDialogsManager dialogsManager = ToolsSwingLocator.getThreadSafeDialogsManager();
620
            I18nManager i18n = ToolsLocator.getI18nManager();
621
            dialogsManager.messageDialog(
622
                    i18n.getTranslation("_The_process_has_created_local_changes_that_would_need_to_be_committed_to_the_repository"), 
623
                    null, 
624
                    i18n.getTranslation("_VCSGis_Merge"), 
625
                    JOptionPane.INFORMATION_MESSAGE, 
626
                    "VCSGIS_merge_need_commit");
627
            context.selectTab(LOCAL_TAB_INDEX);
628
            context.selectOnlyALocalEntity(selectedTable);
629
        }
630
        context.doUpdateComponents();
631
        context.updateLocalChangesTable();
632
    }
633

    
634
    private void doShowForm() {
635
        if (this.changes == null) {
636
            return;
637
        }
638
        int row = this.tblRemoteChanges.getSelectedRow();
639
        VCSGisRepositoryChange change = this.changes.get64(row);
640
        if (change.getOperation() == OP_DELETE) {
641
            return;
642
        }
643
        VCSGisWorkspace ws = this.getWorkspace();
644
        if (ws == null) {
645
            return;
646
        }
647
        VCSGisWorkspaceEntity entity = ws.getWorkspaceEntityByCode(change.getEntityCode());
648

    
649
        if (entity == null) {
650
            VCSGisEntity repoEntity = ws.getEntity(change.getEntityCode());
651
            FeatureType featureType = repoEntity.getFeatureType();
652
            JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(featureType);
653
            DynObject values = ToolsLocator.getDynObjectManager().createDynObject(featureType);
654
            Json.addAll(values, change.getRelatedFeatureDataAsJson());
655
            form.setValues(values);
656
            form.setReadOnly(true);
657
            WindowManager winManager = ToolsSwingLocator.getWindowManager();
658
            form.asJComponent().setPreferredSize(new Dimension(400, 200));
659
            winManager.showWindow(form.asJComponent(), "Remote change: " + change.getLabel(), WindowManager.MODE.WINDOW);
660
            return;
661
        }
662

    
663
        FeatureStore store = null;
664
        try {
665
            DataSwingManager dataSwingManager = DALSwingLocator.getDataSwingManager();
666

    
667
            store = ws.getFeatureStore(entity.getEntityName());
668
            Feature feature = store.createNewFeature(change.getRelatedFeatureDataAsJson());
669
            JFeatureForm form = dataSwingManager.createJFeatureForm(feature);
670
            form.getDynForm().setReadOnly(true);
671
            WindowManager winManager = ToolsSwingLocator.getWindowManager();
672
            form.asJComponent().setPreferredSize(new Dimension(400, 200));
673
            winManager.showWindow(form.asJComponent(), "Remote change: " + change.getLabel(), WindowManager.MODE.WINDOW);
674
        } catch (Exception ex) {
675
            LOGGER.warn("Can't show form for change '" + change.getCode() + "'.", ex);
676
        } finally {
677
            DisposeUtils.disposeQuietly(store);
678
        }
679

    
680
    }
681

    
682
    private void doReloadChanges() {
683
        VCSGisWorkspace ws = this.getWorkspace();
684
        if (ws == null) {
685
            return;
686
        }
687
        if (this.changes != null) {
688
            this.changes.removeAllChangeListener();
689
        }
690
        LabeledValue selected = (LabeledValue) lstRemoteTables.getSelectedValue();
691
        if (selected != null) {
692
            I18nManager i18n = ToolsLocator.getI18nManager();
693
            VCSGisEntity entity = (VCSGisEntity) selected.getValue();
694
            message("Reloading list of remote changes...");
695
            this.changes = ws.getRemoteChangesByEntity(entity.getEntityName());
696
            this.changes.addChangeListener((ChangeEvent e) -> {
697
                context.doUpdateComponents();
698
            });
699
            ChangesTableModel changesModel = new ChangesTableModel(changes, ws);
700
            this.tblRemoteChanges.setModel(changesModel);
701

    
702
            int columns = this.tblRemoteChanges.getColumnModel().getColumnCount();
703
            for (int i = 1; i < columns; i++) {
704
                this.tblRemoteChanges.getColumnModel().getColumn(i).setCellRenderer(new DefaultTableCellRenderer() {
705
                    @Override
706
                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
707
                        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
708
                        VCSGisChange changeRow = changes.get64(row);
709
                        VCSGisSwingCommons.setColorCompoment(c, changeRow.getStatus());
710
                        return c;
711
                    }
712
                });
713
            }
714

    
715
            context.doUpdateComponents();
716
            context.message(i18n.getTranslation(
717
                    "_Repository_changes_list_updated", 
718
                    new String[] { String.valueOf(changes.size64()) }
719
                )
720
            );
721
            this.lblRemoteChangesCount.setText(String.valueOf(changes.size64()));
722
        } else {
723
            this.changes = null;
724
            this.tblRemoteChanges.setModel(new DefaultTableModel());
725
            this.lblRemoteChangesCount.setText("0");
726
        }
727

    
728
    }
729

    
730
    private void doCleanChanges() {
731
        VCSGisWorkspace ws = this.getWorkspace();
732
        if (ws == null) {
733
            return;
734
        }
735
        LabeledValue tableSelected = (LabeledValue) lstRemoteTables.getSelectedValue();
736
        if (tableSelected != null) {
737
            final VCSGisEntity entity = (VCSGisEntity) tableSelected.getValue();
738
            Thread task = new Thread(() -> {
739
                try {
740
                    context.processing = true;
741
                    context.doUpdateComponents();
742
                    message("Removing list of remote changes from " + entity.getEntityName() + "...");
743
                    ws.updateClean(entity.getEntityCode());
744
                    message("Ready.");
745
                } finally {
746
                    context.processing = false;
747
                    context.doUpdateComponents();
748
                }
749
            }, "VCSGisUpdateClean");
750
            task.start();
751
        }
752

    
753
    }
754

    
755
    private void doDownloadChangesOfSelectedTable() {
756
        VCSGisWorkspace ws = this.getWorkspace();
757
        if (ws == null) {
758
            return;
759
        }
760
        LabeledValue selected = (LabeledValue) lstRemoteTables.getSelectedValue();
761
        if (selected == null) {
762
            return;
763
        }
764
        Thread task = new Thread(() -> {
765
                try {
766
                    context.processing = true;
767
                    context.doUpdateComponents();
768
                    VCSGisEntity entity = (VCSGisEntity) selected.getValue();
769
                    message("Removing list of remote changes of " + entity.getEntityName() + "...");
770
                    ws.updateClean(entity.getEntityName());
771
                    message("Downloading list of remote changes of " + entity.getEntityName() + "...");
772
                    ws.updatePrepare(entity.getEntityName());
773
                    context.updateLocalChangesTable();
774
                } finally {
775
                    context.processing = false;
776
                    context.doUpdateComponents();
777
                    doReloadChanges();
778
                }
779
            }, "VCSGisUpdatePrepare"
780
        );
781
        context.processing = true;
782
        context.doUpdateComponents();
783
        task.start();
784
        message("_Ready");
785
    }
786

    
787
    private void doReloadTables(boolean forceUpdateEntities) {
788
        DefaultListModel model = new DefaultListModel();
789
        VCSGisWorkspace ws = this.getWorkspace();
790
        if (ws == null) {
791
            this.lstRemoteTables.setModel(model);
792
            return;
793
        }
794
        message("Updating list of tables from remote repository...");// "+ws.getRepository().getLabel()+")...");
795
        this.context.updateEntitiesFromRepository(forceUpdateEntities);
796
        message("Loading list of tables...");
797

    
798
        for (VCSGisEntity entity : ws.getRepositoryEntities()) {
799
            model.addElement(new LabeledValueImpl<>(entity.getEntityName(), entity));
800
        }
801
        this.lstRemoteTables.setModel(model);
802
        context.doUpdateComponents();
803
        message("Ready.");
804
    }
805

    
806
    public boolean isProcessing() {
807
        return context.processing;
808
    }
809
    
810
    private Geometry getRepositoryGeometryOfSelectedChange() {
811
        Geometry geom = null;
812
        int selected = this.tblRemoteChanges.getSelectedRow();
813
        if(selected >= 0){
814
            VCSGisRepositoryChange change = changes.get64(selected);
815
            geom = change.getGeometry();
816
        }
817
        return geom;
818
    }
819
    
820
    private Geometry getWorkspaceGeometryOfSelectedChange() {
821
        Geometry geom = null;
822
        int selected = this.tblRemoteChanges.getSelectedRow();
823
        if(selected >= 0){
824
            VCSGisRepositoryChange change = changes.get64(selected);
825
            
826
            Feature f = getWorkspace().getRelatedFeature(change);
827
            if(f!= null){
828
                geom = f.getDefaultGeometry();
829
            }
830
        }
831
        return geom;
832
    }
833
    
834
    private FeatureStore getWorkspaceStoreOfSelectedChange() {
835
        FeatureStore store = null;
836
        int selected = this.tblRemoteChanges.getSelectedRow();
837
        if(selected >= 0){
838
            VCSGisRepositoryChange change = changes.get64(selected);
839
            
840
            Feature f = getWorkspace().getRelatedFeature(change);
841
            if(f!= null){
842
                store = f.getStore();
843
            }
844
        }
845
        return store;
846
    }
847
    
848
    private void doZoomToSelectedChange() {
849
        cleanHighligthed();
850
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
851
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
852
        VCSGisSwingServices services = swingManager.getDefaultServices();
853
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
854
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
855
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
856
//        services.zoomActiveViewToGeometry(VCSGisSwingCommons.createBBox(repoGeom, geom));
857
        services.zoomViewsHavingAStoreToGeometry(store, VCSGisSwingCommons.createBBox(repoGeom, geom));
858
        if(repoGeom != null){
859
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
860
        }
861
        if(geom != null){
862
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
863
        }
864
    }
865

    
866
    private void doCenterToSelectedChange() {
867
        cleanHighligthed();
868
        VCSGisManager manager = VCSGisLocator.getVCSGisManager();
869
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
870
        VCSGisSwingServices services = swingManager.getDefaultServices();
871
        FeatureStore store = getWorkspaceStoreOfSelectedChange();
872
        Geometry repoGeom = getRepositoryGeometryOfSelectedChange();
873
        Geometry geom = getWorkspaceGeometryOfSelectedChange();
874
//        services.centerActiveViewToGeometry(VCSGisSwingCommons.createBBox(repoGeom, geom));
875
        services.centerViewsHavingAStoreToGeometry(store, VCSGisSwingCommons.createBBox(repoGeom, geom));
876
        if(repoGeom != null){
877
            services.highlight(HIGHLIGHT_REPOSITORY, repoGeom, store);
878
        }
879
        if(geom != null){
880
            services.highlight(HIGHLIGHT_WORKSPACE, geom, store);
881
        }
882
    }
883

    
884
    private void doCheckout() {
885
        I18nManager i18n = ToolsLocator.getI18nManager();
886
        
887
        final VCSGisWorkspace workspace = this.getWorkspace();
888
        VCSGisEntity entity = getSelectedTable();
889

    
890
        if (workspace != null && entity != null) {
891
            Thread task = new Thread(() -> {
892
                try {
893
                    context.processing = true;
894
                    context.doUpdateComponents();
895
                    int r = workspace.checkout(entity.getEntityName());
896
                    if (r != ERR_OK) {
897
                        this.message(i18n.getTranslation("_Cant_checkout"));
898
                    } else {
899
                        postCheckout(r, entity);
900
                    }
901
                } finally {
902
                    context.processing = false;
903
                    context.doUpdateComponents();
904
                    context.updateLocalChangesTable();
905
                }
906
            }, "VCSGisCheckout");
907

    
908
            this.context.processing = true;
909
            doUpdateComponents();
910
            task.start();
911

    
912
        }
913
    }
914
    
915
    private void postCheckout(int checkoutStatus, VCSGisEntity entity) {
916
        if (notInSwingThreadInvokeLater(() -> {
917
            postCheckout(checkoutStatus, entity);
918
        })) {
919
            return;
920
        }
921
        VCSGisSwingManager swingManager = VCSGisSwingLocator.getVCSGisSwingManager();
922
        VCSGisSwingServices services = swingManager.getDefaultServices();
923
        I18nManager i18n = ToolsLocator.getI18nManager();
924

    
925
        final VCSGisWorkspace workspace = this.getWorkspace();
926

    
927
        if (checkoutStatus == ERR_OK) {
928
            this.context.setVisibleStatus(false);
929

    
930
            if (StringUtils.isNotBlank(entity.getGeometryFieldName()) && services.isThereAnyActiveView()) {
931
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
932
                dialogs.confirmDialog(i18n.getTranslation("_Do_you_want_add_layer_to_active_view"),
933
                        i18n.getTranslation("_VCS_Checkout"),
934
                        JOptionPane.YES_NO_OPTION,
935
                        JOptionPane.QUESTION_MESSAGE,
936
                        "VCSGis_Checkout_add_layer_to_view"
937
                );
938

    
939
                FeatureStore store = workspace.getFeatureStore(entity.getEntityName());
940
                String layerName = workspace.getLabel() + " - " + store.getName();
941
                services.addLayerToActiveView(store, layerName);
942
            } else {
943
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
944
                int res = dialogs.confirmDialog(i18n.getTranslation("_Do_you_want_add_table_to_project"),
945
                        i18n.getTranslation("_VCS_Checkout"),
946
                        JOptionPane.YES_NO_OPTION,
947
                        JOptionPane.QUESTION_MESSAGE,
948
                        "VCSGis_Checkout_add_table_to_project"
949
                );
950

    
951
                if (res == JOptionPane.YES_OPTION) {
952
                    FeatureStore store = workspace.getFeatureStore(entity.getEntityName());
953
                    services.addTableToProject(workspace, store);
954
                }
955
            }
956
        }
957

    
958
        doReloadChanges();
959
        VCSGisEntity selectedTable = getSelectedTable();
960
        FeatureStore store = getWorkspace().getFeatureStore(selectedTable.getEntityName());
961
        refreshDocument(store);
962
    }
963

    
964
    
965
    private VCSGisEntity getSelectedTable() {
966
        LabeledValue<VCSGisEntity> lValue = (LabeledValue<VCSGisEntity>) lstRemoteTables.getSelectedValue();
967
        if(lValue == null){
968
            return null;
969
        }
970
        return lValue.getValue();
971
    }
972
    
973
    private Boolean isSelectedTableInWorkspace() {
974
        VCSGisEntity entity = getSelectedTable();
975
        if(entity == null){
976
            return null;
977
        }
978
        VCSGisWorkspace ws = getWorkspace();
979
        if(ws == null){
980
            return null;
981
        }
982
        return ws.getWorkspaceEntity(entity.getEntityCode())!=null;
983
    }
984
    
985
}