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.i18nsystem.SimpleTranslator;
37 import info.magnolia.ui.api.overlay.ConfirmationCallback;
38 import info.magnolia.ui.api.shell.Shell;
39 import info.magnolia.ui.framework.AdmincentralNodeTypes;
40 import info.magnolia.ui.vaadin.integration.jcr.AbstractJcrNodeAdapter;
41 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
42
43 import java.util.List;
44 import java.util.Map;
45
46 import org.apache.commons.lang3.StringUtils;
47
48 import com.vaadin.event.FieldEvents.BlurEvent;
49 import com.vaadin.event.FieldEvents.BlurListener;
50 import com.vaadin.event.FieldEvents.FocusEvent;
51 import com.vaadin.event.FieldEvents.FocusListener;
52 import com.vaadin.event.ShortcutListener;
53 import com.vaadin.ui.Button.ClickEvent;
54 import com.vaadin.ui.Button.ClickListener;
55 import com.vaadin.ui.CssLayout;
56 import com.vaadin.ui.DragAndDropWrapper;
57 import com.vaadin.ui.NativeButton;
58 import com.vaadin.v7.ui.TextField;
59
60
61
62
63 public final class FavoritesGroup extends CssLayout implements EditableFavoriteItem, EditingEvent.EditingNotifier {
64
65 private TextField titleField;
66 private NativeButton editButton;
67 private NativeButton removeButton;
68 private String title;
69 private String relPath;
70 private boolean editable;
71 private CssLayout wrapper;
72 private EnterKeyShortcutListener enterKeyShortcutListener;
73 private EscapeKeyShortcutListener escapeKeyShortcutListener;
74 private Shell shell;
75 private final SimpleTranslator i18n;
76 private List<EditableFavoriteItem> editableFavoriteItems;
77 private FavoritesView.Listener listener;
78 private String itemId;
79 private GroupDragAndDropWrapper dragAndDropWrapper;
80
81
82
83
84 public FavoritesGroup(SimpleTranslator i18n) {
85 this.i18n = i18n;
86 addStyleName("no-group");
87 }
88
89 public FavoritesGroup(final AbstractJcrNodeAdapter favoritesGroup, final FavoritesView.Listener listener, final Shell shell, final FavoritesView view, final SimpleTranslator i18n, List<EditableFavoriteItem> editableFavoriteItems) {
90 this.shell = shell;
91 this.i18n = i18n;
92 this.editableFavoriteItems = editableFavoriteItems;
93 this.listener = listener;
94 itemId = FavoritesEntry.createItemId(favoritesGroup);
95
96 addStyleName("favorites-group");
97 construct(favoritesGroup, listener);
98
99 final Map<String, AbstractJcrNodeAdapter> nodeAdapters = favoritesGroup.getChildren();
100
101 for (String key : nodeAdapters.keySet()) {
102 final AbstractJcrNodeAdapter fav = nodeAdapters.get(key);
103 final FavoritesEntryellapp/favorites/FavoritesEntry.html#FavoritesEntry">FavoritesEntry favEntry = new FavoritesEntry(fav, listener, shell, i18n);
104 favEntry.setGroup(this.relPath);
105 editableFavoriteItems.add(favEntry);
106 final EntryDragAndDropWrapperavorites/EntryDragAndDropWrapper.html#EntryDragAndDropWrapper">EntryDragAndDropWrapper wrapper = new EntryDragAndDropWrapper(favEntry, listener);
107 favEntry.addEditingListener(new EditingEvent.EditingListener() {
108 @Override
109 public void onEdit(EditingEvent event) {
110 if (event.isEditing()) {
111 wrapper.setDragStartMode(DragAndDropWrapper.DragStartMode.NONE);
112 } else {
113 wrapper.setDragStartMode(DragAndDropWrapper.DragStartMode.WRAPPER);
114 }
115 }
116 });
117 addComponent(wrapper);
118 }
119 }
120
121 public String getRelPath() {
122 return this.relPath;
123 }
124
125 @Override
126 public String getItemId() {
127 return itemId;
128 }
129
130 @Override
131 public void setToNonEditableState() {
132 setEditable(false);
133 }
134
135 private void setEditable(boolean editable) {
136 this.editable = editable;
137 String icon = "icon-tick";
138 if (editable) {
139 listener.setCurrentEditedItemId(getItemId());
140 titleField.addStyleName("editable");
141 titleField.focus();
142 titleField.selectAll();
143 } else {
144 icon = "icon-edit";
145
146 titleField.setValue(title);
147 titleField.removeStyleName("editable");
148 }
149 titleField.setReadOnly(!editable);
150 editButton.setCaption("<span class=\"" + icon + "\"></span>");
151 fireEvent(new EditingEvent(this, editable));
152 }
153
154 @Override
155 public void setIconsVisibility(boolean visible) {
156 editButton.setVisible(visible);
157 removeButton.setVisible(visible);
158 }
159
160 @Override
161 public boolean iconsAreVisible() {
162 return editButton.isVisible();
163 }
164
165 private void construct(final AbstractJcrNodeAdapter favoritesGroup, final FavoritesView.Listener listener) {
166 wrapper = new CssLayout();
167 wrapper.addStyleName("favorites-group-title");
168
169 this.enterKeyShortcutListener = new EnterKeyShortcutListener(listener);
170 this.escapeKeyShortcutListener = new EscapeKeyShortcutListener();
171
172 this.relPath = favoritesGroup.getNodeName();
173 this.title = favoritesGroup.getItemProperty(AdmincentralNodeTypes.Favorite.TITLE).getValue().toString();
174
175 titleField = new TextField();
176 titleField.setValue(title);
177 titleField.setReadOnly(true);
178 titleField.addFocusListener(new FocusListener() {
179
180 @Override
181 public void focus(FocusEvent event) {
182 titleField.addShortcutListener(enterKeyShortcutListener);
183 titleField.addShortcutListener(escapeKeyShortcutListener);
184 }
185 });
186
187 titleField.addBlurListener(new BlurListener() {
188
189 @Override
190 public void blur(BlurEvent event) {
191 titleField.removeShortcutListener(enterKeyShortcutListener);
192 titleField.removeShortcutListener(escapeKeyShortcutListener);
193 }
194 });
195
196 wrapper.addComponent(titleField);
197
198 editButton = new NativeButton();
199 editButton.setHtmlContentAllowed(true);
200 editButton.setCaption("<span class=\"icon-edit\"></span>");
201 editButton.addStyleName("favorite-action");
202 editButton.addClickListener(new ClickListener() {
203
204 @Override
205 public void buttonClick(ClickEvent event) {
206 doEditTitle(listener);
207 }
208 });
209 editButton.setVisible(false);
210 wrapper.addComponent(editButton);
211
212 removeButton = new NativeButton();
213 removeButton.setHtmlContentAllowed(true);
214 removeButton.setCaption("<span class=\"icon-trash\"></span>");
215 removeButton.addStyleName("favorite-action");
216 removeButton.addClickListener(new ClickListener() {
217 @Override
218 public void buttonClick(ClickEvent event) {
219 shell.openConfirmation(MessageStyleTypeEnum.WARNING, i18n.translate("favorites.group.confirmation.title"), i18n.translate("confirmation.cannot.undo"), i18n.translate("confirmation.delete.yes"), i18n.translate("confirmation.no"), false, new ConfirmationCallback() {
220
221 @Override
222 public void onSuccess() {
223 listener.removeGroup(relPath);
224 }
225
226 @Override
227 public void onCancel() {
228
229 }
230 });
231 }
232 });
233 removeButton.setVisible(false);
234 wrapper.addComponent(removeButton);
235 dragAndDropWrapper = new GroupDragAndDropWrapper(wrapper, listener, this);
236 addComponent(dragAndDropWrapper);
237 }
238
239 private void doEditTitle(final FavoritesView.Listener listener) {
240 if (StringUtils.isBlank(titleField.getValue())) {
241 shell.openNotification(MessageStyleTypeEnum.ERROR, true, i18n.translate("favorites.title.required"));
242 titleField.focus();
243 return;
244 }
245 if (editable) {
246 boolean titleHasChanged = !title.equals(titleField.getValue());
247 if (titleHasChanged) {
248 listener.editGroup(relPath, titleField.getValue());
249 }
250 setEditable(false);
251 } else {
252 setEditable(true);
253 }
254
255 }
256
257 @Override
258 public void addEditingListener(EditingEvent.EditingListener listener) {
259 addListener("onEdit", EditingEvent.class, listener, EditingEvent.EDITING_METHOD);
260 }
261
262 @Override
263 public void removeEditingListener(EditingEvent.EditingListener listener) {
264 removeListener(EditingEvent.class, listener, EditingEvent.EDITING_METHOD);
265 }
266
267 protected GroupDragAndDropWrapper getDragAndDropWrapper() {
268 return dragAndDropWrapper;
269 }
270
271 private class EnterKeyShortcutListener extends ShortcutListener {
272 private FavoritesView.Listener listener;
273
274 public EnterKeyShortcutListener(final FavoritesView.Listener listener) {
275 super("", KeyCode.ENTER, null);
276 this.listener = listener;
277 }
278
279 @Override
280 public void handleAction(Object sender, Object target) {
281 if (editable) {
282 doEditTitle(listener);
283 } else {
284 setIconsVisibility(true);
285 }
286 }
287 }
288
289 private class EscapeKeyShortcutListener extends ShortcutListener {
290
291 public EscapeKeyShortcutListener() {
292 super("", KeyCode.ESCAPE, null);
293 }
294
295 @Override
296 public void handleAction(Object sender, Object target) {
297 setToNonEditableState();
298 }
299 }
300 }