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.dialog;
35
36 import info.magnolia.i18nsystem.I18nizer;
37 import info.magnolia.i18nsystem.SimpleTranslator;
38 import info.magnolia.objectfactory.ComponentProvider;
39 import info.magnolia.ui.api.action.ActionDefinition;
40 import info.magnolia.ui.api.action.ActionExecutionException;
41 import info.magnolia.ui.api.action.ActionExecutor;
42 import info.magnolia.ui.api.app.AppContext;
43 import info.magnolia.ui.api.app.SubAppContext;
44 import info.magnolia.ui.api.context.UiContext;
45 import info.magnolia.ui.api.message.Message;
46 import info.magnolia.ui.api.message.MessageType;
47 import info.magnolia.ui.api.overlay.ConfirmationCallback;
48 import info.magnolia.ui.api.overlay.OverlayLayer.ModalityLevel;
49 import info.magnolia.ui.dialog.actionarea.ActionAreaPresenter;
50 import info.magnolia.ui.dialog.actionarea.ActionListener;
51 import info.magnolia.ui.dialog.actionarea.EditorActionAreaPresenter;
52 import info.magnolia.ui.dialog.actionarea.view.EditorActionAreaView;
53 import info.magnolia.ui.dialog.definition.DialogDefinition;
54 import info.magnolia.ui.vaadin.dialog.BaseDialog;
55 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
56
57 import javax.inject.Inject;
58
59 import net.sf.cglib.proxy.Enhancer;
60
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 import com.vaadin.event.ShortcutAction.KeyCode;
65 import com.vaadin.event.ShortcutAction.ModifierKey;
66 import com.vaadin.event.ShortcutListener;
67 import com.vaadin.server.WebBrowser;
68 import com.vaadin.ui.Panel;
69 import com.vaadin.ui.UI;
70
71
72
73
74 public class BaseDialogPresenter implements DialogPresenter, ActionListener {
75
76 private Logger log = LoggerFactory.getLogger(getClass());
77
78 private DialogView view;
79
80 protected ComponentProvider componentProvider;
81
82 private ActionExecutor executor;
83
84 private EditorActionAreaPresenter editorActionAreaPresenter;
85
86 private final I18nizer i18nizer;
87
88 private final SimpleTranslator i18n;
89
90 private UiContext uiContext;
91
92 private DialogDefinition definition;
93
94 @Inject
95 public BaseDialogPresenter(ComponentProvider componentProvider, ActionExecutor executor, DialogView view, I18nizer i18nizer, SimpleTranslator i18n) {
96 this.componentProvider = componentProvider;
97 this.executor = executor;
98 this.view = view;
99 this.i18nizer = i18nizer;
100 this.i18n = i18n;
101 }
102
103 @Override
104 public DialogView getView() {
105 return view;
106 }
107
108 @Override
109 public ActionAreaPresenter getActionArea() {
110 return editorActionAreaPresenter;
111 }
112
113 @Override
114 public void closeDialog() {
115 view.close();
116 }
117
118 @Override
119 public void addShortcut(final String actionName, final int keyCode, final int... modifiers) {
120
121 view.addShortcut(new ShortcutListener(actionName, keyCode, modifiers) {
122 @Override
123 public void handleAction(Object sender, Object target) {
124 executeAction(actionName, new Object[0]);
125 }
126 });
127 }
128
129 @Override
130 public DialogView start(DialogDefinition dialogDefinition, UiContext uiContext) {
131 this.uiContext = uiContext;
132
133 if (Enhancer.isEnhanced(dialogDefinition.getClass())) {
134 this.definition = dialogDefinition;
135 } else {
136 this.definition = i18nizer.decorate(dialogDefinition);
137 }
138
139 this.editorActionAreaPresenter = componentProvider.newInstance(definition.getActionArea().getPresenterClass());
140 EditorActionAreaView editorActionAreaView = editorActionAreaPresenter.start(filterActions(), definition.getActionArea(), this, uiContext);
141
142
143 int osSpecificModifierKey;
144 UI ui = UI.getCurrent();
145 if (ui != null) {
146 WebBrowser browser = ui.getPage().getWebBrowser();
147 if (browser.isWindows()) {
148 osSpecificModifierKey = ModifierKey.CTRL;
149 } else {
150
151 osSpecificModifierKey = ModifierKey.META;
152 }
153
154 if (definition.getActions().containsKey(BaseDialog.COMMIT_ACTION_NAME)) {
155 addShortcut(BaseDialog.COMMIT_ACTION_NAME, KeyCode.S, osSpecificModifierKey);
156 }
157 if (definition.getActions().containsKey(BaseDialog.CANCEL_ACTION_NAME)) {
158 addShortcut(BaseDialog.CANCEL_ACTION_NAME, KeyCode.W, osSpecificModifierKey);
159 }
160 if (definition.getModalityLevel() == ModalityLevel.LIGHT) {
161 view.addShortcut(new CloseDialogShortcutListener(KeyCode.ESCAPE));
162 }
163
164 } else {
165 log.warn("The current Vaadin UI was null when starting {}, as a result dialog keyboard shortcuts will not work.", this);
166 }
167
168 view.addShortcut(new CloseDialogAfterConfirmationShortcutListener(KeyCode.ESCAPE));
169 view.addShortcut(new CommitDialogShortcutListener(KeyCode.ENTER));
170
171 this.view.setActionAreaView(editorActionAreaView);
172 this.view.setModalityLevel(definition.getModalityLevel());
173 if (definition.isWide()){
174 this.view.setWide(true);
175 }
176 return this.view;
177 }
178
179 protected Iterable<ActionDefinition> filterActions() {
180 return getDefinition().getActions().values();
181 }
182
183 protected Object[] getActionParameters(String actionName) {
184 return new Object[] { this };
185 }
186
187 @Override
188 public void onActionFired(String actionName, Object... actionContextParams) {
189 executeAction(actionName, actionContextParams);
190 }
191
192 protected void executeAction(String actionName, Object[] actionContextParams) {
193 Object[] providedParameters = getActionParameters(actionName);
194 Object[] combinedParameters = new Object[providedParameters.length + actionContextParams.length];
195 System.arraycopy(providedParameters, 0, combinedParameters, 0, providedParameters.length);
196 System.arraycopy(actionContextParams, 0, combinedParameters, providedParameters.length, actionContextParams.length);
197 try {
198 executor.execute(actionName, combinedParameters);
199 } catch (ActionExecutionException e) {
200 String exceptionStatement = i18n.translate("ui-dialog.actionexecutionerror.basemessage");
201 Message error = new Message(MessageType.ERROR, exceptionStatement, e.getMessage());
202 log.error(exceptionStatement, e);
203 if (uiContext instanceof AppContext) {
204 ((AppContext) uiContext).sendLocalMessage(error);
205 } else if (uiContext instanceof SubAppContext) {
206 ((SubAppContext) uiContext).getAppContext().sendLocalMessage(error);
207 }
208
209 }
210 }
211
212 protected DialogDefinition getDefinition() {
213 return definition;
214 }
215
216 protected ActionExecutor getExecutor() {
217 return executor;
218 }
219
220 protected I18nizer getI18nizer() {
221 return i18nizer;
222 }
223
224
225
226
227 protected class CloseDialogShortcutListener extends ShortcutListener {
228
229 public CloseDialogShortcutListener(int keyCode, int... modifierKey) {
230 super("", keyCode, modifierKey);
231 }
232
233 @Override
234 public void handleAction(Object sender, Object target) {
235 closeDialog();
236 }
237 }
238
239
240
241
242 protected class CloseDialogAfterConfirmationShortcutListener extends ShortcutListener {
243
244 public CloseDialogAfterConfirmationShortcutListener(int keyCode, int... modifierKey) {
245 super("", keyCode, modifierKey);
246 }
247
248 @Override
249 public void handleAction(Object sender, Object target) {
250 uiContext.openConfirmation(
251 MessageStyleTypeEnum.WARNING, i18n.translate("ui-dialog.closeConfirmation.title"), i18n.translate("ui-dialog.closeConfirmation.body"), i18n.translate("ui-dialog.closeConfirmation.confirmButton"), i18n.translate("ui-dialog.cancelButton"), false,
252 new ConfirmationCallback() {
253 @Override
254 public void onSuccess() {
255 closeDialog();
256 }
257
258 @Override
259 public void onCancel() {
260 if (getView() instanceof Panel) {
261 ((Panel) getView()).focus();
262 }
263 }
264 });
265 }
266 }
267
268
269
270
271 protected class CommitDialogShortcutListener extends ShortcutListener {
272
273 public CommitDialogShortcutListener(int keyCode, int... modifierKey) {
274 super("", keyCode, modifierKey);
275 }
276
277 @Override
278 public void handleAction(Object sender, Object target) {
279
280 executeAction(BaseDialog.COMMIT_ACTION_NAME, new Object[0]);
281 }
282 }
283 }