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.data.Item;
46 import com.vaadin.data.fieldgroup.FieldGroup;
47 import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
48 import com.vaadin.data.util.ObjectProperty;
49 import com.vaadin.event.FieldEvents;
50 import com.vaadin.event.LayoutEvents.LayoutClickEvent;
51 import com.vaadin.event.LayoutEvents.LayoutClickListener;
52 import com.vaadin.event.ShortcutAction.KeyCode;
53 import com.vaadin.event.ShortcutListener;
54 import com.vaadin.ui.AbstractSelect;
55 import com.vaadin.ui.Button;
56 import com.vaadin.ui.Button.ClickEvent;
57 import com.vaadin.ui.Button.ClickListener;
58 import com.vaadin.ui.ComboBox;
59 import com.vaadin.ui.CssLayout;
60 import com.vaadin.ui.CustomComponent;
61 import com.vaadin.ui.FormLayout;
62 import com.vaadin.ui.Label;
63 import com.vaadin.ui.TabSheet;
64 import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
65 import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
66 import com.vaadin.ui.TextField;
67 import com.vaadin.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.setImmediate(false);
275 group.setNewItemHandler(new AbstractSelect.NewItemHandler() {
276 @Override
277 public void addNewItem(String newItemCaption) {
278 String newGroupId = Path.getValidatedLabel(newItemCaption);
279 group.addItem(newGroupId);
280 group.setItemCaption(newGroupId, newItemCaption);
281 group.setValue(newGroupId);
282 }
283 });
284
285
286
287 group.addBlurListener(new FieldEvents.BlurListener() {
288 @Override
289 public void blur(FieldEvents.BlurEvent event) {
290 String value = (String) group.getValue();
291 group.setValue(value);
292 }
293 });
294
295 group.setDescription(i18n.translate("favorites.form.groups"));
296 layout.addComponent(group);
297
298
299 form = new FieldGroup();
300 form.bind(title, "title");
301 form.bind(url, "url");
302 form.bind(group, "group");
303
304 final CssLayout buttons = new CssLayout();
305 buttons.addStyleName("buttons");
306
307 final Button addButton = new Button(i18n.translate("favorites.button.add"), new ClickListener() {
308
309 @Override
310 public void buttonClick(ClickEvent event) {
311 addFavorite();
312 }
313 });
314 addButton.addStyleName("commit");
315 buttons.addComponent(addButton);
316 layout.addComponent(buttons);
317
318 this.enterShortcutListener = new ShortcutListener("", KeyCode.ENTER, null) {
319
320 @Override
321 public void handleAction(Object sender, Object target) {
322 addFavorite();
323 }
324 };
325
326 setCompositionRoot(layout);
327 }
328
329 void setDataSource(Item newFavorite) {
330 form.setItemDataSource(newFavorite);
331 }
332
333 void setAvailableGroups(Map<String, String> availableGroups) {
334 group.removeAllItems();
335 for (Entry<String, String> entry : availableGroups.entrySet()) {
336 String id = entry.getKey();
337 group.addItem(id);
338 group.setItemCaption(id, entry.getValue());
339 }
340 this.availableGroups = availableGroups;
341 }
342
343 public void addEnterKeyShortcutListener() {
344 addShortcutListener(enterShortcutListener);
345 title.focus();
346 }
347
348 public void removeEnterKeyShortcutListener() {
349 removeShortcutListener(enterShortcutListener);
350 }
351
352 private void addFavorite() {
353 try {
354 JcrNewNodeAdapter newFavorite = (JcrNewNodeAdapter) form.getItemDataSource();
355 form.commit();
356
357
358 if (group == null || group.getValue() == null || !selectedGroupIsNew()) {
359 listener.addFavorite(newFavorite);
360 } else {
361 JcrNewNodeAdapter newGroup = ((FavoritesPresenter) listener).createNewGroupSuggestion();
362 String newGroupId = (String) group.getValue();
363 String newGroupLabel = group.getItemCaption(newGroupId);
364
365 newGroup.addItemProperty("group", new ObjectProperty<String>(newGroupId));
366 newGroup.addItemProperty("title", new ObjectProperty<String>(newGroupLabel));
367 listener.addFavoriteAndGroup(newFavorite, newGroup);
368 }
369 close();
370 } catch (CommitException e) {
371 shell.openNotification(MessageStyleTypeEnum.ERROR, true, i18n.translate("favorites.fields.required"));
372 }
373 }
374
375 private boolean selectedGroupIsNew() {
376 if (availableGroups == null || availableGroups.size() == 0) {
377 return true;
378 } else {
379 Object value = group.getValue();
380 if (value != null && availableGroups != null && availableGroups.size() > 0) {
381 return !availableGroups.containsKey(value);
382 }
383 }
384 return false;
385 }
386
387 }
388
389
390
391
392 private class InternalFavoriteGroupForm extends CustomComponent {
393
394 private TextField title = new TextField(i18n.translate("favorites.form.title"));
395
396 private ShortcutListener enterShortcutListener;
397 private final FieldGroup form;
398
399 public InternalFavoriteGroupForm() {
400 addStyleName("favorites-form-content");
401 FormLayout layout = new FormLayout();
402
403 title.setRequired(true);
404 title.setDescription(i18n.translate("favorites.form.title"));
405 title.addStyleName("group-title");
406 layout.addComponent(title);
407
408
409 form = new FieldGroup();
410 form.bind(title, "title");
411
412 final CssLayout buttons = new CssLayout();
413 buttons.addStyleName("buttons");
414
415 final Button addButton = new Button(i18n.translate("favorites.button.add"), new ClickListener() {
416
417 @Override
418 public void buttonClick(ClickEvent event) {
419 addGroup();
420 }
421 });
422 addButton.addStyleName("v-button-commit");
423 buttons.addComponent(addButton);
424 layout.addComponent(buttons);
425
426 this.enterShortcutListener = new ShortcutListener("", KeyCode.ENTER, null) {
427
428 @Override
429 public void handleAction(Object sender, Object target) {
430 addGroup();
431 }
432 };
433
434 setCompositionRoot(layout);
435 }
436
437 void setDataSource(Item newGroup) {
438 form.setItemDataSource(newGroup);
439 }
440
441 public void addEnterKeyShortcutListener() {
442 addShortcutListener(enterShortcutListener);
443 title.focus();
444 }
445
446 public void removeEnterKeyShortcutListener() {
447 removeShortcutListener(enterShortcutListener);
448 }
449
450 private void addGroup() {
451 try {
452 JcrNewNodeAdapter newGroup = (JcrNewNodeAdapter) form.getItemDataSource();
453 form.commit();
454 listener.addGroup(newGroup);
455 close();
456 } catch (CommitException e) {
457 shell.openNotification(MessageStyleTypeEnum.ERROR, true, i18n.translate("favorites.fields.required"));
458 }
459 }
460 }
461 }