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.vaadin.gwt.client.editor.dom;
35
36 import info.magnolia.cms.security.operations.OperationPermissionDefinition;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.ui.vaadin.gwt.client.editor.event.ClientActionEvent;
39 import info.magnolia.ui.vaadin.gwt.client.editor.event.ComponentStartMoveEvent;
40 import info.magnolia.ui.vaadin.gwt.client.editor.event.ComponentStopMoveEvent;
41 import info.magnolia.ui.vaadin.gwt.client.editor.event.EditComponentEvent;
42 import info.magnolia.ui.vaadin.gwt.client.editor.event.SortComponentEvent;
43 import info.magnolia.ui.vaadin.gwt.client.shared.AreaElement;
44 import info.magnolia.ui.vaadin.gwt.client.shared.ComponentElement;
45 import info.magnolia.ui.vaadin.gwt.client.widget.controlbar.ComponentBar;
46 import info.magnolia.ui.vaadin.gwt.client.widget.controlbar.listener.ComponentListener;
47 import info.magnolia.ui.vaadin.gwt.client.widget.dnd.MoveWidget;
48
49 import java.util.Iterator;
50 import java.util.LinkedList;
51 import java.util.List;
52 import java.util.Map;
53
54 import com.google.gwt.dom.client.Element;
55 import com.google.gwt.event.shared.EventBus;
56 import com.google.gwt.event.shared.HandlerRegistration;
57 import com.google.gwt.user.client.DOM;
58
59
60
61
62
63
64 public class MgnlComponent extends MgnlElement implements ComponentListener {
65
66 private final EventBus eventBus;
67 private List<HandlerRegistration> handlers = new LinkedList<HandlerRegistration>();
68
69 public MgnlComponent(MgnlElement parent, EventBus eventBus) {
70 super(parent);
71 this.eventBus = eventBus;
72 }
73
74 @Override
75 public ComponentElement getTypedElement() {
76 ComponentElement component = new ComponentElement(getAttribute("workspace"), getAttribute("path"), getAttribute("dialog"));
77 boolean inherited = Boolean.parseBoolean(getAttribute("inherited"));
78
79 boolean isWritable = hasEditButton();
80 component.setWritable(isWritable);
81
82 boolean isEditable = isEditable() && isWritable;
83 component.setEditable(isEditable);
84
85 boolean deletable = isDeletable() && !inherited;
86 component.setDeletable(deletable);
87
88 boolean moveable = isMovable();
89 component.setMoveable(moveable);
90
91 component.setDuplicatable(isDuplicatable());
92
93 return component;
94 }
95
96 boolean isDuplicatable() {
97 MgnlArea parentArea = getParentArea();
98 if (parentArea != null) {
99 return !parentArea.isTypeSingle() && !parentArea.isMaxComponentsReached();
100 }
101 return false;
102 }
103
104 private boolean isDeletable() {
105 boolean deletable = true;
106 if (getAttributes().containsKey(OperationPermissionDefinition.DELETABLE)) {
107 deletable = Boolean.parseBoolean(getAttribute(OperationPermissionDefinition.DELETABLE));
108 }
109 return deletable;
110 }
111
112 private boolean isEditable() {
113 if (isInherited()) {
114 return false;
115 }
116 String editableAttr = getAttribute("editable");
117 return editableAttr == null || Boolean.parseBoolean(editableAttr);
118 }
119
120 @Override
121 public void editComponent() {
122 eventBus.fireEvent(new EditComponentEvent(getTypedElement()));
123 }
124
125 @Override
126 public void onAction(String actionName, Map<String, String> parameters) {
127 eventBus.fireEvent(new ClientActionEvent(actionName, getTypedElement(), parameters));
128 }
129
130
131
132
133
134 private void sortComponent(MgnlComponent target) {
135 MgnlArea area = getParentArea();
136 if (area != null) {
137
138
139 AreaElement areaElement = area.getTypedElement();
140 areaElement.setSourceComponent(getTypedElement());
141 areaElement.setTargetComponent(target.getTypedElement());
142 areaElement.setSortOrder(getSortOrder(target));
143
144 SortComponentEvent sortComponentEvent = new SortComponentEvent(areaElement);
145 eventBus.fireEvent(sortComponentEvent);
146 }
147 }
148
149 public String getLabel() {
150 return getAttribute("label");
151 }
152
153 public boolean hasEditButton() {
154 boolean inherited = Boolean.parseBoolean(getAttribute("inherited"));
155 boolean hasDialog = getAttribute("dialog") != null && !"".equals(getAttribute("dialog"));
156 boolean writable = true;
157 if (getAttributes().containsKey(OperationPermissionDefinition.WRITABLE)) {
158 writable = Boolean.parseBoolean(getAttribute(OperationPermissionDefinition.WRITABLE));
159 }
160 return writable && hasDialog && !inherited;
161 }
162
163 public int getActivationStatus() {
164 if (containsAttribute(ACTIVATION_STATUS_KEY)) {
165 return Integer.parseInt(getAttribute(ACTIVATION_STATUS_KEY));
166 }
167 return NodeTypes.Activatable.ACTIVATION_STATUS_NOT_ACTIVATED;
168 }
169
170 public boolean isMovable() {
171 boolean inherited = Boolean.parseBoolean(getAttribute("inherited"));
172 MgnlArea parentArea = this.getParentArea();
173 boolean parentAreaIsTypeSingle = parentArea != null && "single".equals(parentArea.getAttribute("type"));
174 boolean movable = true;
175 if (getAttributes().containsKey(OperationPermissionDefinition.MOVEABLE)) {
176 movable = Boolean.parseBoolean(getAttribute(OperationPermissionDefinition.MOVEABLE));
177 }
178 return movable && !inherited && !parentAreaIsTypeSingle;
179 }
180
181
182
183
184
185
186
187 @Override
188 public void onMoveStart(boolean isDrag) {
189 if (isDrag) {
190 doStartMove(isDrag);
191 } else {
192 eventBus.fireEvent(new ComponentStartMoveEvent());
193 }
194 }
195
196
197
198
199
200
201 public void doStartMove(boolean isDrag) {
202 setMoveSource(true);
203
204 for (MgnlComponent component : getSiblingComponents()) {
205 component.registerMoveTarget(isDrag);
206 }
207
208 handlers.add(eventBus.addHandler(ComponentStopMoveEvent.TYPE, new ComponentStopMoveEvent.ComponentStopMoveEventHandler() {
209 @Override
210 public void onStop(ComponentStopMoveEvent componentStopMoveEvent) {
211
212 setMoveSource(false);
213
214 Iterator<HandlerRegistration> it = handlers.iterator();
215 while (it.hasNext()) {
216 it.next().removeHandler();
217 it.remove();
218 }
219 MgnlComponent target = componentStopMoveEvent.getTargetComponent();
220 if (target != null) {
221 sortComponent(target);
222 }
223 }
224 }));
225 }
226
227
228
229
230
231
232 @Override
233 public void onMoveStop() {
234 eventBus.fireEvent(new ComponentStopMoveEvent(this, false));
235 }
236
237
238
239
240
241
242
243
244 @Override
245 public void onMoveCancel() {
246 eventBus.fireEvent(new ComponentStopMoveEvent(null, false));
247 }
248
249
250
251
252
253 private void registerMoveTarget(final boolean isDrag) {
254 setMoveTarget(true);
255
256 if (isDrag) {
257 registerDragAndDropHandlers();
258 } else {
259 setDraggable(false);
260 registerMoveHandlers();
261 }
262 handlers.add(eventBus.addHandler(ComponentStopMoveEvent.TYPE, new ComponentStopMoveEvent.ComponentStopMoveEventHandler() {
263 @Override
264 public void onStop(ComponentStopMoveEvent componentMoveEvent) {
265 unregisterMoveTarget(isDrag);
266 setMoveOver(false);
267 }
268 }));
269 }
270
271
272
273
274
275 private void unregisterMoveTarget(boolean isDrag) {
276 setMoveTarget(false);
277
278 if (isDrag) {
279 unregisterDragAndDropHandlers();
280 } else {
281 setDraggable(true);
282 unregisterMoveHandlers();
283 }
284
285 Iterator<HandlerRegistration> it = handlers.iterator();
286 while (it.hasNext()) {
287 it.next().removeHandler();
288 it.remove();
289 }
290 }
291
292 private void registerMoveHandlers() {
293 if (getControlBar() != null) {
294 getControlBar().registerMoveHandlers();
295 }
296 }
297
298 private void unregisterMoveHandlers() {
299 if (getControlBar() != null) {
300 getControlBar().unregisterMoveHandlers();
301 }
302 }
303
304 private void registerDragAndDropHandlers() {
305 if (getControlBar() != null) {
306 getControlBar().registerDragAndDropHandlers();
307 }
308 }
309
310 private void unregisterDragAndDropHandlers() {
311 if (getControlBar() != null) {
312 getControlBar().unregisterDragAndDropHandlers();
313 }
314 }
315
316 private void setDraggable(boolean draggable) {
317 if (getControlBar() != null) {
318 getControlBar().setDraggable(draggable);
319 }
320 }
321
322 public void setVisible(boolean visible) {
323 if (getControlBar() != null) {
324 getControlBar().setVisible(visible);
325 }
326 }
327
328 public void removeFocus() {
329 if (getControlBar() != null) {
330 getControlBar().removeFocus();
331 }
332 }
333
334 public void setFocus() {
335 if (getControlBar() != null) {
336 getControlBar().setFocus(false);
337 }
338 }
339
340 public void setMoveTarget(boolean moveTarget) {
341 if (getControlBar() != null) {
342 getControlBar().setMoveTarget(moveTarget);
343 }
344 }
345
346 public void setMoveOver(boolean moveTarget) {
347 if (getControlBar() != null) {
348 getControlBar().setMoveOver(moveTarget);
349 }
350 }
351
352 private void setMoveSource(boolean source) {
353 if (getControlBar() != null) {
354 getControlBar().setMoveSource(source);
355 }
356 }
357
358 @Override
359 protected ComponentBar getControlBar() {
360 return (ComponentBar) super.getControlBar();
361 }
362
363 private String getSortOrder(MgnlComponent target) {
364
365 int xTarget = target.getControlBar().getAbsoluteLeft();
366 int yTarget = target.getControlBar().getAbsoluteTop();
367 int xThis = getControlBar().getAbsoluteLeft();
368 int yThis = getControlBar().getAbsoluteTop();
369
370 boolean isDragUp = yThis > yTarget;
371 boolean isDragDown = !isDragUp;
372 boolean isDragLeft = xThis > xTarget;
373 boolean isDragRight = !isDragLeft;
374
375 String order = null;
376
377 if (isDragUp || isDragLeft) {
378 order = "before";
379 } else if (isDragDown || isDragRight) {
380 order = "after";
381 }
382 return order;
383 }
384
385 private List<MgnlComponent> getSiblingComponents() {
386 List<MgnlComponent> siblings = new LinkedList<MgnlComponent>();
387 MgnlArea area = getParentArea();
388 for (MgnlComponent component : area.getComponents()) {
389 if (component != this) {
390 siblings.add(component);
391 }
392 }
393 return siblings;
394 }
395
396 public MoveWidget getMoveWidget() {
397 Element element = DOM.clone(getControlBar().getElement(), true);
398 return new MoveWidget(element, getWidth(), getHeight());
399 }
400
401 private int getHeight() {
402 if (getControlBar() != null) {
403 return getControlBar().getOffsetHeight();
404 }
405 return 0;
406 }
407
408 private int getWidth() {
409 if (getControlBar() != null) {
410 return getControlBar().getOffsetWidth();
411 }
412 return 0;
413 }
414 }