]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java
Merge remote-tracking branch 'origin/master' into v2.x
[lgpl/argeo-commons.git] / org.argeo.eclipse.ui / src / org / argeo / eclipse / ui / dialogs / LightweightDialog.java
1 package org.argeo.eclipse.ui.dialogs;
2
3 import org.apache.commons.logging.Log;
4 import org.apache.commons.logging.LogFactory;
5 import org.argeo.eclipse.ui.EclipseUiException;
6 import org.eclipse.swt.SWT;
7 import org.eclipse.swt.events.FocusEvent;
8 import org.eclipse.swt.events.FocusListener;
9 import org.eclipse.swt.events.ShellAdapter;
10 import org.eclipse.swt.events.ShellEvent;
11 import org.eclipse.swt.graphics.Point;
12 import org.eclipse.swt.graphics.Rectangle;
13 import org.eclipse.swt.layout.GridData;
14 import org.eclipse.swt.layout.GridLayout;
15 import org.eclipse.swt.widgets.Composite;
16 import org.eclipse.swt.widgets.Control;
17 import org.eclipse.swt.widgets.Display;
18 import org.eclipse.swt.widgets.Shell;
19
20 /** Generic lightweight dialog, not based on JFace. */
21 @Deprecated
22 public class LightweightDialog {
23 private final static Log log = LogFactory.getLog(LightweightDialog.class);
24
25 // must be the same value as org.eclipse.jface.window.Window#OK
26 public final static int OK = 0;
27 // must be the same value as org.eclipse.jface.window.Window#CANCEL
28 public final static int CANCEL = 1;
29
30 private Shell parentShell;
31 private Shell backgroundShell;
32 private Shell foregoundShell;
33
34 private Integer returnCode = null;
35 private boolean block = true;
36
37 private String title;
38
39 /** Tries to find a display */
40 private static Display getDisplay() {
41 try {
42 Display display = Display.getCurrent();
43 if (display != null)
44 return display;
45 else
46 return Display.getDefault();
47 } catch (Exception e) {
48 return Display.getCurrent();
49 }
50 }
51
52 public LightweightDialog(Shell parentShell) {
53 this.parentShell = parentShell;
54 }
55
56 public int open() {
57 if (foregoundShell != null)
58 throw new EclipseUiException("There is already a shell");
59 backgroundShell = new Shell(parentShell, SWT.ON_TOP);
60 backgroundShell.setFullScreen(true);
61 // if (parentShell != null) {
62 // backgroundShell.setBounds(parentShell.getBounds());
63 // } else
64 // backgroundShell.setMaximized(true);
65 backgroundShell.setAlpha(128);
66 backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
67 foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
68 if (title != null)
69 setTitle(title);
70 foregoundShell.setLayout(new GridLayout());
71 foregoundShell.setSize(getInitialSize());
72 createDialogArea(foregoundShell);
73 // shell.pack();
74 // shell.layout();
75
76 Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP
77 Point dialogSize = foregoundShell.getSize();
78 int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
79 int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
80 foregoundShell.setLocation(x, y);
81
82 foregoundShell.addShellListener(new ShellAdapter() {
83 private static final long serialVersionUID = -2701270481953688763L;
84
85 @Override
86 public void shellDeactivated(ShellEvent e) {
87 if (hasChildShells())
88 return;
89 if (returnCode == null)// not yet closed
90 closeShell(CANCEL);
91 }
92
93 @Override
94 public void shellClosed(ShellEvent e) {
95 notifyClose();
96 }
97
98 });
99
100 backgroundShell.open();
101 foregoundShell.open();
102 // after the foreground shell has been opened
103 backgroundShell.addFocusListener(new FocusListener() {
104 private static final long serialVersionUID = 3137408447474661070L;
105
106 @Override
107 public void focusLost(FocusEvent event) {
108 }
109
110 @Override
111 public void focusGained(FocusEvent event) {
112 if (hasChildShells())
113 return;
114 if (returnCode == null)// not yet closed
115 closeShell(CANCEL);
116 }
117 });
118
119 if (block) {
120 block();
121 }
122 if (returnCode == null)
123 returnCode = OK;
124 return returnCode;
125 }
126
127 public void block() {
128 try {
129 runEventLoop(foregoundShell);
130 } catch (ThreadDeath t) {
131 returnCode = CANCEL;
132 if (log.isTraceEnabled())
133 log.error("Thread death, canceling dialog", t);
134 } catch (Throwable t) {
135 returnCode = CANCEL;
136 log.error("Cannot open blocking lightweight dialog", t);
137 }
138 }
139
140 private boolean hasChildShells() {
141 if (foregoundShell == null)
142 return false;
143 return foregoundShell.getShells().length != 0;
144 }
145
146 // public synchronized int openAndWait() {
147 // open();
148 // while (returnCode == null)
149 // try {
150 // wait(100);
151 // } catch (InterruptedException e) {
152 // // silent
153 // }
154 // return returnCode;
155 // }
156
157 private synchronized void notifyClose() {
158 if (returnCode == null)
159 returnCode = CANCEL;
160 notifyAll();
161 }
162
163 protected void closeShell(int returnCode) {
164 this.returnCode = returnCode;
165 if (CANCEL == returnCode)
166 onCancel();
167 if (foregoundShell != null && !foregoundShell.isDisposed()) {
168 foregoundShell.close();
169 foregoundShell.dispose();
170 foregoundShell = null;
171 }
172
173 if (backgroundShell != null && !backgroundShell.isDisposed()) {
174 backgroundShell.close();
175 backgroundShell.dispose();
176 }
177 }
178
179 protected Point getInitialSize() {
180 // if (exception != null)
181 // return new Point(800, 600);
182 // else
183 return new Point(600, 400);
184 }
185
186 protected Control createDialogArea(Composite parent) {
187 Composite dialogarea = new Composite(parent, SWT.NONE);
188 dialogarea.setLayout(new GridLayout());
189 dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
190 return dialogarea;
191 }
192
193 protected Shell getBackgroundShell() {
194 return backgroundShell;
195 }
196
197 protected Shell getForegoundShell() {
198 return foregoundShell;
199 }
200
201 public void setBlockOnOpen(boolean shouldBlock) {
202 block = shouldBlock;
203 }
204
205 public void pack() {
206 foregoundShell.pack();
207 }
208
209 private void runEventLoop(Shell loopShell) {
210 Display display;
211 if (foregoundShell == null) {
212 display = Display.getCurrent();
213 } else {
214 display = loopShell.getDisplay();
215 }
216
217 while (loopShell != null && !loopShell.isDisposed()) {
218 try {
219 if (!display.readAndDispatch()) {
220 display.sleep();
221 }
222 } catch (UnsupportedOperationException e) {
223 throw e;
224 } catch (Throwable e) {
225 handleException(e);
226 }
227 }
228 if (!display.isDisposed())
229 display.update();
230 }
231
232 protected void handleException(Throwable t) {
233 if (t instanceof ThreadDeath) {
234 // Don't catch ThreadDeath as this is a normal occurrence when
235 // the thread dies
236 throw (ThreadDeath) t;
237 }
238 // Try to keep running.
239 t.printStackTrace();
240 }
241
242 /** @return false, if the dialog should not be closed. */
243 protected boolean onCancel() {
244 return true;
245 }
246
247 public void setTitle(String title) {
248 this.title = title;
249 if (title != null && getForegoundShell() != null)
250 getForegoundShell().setText(title);
251 }
252
253 public Integer getReturnCode() {
254 return returnCode;
255 }
256
257 }