Project

General

Profile

Revision 198c9340

ID198c93406e8052d0d2074a1e0c87023db56f6ebe
Parent 9ce386b8
Child ca1b4808

Added by Katja Luther about 1 year ago

ref #8256: add table of all status preferences in preference page

View differences:

eu.etaxonomy.taxeditor.store/OSGI-INF/l10n/bundle.properties
279 279
command.commandname.22 = Create Structure Tree
280 280
command.commandname.23 = Create Property Tree
281 281
handledmenuitem.label.22 = OWL Term Export
282
handledmenuitem.label.23 = Owl Import
282
handledmenuitem.label.23 = Owl Import
283

  
284
page.name.104 = Distribution Data
285
page.name.105 = Vocabularies and Status
eu.etaxonomy.taxeditor.store/OSGI-INF/l10n/bundle_de.properties
279 279
command.commandname.22 = Strukturbaum erstellen
280 280
command.commandname.23 = Propertybaum erstellen
281 281
handledmenuitem.label.22 = OWL Term Export
282
handledmenuitem.label.23 = Owl Import
282
handledmenuitem.label.23 = Owl Import
283

  
284
page.name.104 = Verbreitungsdaten
285
page.name.105 = Vokabulare und Status
eu.etaxonomy.taxeditor.store/plugin.xml
581 581
         id="eu.etaxonomy.taxeditor.preference.MediaPreferences"
582 582
         name="%page.name.27">
583 583
   </page>
584
   <page
584
    <page
585 585
         category="eu.etaxonomy.taxeditor.preference.UIPreferences"
586
         class="eu.etaxonomy.taxeditor.preference.DistributionGeneralPreference"
587
         id="eu.etaxonomy.taxeditor.preference.DistributionGeneralPreference"
588
         name="%page.name.104">
589
   </page>
590
   <page
591
         category="eu.etaxonomy.taxeditor.preference.DistributionGeneralPreference"
586 592
         class="eu.etaxonomy.taxeditor.preference.ChecklistEditorGeneralPreference"
587 593
         id="eu.etaxonomy.taxeditor.preference.ChecklistEditorGeneralPreferencePage"
588 594
         name="%page.name.28">
589 595
   </page>
596
    <page
597
         category="eu.etaxonomy.taxeditor.preference.DistributionGeneralPreference"
598
         class="eu.etaxonomy.taxeditor.preference.DistributionStatusAndNamedAreaVocabularies"
599
         id="eu.etaxonomy.taxeditor.preference.DistributionStatusAndNamedAreaVocabulariesPage"
600
         name="%page.name.105">
601
   </page>
590 602
   <page
591 603
         category="eu.etaxonomy.taxeditor.preferences.general"
592 604
         class="eu.etaxonomy.taxeditor.preference.LanguageEditorPreferencePage"
......
707 719
   </page>-->
708 720
    <page 
709 721
         category="eu.etaxonomy.taxeditor.preferences.general"
722
         class="eu.etaxonomy.taxeditor.preference.DistributionGeneralPreference"
723
         id="eu.etaxonomy.taxeditor.store.Distribution"
724
         name="%page.name.104">
725
   </page>
726
   <page 
727
         category="eu.etaxonomy.taxeditor.store.Distribution"
710 728
         class="eu.etaxonomy.taxeditor.databaseAdmin.preferencePage.ChecklistEditorGeneralAdminPreference"
711 729
         id="eu.etaxonomy.taxeditor.store.checklist"
712 730
         name="%page.name.21">
713 731
   </page>
732
   <page 
733
         category="eu.etaxonomy.taxeditor.store.Distribution"
734
         class="eu.etaxonomy.taxeditor.databaseAdmin.preferencePage.DistributionStatusAndNamedAreaVocabulariesAdminPreference"
735
         id="eu.etaxonomy.taxeditor.store.distributionVocabulariesAndStatus"
736
         name="%page.name.105">
737
   </page>
714 738
   <page
715 739
         category="eu.etaxonomy.taxeditor.store.abcdImportPreference"
716 740
         class="eu.etaxonomy.taxeditor.databaseAdmin.preferencePage.AbcdImportProvider"
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/databaseAdmin/preferencePage/ChecklistEditorGeneralAdminPreference.java
97 97
            pref.setAllowOverride(prefStatusDisplayInCombo.isAllowOverride());
98 98
            service.set(pref);
99 99
        }
100
//        if (statusPref != null){
101
//            service.set(statusPref);
102
//        }
103
//        if (areaVocPref != null){
104
//            service.set(areaVocPref);
105
//        }
100

  
106 101
        PreferencesUtil.updateDBPreferences();
107 102

  
108 103
        return true;
......
166 161
            this.ownDescriptionForDistributionEditor = Boolean.valueOf(PreferencePredicate.OwnDescriptionForDistributionEditor.getDefaultValue().toString());
167 162
        }
168 163

  
169
        commandHandlerString = "eu.etaxonomy.taxeditor.store.open.OpenDistributionEditorWizardAdminHandler";
170
        commandHandlerStringStatus = "eu.etaxonomy.taxeditor.store.open.OpenDistributionPerAreaStatusWizardHandler";
164

  
171 165

  
172 166
        setValid(false);
173 167
    }
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/databaseAdmin/preferencePage/DistributionStatusAndNamedAreaVocabulariesAdminPreference.java
1
/**
2
* Copyright (C) 2019 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.databaseAdmin.preferencePage;
10

  
11
import eu.etaxonomy.taxeditor.preference.DistributionStatusAndNamedAreaVocabularies;
12

  
13
/**
14
 * @author k.luther
15
 * @since 02.07.2019
16
 *
17
 */
