001: /*
002: * @(#)QtWindowPeer.java 1.47 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package sun.awt.qt;
028:
029: import sun.awt.peer.WindowPeer;
030: import java.awt.*;
031: import java.awt.event.*;
032:
033: /**
034: * QtWindowPeer.java
035: *
036: * @author Indrayana Rustandi
037: * @author Nicholas Allen
038: */
039:
040: class QtWindowPeer extends QtPanelPeer implements WindowPeer {
041: private static native void initIDs();
042:
043: public native void setActiveNative();
044:
045: public native void setFocusInWindow(QtComponentPeer toFocus);
046:
047: // 6182409: Window.pack does not work correctly.
048: // The winsets object, if set, overwrites the insets object in the
049: // QtContainerPeer. It is necessary to introduce a different object
050: // because we are guessing/setting winsets in the peer constructor
051: // and this conflicts with QtContainerPeer constructor where insets
052: // is initialized to new Insets(0, 0, 0, 0). If we update super.insets
053: // instead of winsets, the super.insets gets overwritten at the end.
054: // See also setInsets() and updateInsets().
055: protected Insets winsets;
056: private Rectangle paintRect = null;
057:
058: static {
059: initIDs();
060: }
061:
062: QtWindowPeer(QtToolkit toolkit, Window target) {
063: super (toolkit, target);
064: }
065:
066: protected native void create(QtComponentPeer parentPeer);
067:
068: public void show() {
069: /*
070: * Fixed (partially) bug 4828042 where the initial splash screen
071: * (an instance of java.awt.Window) was setMainWidget()'ed.
072: * We now dictate that only java.awt.Frame can be honored as the
073: * main widget.
074: */
075: if (this instanceof QtFramePeer) {
076: toolkit.setMainWidget(this );
077: }
078:
079: // bug 6186499 - we need to set the focus in native before showing
080: // the window. Otherwise, Qt will first focus the frame, then the
081: // widget that we want to have the focus
082: Component toFocus = ((Window) target).getMostRecentFocusOwner();
083: if (toFocus == null)
084: toFocus = ((Window) target).getFocusTraversalPolicy()
085: .getInitialComponent((Window) target);
086: sun.awt.peer.ComponentPeer peer = QtToolkit
087: .getComponentPeer(toFocus);
088: if (peer instanceof QtComponentPeer)
089: setFocusInWindow((QtComponentPeer) peer);
090: // bug 6186499
091: super .show();
092:
093: // 6224133.
094: // No longer needed.
095: // toolkit.setRun(true);
096: // 6224133.
097:
098: computeInsets(); //6182365
099:
100: /* Don't call setBounds here - bounds is already set at QtComponentPeer's
101: constructor, and we don't know the insets of this window right after
102: the show() anyway. */
103: //Rectangle bounds = target.getBounds();
104: //setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
105: //don't return from this method until we receive notifiation that
106: //we're actually visible on the screen
107: }
108:
109: // 6182409: Window.pack does not work correctly.
110: // Called from computeInsets() native method impl.
111: // The 6182365 comment is no longer valid.
112: /* 6182365. For x86 only. Called from Qt's paint event delivery */
113: private void restoreBounds() {
114: Rectangle bounds = target.getBounds();
115: if (QtComponentPeer.isPacked(target)) {
116: if (insetsChanged) {
117:
118: // must obey the interior size constraint of our target.
119: // Now that we have an accurate insets, update the Java layer
120: // about the correct target bounds if necessary.
121: bounds.setSize(bounds.width + getWidthDelta(),
122: bounds.height + getHeightDelta());
123: target.setSize(bounds.width, bounds.height);
124: }
125: } else {
126: // Window was NOT packed before show and the insets may or may not
127: // have changed.
128: }
129:
130: // The bounds may have been set correctly by the application before
131: // target.show(), but we have found out that it is necessary to do
132: // another peer.setBounds(), followed by, if necessary, the layout
133: // of the Window so that the window is positioned correctly on the
134: // screen.
135: setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
136: if (insetsChanged) {
137: target.invalidate();
138: target.validate();
139: }
140:
141: resetInsetsDeltas();
142: }
143:
144: // 6182409: Window.pack does not work correctly.
145: // The follow delta related functions are for pack() to work correctly.
146: // Subclasses may override them, for example, QtFramePeer.
147: protected int getWidthDelta() {
148: return leftBorderDelta + rightBorderDelta;
149: }
150:
151: protected int getHeightDelta() {
152: return topBorderDelta + bottomBorderDelta;
153: }
154:
155: protected void resetInsetsDeltas() {
156: topBorderDelta = leftBorderDelta = bottomBorderDelta = rightBorderDelta = 0;
157: insetsChanged = false;
158: }
159:
160: public native void computeInsets(); //6182365
161:
162: public native void toFront();
163:
164: public native void toBack();
165:
166: public native int warningLabelHeight(); //6233632
167:
168: public native void setResizable(boolean resizable);
169:
170: /** This is overridden to set the bounds on the window manager's
171: frame. */
172:
173: public void setBounds(int x, int y, int w, int h) {
174: super .setBounds(x + leftBorder, y + topBorder, Math.max(w
175: - leftBorder - rightBorder, 0), Math.max(h - topBorder
176: - bottomBorder, 0));
177: }
178:
179: // Bug 5108647.
180: // Overrides QtComponentPeer.setBoundsNative() in order to
181: // check whether this peer is user resizable.
182: native void setBoundsNative(int x, int y, int width, int height);
183:
184: public Graphics getGraphics() {
185: Graphics g = super .getGraphics();
186:
187: if (g != null) {
188: g.translate(-leftBorder, -topBorder);
189: }
190:
191: return g;
192: }
193:
194: void postMouseEvent(int id, long when, int modifiers, int x, int y,
195: int clickCount, boolean popupTrigger, int nativeEvent) {
196: super .postMouseEvent(id, when, modifiers, x + leftBorder, y
197: + topBorder, clickCount, popupTrigger, nativeEvent);
198: }
199:
200: /**
201: * Called to inform the Frame that its size has changed and it
202: * should layout its children.
203: */
204:
205: private void postResizedEvent() {
206: QtToolkit.postEvent(new ComponentEvent(target,
207: ComponentEvent.COMPONENT_RESIZED));
208: }
209:
210: private void postMovedEvent() {
211: QtToolkit.postEvent(new ComponentEvent(target,
212: ComponentEvent.COMPONENT_MOVED));
213: }
214:
215: private void postShownEvent() {
216: QtToolkit.postEvent(new ComponentEvent(target,
217: ComponentEvent.COMPONENT_SHOWN));
218: }
219:
220: protected void postWindowEvent(int type) {
221: WindowEvent we = new WindowEvent((Window) target, type);
222: if (type == WindowEvent.WINDOW_ACTIVATED) {
223: if (!postedActivatedEvent) {
224: QtToolkit.postEvent(we);
225: postedActivatedEvent = true;
226: }
227: } else if (type == WindowEvent.WINDOW_DEACTIVATED) {
228: if (postedActivatedEvent) {
229: QtToolkit.postEvent(we);
230: postedActivatedEvent = false;
231: }
232: } else {
233: QtToolkit.postEvent(we);
234: }
235: }
236:
237: // Bug 6211281
238: protected void postWindowEvent(AWTEvent event) {
239: QtToolkit.postEvent(event);
240: }
241:
242: // 6182409: Window.pack does not work correctly.
243: // Overrides QtContainerPeer.getInsets() so that the native layer can
244: // update the Java window peer about new insets value when they become
245: // available.
246: public Insets getInsets() {
247: Insets newInsets;
248: if (winsets != null) {
249: //6233632
250: newInsets = new Insets(winsets.top, winsets.left,
251: winsets.bottom + warningLabelHeight(),
252: winsets.right);
253: return newInsets;
254: //6233632 return winsets;
255: } else {
256: return super .getInsets();
257: }
258: }
259:
260: // 6182409: Window.pack does not work correctly.
261: /**
262: * Sets the window peer's insets.
263: */
264: protected void setInsets(Insets newInsets, boolean isInsetsChanged) {
265: this .winsets = newInsets;
266: this .insetsChanged = isInsetsChanged;
267: }
268:
269: /** Calculates the insets using any values appropriate (such as borders). */
270: Insets calculateInsets() {
271: return new Insets(topBorder, leftBorder, bottomBorder,
272: rightBorder);
273: }
274:
275: // 6182409: Window.pack does not work correctly.
276: /**
277: * Sets this Frame/Dialog's inset values.
278: * Invoked by the frame/dialog native layer which guesses the borders
279: * for decorated windows. Pass isInsetsChanged = false.
280: */
281: private void setInsets(int top, int left, int bottom, int right) {
282: setInsets(top, left, bottom, right, false);
283: }
284:
285: private void setInsets(int top, int left, int bottom, int right,
286: boolean isInsetsChanged) {
287: topBorder = top;
288: leftBorder = left;
289: bottomBorder = bottom;
290: rightBorder = right;
291:
292: setInsets(calculateInsets(), isInsetsChanged);
293: }
294:
295: // 6182409: Window.pack does not work correctly.
296: /**
297: * Updates this Frame/Dialog's inset values.
298: * Invoked by the native layer after the window is realized.
299: */
300: protected void updateInsets(int top, int left, int bottom, int right) {
301: topBorderDelta = top - topBorder;
302: leftBorderDelta = left - leftBorder;
303: bottomBorderDelta = bottom - bottomBorder;
304: rightBorderDelta = right - rightBorder;
305:
306: if (topBorderDelta != 0 || leftBorderDelta != 0
307: || rightBorderDelta != 0 && bottomBorderDelta != 0) {
308: setInsets(top, left, bottom, right, true);
309:
310: }
311: }
312:
313: static void setQWSCoords(int x, int y) {
314: qwsX = x;
315: qwsY = y;
316: }
317:
318: int getOriginX() {
319: return -leftBorder;
320: }
321:
322: int getOriginY() {
323: return -topBorder;
324: }
325:
326: int topBorder, leftBorder, bottomBorder, rightBorder;
327:
328: // 6182409: Window.pack does not work correctly.
329: // Indicates the deltas for decorations before/after peer.show().
330: int topBorderDelta, leftBorderDelta, bottomBorderDelta,
331: rightBorderDelta;
332:
333: // 6182409: Window.pack does not work correctly.
334: // Indicates whether insets have changed before/after peer.show().
335: boolean insetsChanged;
336:
337: static int qwsX, qwsY;
338: static boolean qwsInit = false;
339:
340: private boolean postedActivatedEvent;
341:
342: // 5108404
343: // Called from the native code with qt-library lock held, so call the
344: // hide method in the event queue thread
345: void hideLater() {
346: EventQueue.invokeLater(new Runnable() {
347: public void run() {
348: target.hide();
349: }
350: });
351: }
352:
353: // 5108404
354:
355: public void setActive() {
356: if (target.isVisible() && target.isFocusable())
357: setActiveNative();
358: }
359:
360: public void hide() {
361: // bug 6186499
362: // if we are the focused window, generate a WINDOW_LOST_FOCUS event
363: // before hiding ourselves - because Qt won't necessarily do so
364: if (((Window) target).isFocused())
365: postWindowEvent(WindowEvent.WINDOW_LOST_FOCUS);
366: super .hide();
367: // bug 6186499
368: }
369: }
|