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