18
public class DistributionStatusAndNamedAreaVocabulariesAdminPreference
19
        extends DistributionStatusAndNamedAreaVocabularies {
20

  
21

  
22
    @Override
23
    public void getValues() {
24
        super.getValues();
25
        isAdminPreference = true;
26
        commandHandlerString = "eu.etaxonomy.taxeditor.store.open.OpenDistributionEditorWizardAdminHandler";
27
        commandHandlerStringStatus = "eu.etaxonomy.taxeditor.store.open.OpenDistributionPerAreaStatusWizardHandler";
28
    }
29

  
30
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/databaseAdmin/preferencePage/SupplementalDataAdminPreference.java
39 39
        pref.setAllowOverride(isAllowOverrideShowIDNamspace);
40 40
        PreferencesUtil.setPreferencesToDB(pref, setToDefault);
41 41

  
42
        if (isShowNamespace == null){
42
        if (isShowIDSource == null){
43 43
            setToDefault = true;
44
            isShowNamespace = true;
44
            isShowIDSource = true;
45 45
         }
46
        pref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.ShowNamespaceInSource, Boolean.toString(this.isShowNamespace));
47
        pref.setAllowOverride(isAllowOverrideShowNamspace);
46
        pref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.ShowNamespaceInSource, Boolean.toString(this.isShowIDSource));
47
        pref.setAllowOverride(isAllowOverrideShowIDSource);
48 48
        PreferencesUtil.setPreferencesToDB(pref, setToDefault);
49 49

  
50 50
        PreferencesUtil.updateDBPreferences();
......
72 72
            prefShowNamespace = CdmPreference.NewTaxEditorInstance(PreferencePredicate.ShowNamespaceInSource, null);
73 73
            prefShowNamespace.setAllowOverride(true);
74 74
        }
75
        isShowNamespace = prefShowNamespace.getValue()!= null? Boolean.parseBoolean(prefShowNamespace.getValue()): null;
76
        isAllowOverrideShowNamspace = prefShowNamespace.isAllowOverride();
75
        isShowIDSource = prefShowNamespace.getValue()!= null? Boolean.parseBoolean(prefShowNamespace.getValue()): null;
76
        isAllowOverrideShowIDSource = prefShowNamespace.isAllowOverride();
77 77
    }
78 78
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/event/WorkbenchEventConstants.java
41 41

  
42 42
    public static final String REMOVE_USER = "UPDATE/GROUP/REMOVEUSER";
43 43

  
44
    public static final String REFRESH_DISTRIBUTION_PREFERENCES = "REFRESH/DISTRIBUTION/PREFERENCE";
45

  
44 46
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/l10n/Messages.java
570 570

  
571 571
    public static String Distribution_status_selection;
572 572
    public static String DistributionAdminPreferences_SELECT_STATUS;
573
    public static String DistributionAdminPreferences_PER_AREA_STATUS;
573 574

  
574 575
    public static String DatabasePreferncesPage_Show_MediaView;
575 576
    public static String DatabasePreferncesPage_Show_ChecklistPerspective;
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/l10n/messages.properties
462 462

  
463 463
Distribution_status_selection=Status Selection
464 464
DistributionAdminPreferences_SELECT_STATUS=List of available distribution status
465
DistributionAdminPreferences_PER_AREA_STATUS=List of preferences defining available status per area.\nIn this list you can define whether the preference can be overwritten or delete it.
465 466

  
466 467
MarkerTypeMenuPreferences_display=Choose available markers
467 468
MeasurementUnitMenuPreferences_edit=Edit displayed measurement units
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/l10n/messages_de.properties
463 463

  
464 464
Distribution_status_selection=Status Auswahl
465 465
DistributionAdminPreferences_SELECT_STATUS=Liste der verf?gbaren Verbreitungs-Status
466
DistributionAdminPreferences_PER_AREA_STATUS=Liste der pro Area definierten Status Preferenzen\nSie k?nnen in der Liste definieren, ob das lokale ?berschreiben erlaubt sein soll und die Preferenz l?schen
466 467

  
467 468
MarkerTypeMenuPreferences_display=Auswahl der zur Verf\u00FCgung stehenden Marker
468 469
MeasurementUnitMenuPreferences_edit=Angezeigte Ma?einheiten
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/CdmPreferenceCache.java
102 102

  
103 103
    }
104 104

  
105
    public boolean remove(CdmPreference pref){
106
        if (preferenceCache.containsKey(pref.getPredicate())){
107
            List<CdmPreference> cachedPreferences = preferenceCache.get(pref.getPredicate());
108
            CdmPreference prefToRemove = null;
109
            for (CdmPreference cachedPref:cachedPreferences){
110
                if (pref.getKey().equals(cachedPref.getKey())){
111
                    prefToRemove = cachedPref;
112
                }
113
            }
114
            cachedPreferences.remove(prefToRemove);
115
        }
116
        return true;
117

  
118
    }
