blob: 84257a5cda0d7c3ded8c742e56ecc20912935658 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package java.awt;
26
27import java.awt.event.*;
28
29import sun.awt.AppContext;
30
31abstract class ModalEventFilter implements EventFilter {
32
33 protected Dialog modalDialog;
34 protected boolean disabled;
35
36 protected ModalEventFilter(Dialog modalDialog) {
37 this.modalDialog = modalDialog;
38 disabled = false;
39 }
40
41 Dialog getModalDialog() {
42 return modalDialog;
43 }
44
45 public FilterAction acceptEvent(AWTEvent event) {
46 if (disabled || !modalDialog.isVisible()) {
47 return FilterAction.ACCEPT;
48 }
49 int eventID = event.getID();
50 if ((eventID >= MouseEvent.MOUSE_FIRST &&
51 eventID <= MouseEvent.MOUSE_LAST) ||
52 (eventID >= ActionEvent.ACTION_FIRST &&
53 eventID <= ActionEvent.ACTION_LAST) ||
54 eventID == WindowEvent.WINDOW_CLOSING)
55 {
56 Object o = event.getSource();
57 if (o instanceof sun.awt.ModalExclude) {
58 // Exclude this object from modality and
59 // continue to pump it's events.
60 } else if (o instanceof Component) {
61 Component c = (Component)o;
62 while ((c != null) && !(c instanceof Window)) {
63 c = c.getParent_NoClientCode();
64 }
65 if (c != null) {
66 return acceptWindow((Window)c);
67 }
68 }
69 }
70 return FilterAction.ACCEPT;
71 }
72
73 protected abstract FilterAction acceptWindow(Window w);
74
75 // When a modal dialog is hidden its modal filter may not be deleted from
76 // EventDispatchThread event filters immediately, so we need to mark the filter
77 // as disabled to prevent it from working. Simple checking for visibility of
78 // the modalDialog is not enough, as it can be hidden and then shown again
79 // with a new event pump and a new filter
80 void disable() {
81 disabled = true;
82 }
83
84 int compareTo(ModalEventFilter another) {
85 Dialog anotherDialog = another.getModalDialog();
86 // check if modalDialog is from anotherDialog's hierarchy
87 // or vice versa
88 Component c = modalDialog;
89 while (c != null) {
90 if (c == anotherDialog) {
91 return 1;
92 }
93 c = c.getParent_NoClientCode();
94 }
95 c = anotherDialog;
96 while (c != null) {
97 if (c == modalDialog) {
98 return -1;
99 }
100 c = c.getParent_NoClientCode();
101 }
102 // check if one dialog blocks (directly or indirectly) another
103 Dialog blocker = modalDialog.getModalBlocker();
104 while (blocker != null) {
105 if (blocker == anotherDialog) {
106 return -1;
107 }
108 blocker = blocker.getModalBlocker();
109 }
110 blocker = anotherDialog.getModalBlocker();
111 while (blocker != null) {
112 if (blocker == modalDialog) {
113 return 1;
114 }
115 blocker = blocker.getModalBlocker();
116 }
117 // compare modality types
118 return modalDialog.getModalityType().compareTo(anotherDialog.getModalityType());
119 }
120
121 static ModalEventFilter createFilterForDialog(Dialog modalDialog) {
122 switch (modalDialog.getModalityType()) {
123 case DOCUMENT_MODAL: return new DocumentModalEventFilter(modalDialog);
124 case APPLICATION_MODAL: return new ApplicationModalEventFilter(modalDialog);
125 case TOOLKIT_MODAL: return new ToolkitModalEventFilter(modalDialog);
126 }
127 return null;
128 }
129
130 private static class ToolkitModalEventFilter extends ModalEventFilter {
131
132 private AppContext appContext;
133
134 ToolkitModalEventFilter(Dialog modalDialog) {
135 super(modalDialog);
136 appContext = modalDialog.appContext;
137 }
138
139 protected FilterAction acceptWindow(Window w) {
140 if (w.isModalExcluded(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE)) {
141 return FilterAction.ACCEPT;
142 }
143 if (w.appContext != appContext) {
144 return FilterAction.REJECT;
145 }
146 while (w != null) {
147 if (w == modalDialog) {
148 return FilterAction.ACCEPT_IMMEDIATELY;
149 }
150 w = w.getOwner();
151 }
152 return FilterAction.REJECT;
153 }
154 }
155
156 private static class ApplicationModalEventFilter extends ModalEventFilter {
157
158 private AppContext appContext;
159
160 ApplicationModalEventFilter(Dialog modalDialog) {
161 super(modalDialog);
162 appContext = modalDialog.appContext;
163 }
164
165 protected FilterAction acceptWindow(Window w) {
166 if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) {
167 return FilterAction.ACCEPT;
168 }
169 if (w.appContext == appContext) {
170 while (w != null) {
171 if (w == modalDialog) {
172 return FilterAction.ACCEPT_IMMEDIATELY;
173 }
174 w = w.getOwner();
175 }
176 return FilterAction.REJECT;
177 }
178 return FilterAction.ACCEPT;
179 }
180 }
181
182 private static class DocumentModalEventFilter extends ModalEventFilter {
183
184 private Window documentRoot;
185
186 DocumentModalEventFilter(Dialog modalDialog) {
187 super(modalDialog);
188 documentRoot = modalDialog.getDocumentRoot();
189 }
190
191 protected FilterAction acceptWindow(Window w) {
192 // application- and toolkit-excluded windows are blocked by
193 // document-modal dialogs from their child hierarchy
194 if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) {
195 Window w1 = modalDialog.getOwner();
196 while (w1 != null) {
197 if (w1 == w) {
198 return FilterAction.REJECT;
199 }
200 w1 = w1.getOwner();
201 }
202 return FilterAction.ACCEPT;
203 }
204 while (w != null) {
205 if (w == modalDialog) {
206 return FilterAction.ACCEPT_IMMEDIATELY;
207 }
208 if (w == documentRoot) {
209 return FilterAction.REJECT;
210 }
211 w = w.getOwner();
212 }
213 return FilterAction.ACCEPT;
214 }
215 }
216}