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