119

  
105 120
    public void getAllTaxEditorDBPreferences(){
106 121
        ICdmRepository controller;
107 122
        controller = CdmStore.getCurrentApplicationConfiguration();
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/ChecklistEditorGeneralPreference.java
9 9
package eu.etaxonomy.taxeditor.preference;
10 10

  
11 11
import org.eclipse.swt.SWT;
12
import org.eclipse.swt.custom.CLabel;
13 12
import org.eclipse.swt.events.SelectionAdapter;
14 13
import org.eclipse.swt.events.SelectionEvent;
15 14
import org.eclipse.swt.events.SelectionListener;
......
19 18
import org.eclipse.swt.widgets.Combo;
20 19
import org.eclipse.swt.widgets.Composite;
21 20
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.swt.widgets.Event;
23 21
import org.eclipse.swt.widgets.Label;
24
import org.eclipse.swt.widgets.Listener;
25 22

  
26 23
import eu.etaxonomy.cdm.model.metadata.CdmPreference;
27 24
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
......
30 27
import eu.etaxonomy.cdm.model.metadata.TermOrder;
31 28
import eu.etaxonomy.taxeditor.l10n.Messages;
32 29
import eu.etaxonomy.taxeditor.preference.menu.CdmPreferencePage;
33
import eu.etaxonomy.taxeditor.ui.element.CommandHandlerButton;
34 30

  
35 31
/**
36 32
 * @author a.oppermann
......
68 64
    protected Button allowOverrideStatusDisplayInComboButton;
69 65
    protected Combo areaDisplaySelectionCombo;
70 66
    protected Button allowOverrideAreaDisplayButton;
71
    protected String commandHandlerString;
72
    protected String commandHandlerStringStatus;
67

  
73 68

  
74 69
    protected CdmPreference distributionEditorPref;
75
    protected CdmPreference prefStatus;
76
    protected CdmPreference prefAreaVoc;
77
    protected CdmPreference prefAreaDisplay;
70

  
78 71
    protected CdmPreference prefStatusDisplay;
72
    protected CdmPreference prefAreaDisplay;
73

  
79 74
    protected CdmPreference prefStatusDisplayInCombo;
80 75
    protected CdmPreference prefAreaSort;
81 76
    protected CdmPreference prefRank;
......
92 87
    final String SHOW_RANK = "Show Rank";
93 88
    final String NO_RANK = "No Rank";
94 89

  
95
    protected CdmPreference areaVocPref = null;
96
    protected CdmPreference statusPref = null;
97
    private CommandHandlerButton button_openSelectAreaVocabularies;
98 90

  
99
    private CommandHandlerButton button_openStatusWizard;
91

  
100 92

  
101 93
    @Override
102 94
    protected Control createContents(Composite parent) {
......
200 192
                    }
201 193
                });
202 194
            }
203

  
204
            GridData gridData = new GridData();
205
            gridData = new GridData(GridData.BEGINNING, GridData.CENTER, true, false);
206

  
207 195
            areaOrderSelectionCombo = createCombo(child, TermOrder.values(), PreferencePredicate.AreasSortedInDistributionEditor, Messages.ChecklistEditorGeneralPreference_Configure_area_order, isAdminPreference);
208 196

  
209 197
            index = 0;
......
379 367
            }
380 368

  
381 369

  
382
            final CLabel labelStatus = new CLabel(child, SWT.NULL);
383
            labelStatus.setText(Messages.DistributionAdminPreferences_SELECT_STATUS);
384
            labelStatus.setLayoutData(textGrid);
385

  
386
            button_openStatusWizard = new CommandHandlerButton(child, SWT.PUSH, commandHandlerStringStatus);
387

  
388
            button_openStatusWizard.setText(Messages.Distribution_status_selection);
389
            button_openStatusWizard.addListener(SWT.Selection, new Listener() {
390
                @Override
391
                public void handleEvent(Event e) {
392
                    switch (e.type) {
393
                    case SWT.Selection:
394
                        setApply(true);
395
                        break;
396
                    }
397
                }
398
            });
399 370

  
400
            final CLabel label = new CLabel(child, SWT.NULL);
401
            label.setText(Messages.ChecklistEditorGeneralPreference_open_wizard);
402
            label.setLayoutData(textGrid);
403

  
404
            button_openSelectAreaVocabularies = new CommandHandlerButton(child, SWT.PUSH, commandHandlerString);
405
            button_openSelectAreaVocabularies
406
                    .setText(Messages.ChecklistEditorGeneralPreference_open_distribution_selection);
407 371

  
408 372
            if (!isAdminPreference) {
409 373

  
......
412 376
                    activateComp.setEnabled(false);
413 377
                }
414 378

  
415
                if (prefAreaVoc != null && !prefAreaVoc.isAllowOverride()) {
416
                    button_openSelectAreaVocabularies.setButtonEnabled(false);
417
                }
418
                if (prefStatus != null && !prefStatus.isAllowOverride()) {
419
                    button_openStatusWizard.setButtonEnabled(false);
420
                }
379

  
421 380
                if (prefRank != null && !prefRank.isAllowOverride()) {
422 381
                    activateRankCombo.setEnabled(false);
423 382
                }
......
678 637
            distributionEditorPref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.DistributionEditorActivated, PreferencePredicate.DistributionEditorActivated.getDefaultValue() != null ?  PreferencePredicate.DistributionEditorActivated.getDefaultValue().toString(): null);
679 638
        }
680 639

  
681
        prefAreaVoc = PreferencesUtil.getPreferenceFromDB(PreferencePredicate.AvailableDistributionAreaVocabularies);
682
        if (prefAreaVoc == null){
683
            prefAreaVoc = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionAreaVocabularies, PreferencePredicate.AvailableDistributionAreaVocabularies.getDefaultValue() != null ?  PreferencePredicate.AvailableDistributionAreaVocabularies.getDefaultValue().toString(): null);
684
        }
685

  
686 640

  
687
        prefStatus = PreferencesUtil.getPreferenceFromDB(PreferencePredicate.AvailableDistributionStatus);
688
        if (prefStatus == null){
689
            prefStatus = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionStatus, PreferencePredicate.AvailableDistributionStatus.getDefaultValue() != null ?  PreferencePredicate.AvailableDistributionStatus.getDefaultValue().toString(): null);
690
        }
691 641

  
692 642

  
693 643
        prefAreaDisplay = PreferencesUtil.getPreferenceFromDB(PreferencePredicate.DisplayOfAreasInDistributionEditor);
......
830 780
            //prefOwnDescription = CdmPreference.NewTaxEditorInstance(PreferencePredicate.OwnDescriptionForDistributionEditor, PreferencePredicate.OwnDescriptionForDistributionEditor.getDefaultValue() != null ?  PreferencePredicate.OwnDescriptionForDistributionEditor.getDefaultValue().toString(): null);
831 781
        }
832 782

  
833
        commandHandlerString = "eu.etaxonomy.taxeditor.store.open.OpenDistributionEditorWizardHandler";
834
        commandHandlerStringStatus = "eu.etaxonomy.taxeditor.store.open.OpenDistributionStatusWizardHandler";
783

  
835 784
    }
836 785

  
837 786
    @Override
......
956 905

  
957 906
        overrideOwnDescriptionForDistributionEditor = true;
958 907

  
959
        this.statusPref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionStatus, null);
960
        this.areaVocPref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionAreaVocabularies,
961
                null);
908

  
962 909
        if (!isAdminPreference) {
963 910
            PreferencesUtil.recursiveSetEnabled(child, isEditorActivated);
964 911

  
965
            if (!prefAreaVoc.isAllowOverride()) {
966
                button_openSelectAreaVocabularies.setButtonEnabled(false);
967
            }
968
            if (!prefStatus.isAllowOverride()) {
969
                button_openStatusWizard.setButtonEnabled(false);
970
            }
912

  
971 913
            if (!prefRank.isAllowOverride()) {
972 914
                activateRankCombo.setEnabled(false);
973 915

  
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/DistributionGeneralPreference.java
1
/**
2
* Copyright (C) 2019 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.preference;
10

  
11
import org.eclipse.swt.widgets.Composite;
12
import org.eclipse.swt.widgets.Control;
13

  
14
import eu.etaxonomy.taxeditor.preference.menu.CdmPreferencePage;
15

  
16
/**
17
 * @author k.luther
18
 * @since 02.07.2019
19
 *
20
 */
21
public class DistributionGeneralPreference extends CdmPreferencePage {
22

  
23
    /**
24
     * {@inheritDoc}
25
     */
26
    @Override
27
    protected Control createContents(Composite parent) {
28
        noDefaultAndApplyButton();
29
        return null;
30
    }
31

  
32
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/DistributionStatusAndNamedAreaVocabularies.java
1
/**
2
* Copyright (C) 2019 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.preference;
10

  
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.Iterator;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

  
18
import javax.inject.Inject;
19

  
20
import org.eclipse.e4.core.di.annotations.Optional;
21
import org.eclipse.e4.ui.di.UIEventTopic;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.custom.CLabel;
24
import org.eclipse.swt.custom.TableEditor;
25
import org.eclipse.swt.events.SelectionAdapter;
26
import org.eclipse.swt.events.SelectionEvent;
27
import org.eclipse.swt.layout.GridData;
28
import org.eclipse.swt.layout.GridLayout;
29
import org.eclipse.swt.widgets.Button;
30
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.swt.widgets.Event;
33
import org.eclipse.swt.widgets.Listener;
34
import org.eclipse.swt.widgets.Table;
35
import org.eclipse.swt.widgets.TableColumn;
36
import org.eclipse.swt.widgets.TableItem;
37

  
38
import eu.etaxonomy.cdm.model.location.NamedArea;
39
import eu.etaxonomy.cdm.model.metadata.CdmPreference;
40
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
41
import eu.etaxonomy.cdm.model.metadata.PreferenceResolver;
42
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
43
import eu.etaxonomy.taxeditor.l10n.Messages;
44
import eu.etaxonomy.taxeditor.model.ImageResources;
45
import eu.etaxonomy.taxeditor.preference.menu.CdmPreferencePage;
46
import eu.etaxonomy.taxeditor.store.CdmStore;
47
import eu.etaxonomy.taxeditor.ui.element.CommandHandlerButton;
48

  
49
/**
50
 * @author k.luther
51
 * @since 02.07.2019
52
 *
53
 */
54
public class DistributionStatusAndNamedAreaVocabularies extends CdmPreferencePage {
55

  
56
    protected String commandHandlerString;
57
    protected String commandHandlerStringStatus;
58

  
59
    protected List<CdmPreference> prefStatus;
60
    protected List<CdmPreference> prefStatusToDelete = new ArrayList<>();
61

  
62
    protected CdmPreference prefAreaVoc;
63

  
64
    private CommandHandlerButton button_openSelectAreaVocabularies;
65

  
66
    private CommandHandlerButton button_openStatusWizard;
67

  
68
    private Map<UUID, NamedArea> namedAreaUUIDMap = new HashMap();
69

  
70
    private Table table;
71

  
72
    /**
73
     * {@inheritDoc}
74
     */
75
    @Override
76
    protected Control createContents(Composite parent) {
77
        getValues();
78
        Composite composite = new Composite(parent, SWT.NULL);
79
        composite.setLayout(new GridLayout());
80
        GridData textGrid = createTextGridData();
81
        textGrid.verticalSpan = 2;
82

  
83

  
84
        if (isAdminPreference){
85
            final CLabel labelPerAreaStatus = new CLabel(composite, SWT.NULL);
86
            labelPerAreaStatus.setText(Messages.DistributionAdminPreferences_PER_AREA_STATUS);
87
            labelPerAreaStatus.setLayoutData(textGrid);
88
            createTable(composite);
89
        }
90

  
91
        final CLabel labelStatus = new CLabel(composite, SWT.NULL);
92
        labelStatus.setText(Messages.DistributionAdminPreferences_SELECT_STATUS);
93
        labelStatus.setLayoutData(textGrid);
94
        composite.pack ();
95
        button_openStatusWizard = new CommandHandlerButton(composite, SWT.PUSH, commandHandlerStringStatus);
96

  
97
        button_openStatusWizard.setText(Messages.Distribution_status_selection);
98
        button_openStatusWizard.addListener(SWT.Selection, new Listener() {
99
            @Override
100
            public void handleEvent(Event e) {
101
                switch (e.type) {
102
                case SWT.Selection:
103
                    setApply(true);
104
                    break;
105
                }
106
            }
107
        });
108

  
109
        final CLabel label = new CLabel(composite, SWT.NULL);
110
        label.setText(Messages.ChecklistEditorGeneralPreference_open_wizard);
111
        label.setLayoutData(textGrid);
112

  
113
        button_openSelectAreaVocabularies = new CommandHandlerButton(composite, SWT.PUSH, commandHandlerString);
114
        button_openSelectAreaVocabularies
115
                .setText(Messages.ChecklistEditorGeneralPreference_open_distribution_selection);
116

  
117
        if (!isAdminPreference){
118
            if (prefAreaVoc != null && !prefAreaVoc.isAllowOverride()) {
119
                button_openSelectAreaVocabularies.setButtonEnabled(false);
120
            }
121
//            if (prefStatus != null && !prefStatus.isAllowOverride()) {
122
//                button_openStatusWizard.setButtonEnabled(false);
123
//            }
124
        }
125
        return composite;
126
    }
127

  
128
    public void createTable(Composite composite) {
129
        table = new Table(
130
                composite, SWT.BORDER /*| SWT.CHECK */| SWT.FULL_SELECTION | SWT.SINGLE
131
        );
132

  
133
        table.setLinesVisible(true);
134
        table.setHeaderVisible(true);
135
        GridData tableGrid = createTextGridData();
136
        table.setLayoutData(tableGrid);
137
        Iterator<CdmPreference> prefIterator = prefStatus.iterator();
138
        CdmPreference pref;
139
        TableColumn column = new TableColumn(table, SWT.NONE);
140
        column.setText("Predicate/Subject");
141
        column.setWidth(500);
142
        column = new TableColumn(table, SWT.NONE);
143
        if (isAdminPreference){
144
            column.setText("Allow Override");
145
        }else{
146
            column.setText("Use Default");
147
        }
148
        column.setWidth(100);
149
        column = new TableColumn(table, SWT.NONE);
150
        column.setText("Delete");
151
        column.setWidth(100);
152

  
153

  
154

  
155
        while (prefIterator.hasNext()){
156
            pref = prefIterator.next();
157
            createTableRow(pref);
158

  
159
        }
160
    }
161

  
162
    public void createTableRow(CdmPreference pref) {
163
        TableItem item = new TableItem(table, SWT.NONE);
164
        for (int col = 0; col < 3; col ++) {
165
            String namedAreaString = null;
166
            if (col == 0){
167
               String uuidString = getUUIDFromSubject(pref);
168
               if (uuidString != null){
169
                   try{
170
                   UUID uuid = UUID.fromString(uuidString);
171
                   namedAreaString = namedAreaUUIDMap.get(UUID.fromString(uuidString)).getLabel();
172
                   }catch(IllegalArgumentException e){
173
                       // no UUID
174
                   }
175
               }
176
               if (namedAreaString != null){
177
                   String subjectString = pref.getSubjectString().replace(pref.getSubject().getLastPart(), namedAreaString);
178
                   item.setText(col, pref.getPredicate() +subjectString);
179
               }else{
180
                   item.setText(col, pref.getPredicate() +pref.getSubjectString());
181
               }
182

  
183
            }else if (col == 1) {
184
                Button allowOverrideButton = new Button(table, SWT.CHECK);
185
                allowOverrideButton.setData(pref);
186
                TableEditor editor = new TableEditor(table);
187
                editor.horizontalAlignment = SWT.LEFT;
188
                editor.grabHorizontal = true;
189
                editor.setEditor(allowOverrideButton, item, col);
190
                allowOverrideButton.setSelection(pref.isAllowOverride());
191
                allowOverrideButton.addSelectionListener(new SelectionAdapter(){
192
                    @Override
193
                    public void widgetSelected(SelectionEvent e){
194
                        setApply(true);
195
                        Button thisButton= (Button) e.widget;
196
                        CdmPreference preference=(CdmPreference)thisButton.getData();
197
                        preference = PreferenceResolver.resolve(prefStatus, preference.getKey());
198
                        if (isAdminPreference){
199
                            preference.setAllowOverride(!preference.isAllowOverride());
200
                        }else{
201

  
202
                        }
203
                    }
204
                  });
205
            } else if (col == 2){
206
                Button delButton = new Button(table, SWT.PUSH);
207
                delButton.setImage(ImageResources
208
                        .getImage(ImageResources.TRASH_ICON));
209
                delButton.setData(pref);
210
                delButton.pack();
211
                delButton.addSelectionListener(new SelectionAdapter(){
212
                    @Override
213
                    public void widgetSelected(SelectionEvent e){
214
                        Button thisButton= (Button) e.widget;
215
                        CdmPreference preference=(CdmPreference)thisButton.getData();
216
                        int index = prefStatus.indexOf(preference);
217
                        table.getItem(index).setText("Deleted");
218
                        //prefStatus.remove(preference);
219
                        prefStatusToDelete.add(preference);
220
                        setApply(true);
221

  
222
                    }
223
                  });
224
                TableEditor editor = new TableEditor(table);
225
                editor.horizontalAlignment = SWT.LEFT;
226
                editor.grabHorizontal = true;
227
                editor.setEditor(delButton, item, col);
228

  
229
            }
230
        }
231
    }
232

  
233
    @Override
234
    public void getValues() {
235
        isAdminPreference = false;
236
        CdmPreferenceCache cache = CdmPreferenceCache.instance();
237
        cache.getAllTaxEditorDBPreferences();
238
        prefAreaVoc = PreferencesUtil.getPreferenceFromDB(PreferencePredicate.AvailableDistributionAreaVocabularies);
239
        if (prefAreaVoc == null){
240
            prefAreaVoc = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionAreaVocabularies, PreferencePredicate.AvailableDistributionAreaVocabularies.getDefaultValue() != null ?  PreferencePredicate.AvailableDistributionAreaVocabularies.getDefaultValue().toString(): null);
241
        }
242

  
243

  
244
        prefStatus = cache.getAllForPredicate(PreferencePredicate.AvailableDistributionStatus.getKey());
245
        if (prefStatus == null){
246
            prefStatus = new ArrayList();
247
            CdmPreference statusPref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionStatus, PreferencePredicate.AvailableDistributionStatus.getDefaultValue() != null ?  PreferencePredicate.AvailableDistributionStatus.getDefaultValue().toString(): null);
248
            prefStatus.add(statusPref);
249
        }
250
        createNamedAreaUUIDMap();
251

  
252
        commandHandlerString = "eu.etaxonomy.taxeditor.store.open.OpenDistributionEditorWizardHandler";
253
        commandHandlerStringStatus = "eu.etaxonomy.taxeditor.store.open.OpenDistributionStatusWizardHandler";
254
        setApply(true);
255
    }
256

  
257
    /**
258
     *
259
     */
260
    private void createNamedAreaUUIDMap() {
261
        List<UUID> uuids = new ArrayList();
262
        for (CdmPreference pref: prefStatus){
263
            try{
264
                String lastPart = getUUIDFromSubject(pref);
265
                UUID uuid = UUID.fromString(lastPart);
266
                uuids.add(uuid);
267
            }catch (IllegalArgumentException e){
268
                // no uuid in subject
269
            }
270

  
271
        }
272
        if (!uuids.isEmpty()){
273
            List<NamedArea> areas =CdmStore.getTermManager().getTerms(uuids, NamedArea.class);
274
            for (NamedArea area: areas){
275
                namedAreaUUIDMap.put(area.getUuid(), area);
276
            }
277
        }
278

  
279
    }
280

  
281
    public String getUUIDFromSubject(CdmPreference pref) {
282
        String lastPart = pref.getSubject().getLastPart();
283
        lastPart = lastPart.replace("NamedArea[", "");
284
        lastPart = lastPart.replace("]", "");
285
        return lastPart;
286
    }
287

  
288
    @Override
289
    protected void performDefaults() {
290
        if (!isAdminPreference){
291
            if (!prefAreaVoc.isAllowOverride()) {
292
                button_openSelectAreaVocabularies.setButtonEnabled(false);
293
            }
294

  
295
        }
296
        prefStatus = new ArrayList();
297
        CdmPreference statusPref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionStatus, PreferencePredicate.AvailableDistributionStatus.getDefaultValue() != null ?  PreferencePredicate.AvailableDistributionStatus.getDefaultValue().toString(): null);
298
        prefStatus.add(statusPref);
299
        prefAreaVoc = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionAreaVocabularies,
300
                null);
