This source file includes following definitions.
- onClick
- onClick
- createDialog
- addButton
- toAlertDialog
- display1
- display
- onDismiss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.gnu.emacs;
21
22 import java.util.List;
23 import java.util.ArrayList;
24
25 import android.app.AlertDialog;
26
27 import android.content.Context;
28 import android.content.DialogInterface;
29
30 import android.content.res.Resources.NotFoundException;
31 import android.content.res.Resources.Theme;
32 import android.content.res.TypedArray;
33
34 import android.os.Build;
35
36 import android.provider.Settings;
37
38 import android.util.Log;
39
40 import android.widget.Button;
41 import android.widget.LinearLayout;
42 import android.widget.FrameLayout;
43
44 import android.view.View;
45 import android.view.ViewGroup;
46 import android.view.Window;
47 import android.view.WindowManager;
48
49
50
51
52
53 public final class EmacsDialog implements DialogInterface.OnDismissListener
54 {
55 private static final String TAG = "EmacsDialog";
56
57
58 private List<EmacsButton> buttons;
59
60
61 private String title;
62
63
64 private String text;
65
66
67 private boolean wasButtonClicked;
68
69
70 private AlertDialog dismissDialog;
71
72
73 private int menuEventSerial;
74
75 private final class EmacsButton implements View.OnClickListener,
76 DialogInterface.OnClickListener
77 {
78
79 public String name;
80
81
82 public int id;
83
84
85 public boolean enabled;
86
87 @Override
88 public void
89 onClick (View view)
90 {
91 Log.d (TAG, "onClicked " + this);
92
93 wasButtonClicked = true;
94 EmacsNative.sendContextMenu ((short) 0, id, menuEventSerial);
95 dismissDialog.dismiss ();
96 }
97
98 @Override
99 public void
100 onClick (DialogInterface dialog, int which)
101 {
102 Log.d (TAG, "onClicked " + this);
103
104 wasButtonClicked = true;
105 EmacsNative.sendContextMenu ((short) 0, id, menuEventSerial);
106 }
107 };
108
109
110
111
112
113 public static EmacsDialog
114 createDialog (String title, String text, int menuEventSerial)
115 {
116 EmacsDialog dialog;
117
118 dialog = new EmacsDialog ();
119 dialog.buttons = new ArrayList<EmacsButton> ();
120 dialog.title = title;
121 dialog.text = text;
122 dialog.menuEventSerial = menuEventSerial;
123
124 return dialog;
125 }
126
127
128
129
130 public void
131 addButton (String name, int id, boolean disable)
132 {
133 EmacsButton button;
134
135 button = new EmacsButton ();
136 button.name = name;
137 button.id = id;
138 button.enabled = !disable;
139 buttons.add (button);
140 }
141
142
143
144
145
146
147
148
149
150
151 public AlertDialog
152 toAlertDialog (Context context)
153 {
154 AlertDialog dialog;
155 int size, styleId, flag;
156 int[] attrs;
157 EmacsButton button;
158 EmacsDialogButtonLayout layout;
159 Button buttonView;
160 ViewGroup.LayoutParams layoutParams;
161 Theme theme;
162 TypedArray attributes;
163 Window window;
164
165 size = buttons.size ();
166 styleId = -1;
167
168 if (size <= 3)
169 {
170 dialog = new AlertDialog.Builder (context).create ();
171 dialog.setMessage (text);
172 dialog.setCancelable (true);
173 dialog.setOnDismissListener (this);
174
175 if (title != null)
176 dialog.setTitle (title);
177
178
179
180
181 if (size >= 1)
182 {
183 button = buttons.get (0);
184 dialog.setButton (DialogInterface.BUTTON_POSITIVE,
185 button.name, button);
186 }
187
188 if (size >= 2)
189 {
190 button = buttons.get (1);
191 dialog.setButton (DialogInterface.BUTTON_NEGATIVE,
192 button.name, button);
193 }
194
195 if (size >= 3)
196 {
197 button = buttons.get (2);
198 dialog.setButton (DialogInterface.BUTTON_NEUTRAL,
199 button.name, button);
200 }
201 }
202 else
203 {
204
205
206
207
208 layout = new EmacsDialogButtonLayout (context);
209 layoutParams
210 = new FrameLayout.LayoutParams (ViewGroup.LayoutParams.MATCH_PARENT,
211 ViewGroup.LayoutParams.WRAP_CONTENT);
212 layout.setLayoutParams (layoutParams);
213
214
215
216
217
218
219 dialog = new AlertDialog.Builder (context).setView (layout).create ();
220 dialog.setMessage (text);
221 dialog.setCancelable (true);
222 dialog.setOnDismissListener (this);
223
224 if (title != null)
225 dialog.setTitle (title);
226
227
228
229
230
231 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
232 {
233
234 theme = dialog.getContext ().getTheme ();
235
236
237 attrs
238 = new int [] { android.R.attr.buttonBarNeutralButtonStyle, };
239
240 try
241 {
242 attributes = theme.obtainStyledAttributes (attrs);
243
244
245
246 styleId = attributes.getResourceId (0, -1);
247
248
249 attributes.recycle ();
250 }
251 catch (NotFoundException e)
252 {
253
254 }
255 }
256
257
258
259
260 for (EmacsButton emacsButton : buttons)
261 {
262 if (styleId == -1)
263
264 buttonView = new Button (context);
265 else
266
267 buttonView = new Button (context, null, 0, styleId);
268
269
270 buttonView.setText (emacsButton.name);
271 buttonView.setOnClickListener (emacsButton);
272 buttonView.setEnabled (emacsButton.enabled);
273 layout.addView (buttonView);
274 }
275 }
276
277 return dialog;
278 }
279
280
281
282 @SuppressWarnings("deprecation")
283 private boolean
284 display1 ()
285 {
286 Context context;
287 int size, type;
288 Button buttonView;
289 EmacsButton button;
290 AlertDialog dialog;
291 Window window;
292
293 if (EmacsActivity.focusedActivities.isEmpty ())
294 {
295
296
297
298
299
300
301
302
303 Log.d (TAG, "display1: no focused activities...");
304 Log.d (TAG, ("display1: EmacsOpenActivity.currentActivity: "
305 + EmacsOpenActivity.currentActivity));
306
307 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
308 || Settings.canDrawOverlays (EmacsService.SERVICE))
309 context = EmacsService.SERVICE;
310 else if (EmacsOpenActivity.currentActivity != null)
311 context = EmacsOpenActivity.currentActivity;
312 else
313 context = EmacsActivity.lastFocusedActivity;
314
315 if (context == null)
316 return false;
317 }
318 else
319
320
321
322 context = EmacsActivity.focusedActivities.get (0);
323
324 Log.d (TAG, "display1: using context " + context);
325
326 dialog = dismissDialog = toAlertDialog (context);
327
328 try
329 {
330 if (context == EmacsService.SERVICE)
331 {
332
333
334
335 window = dialog.getWindow ();
336 type = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
337 ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
338 : WindowManager.LayoutParams.TYPE_PHONE);
339 window.setType (type);
340 }
341
342 dismissDialog.show ();
343 }
344 catch (Exception exception)
345 {
346
347
348 return false;
349 }
350
351
352
353
354 size = buttons.size ();
355
356 if (size <= 3)
357 {
358 if (size >= 1)
359 {
360 button = buttons.get (0);
361 buttonView
362 = dialog.getButton (DialogInterface.BUTTON_POSITIVE);
363 buttonView.setEnabled (button.enabled);
364 }
365
366 if (size >= 2)
367 {
368 button = buttons.get (1);
369 buttonView
370 = dialog.getButton (DialogInterface.BUTTON_NEGATIVE);
371 buttonView.setEnabled (button.enabled);
372 }
373
374 if (size >= 3)
375 {
376 button = buttons.get (2);
377 buttonView
378 = dialog.getButton (DialogInterface.BUTTON_NEUTRAL);
379 buttonView.setEnabled (button.enabled);
380 }
381 }
382
383 return true;
384 }
385
386
387
388
389
390 public boolean
391 display ()
392 {
393 Runnable runnable;
394 final EmacsHolder<Boolean> rc;
395
396 rc = new EmacsHolder<Boolean> ();
397 runnable = new Runnable () {
398 @Override
399 public void
400 run ()
401 {
402 synchronized (this)
403 {
404 rc.thing = display1 ();
405 notify ();
406 }
407 }
408 };
409
410 EmacsService.syncRunnable (runnable);
411 return rc.thing;
412 }
413
414
415
416 @Override
417 public void
418 onDismiss (DialogInterface dialog)
419 {
420 Log.d (TAG, "onDismiss: " + this);
421
422 if (wasButtonClicked)
423 return;
424
425 EmacsNative.sendContextMenu ((short) 0, 0, menuEventSerial);
426 }
427 };