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