1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.admincentral.shellapp.favorites;
35
36 import info.magnolia.cms.core.Path;
37 import info.magnolia.i18nsystem.SimpleTranslator;
38 import info.magnolia.ui.api.shell.Shell;
39 import info.magnolia.ui.vaadin.integration.jcr.JcrNewNodeAdapter;
40 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
41
42 import java.util.Map;
43 import java.util.Map.Entry;
44
45 import com.vaadin.event.FieldEvents;
46 import com.vaadin.event.LayoutEvents.LayoutClickEvent;
47 import com.vaadin.event.LayoutEvents.LayoutClickListener;
48 import com.vaadin.event.ShortcutAction.KeyCode;
49 import com.vaadin.event.ShortcutListener;
50 import com.vaadin.ui.Button;
51 import com.vaadin.ui.Button.ClickEvent;
52 import com.vaadin.ui.Button.ClickListener;
53 import com.vaadin.ui.CssLayout;
54 import com.vaadin.ui.CustomComponent;
55 import com.vaadin.ui.FormLayout;
56 import com.vaadin.ui.TabSheet;
57 import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
58 import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
59 import com.vaadin.v7.data.Item;
60 import com.vaadin.v7.data.fieldgroup.FieldGroup;
61 import com.vaadin.v7.data.fieldgroup.FieldGroup.CommitException;
62 import com.vaadin.v7.data.util.ObjectProperty;
63 import com.vaadin.v7.ui.AbstractSelect;
64 import com.vaadin.v7.ui.ComboBox;
65 import com.vaadin.v7.ui.Label;
66 import com.vaadin.v7.ui.TextField;
67 import com.vaadin.v7.ui.VerticalLayout;
68
69
70
71
72 public final class FavoritesForm extends CustomComponent {
73
74 private static final String EDIT_ACTION_STYLENAME = "favItemEdit";
75
76 private FavoritesView.Listener listener;
77 private Shell shell;
78 private TabSheet tabsheet;
79 private Label arrowIcon;
80 private InternalFavoriteEntryForm favoriteEntryForm;
81 private InternalFavoriteGroupForm favoriteGroupForm;
82 private final SimpleTranslator i18n;
83
84 private Label editIcon;
85 private Label editLabel;
86
87 public FavoritesForm(FavoritesView.Listener listener, Shell shell, SimpleTranslator i18n) {
88 this.listener = listener;
89 this.shell = shell;
90 this.i18n = i18n;
91 init();
92 }
93
94
95
96
97
98
99
100
101 @Deprecated
102 public FavoritesForm(final JcrNewNodeAdapter newFavorite, final JcrNewNodeAdapter newGroup, final Map<String, String> availableGroups,
103 final FavoritesView.Listener listener, final Shell shell, final SimpleTranslator i18n) {
104 this(listener, shell, i18n);
105 }
106
107 private void init() {
108 addStyleName("favorites-form");
109 final VerticalLayout favoriteForm = new VerticalLayout();
110 favoriteEntryForm = new InternalFavoriteEntryForm();
111 favoriteGroupForm = new InternalFavoriteGroupForm();
112
113 tabsheet = new TabSheet();
114 tabsheet.addStyleName("favorites-tabs");
115 tabsheet.addTab(favoriteEntryForm, i18n.translate("favorites.form.favorite.add"));
116 tabsheet.addTab(favoriteGroupForm, i18n.translate("favorites.form.group.add"));
117
118 tabsheet.addSelectedTabChangeListener(new SelectedTabChangeListener() {
119
120 @Override
121 public void selectedTabChange(SelectedTabChangeEvent event) {
122 if (event.getTabSheet().getSelectedTab() instanceof InternalFavoriteEntryForm) {
123 favoriteGroupForm.removeEnterKeyShortcutListener();
124 favoriteEntryForm.addEnterKeyShortcutListener();
125 } else {
126 favoriteEntryForm.removeEnterKeyShortcutListener();
127 favoriteGroupForm.addEnterKeyShortcutListener();
128 }
129 }
130 });
131
132 final CssLayout header = new CssLayout();
133 header.addStyleName("dialog-header");
134 header.setSizeFull();
135 header.addLayoutClickListener(new LayoutClickListener() {
136 @Override
137 public void layoutClick(LayoutClickEvent event) {
138
139 if (event.getClickedComponent() == editIcon || event.getChildComponent() == editLabel) {
140 if (!listener.hasItems() || listener.itemsAreEditable()) {
141 listener.setToInitialState();
142 } else {
143 listener.setItemsEditable(true);
144 }
145 } else {
146
147 if (isOpen()) {
148 close();
149 } else {
150 open();
151 }
152 }
153 }
154 });
155
156
157 final Label addNewIcon = new Label();
158 addNewIcon.setSizeUndefined();
159 addNewIcon.addStyleName("icon");
160 addNewIcon.addStyleName("icon-add-fav");
161 final Label addNewLabel = new Label(i18n.translate("favorites.form.add"));
162 addNewLabel.setSizeUndefined();
163 addNewLabel.addStyleName("title");
164
165
166 editIcon = new Label();
167 editIcon.setSizeUndefined();
168 editIcon.addStyleName(EDIT_ACTION_STYLENAME);
169 editIcon.addStyleName("icon");
170 editIcon.addStyleName("icon-edit");
171
172 editLabel = new Label(i18n.translate("favorites.form.favorite.edit"));
173 editLabel.setSizeUndefined();
174 editLabel.addStyleName("title");
175 editLabel.addStyleName(EDIT_ACTION_STYLENAME);
176
177
178 arrowIcon = new Label();
179 arrowIcon.setSizeUndefined();
180 arrowIcon.addStyleName("icon");
181 arrowIcon.addStyleName("arrow");
182 arrowIcon.addStyleName("icon-arrow2_n");
183
184
185 header.addComponent(addNewIcon);
186 header.addComponent(addNewLabel);
187 header.addComponent(editIcon);
188 header.addComponent(editLabel);
189 header.addComponent(arrowIcon);
190 favoriteForm.addComponent(header);
191 favoriteForm.addComponent(tabsheet);
192
193
194 close();
195 setCompositionRoot(favoriteForm);
196 }
197
198 public void setNewFavorite(Item newFavorite) {
199 favoriteEntryForm.setDataSource(newFavorite);
200 }
201
202 public void setNewGroup(Item newGroup) {
203 favoriteGroupForm.setDataSource(newGroup);
204 }
205
206 public void setAvailableGroups(Map<String, String> availableGroups) {
207 favoriteEntryForm.setAvailableGroups(availableGroups);
208 }
209
210 public void setEditActionEnabled(boolean enabled) {
211 if (!enabled) {
212 editIcon.addStyleName("disabled");
213 editLabel.addStyleName("disabled");
214 } else {
215 editIcon.removeStyleName("disabled");
216 editLabel.removeStyleName("disabled");
217 }
218 }
219
220 public void close() {
221 tabsheet.setVisible(false);
222
223 if (tabsheet.getSelectedTab() != favoriteEntryForm) {
224 tabsheet.setSelectedTab(favoriteEntryForm);
225 }
226 arrowIcon.removeStyleName("icon-arrow2_s");
227 arrowIcon.addStyleName("icon-arrow2_n");
228
229 favoriteEntryForm.removeEnterKeyShortcutListener();
230 favoriteGroupForm.removeEnterKeyShortcutListener();
231 }
232
233 public void open() {
234 tabsheet.setVisible(true);
235 arrowIcon.removeStyleName("icon-arrow2_n");
236 arrowIcon.addStyleName("icon-arrow2_s");
237 favoriteEntryForm.addEnterKeyShortcutListener();
238
239 }
240
241 public boolean isOpen() {
242 return tabsheet.isVisible();
243 }
244
245
246
247
248 private class InternalFavoriteEntryForm extends CustomComponent {
249
250 private TextField url = new TextField(i18n.translate("favorites.form.location"));
251 private TextField title = new TextField(i18n.translate("favorites.form.title"));
252 private ComboBox group;
253
254 private ShortcutListener enterShortcutListener;
255
256 private final FieldGroup form;
257
258 private Map<String, String> availableGroups;
259
260 public InternalFavoriteEntryForm() {
261 addStyleName("favorites-form-content");
262 FormLayout layout = new FormLayout();
263
264 title.setRequired(true);
265 title.setDescription(i18n.translate("favorites.form.title"));
266
267 url.setRequired(true);
268 url.setDescription(i18n.translate("favorites.form.location"));
269 layout.addComponent(title);
270 layout.addComponent(url);
271
272 group = new ComboBox(i18n.translate("favorites.form.groups"));
273 group.setNewItemsAllowed(true);
274 group.setNewItemHandler(new AbstractSelect.NewItemHandler() {
275 @Override
276 public void addNewItem(String newItemCaption) {
277 String newGroupId = Path.getValidatedLabel(newItemCaption);
278 group.addItem(newGroupId);
279 group.setItemCaption(newGroupId, newItemCaption);
280 group.setValue(newGroupId);
281 }
282 });
283
284
285
286 group.addBlurListener((FieldEvents.BlurListener) event -> {
287 String value = (String) group.getValue();
288 group.setValue(value);
289 });
290
291 group.setDescription(i18n.translate("favorites.form.groups"));
292 layout.addComponent(group);
293
294
295 form = new FieldGroup();
296 form.bind(title, "title");
297 form.bind(url, "url");
298 form.bind(group, "group");
299
300 final CssLayout buttons = new CssLayout();
301 buttons.addStyleName("buttons");
302
303 final Button addButton = new Button(i18n.translate("favorites.button.add"), new ClickListener() {
304
305 @Override
306 public void buttonClick(ClickEvent event) {
307 addFavorite();
308 }
309 });
310 addButton.addStyleName("commit");
311 buttons.addComponent(addButton);
312 layout.addComponent(buttons);
313
314 this.enterShortcutListener = new ShortcutListener("", KeyCode.ENTER, null) {
315
316 @Override
317 public void handleAction(Object sender, Object target) {
318 addFavorite();
319 }
320 };
321
322 setCompositionRoot(layout);
323 }
324
325 void setDataSource(Item newFavorite) {
326 form.setItemDataSource(newFavorite);
327 }
328
329 void setAvailableGroups(Map<String, String> availableGroups) {
330 group.removeAllItems();
331 for (Entry<String, String> entry : availableGroups.entrySet()) {
332 String id = entry.getKey();
333 group.addItem(id);
334 group.setItemCaption(id, entry.getValue());
335 }
336 this.availableGroups = availableGroups;
337 }
338
339 public void addEnterKeyShortcutListener() {
340 addShortcutListener(enterShortcutListener);
341 title.focus();
342 }
343
344 public void removeEnterKeyShortcutListener() {
345 removeShortcutListener(enterShortcutListener);
346 }
347
348 private void addFavorite() {
349 try {
350 JcrNewNodeAdapter newFavorite = (JcrNewNodeAdapter) form.getItemDataSource();
351 form.commit();
352
353
354 if (group == null || group.getValue() == null || !selectedGroupIsNew()) {
355 listener.addFavorite(newFavorite);
356 } else {
357 JcrNewNodeAdapter newGroup = ((FavoritesPresenter) listener).createNewGroupSuggestion();
358 String newGroupId = (String) group.getValue();
359 String newGroupLabel = group.getItemCaption(newGroupId);
360
361 newGroup.addItemProperty("group", new ObjectProperty<String>(newGroupId));
362 newGroup.addItemProperty("title", new ObjectProperty<String>(newGroupLabel));
363 listener.addFavoriteAndGroup(newFavorite, newGroup);
364 }
365 close();
366 } catch (CommitException e) {
367 shell.openNotification(MessageStyleTypeEnum.ERROR, true, i18n.translate("favorites.fields.required"));
368 }
369 }
370
371 private boolean selectedGroupIsNew() {
372 if (availableGroups == null || availableGroups.size() == 0) {
373 return true;
374 } else {
375 Object value = group.getValue();
376 if (value != null && availableGroups != null && availableGroups.size() > 0) {
377 return !availableGroups.containsKey(value);
378 }
379 }
380 return false;
381 }
382
383 }
384
385
386
387
388 private class InternalFavoriteGroupForm extends CustomComponent {
389
390 private TextField title = new TextField(i18n.translate("favorites.form.title"));
391
392 private ShortcutListener enterShortcutListener;
393 private final FieldGroup form;
394
395 public InternalFavoriteGroupForm() {
396 addStyleName("favorites-form-content");
397 FormLayout layout = new FormLayout();
398
399 title.setRequired(true);
400 title.setDescription(i18n.translate("favorites.form.title"));
401 title.addStyleName("group-title");
402 layout.addComponent(title);
403
404
405 form = new FieldGroup();
406 form.bind(title, "title");
407
408 final CssLayout buttons = new CssLayout();
409 buttons.addStyleName("buttons");
410
411 final Button addButton = new Button(i18n.translate("favorites.button.add"), new ClickListener() {
412
413 @Override
414 public void buttonClick(ClickEvent event) {
415 addGroup();
416 }
417 });
418 addButton.addStyleName("v-button-commit");
419 buttons.addComponent(addButton);
420 layout.addComponent(buttons);
421
422 this.enterShortcutListener = new ShortcutListener("", KeyCode.ENTER, null) {
423
424 @Override
425 public void handleAction(Object sender, Object target) {
426 addGroup();
427 }
428 };
429
430 setCompositionRoot(layout);
431 }
432
433 void setDataSource(Item newGroup) {
434 form.setItemDataSource(newGroup);
435 }
436
437 public void addEnterKeyShortcutListener() {
438 addShortcutListener(enterShortcutListener);
439 title.focus();
440 }
441
442 public void removeEnterKeyShortcutListener() {
443 removeShortcutListener(enterShortcutListener);
444 }
445
446 private void addGroup() {
447 try {
448 JcrNewNodeAdapter newGroup = (JcrNewNodeAdapter) form.getItemDataSource();
449 form.commit();
450 listener.addGroup(newGroup);
451 close();
452 } catch (CommitException e) {
453 shell.openNotification(MessageStyleTypeEnum.ERROR, true, i18n.translate("favorites.fields.required"));
454 }
455 }
456 }
457 }