301
        refresh();
302
    }
303

  
304
    @Override
305
    public boolean performOk(){
306
        if (!isApply()){
307
            return true;
308
        }
309
        List<CdmPreference> toDelete = new ArrayList<>();
310
        for (CdmPreference pref:prefStatusToDelete){
311
            CdmPreference prefToDelete = CdmPreference.NewInstance(pref.getKey(), null);
312
            toDelete.add(prefToDelete);
313
        }
314
        prefStatus.addAll(toDelete);
315
        PreferencesUtil.setPreferencesToDB(prefStatus);
316
        return true;
317
    }
318

  
319

  
320
    @Inject
321
    @Optional
322
    public void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_DATASOURCE)boolean refresh){
323
        if(refresh){
324
            refresh();
325
        }
326
    }
327

  
328
    /**
329
     *
330
     */
331
    private void refresh() {
332
        getValues();
333
        table.removeAll();
334
        Iterator<CdmPreference> prefIterator = prefStatus.iterator();
335
        CdmPreference pref;
336
        while (prefIterator.hasNext()){
337
            pref = prefIterator.next();
338
            createTableRow(pref);
339

  
340
        }
341
        table.redraw();
342
        table.pack();
343

  
344
    }
345
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/PreferencesUtil.java
1723 1723
    public static void setPreferencesToDB(List<CdmPreference> preferences) {
1724 1724

  
1725 1725
        ICdmRepository controller;
1726
        try{
1726
        //try{
1727 1727
            if(CdmStore.isActive()){
1728 1728
                controller = CdmStore.getCurrentApplicationConfiguration();
1729 1729
                for (CdmPreference preference: preferences){
1730 1730
                    if (preference.getValue() == null && preference.isAllowOverride()){
1731 1731
                        controller.getPreferenceService().remove(preference.getKey());
1732

  
1732 1733
                    }else{
1733 1734
                        controller.getPreferenceService().set(preference);
1735

  
1734 1736
                    }
1735
                    CdmPreferenceCache.instance().put(preference);
1737

  
1736 1738
                }
1739
                CdmPreferenceCache.instance().getAllTaxEditorDBPreferences();
1740

  
1737 1741
            }
1738
        }catch(Exception e){
1742
        /*}catch(Exception e){
1739 1743
            e.printStackTrace();
1740
        }
1744
        }*/
1741 1745
    }
1742 1746

  
1743 1747
    /**
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/SupplementalDataPreferences.java
35 35

  
36 36

  
37 37
    protected Boolean isShowIDNamspace;
38
    protected Boolean isShowNamespace;
38
    protected Boolean isShowIDSource;
39 39

  
40 40
    protected boolean isAllowOverrideShowIDNamspace;
41
    protected boolean isAllowOverrideShowNamspace;
41
    protected boolean isAllowOverrideShowIDSource;
42 42

  
43 43
    protected boolean isOverrideShowIDNamspace;
44
    protected boolean isOverrideShowNamspace;
44
    protected boolean isOverrideShowIDSource;
45 45

  
46 46

  
47 47
    protected Combo showIDNamspaceButton;
48 48
    protected Button allowOverrideShowIDNamspaceButton;
49
    protected Combo showNamspaceButton;
50
    protected Button allowOverrideNamspaceButton;
49
    protected Combo showIDSourceButton;
50
    protected Button allowOverrideIDSourceButton;
51 51

  
52 52
    final String SHOW = Messages.GeneralPreference_yes;
53 53
    final String DO_NOT_SHOW = Messages.GeneralPreference_no;
......
91 91
        }
92 92

  
93 93

  
94
        showNamspaceButton = createBooleanCombo(composite, SHOW, DO_NOT_SHOW, PreferencePredicate.ShowNamespaceInSource, "Show Namespace in Source",
94
        showIDSourceButton = createBooleanCombo(composite, SHOW, DO_NOT_SHOW, PreferencePredicate.ShowNamespaceInSource, "Show ID in Source",
95 95
                isAdminPreference);
96 96

  
97
        showNamspaceButton.addSelectionListener(this);
98
        if (isShowNamespace == null || (!isOverrideShowNamspace && !isAdminPreference)){
99
            showNamspaceButton.select(0);
100
        }else if (isShowNamespace){
101
            showNamspaceButton.select(1);
97
        showIDSourceButton.addSelectionListener(this);
98
        if (isShowIDSource == null || (!isOverrideShowIDSource && !isAdminPreference)){
99
            showIDSourceButton.select(0);
100
        }else if (isShowIDSource){
101
            showIDSourceButton.select(1);
102 102
        }else{
103
            showNamspaceButton.select(2);
103
            showIDSourceButton.select(2);
104 104
        }
105 105

  
106 106
        if (isAdminPreference){
107
            allowOverrideNamspaceButton = createAllowOverrideButton(composite);
108
            allowOverrideNamspaceButton.setSelection(isAllowOverrideShowNamspace);
109
            allowOverrideNamspaceButton.addSelectionListener(new SelectionAdapter(){
107
            allowOverrideIDSourceButton = createAllowOverrideButton(composite);
108
            allowOverrideIDSourceButton.setSelection(isAllowOverrideShowIDSource);
109
            allowOverrideIDSourceButton.addSelectionListener(new SelectionAdapter(){
110 110
                @Override
111 111
                public void widgetSelected(SelectionEvent e) {
112
                    isAllowOverrideShowNamspace = allowOverrideNamspaceButton.getSelection();
112
                    isAllowOverrideShowIDSource = allowOverrideIDSourceButton.getSelection();
113 113
                    setApply(true);
114 114
                }
115 115
            });
......
117 117
        if (!isAllowOverrideShowIDNamspace && !isAdminPreference){
118 118
            showIDNamspaceButton.setEnabled(false);
119 119
        }
120
        if (!isAllowOverrideShowNamspace && !isAdminPreference){
121
            showNamspaceButton.setEnabled(false);
120
        if (!isAllowOverrideShowIDSource && !isAdminPreference){
121
            showIDSourceButton.setEnabled(false);
122 122
        }
123 123

  
124 124

  
......
133 133
            PreferencesUtil.setBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowIdInSource.getKey()), isOverrideShowIDNamspace);
134 134
            PreferencesUtil.setBooleanValue(PreferencePredicate.ShowIdInSource.getKey(), isShowIDNamspace);
135 135
        }
136
        if (isAllowOverrideShowNamspace){
137
            PreferencesUtil.setBooleanValue(PreferencePredicate.ShowNamespaceInSource.getKey(), isShowNamespace);
138
            PreferencesUtil.setBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowNamespaceInSource.getKey()), isOverrideShowNamspace);
136
        if (isAllowOverrideShowIDSource){
137
            PreferencesUtil.setBooleanValue(PreferencePredicate.ShowNamespaceInSource.getKey(), isShowIDSource);
138
            PreferencesUtil.setBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowNamespaceInSource.getKey()), isOverrideShowIDSource);
139 139
        }
140 140

  
141 141

  
......
156 156
            isAllowOverrideShowIDNamspace = true;
157 157
        }
158 158

  
159
        isShowNamespace = PreferencesUtil.getBooleanValue(PreferencePredicate.ShowNamespaceInSource.getKey(), true);
160
        isOverrideShowNamspace = PreferencesUtil.getBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowNamespaceInSource.getKey()), true) != null? PreferencesUtil.getBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowNamespaceInSource.getKey()), true):false;
159
        isShowIDSource = PreferencesUtil.getBooleanValue(PreferencePredicate.ShowNamespaceInSource.getKey(), true);
160
        isOverrideShowIDSource = PreferencesUtil.getBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowNamespaceInSource.getKey()), true) != null? PreferencesUtil.getBooleanValue(PreferencesUtil.prefOverrideKey(PreferencePredicate.ShowNamespaceInSource.getKey()), true):false;
161 161
        key = CdmPreference.NewKey(PreferenceSubject.NewTaxEditorInstance(), PreferencePredicate.ShowNamespaceInSource);
162 162
        pref = cache.findBestMatching(key);
163 163
        if (pref != null){
164
            isAllowOverrideShowNamspace = pref.isAllowOverride();
164
            isAllowOverrideShowIDSource = pref.isAllowOverride();
165 165
        }else{
166
            isAllowOverrideShowNamspace = true;
166
            isAllowOverrideShowIDSource = true;
167 167
        }
168 168

  
169 169

  
......
191 191
                isShowIDNamspace = false;
192 192
            }
193 193
        }
194
        if (e.getSource().equals(this.showNamspaceButton)) {
195
            String text = showNamspaceButton.getText();
194
        if (e.getSource().equals(this.showIDSourceButton)) {
195
            String text = showIDSourceButton.getText();
196 196
            if (text.equals(Messages.Preference_Use_Default)){
197
                isOverrideShowNamspace = false;
197
                isOverrideShowIDSource = false;
198 198
            }else{
199
                isOverrideShowNamspace = true;
199
                isOverrideShowIDSource = true;
200 200
            }
201 201
            if (text.equals(SHOW)){
202
                isShowNamespace = true;
202
                isShowIDSource = true;
203 203
            }else{
204
                isShowNamespace = false;
204
                isShowIDSource = false;
205 205
            }
206 206
        }
207 207

  
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/wizard/AvailableDistributionPerAreaStatusPage.java
150 150
            }
151 151

  
152 152
        });
153
        btnRemove = new Button(toolbar, SWT.NONE);
154
        btnRemove.addSelectionListener(new SelectionListener(){
155

  
156
            @Override
157
            public void widgetSelected(SelectionEvent e) {
158

  
159
                PrefKey key = newAreaSpecificStatusPreference();
160
                actualPref = PreferenceResolver.resolve(perAreaPreferences, key);
161
                actualPref = CdmPreference.NewInstance(key, null);
162

  
163
                perAreaPreferences.add(actualPref);
164
                status.setText("Preference for area " + actualArea.getLabel() + " removed.");
165
                status.setVisible(true);
166

  
167
                actualArea = null;
168

  
169
                areaText.setText("");
170
                rememberCheckedValues(getCheckedValuesFromPreferences());
171

  
172
            }
173

  
174
            @Override
175
            public void widgetDefaultSelected(SelectionEvent e) {
176
                // TODO Auto-generated method stub
177

  
178
            }
179

  
180
        });
181
        btnRemove.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
182
        btnRemove.setToolTipText("");
153
//        btnRemove = new Button(toolbar, SWT.NONE);
154
//        btnRemove.addSelectionListener(new SelectionListener(){
155
//
156
//            @Override
157
//            public void widgetSelected(SelectionEvent e) {
158
//
159
//                PrefKey key = newAreaSpecificStatusPreference();
160
//                actualPref = PreferenceResolver.resolve(perAreaPreferences, key);
161
//                actualPref = CdmPreference.NewInstance(key, null);
162
//                if (actualPref.getKey().equals(pref.getKey())){
163
//                    pref = actualPref;
164
//                }
165
//
166
//                perAreaPreferences.add(actualPref);
167
//                if (actualArea != null){
168
//                    status.setText("Preference for area " + actualArea.getLabel() + " removed. Now the status defined for all areas are displayed");
169
//                }else{
170
//                    status.setText("Preference for all areas is removed. Now all status will be displayed");
171
//                }
172
//                status.setVisible(true);
173
//
174
//                actualArea = null;
175
//
176
//                areaText.setText("");
177
//                rememberCheckedValues(getCheckedValuesFromPreferences());
178
//
179
//            }
180
//
181
//            @Override
182
//            public void widgetDefaultSelected(SelectionEvent e) {
183
//                // TODO Auto-generated method stub
184
//
185
//            }
186
//
187
//        });
188
//        btnRemove.setImage(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON));
189
//        btnRemove.setToolTipText("");
183 190
        status = new Label(toolbar, SWT.NONE);
184 191
        status.setVisible(false);
185 192
    }
......
271 278
    }
272 279

  
273 280
    private PrefKey newAreaSpecificStatusPreference(){
274
        PrefKey prefKey = CdmPreference.NewKey(PreferenceSubject.NewInstance(PreferenceSubject.ROOT+"NamedArea["+actualArea.getUuid().toString()+"]"+PreferenceSubject.SEP), PreferencePredicate.AvailableDistributionStatus);
281
        PrefKey prefKey;
282
        if (actualArea != null){
283
            prefKey  = CdmPreference.NewKey(PreferenceSubject.NewInstance(PreferenceSubject.ROOT+"NamedArea["+actualArea.getUuid().toString()+"]"+PreferenceSubject.SEP), PreferencePredicate.AvailableDistributionStatus);
284
        }else{
285
            prefKey = CdmPreference.NewKey(PreferenceSubject.NewTaxEditorInstance(), PreferencePredicate.AvailableDistributionStatus);
286
        }
275 287
        return prefKey;
276 288
    }
277 289

  
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/wizard/AvailableDistributionPerAreaStatusWizard.java
19 19
import eu.etaxonomy.cdm.model.metadata.CdmPreference;
20 20
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
21 21
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
22
import eu.etaxonomy.taxeditor.event.EventUtility;
23
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
22 24
import eu.etaxonomy.taxeditor.l10n.Messages;
23 25
import eu.etaxonomy.taxeditor.preference.CdmPreferenceCache;
24 26
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
......
95 97

  
96 98
       // PreferencesUtil.setBooleanValue(PreferencesUtil.createOverridePreferenceString(PreferencePredicate.AvailableDistributionStatus.getKey()), aPage.override);
97 99
        PreferencesUtil.firePreferencesChanged(this.getClass());
100
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_DISTRIBUTION_PREFERENCES, true);
98 101
        return true;
99 102
    }
100 103

  
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/description/detail/DistributionDetailElement.java
90 90
		}
91 91
        CdmPreference pref = CdmPreferenceCache.instance().get(key);
92 92
        // if there is no preference for the area, look for the general
93
        if (pref == null){
93
        if (pref == null || pref.isAllowOverride()){
94 94
            pref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.AvailableDistributionStatus, PreferencesUtil.getStringValue(PreferencePredicate.AvailableDistributionStatus.getKey()));
95 95
        }
96 96

  

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)