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