Revision bc5816ee
Added by Andreas Kohlbecker almost 7 years ago
pom.xml | ||
---|---|---|
455 | 455 |
<artifactId>switch</artifactId> |
456 | 456 |
<version>3.0.0</version> |
457 | 457 |
</dependency> |
458 |
<dependency> |
|
459 |
<groupId>com.vaadin.addon</groupId> |
|
460 |
<artifactId>vaadin-onoffswitch</artifactId> |
|
461 |
<version>0.0.1</version> |
|
462 |
</dependency> |
|
463 | 458 |
<!-- <dependency> |
464 | 459 |
only in the edit repo |
465 | 460 |
<groupId>org.vaadin.addons</groupId> |
src/main/java/eu/etaxonomy/cdm/vaadin/AppWidgetSet.gwt.xml | ||
---|---|---|
43 | 43 |
|
44 | 44 |
<inherits name="org.vaadin.teemu.switchui.SwitchComponentWidgetset" /> |
45 | 45 |
|
46 |
<inherits name="com.vaadin.addon.onoffswitch.WidgetSet" /> |
|
46 |
|
|
47 | 47 |
</module> |
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/PersonField.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.cdm.vaadin.component.common; |
|
10 |
|
|
11 |
import com.vaadin.data.fieldgroup.BeanFieldGroup; |
|
12 |
import com.vaadin.ui.Component; |
|
13 |
import com.vaadin.ui.CssLayout; |
|
14 |
import com.vaadin.ui.TextField; |
|
15 |
import com.vaadin.ui.themes.ValoTheme; |
|
16 |
|
|
17 |
import eu.etaxonomy.cdm.model.agent.Person; |
|
18 |
import eu.etaxonomy.vaadin.component.CompositeCustomField; |
|
19 |
import eu.etaxonomy.vaadin.component.SwitchButton; |
|
20 |
|
|
21 |
/** |
|
22 |
* @author a.kohlbecker |
|
23 |
* @since May 11, 2017 |
|
24 |
* |
|
25 |
*/ |
|
26 |
public class PersonField extends CompositeCustomField<Person> { |
|
27 |
|
|
28 |
private static final long serialVersionUID = 8346575511284469356L; |
|
29 |
|
|
30 |
private static final String PRIMARY_STYLE = "v-person-field"; |
|
31 |
|
|
32 |
private BeanFieldGroup<Person> fieldGroup = new BeanFieldGroup<>(Person.class); |
|
33 |
|
|
34 |
enum Mode { |
|
35 |
CACHE_MODE, DETAILS_MODE; |
|
36 |
|
|
37 |
public String toCssClass() { |
|
38 |
return name().toLowerCase().replace("_", "-"); |
|
39 |
} |
|
40 |
} |
|
41 |
|
|
42 |
private Mode currentMode = null; |
|
43 |
|
|
44 |
private float baseWidth = 100 / 8; |
|
45 |
|
|
46 |
private CssLayout root = new CssLayout(); |
|
47 |
private TextField cacheField = new TextField(); |
|
48 |
private CssLayout detailsContainer = new CssLayout(); |
|
49 |
private TextField firstNameField = new TextField(); |
|
50 |
private TextField lastNameField = new TextField(); |
|
51 |
private TextField prefixField = new TextField(); |
|
52 |
private TextField suffixField = new TextField(); |
|
53 |
private SwitchButton unlockSwitch = new SwitchButton(); |
|
54 |
|
|
55 |
|
|
56 |
|
|
57 |
/** |
|
58 |
* @param caption |
|
59 |
*/ |
|
60 |
public PersonField(String caption) { |
|
61 |
|
|
62 |
this(); |
|
63 |
setCaption(caption); |
|
64 |
} |
|
65 |
|
|
66 |
/** |
|
67 |
* @param caption |
|
68 |
*/ |
|
69 |
public PersonField() { |
|
70 |
|
|
71 |
root.setPrimaryStyleName(PRIMARY_STYLE); |
|
72 |
|
|
73 |
addStyledComponent(cacheField); |
|
74 |
addStyledComponent(firstNameField); |
|
75 |
addStyledComponent(lastNameField); |
|
76 |
addStyledComponent(prefixField); |
|
77 |
addStyledComponent(suffixField); |
|
78 |
addStyledComponent(unlockSwitch); |
|
79 |
|
|
80 |
addSizedComponent(root); |
|
81 |
} |
|
82 |
|
|
83 |
private void setMode(Mode mode){ |
|
84 |
if(mode.equals(currentMode)){ |
|
85 |
return; |
|
86 |
} |
|
87 |
if(currentMode != null){ |
|
88 |
String removeMode = currentMode.toCssClass(); |
|
89 |
root.removeStyleName(removeMode); |
|
90 |
} |
|
91 |
String newMode = mode.toCssClass(); |
|
92 |
root.addStyleName(newMode); |
|
93 |
currentMode = mode; |
|
94 |
} |
|
95 |
|
|
96 |
|
|
97 |
/** |
|
98 |
* {@inheritDoc} |
|
99 |
*/ |
|
100 |
@Override |
|
101 |
protected Component initContent() { |
|
102 |
|
|
103 |
root.addComponent(cacheField); |
|
104 |
root.addComponent(unlockSwitch); |
|
105 |
|
|
106 |
cacheField.setWidth(100, Unit.PERCENTAGE); |
|
107 |
|
|
108 |
prefixField.setWidth(baseWidth, Unit.PERCENTAGE); |
|
109 |
prefixField.setInputPrompt("Prefix"); |
|
110 |
|
|
111 |
firstNameField.setWidth(baseWidth * 3, Unit.PERCENTAGE); |
|
112 |
firstNameField.setInputPrompt("First Name"); |
|
113 |
|
|
114 |
lastNameField.setWidth(baseWidth * 3, Unit.PERCENTAGE); |
|
115 |
lastNameField.setInputPrompt("Last Name"); |
|
116 |
|
|
117 |
suffixField.setWidth(baseWidth, Unit.PERCENTAGE); |
|
118 |
suffixField.setInputPrompt("Suffix"); |
|
119 |
|
|
120 |
detailsContainer.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); |
|
121 |
detailsContainer.addComponent(prefixField); |
|
122 |
detailsContainer.addComponent(firstNameField); |
|
123 |
detailsContainer.addComponent(lastNameField); |
|
124 |
detailsContainer.addComponent(suffixField); |
|
125 |
root.addComponent(detailsContainer); |
|
126 |
|
|
127 |
unlockSwitch.addValueChangeListener(e -> { |
|
128 |
if(refreshMode()){ |
|
129 |
switch (currentMode) { |
|
130 |
case CACHE_MODE: |
|
131 |
cacheField.focus(); |
|
132 |
break; |
|
133 |
case DETAILS_MODE: |
|
134 |
firstNameField.focus(); |
|
135 |
break; |
|
136 |
default: |
|
137 |
break; |
|
138 |
|
|
139 |
} |
|
140 |
} |
|
141 |
}); |
|
142 |
unlockSwitch.setValueSetLister(e -> { |
|
143 |
refreshMode(); |
|
144 |
}); |
|
145 |
|
|
146 |
addDefaultStyles(); |
|
147 |
setMode(Mode.DETAILS_MODE); |
|
148 |
|
|
149 |
fieldGroup.bind(cacheField, "titleCache"); |
|
150 |
fieldGroup.bind(prefixField, "prefix"); |
|
151 |
fieldGroup.bind(firstNameField, "firstname"); |
|
152 |
fieldGroup.bind(lastNameField, "lastname"); |
|
153 |
fieldGroup.bind(suffixField, "suffix"); |
|
154 |
fieldGroup.bind(unlockSwitch, "protectedTitleCache"); |
|
155 |
fieldGroup.setBuffered(false); |
|
156 |
|
|
157 |
return root; |
|
158 |
} |
|
159 |
|
|
160 |
/** |
|
161 |
* |
|
162 |
* @return true if the mode has changed |
|
163 |
*/ |
|
164 |
protected boolean refreshMode() { |
|
165 |
Mode lastMode = currentMode; |
|
166 |
setMode(unlockSwitch.getValue() ? Mode.CACHE_MODE: Mode.DETAILS_MODE); |
|
167 |
return !lastMode.equals(currentMode); |
|
168 |
} |
|
169 |
|
|
170 |
/** |
|
171 |
* {@inheritDoc} |
|
172 |
*/ |
|
173 |
@Override |
|
174 |
public Class<? extends Person> getType() { |
|
175 |
return Person.class; |
|
176 |
} |
|
177 |
|
|
178 |
@Override |
|
179 |
public void setValue(Person person){ |
|
180 |
super.setValue(person); |
|
181 |
} |
|
182 |
|
|
183 |
/** |
|
184 |
* {@inheritDoc} |
|
185 |
*/ |
|
186 |
@Override |
|
187 |
protected void setInternalValue(Person newValue) { |
|
188 |
super.setInternalValue(newValue); |
|
189 |
fieldGroup.setItemDataSource(newValue); |
|
190 |
// refreshMode(); |
|
191 |
} |
|
192 |
|
|
193 |
@Override |
|
194 |
protected void addDefaultStyles(){ |
|
195 |
cacheField.addStyleName("cache-field"); |
|
196 |
detailsContainer.addStyleName("details-fields"); |
|
197 |
} |
|
198 |
} |
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/TeamOrPersonField.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.cdm.vaadin.component.common; |
|
10 |
|
|
11 |
import com.vaadin.data.fieldgroup.BeanFieldGroup; |
|
12 |
import com.vaadin.data.util.BeanItem; |
|
13 |
import com.vaadin.server.UserError; |
|
14 |
import com.vaadin.ui.Component; |
|
15 |
import com.vaadin.ui.CssLayout; |
|
16 |
|
|
17 |
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; |
|
18 |
import eu.etaxonomy.cdm.model.agent.Person; |
|
19 |
import eu.etaxonomy.cdm.model.agent.Team; |
|
20 |
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase; |
|
21 |
import eu.etaxonomy.vaadin.component.CompositeCustomField; |
|
22 |
import eu.etaxonomy.vaadin.component.FieldListEditor; |
|
23 |
import eu.etaxonomy.vaadin.component.SwitchableTextField; |
|
24 |
|
|
25 |
/** |
|
26 |
* @author a.kohlbecker |
|
27 |
* @since May 11, 2017 |
|
28 |
* |
|
29 |
*/ |
|
30 |
public class TeamOrPersonField extends CompositeCustomField<TeamOrPersonBase<?>> { |
|
31 |
|
|
32 |
private static final long serialVersionUID = 660806402243118112L; |
|
33 |
|
|
34 |
private static final String PRIMARY_STYLE = "v-team-or-person-field"; |
|
35 |
|
|
36 |
private CssLayout root = new CssLayout(); |
|
37 |
private CssLayout compositeWrapper = new CssLayout(); |
|
38 |
|
|
39 |
// Fields for case when value is a Person |
|
40 |
private PersonField personField = new PersonField(); |
|
41 |
|
|
42 |
// Fields for case when value is a Team |
|
43 |
private SwitchableTextField titleField = new SwitchableTextField("Team (bibliographic)"); |
|
44 |
private SwitchableTextField nomenclaturalTitleField = new SwitchableTextField("Team (nomenclatural)"); |
|
45 |
private FieldListEditor<Person, PersonField> personsListEditor = new FieldListEditor<Person, PersonField>(Person.class, PersonField.class, "Teammembers"); |
|
46 |
|
|
47 |
private BeanFieldGroup<Team> fieldGroup = new BeanFieldGroup<>(Team.class); |
|
48 |
|
|
49 |
public TeamOrPersonField(String caption){ |
|
50 |
|
|
51 |
setCaption(caption); |
|
52 |
|
|
53 |
addStyledComponent(personField); |
|
54 |
addStyledComponent(titleField); |
|
55 |
addStyledComponent(nomenclaturalTitleField); |
|
56 |
addStyledComponent(personsListEditor); |
|
57 |
|
|
58 |
addSizedComponent(root); |
|
59 |
addSizedComponent(compositeWrapper); |
|
60 |
addSizedComponent(personField); |
|
61 |
addSizedComponent(titleField); |
|
62 |
addSizedComponent(nomenclaturalTitleField); |
|
63 |
addSizedComponent(personsListEditor); |
|
64 |
} |
|
65 |
|
|
66 |
/** |
|
67 |
* {@inheritDoc} |
|
68 |
*/ |
|
69 |
@Override |
|
70 |
protected Component initContent() { |
|
71 |
root.setPrimaryStyleName(PRIMARY_STYLE); |
|
72 |
compositeWrapper.setStyleName("margin-wrapper"); |
|
73 |
root.addComponent(compositeWrapper); |
|
74 |
return root; |
|
75 |
} |
|
76 |
|
|
77 |
/** |
|
78 |
* {@inheritDoc} |
|
79 |
*/ |
|
80 |
@Override |
|
81 |
public Class getType() { |
|
82 |
return TeamOrPersonBase.class; |
|
83 |
} |
|
84 |
|
|
85 |
/** |
|
86 |
* {@inheritDoc} |
|
87 |
*/ |
|
88 |
@Override |
|
89 |
protected void setInternalValue(TeamOrPersonBase<?> newValue) { |
|
90 |
|
|
91 |
super.setInternalValue(newValue); |
|
92 |
|
|
93 |
newValue = HibernateProxyHelper.deproxy(newValue); |
|
94 |
|
|
95 |
if(Person.class.isAssignableFrom(newValue.getClass())){ |
|
96 |
// value is a Person: |
|
97 |
compositeWrapper.addComponent(personField); |
|
98 |
|
|
99 |
personField.setValue((Person) newValue); |
|
100 |
} |
|
101 |
else if(Team.class.isAssignableFrom(newValue.getClass())){ |
|
102 |
// otherwise it a Team |
|
103 |
|
|
104 |
compositeWrapper.addComponents(titleField, nomenclaturalTitleField, personsListEditor); |
|
105 |
|
|
106 |
titleField.bindTo(fieldGroup, "titleCache", "protectedTitleCache"); |
|
107 |
nomenclaturalTitleField.bindTo(fieldGroup, "nomenclaturalTitle", "protectedNomenclaturalTitleCache"); |
|
108 |
fieldGroup.bind(personsListEditor, "teamMembers"); |
|
109 |
|
|
110 |
fieldGroup.setItemDataSource(new BeanItem<Team>((Team)newValue)); |
|
111 |
} else { |
|
112 |
setComponentError(new UserError("TeamOrPersonField Error: Unsupported value type: " + newValue.getClass().getName())); |
|
113 |
} |
|
114 |
} |
|
115 |
|
|
116 |
/** |
|
117 |
* {@inheritDoc} |
|
118 |
*/ |
|
119 |
@Override |
|
120 |
protected void addDefaultStyles() { |
|
121 |
// no default styles here |
|
122 |
|
|
123 |
} |
|
124 |
|
|
125 |
|
|
126 |
|
|
127 |
} |
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/TimePeriodField.java | ||
---|---|---|
225 | 225 |
protected void setInternalValue(TimePeriod newValue) { |
226 | 226 |
super.setInternalValue(newValue); |
227 | 227 |
fieldGroup.setItemDataSource(new BeanItem<TimePeriod>(newValue)); |
228 |
|
|
229 | 228 |
updateCacheField(); |
230 | 229 |
} |
231 | 230 |
|
src/main/java/eu/etaxonomy/cdm/vaadin/ui/RegistrationUI.java | ||
---|---|---|
144 | 144 |
Page page = Page.getCurrent(); |
145 | 145 |
String fragment = page.getUriFragment(); |
146 | 146 |
String state = null; |
147 |
if(fragment.startsWith("!")){ |
|
147 |
if(fragment != null && fragment.startsWith("!")){
|
|
148 | 148 |
state = fragment.substring(1, fragment.length()); |
149 | 149 |
} |
150 | 150 |
return state; |
src/main/java/eu/etaxonomy/cdm/vaadin/view/reference/ReferencePopupEditor.java | ||
---|---|---|
22 | 22 |
|
23 | 23 |
import eu.etaxonomy.cdm.model.reference.Reference; |
24 | 24 |
import eu.etaxonomy.cdm.model.reference.ReferenceType; |
25 |
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField; |
|
25 | 26 |
import eu.etaxonomy.cdm.vaadin.component.common.TimePeriodField; |
26 | 27 |
import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView; |
27 | 28 |
import eu.etaxonomy.vaadin.mvp.AbstractCdmPopupEditor; |
... | ... | |
42 | 43 |
|
43 | 44 |
private final static int GRID_COLS = 4; |
44 | 45 |
|
45 |
private final static int GRID_ROWS = 9;
|
|
46 |
private final static int GRID_ROWS = 10;
|
|
46 | 47 |
|
47 | 48 |
/** |
48 | 49 |
* @param layout |
... | ... | |
91 | 92 |
addSwitchableTextField("Abbrev. cache", "abbrevTitleCache", "protectedAbbrevTitleCache", 0, row, GRID_COLS-1, row).setWidth(100, Unit.PERCENTAGE); |
92 | 93 |
row++; |
93 | 94 |
titleField = addTextField("Title", "title", 0, row, GRID_COLS-1, row); |
94 |
titleField.setRequired(true); |
|
95 | 95 |
titleField.setWidth(100, Unit.PERCENTAGE); |
96 | 96 |
row++; |
97 | 97 |
addTextField("NomenclaturalTitle", "abbrevTitle", 0, row, GRID_COLS-1, row).setWidth(100, Unit.PERCENTAGE); |
98 | 98 |
row++; |
99 |
// addTextField("Author(s)", "authorship", 0, 4, 1, 4)).setRequired(true); |
|
100 |
addTextField("Editor", "editor", 2, row, 3, row).setWidth(100, Unit.PERCENTAGE); |
|
99 |
TeamOrPersonField authorshipField = new TeamOrPersonField("Author(s)"); |
|
100 |
authorshipField.setWidth(100, Unit.PERCENTAGE); |
|
101 |
addField(authorshipField, "authorship", 0, row, 3, row); |
|
101 | 102 |
row++; |
102 | 103 |
addTextField("Series", "seriesPart", 0, row); |
103 | 104 |
addTextField("Volume", "volume", 1, row); |
104 | 105 |
addTextField("Pages", "pages", 2, row); |
106 |
addTextField("Editor", "editor", 3, row).setWidth(100, Unit.PERCENTAGE); |
|
105 | 107 |
row++; |
106 | 108 |
addTextField("Place published", "placePublished", 0, row, 1, row).setWidth(100, Unit.PERCENTAGE); |
107 | 109 |
TextField publisherField = addTextField("Publisher", "publisher", 2, row, 3, row); |
108 |
publisherField.setRequired(true); |
|
109 | 110 |
publisherField.setWidth(100, Unit.PERCENTAGE); |
110 | 111 |
TimePeriodField timePeriodField = new TimePeriodField("Date published"); |
111 | 112 |
addField(timePeriodField, "datePublished"); |
112 | 113 |
row++; |
113 |
// TODO implement a TimePeriod component |
|
114 | 114 |
addTextField("ISSN", "issn", 0, row); |
115 | 115 |
addTextField("ISBN", "isbn", 1, row); |
116 | 116 |
addTextField("DOI", "doi", 2, row); |
117 | 117 |
addTextField("Uri", "uri", 3, row); |
118 | 118 |
|
119 |
// titleField.setRequired(true); |
|
120 |
// publisherField.setRequired(true); |
|
121 |
|
|
119 | 122 |
} |
120 | 123 |
|
121 | 124 |
/** |
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkflowPresenter.java | ||
---|---|---|
16 | 16 |
import org.springframework.beans.factory.annotation.Autowired; |
17 | 17 |
import org.springframework.beans.factory.annotation.Qualifier; |
18 | 18 |
import org.springframework.context.event.EventListener; |
19 |
import org.springframework.transaction.TransactionStatus; |
|
19 | 20 |
|
20 | 21 |
import com.vaadin.server.SystemError; |
21 | 22 |
import com.vaadin.spring.annotation.SpringComponent; |
... | ... | |
122 | 123 |
|
123 | 124 |
@EventListener(condition = "#event.type ==T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Type).EDIT") |
124 | 125 |
public void onReferenceEditEvent(ReferenceEditorAction event) { |
126 |
TransactionStatus tx = getRepo().startTransaction(false); |
|
125 | 127 |
Reference reference = getRepo().getReferenceService().find(event.getEntityId()); |
126 | 128 |
ReferencePopupEditor popup = getNavigationManager().showInPopup(ReferencePopupEditor.class); |
127 | 129 |
popup.showInEditor(reference); |
130 |
getRepo().commitTransaction(tx); |
|
128 | 131 |
} |
129 | 132 |
|
130 | 133 |
|
src/main/java/eu/etaxonomy/vaadin/component/CompositeCustomField.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.vaadin.component; |
|
10 |
|
|
11 |
import java.util.ArrayList; |
|
12 |
import java.util.Arrays; |
|
13 |
import java.util.List; |
|
14 |
|
|
15 |
import com.vaadin.ui.Component; |
|
16 |
import com.vaadin.ui.CustomField; |
|
17 |
|
|
18 |
/** |
|
19 |
* TODO implement height methods for full component size support |
|
20 |
* |
|
21 |
* @author a.kohlbecker |
|
22 |
* @since May 12, 2017 |
|
23 |
* |
|
24 |
*/ |
|
25 |
@SuppressWarnings("serial") |
|
26 |
public abstract class CompositeCustomField<T> extends CustomField<T> { |
|
27 |
|
|
28 |
private List<Component> styledComponents = new ArrayList<>(); |
|
29 |
|
|
30 |
private List<Component> sizedComponents = new ArrayList<>(); |
|
31 |
|
|
32 |
protected List<Component> getStyledComponents() { |
|
33 |
if(styledComponents == null){ |
|
34 |
styledComponents = new ArrayList<>(); |
|
35 |
} |
|
36 |
return styledComponents; |
|
37 |
} |
|
38 |
|
|
39 |
/** |
|
40 |
* Implementations preferably call this method in the constructor |
|
41 |
* |
|
42 |
* @param component |
|
43 |
* @return |
|
44 |
*/ |
|
45 |
protected boolean addStyledComponent(Component component){ |
|
46 |
applyCurrentStyleNames(component); |
|
47 |
return styledComponents.add(component); |
|
48 |
} |
|
49 |
|
|
50 |
/** |
|
51 |
* Implementations preferably call this method in the constructor |
|
52 |
* |
|
53 |
* @param component |
|
54 |
* @return |
|
55 |
*/ |
|
56 |
protected boolean addStyledComponents(Component ... component){ |
|
57 |
List<Component> componentList = Arrays.asList(component); |
|
58 |
componentList.forEach(c -> applyCurrentStyleNames(c)); |
|
59 |
return styledComponents.addAll(componentList); |
|
60 |
} |
|
61 |
|
|
62 |
protected List<Component> getSizedComponents() { |
|
63 |
if(sizedComponents == null){ |
|
64 |
sizedComponents = new ArrayList<>(); |
|
65 |
} |
|
66 |
return sizedComponents; |
|
67 |
} |
|
68 |
|
|
69 |
/** |
|
70 |
* Implementations preferably call this method in the constructor |
|
71 |
* |
|
72 |
* @param component |
|
73 |
* @return |
|
74 |
*/ |
|
75 |
protected boolean addSizedComponent(Component component){ |
|
76 |
applyCurrentSize(component); |
|
77 |
return sizedComponents.add(component); |
|
78 |
} |
|
79 |
|
|
80 |
/** |
|
81 |
* Implementations preferably call this method in the constructor |
|
82 |
* |
|
83 |
* @param component |
|
84 |
* @return |
|
85 |
*/ |
|
86 |
protected boolean addSizedComponents(Component ... component){ |
|
87 |
List<Component> componentList = Arrays.asList(component); |
|
88 |
componentList.forEach(c -> applyCurrentSize(c)); |
|
89 |
return sizedComponents.addAll(componentList); |
|
90 |
} |
|
91 |
|
|
92 |
@Override |
|
93 |
public void setWidth(String width) { |
|
94 |
super.setWidth(width); |
|
95 |
getSizedComponents().forEach(c -> {if(c != null) {c.setWidth(width);}}); |
|
96 |
} |
|
97 |
|
|
98 |
@Override |
|
99 |
public void setWidth(float width, Unit unit){ |
|
100 |
super.setWidth(width, unit); |
|
101 |
getSizedComponents().forEach(c -> {if(c != null) {c.setWidth(width, unit);}}); |
|
102 |
} |
|
103 |
|
|
104 |
@Override |
|
105 |
public void setWidthUndefined() { |
|
106 |
super.setWidthUndefined(); |
|
107 |
getSizedComponents().forEach(c -> {if(c != null) {c.setWidthUndefined();}}); |
|
108 |
} |
|
109 |
|
|
110 |
@Override |
|
111 |
public void setStyleName(String style) { |
|
112 |
super.setStyleName(style); |
|
113 |
getStyledComponents().forEach(c -> c.setStyleName(style)); |
|
114 |
addDefaultStyles(); |
|
115 |
} |
|
116 |
|
|
117 |
@Override |
|
118 |
public void addStyleName(String style) { |
|
119 |
super.addStyleName(style); |
|
120 |
getStyledComponents().forEach(c -> c.addStyleName(style)); |
|
121 |
} |
|
122 |
|
|
123 |
protected void applyCurrentStyleNames(Component newSubComponent){ |
|
124 |
newSubComponent.setStyleName(getStyleName()); |
|
125 |
} |
|
126 |
|
|
127 |
protected void applyCurrentSize(Component newSubComponent){ |
|
128 |
newSubComponent.setWidth(this.getWidth(), this.getWidthUnits()); |
|
129 |
} |
|
130 |
|
|
131 |
/** |
|
132 |
* Implementations can may apply default styles to components added to <code>StyledComponents</code> |
|
133 |
* to prevent these styles from being overwritten when setStyleName() id called on the composite field. |
|
134 |
*/ |
|
135 |
protected abstract void addDefaultStyles(); |
|
136 |
|
|
137 |
} |
src/main/java/eu/etaxonomy/vaadin/component/FieldListEditor.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.vaadin.component; |
|
10 |
|
|
11 |
import java.util.List; |
|
12 |
|
|
13 |
import com.vaadin.data.util.BeanItemContainer; |
|
14 |
import com.vaadin.server.FontAwesome; |
|
15 |
import com.vaadin.ui.AbstractField; |
|
16 |
import com.vaadin.ui.Button; |
|
17 |
import com.vaadin.ui.Component; |
|
18 |
import com.vaadin.ui.CssLayout; |
|
19 |
import com.vaadin.ui.GridLayout; |
|
20 |
import com.vaadin.ui.themes.ValoTheme; |
|
21 |
|
|
22 |
/** |
|
23 |
* @author a.kohlbecker |
|
24 |
* @since May 11, 2017 |
|
25 |
* |
|
26 |
*/ |
|
27 |
public class FieldListEditor<V extends Object, F extends AbstractField<V>> extends CompositeCustomField<List<V>> { |
|
28 |
|
|
29 |
private static final long serialVersionUID = 4670707714503199599L; |
|
30 |
|
|
31 |
private Class<F> fieldType; |
|
32 |
|
|
33 |
private Class<V> itemType; |
|
34 |
|
|
35 |
//NOTE: Managing the item |
|
36 |
// IDs makes BeanContainer more complex to use, but it is necessary in some cases where the |
|
37 |
// equals() or hashCode() methods have been reimplemented in the bean. |
|
38 |
// TODO CdmBase an a reimplemented equals method, do we need to use the BeanContainer instead? |
|
39 |
private BeanItemContainer<V> beans; |
|
40 |
|
|
41 |
//private LinkedList<V> itemList = new LinkedList<>(); |
|
42 |
|
|
43 |
private int GRID_COLS = 2; |
|
44 |
|
|
45 |
private GridLayout grid = new GridLayout(GRID_COLS,1); |
|
46 |
|
|
47 |
public FieldListEditor(Class<V> itemType, Class<F> fieldType, String caption){ |
|
48 |
this.fieldType = fieldType; |
|
49 |
this.itemType = itemType; |
|
50 |
setCaption(caption); |
|
51 |
beans = new BeanItemContainer<V>(itemType); |
|
52 |
} |
|
53 |
|
|
54 |
private Component buttonGroup(){ |
|
55 |
Button add = new Button(FontAwesome.PLUS); |
|
56 |
Button remove = new Button(FontAwesome.MINUS); |
|
57 |
Button moveUp = new Button(FontAwesome.ARROW_UP); |
|
58 |
Button moveDown = new Button(FontAwesome.ARROW_DOWN); |
|
59 |
CssLayout buttonGroup = new CssLayout(add, remove, moveUp, moveDown); |
|
60 |
buttonGroup.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); |
|
61 |
|
|
62 |
addStyledComponents(add, remove, moveUp, moveDown); |
|
63 |
|
|
64 |
return buttonGroup; |
|
65 |
} |
|
66 |
|
|
67 |
/** |
|
68 |
* {@inheritDoc} |
|
69 |
*/ |
|
70 |
@Override |
|
71 |
protected Component initContent() { |
|
72 |
grid.setColumnExpandRatio(0, 1.0f); |
|
73 |
return grid; |
|
74 |
} |
|
75 |
|
|
76 |
/** |
|
77 |
* {@inheritDoc} |
|
78 |
*/ |
|
79 |
@Override |
|
80 |
public Class getType() { |
|
81 |
return List.class; |
|
82 |
} |
|
83 |
|
|
84 |
/** |
|
85 |
* {@inheritDoc} |
|
86 |
*/ |
|
87 |
@Override |
|
88 |
protected void setInternalValue(List<V> newValue) { |
|
89 |
super.setInternalValue(newValue); |
|
90 |
|
|
91 |
beans.addAll(newValue); |
|
92 |
|
|
93 |
grid.setRows(newValue.size()); |
|
94 |
int row = 0; |
|
95 |
for(V val : newValue){ |
|
96 |
try { |
|
97 |
F field = fieldType.newInstance(); |
|
98 |
addStyledComponent(field); |
|
99 |
field.setWidth(100, Unit.PERCENTAGE); |
|
100 |
field.setValue(val); |
|
101 |
grid.addComponent(field, 0, row); |
|
102 |
grid.addComponent(buttonGroup(), 1, row); |
|
103 |
row++; |
|
104 |
} catch (InstantiationException e) { |
|
105 |
// TODO Auto-generated catch block |
|
106 |
e.printStackTrace(); |
|
107 |
} catch (IllegalAccessException e) { |
|
108 |
// TODO Auto-generated catch block |
|
109 |
e.printStackTrace(); |
|
110 |
} |
|
111 |
} |
|
112 |
} |
|
113 |
|
|
114 |
/** |
|
115 |
* {@inheritDoc} |
|
116 |
*/ |
|
117 |
@Override |
|
118 |
public void setWidth(String width) { |
|
119 |
super.setWidth(width); |
|
120 |
grid.setWidth(width); |
|
121 |
} |
|
122 |
|
|
123 |
@Override |
|
124 |
public void setWidth(float width, Unit unit){ |
|
125 |
super.setWidth(width, unit); |
|
126 |
if(grid != null){ |
|
127 |
grid.setWidth(width, unit); |
|
128 |
} |
|
129 |
} |
|
130 |
|
|
131 |
/** |
|
132 |
* {@inheritDoc} |
|
133 |
*/ |
|
134 |
@Override |
|
135 |
protected void addDefaultStyles() { |
|
136 |
// no default styles |
|
137 |
} |
|
138 |
|
|
139 |
|
|
140 |
|
|
141 |
|
|
142 |
|
|
143 |
|
|
144 |
|
|
145 |
|
|
146 |
} |
src/main/java/eu/etaxonomy/vaadin/component/SwitchButton.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.vaadin.component; |
|
10 |
|
|
11 |
import org.vaadin.teemu.switchui.Switch; |
|
12 |
|
|
13 |
/** |
|
14 |
* @author a.kohlbecker |
|
15 |
* @since May 11, 2017 |
|
16 |
* |
|
17 |
*/ |
|
18 |
public class SwitchButton extends Switch { |
|
19 |
|
|
20 |
private static final long serialVersionUID = 2557108593729214773L; |
|
21 |
|
|
22 |
private ValueChangeListener valueSetListener = null; |
|
23 |
|
|
24 |
/** |
|
25 |
* {@inheritDoc} |
|
26 |
*/ |
|
27 |
@Override |
|
28 |
protected void setInternalValue(Boolean newValue) { |
|
29 |
super.setInternalValue(newValue); |
|
30 |
if(valueSetListener != null){ |
|
31 |
valueSetListener.valueChange(new ValueChangeEvent(this)); |
|
32 |
} |
|
33 |
} |
|
34 |
|
|
35 |
public void setValueSetLister(ValueChangeListener valueSetListener){ |
|
36 |
this.valueSetListener = valueSetListener; |
|
37 |
} |
|
38 |
|
|
39 |
} |
src/main/java/eu/etaxonomy/vaadin/component/SwitchableTextField.java | ||
---|---|---|
13 | 13 |
import com.vaadin.data.fieldgroup.FieldGroup; |
14 | 14 |
import com.vaadin.ui.Component; |
15 | 15 |
import com.vaadin.ui.CssLayout; |
16 |
import com.vaadin.ui.CustomField; |
|
17 | 16 |
import com.vaadin.ui.TextField; |
18 | 17 |
|
19 | 18 |
|
... | ... | |
22 | 21 |
* @since May 11, 2017 |
23 | 22 |
* |
24 | 23 |
*/ |
25 |
public class SwitchableTextField extends CustomField<String> { |
|
24 |
public class SwitchableTextField extends CompositeCustomField<String> {
|
|
26 | 25 |
|
27 | 26 |
private static final long serialVersionUID = -4760153886584883137L; |
28 | 27 |
|
... | ... | |
40 | 39 |
textField.setCaption(caption); |
41 | 40 |
unlockSwitch.addValueChangeListener(e -> { |
42 | 41 |
textField.setEnabled(unlockSwitch.getValue()); |
42 |
textField.focus(); |
|
43 | 43 |
}); |
44 | 44 |
unlockSwitch.setValueSetLister(e -> { |
45 | 45 |
textField.setEnabled(unlockSwitch.getValue()); |
46 | 46 |
}); |
47 |
|
|
48 |
addSizedComponent(root); |
|
49 |
addSizedComponent(textField); |
|
50 |
|
|
51 |
addStyledComponent(textField); |
|
52 |
addStyledComponent(unlockSwitch); |
|
47 | 53 |
} |
48 | 54 |
|
49 | 55 |
/** |
... | ... | |
57 | 63 |
textField.setWidth(getWidth(), getWidthUnits()); |
58 | 64 |
root.addComponent(unlockSwitch); |
59 | 65 |
setPrimaryStyleName(PRIMARY_STYLE); |
66 |
|
|
60 | 67 |
return root; |
61 | 68 |
} |
62 | 69 |
|
... | ... | |
68 | 75 |
return String.class; |
69 | 76 |
} |
70 | 77 |
|
71 |
/** |
|
72 |
* @return the serialversionuid |
|
73 |
*/ |
|
74 |
public static long getSerialversionuid() { |
|
75 |
return serialVersionUID; |
|
76 |
} |
|
77 |
|
|
78 | 78 |
/** |
79 | 79 |
* @return the textField |
80 | 80 |
*/ |
... | ... | |
99 | 99 |
* {@inheritDoc} |
100 | 100 |
*/ |
101 | 101 |
@Override |
102 |
public void setWidthUndefined() { |
|
103 |
super.setWidthUndefined(); |
|
104 |
root.setWidthUndefined(); |
|
105 |
textField.setWidthUndefined(); |
|
106 |
} |
|
102 |
protected void addDefaultStyles() { |
|
103 |
// no default styles |
|
107 | 104 |
|
108 |
/** |
|
109 |
* {@inheritDoc} |
|
110 |
*/ |
|
111 |
@Override |
|
112 |
public void setWidth(String width) { |
|
113 |
super.setWidth(width); |
|
114 |
root.setWidth(width); |
|
115 |
textField.setWidth(width); |
|
116 |
} |
|
117 |
|
|
118 |
@Override |
|
119 |
public void setWidth(float width, Unit unit){ |
|
120 |
super.setWidth(width, unit); |
|
121 |
if(root != null){ |
|
122 |
root.setWidth(width, unit); |
|
123 |
textField.setWidth(width, unit); |
|
124 |
} |
|
125 | 105 |
} |
126 | 106 |
|
127 |
@Override |
|
128 |
public void setStyleName(String style) { |
|
129 |
super.setStyleName(style); |
|
130 |
textField.setStyleName(style); |
|
131 |
unlockSwitch.setStyleName(style); |
|
132 |
} |
|
133 |
|
|
134 |
@Override |
|
135 |
public void addStyleName(String style) { |
|
136 |
super.addStyleName(style); |
|
137 |
textField.addStyleName(style); |
|
138 |
unlockSwitch.addStyleName(style); |
|
139 |
} |
|
140 |
|
|
141 |
private class SwitchButton extends Switch { |
|
142 |
|
|
143 |
private static final long serialVersionUID = 2557108593729214773L; |
|
144 |
|
|
145 |
private ValueChangeListener valueSetListener = null; |
|
146 |
|
|
147 |
/** |
|
148 |
* {@inheritDoc} |
|
149 |
*/ |
|
150 |
@Override |
|
151 |
protected void setInternalValue(Boolean newValue) { |
|
152 |
super.setInternalValue(newValue); |
|
153 |
if(valueSetListener != null){ |
|
154 |
valueSetListener.valueChange(new ValueChangeEvent(this)); |
|
155 |
} |
|
156 |
} |
|
157 |
|
|
158 |
public void setValueSetLister(ValueChangeListener valueSetListener){ |
|
159 |
this.valueSetListener = valueSetListener; |
|
160 |
} |
|
161 |
|
|
162 |
|
|
163 |
|
|
164 |
} |
|
165 | 107 |
} |
src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPopupEditor.java | ||
---|---|---|
75 | 75 |
mainLayout.setWidthUndefined(); |
76 | 76 |
|
77 | 77 |
fieldGroup = new BeanFieldGroup<>(dtoType); |
78 |
fieldGroup.setBuffered(false); |
|
78 | 79 |
fieldGroup.addCommitHandler(new SaveHandler()); |
79 | 80 |
|
80 | 81 |
setCompositionRoot(mainLayout); |
... | ... | |
290 | 291 |
protected <T extends Field> T addField(T field, String propertyId, int column1, int row1, |
291 | 292 |
int column2, int row2) |
292 | 293 |
throws OverlapsException, OutOfBoundsException { |
293 |
fieldGroup.bind(field, propertyId); |
|
294 |
if(propertyId != null){ |
|
295 |
fieldGroup.bind(field, propertyId); |
|
296 |
} |
|
294 | 297 |
addComponent(field, column1, row1, column2, row2); |
295 | 298 |
return field; |
296 | 299 |
} |
src/main/java/eu/etaxonomy/vaadin/ui/DevDayWidgetset.gwt.xml | ||
---|---|---|
17 | 17 |
|
18 | 18 |
<inherits name="org.vaadin.teemu.switchui.SwitchComponentWidgetset" /> |
19 | 19 |
|
20 |
<inherits name="com.vaadin.addon.onoffswitch.WidgetSet" /> |
|
20 |
|
|
21 | 21 |
</module> |
src/main/webapp/VAADIN/themes/edit-valo/custom-fields.scss | ||
---|---|---|
1 | 1 |
// styles for custom fields |
2 | 2 |
|
3 |
// ===================== Mixins ==============================// |
|
4 |
|
|
5 |
@mixin composite-field-wrapper() { |
|
6 |
border: valo-border($border: $v-border, $color: $v-background-color, $strength: 0.7); |
|
7 |
border-radius: $v-border-radius; |
|
8 |
background-color: $v-app-background-color; |
|
9 |
padding: round($v-unit-size / 4); |
|
10 |
} |
|
11 |
|
|
12 |
// ===================== Styles ==============================// |
|
13 |
|
|
3 | 14 |
body .edit-valo { // increasing specifity to allow overriding the valo default field themes |
4 | 15 |
|
5 | 16 |
// TimePeriodField |
6 | 17 |
.v-time-period-field { |
7 | 18 |
.margin-wrapper { |
8 |
border: valo-border($border: $v-border, $color: $v-background-color, $strength: 0.7); |
|
9 |
border-radius: $v-border-radius; |
|
10 |
background-color: $v-app-background-color; |
|
11 |
padding: round($v-unit-size / 4); |
|
19 |
@include composite-field-wrapper; |
|
12 | 20 |
} |
13 | 21 |
.to-label { |
14 | 22 |
padding: 0 round($v-unit-size / 2); |
... | ... | |
28 | 36 |
|
29 | 37 |
// v-switchable-textfield |
30 | 38 |
.v-switchable-textfield { |
39 |
position: relative; // needs to be a positioned element |
|
31 | 40 |
height: $v-line-height * 2; |
32 | 41 |
.v-caption { |
33 | 42 |
display: block; |
... | ... | |
43 | 52 |
bottom: 1px; |
44 | 53 |
} |
45 | 54 |
} |
55 |
|
|
56 |
// v-person-field |
|
57 |
.v-person-field { |
|
58 |
.v-caption { |
|
59 |
display: block; |
|
60 |
} |
|
61 |
.cache-field, .details-fields { |
|
62 |
padding-right: $v-unit-size; |
|
63 |
} |
|
64 |
.v-switch { |
|
65 |
z-index: 10; |
|
66 |
width: $v-unit-size; |
|
67 |
position: absolute; |
|
68 |
right: 1px; |
|
69 |
bottom: 1px; |
|
70 |
} |
|
71 |
} |
|
72 |
.v-person-field-cache-mode { |
|
73 |
.cache-field { |
|
74 |
display: block; |
|
75 |
} |
|
76 |
.details-fields { |
|
77 |
display: none; |
|
78 |
} |
|
79 |
} |
|
80 |
.v-person-field-details-mode { |
|
81 |
.cache-field { |
|
82 |
display: none; |
|
83 |
} |
|
84 |
.details-fields { |
|
85 |
display: block; |
|
86 |
} |
|
87 |
} |
|
88 |
|
|
89 |
// team-or-person-field |
|
90 |
.v-team-or-person-field { |
|
91 |
.margin-wrapper { |
|
92 |
@include composite-field-wrapper; |
|
93 |
} |
|
94 |
} |
|
46 | 95 |
} |
Also available in: Unified diff
ref #6612 Team and Person editor widgets implemented and integrated in reference editor