javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/ercp/swt/mobile/MobileShell.java
changeset 21 2a9601315dfc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/ercp/swt/mobile/MobileShell.java	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,561 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (c) 2005 Motorola Inc.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Yu You (Nokia Corp.) - initial API specification
+ *     Motorola Inc. - key state polling
+ *     Nokia Corporation - S60 implementation
+ *     Nokia Corporation - QT implementation
+ *******************************************************************************/
+package org.eclipse.ercp.swt.mobile;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.internal.qt.OS;
+import org.eclipse.swt.internal.qt.PackageProxy;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Internal_PackageSupport;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A shell particularly suitable for devices that require dynamic change of
+ * trims at run-time.
+ * 
+ * <p>
+ * The shell is a "top-level" window that can usually be visible and managed by
+ * the user or a window manager. Two unique features of this shell over a normal
+ * Shell are a new method <code>changeTrim(int, int)</code> to dynamically
+ * change Shell trim styles, and full-screen mode.
+ * </p>
+ * <p>
+ * MobileShell uses the whole available application space in the normal mode. In
+ * this mode, a little screen area (title bar) is often reserved to display text
+ * with or without an icon, and optional trim information. The text shows the
+ * application name text by default. See <code>setText(String)</code> to change
+ * the text value and <code>setImage(Image)</code> to set the icon.
+ * </p>
+ * <p>
+ * Outside the application screen space, mobile devices often reserve a screen
+ * space, named status area, for displaying some extra information regarding the
+ * device and other useful data. Such reserved space is usually accessable and
+ * programmable. MobileShell provides a method <code>setStatus(String)</code> to
+ * display text on the status area. It is up to the implementation to decide how
+ * to process the string, for example, if the content is too long to display.
+ * </p>
+ * <p>
+ * Unlike a normal shell, MobileShell supports a special screen mode to use the
+ * whole device screen space, instead of the application space in the normal
+ * mode. Applications can call a method <code>setFullScreenMode(boolean)</code>,
+ * to switch between normal and full-screen modes at run-time. This feature is
+ * often used in applications like media player and web browser, where those
+ * types of applications can request for a full-screen mode for better rendering
+ * effects.
+ * </p>
+ * <p>
+ * Note: The style SWT.NO_TRIM does not force changing to full-screen mode, but
+ * is a trimming style in which usually no title bar is visible.
+ * </p>
+ * 
+ * <dl>
+ * <dt><b>Trim Styles: </b></dt>
+ * MobileShell inherits styles from the Shell class, including:
+ * <dd>SHELL_TRIM</dd>
+ * <dd>DIALOG_TRIM</dd>
+ * <dd>NO_TRIM</dd>
+ * <dd>TITLE</dd>
+ * <dd>CLOSE</dd>
+ * <dd>BORDER</dd>
+ * </dl>
+ * 
+ * <dl>
+ * <dt><b>Status Styles: </b></dt>
+ * MobileShell introduces the concept of status pane and status pane style
+ * hints. When a status pane hint is not specified, the platform will choose a
+ * status pane style or no status pane.
+ * <dd>NO_STATUS_PANE</dd>
+ * <dd>SMALL_STATUS_PANE</dd>
+ * <dd>LARGE_STATUS_PANE</dd>
+ * </dl>
+ * 
+ * @see org.eclipse.swt.SWT#BORDER
+ * @see org.eclipse.swt.SWT#CLOSE
+ * @see org.eclipse.swt.SWT#TITLE
+ * @see org.eclipse.swt.SWT#NO_TRIM
+ * @see org.eclipse.swt.SWT#SHELL_TRIM
+ * @see org.eclipse.swt.SWT#DIALOG_TRIM
+ * @see org.eclipse.swt.SWT#MODELESS
+ * @see org.eclipse.swt.SWT#PRIMARY_MODAL
+ * @see org.eclipse.swt.SWT#APPLICATION_MODAL
+ * @see org.eclipse.swt.SWT#SYSTEM_MODAL
+ * @see #NO_STATUS_PANE
+ * @see #SMALL_STATUS_PANE
+ * @see #LARGE_STATUS_PANE <p>
+ *      IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ *      </p>
+ */
+public class MobileShell extends Shell {
+
+    String title;
+    Vector keyCodeVector = new Vector(10,10);
+    Listener keyListener;
+
+    /**
+     * Hint to show no status pane
+     */
+    public static final int NO_STATUS_PANE = 1;
+
+    /**
+     * Hint to show small status pane with shell
+     */
+    public static final int SMALL_STATUS_PANE = 2;
+
+    /**
+     * Hint show large status pane with shell
+     */
+    public static final int LARGE_STATUS_PANE = 3;
+    
+    static final class MobileShellPackageProxy extends PackageProxy {
+    }
+
+    /**
+     * Constructs a new instance of this class given only the style value
+     * describing its behavior and appearance. This is equivalent to calling
+     * <code>Shell((Display) null, style)</code>.
+     * <p>
+     * The style value is either one of the style constants defined in class
+     * <code>SWT</code> which is applicable to instances of this class, or must
+     * be built by <em>bitwise OR</em> 'ing together (that is, using the
+     * <code>int</code> "|" operator) two or more of those <code>SWT</code>
+     * style constants. The class description lists the style constants that are
+     * applicable to the class. Style bits are also inherited from superclasses.
+     * </p>
+     * 
+     * @param style
+     *            the style of control to construct
+     * 
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+     *                thread that created the receiver</li>
+     *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
+     *                allowed subclass</li>
+     *                </ul>
+     * 
+     * @see org.eclipse.swt.SWT#BORDER
+     * @see org.eclipse.swt.SWT#CLOSE
+     * @see org.eclipse.swt.SWT#TITLE
+     * @see org.eclipse.swt.SWT#NO_TRIM
+     * @see org.eclipse.swt.SWT#SHELL_TRIM
+     * @see org.eclipse.swt.SWT#DIALOG_TRIM
+     * @see org.eclipse.swt.SWT#MODELESS
+     * @see org.eclipse.swt.SWT#PRIMARY_MODAL
+     * @see org.eclipse.swt.SWT#APPLICATION_MODAL
+     * @see org.eclipse.swt.SWT#SYSTEM_MODAL
+     */
+    public MobileShell(int style) {
+        this((Display) null, style);
+    }
+
+    /**
+     * Constructs a new instance of this class given only the display to create
+     * it on. It is created with style <code>SWT.SHELL_TRIM</code>.
+     * <p>
+     * Note: Currently, null can be passed in for the display argument. This has
+     * the effect of creating the shell on the currently active display if there
+     * is one. If there is no current display, the shell is created on a
+     * "default" display. <b>Passing in null as the display argument is not
+     * considered to be good coding style, and may not be supported in a future
+     * release of SWT. </b>
+     * </p>
+     * 
+     * @param display
+     *            the display to create the shell on. Can be null.
+     * 
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+     *                thread that created the receiver</li>
+     *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
+     *                allowed subclass</li>
+     *                </ul>
+     */
+    public MobileShell(Display display) {
+        this(display, SWT.SHELL_TRIM);
+    }
+
+    /**
+     * Constructs a new instance of this class given the display to create it on
+     * and a style value describing its behavior and appearance.
+     * <p>
+     * The style value is either one of the style constants defined in class
+     * <code>SWT</code> which is applicable to instances of this class, or must
+     * be built by <em>bitwise OR</em> 'ing together (that is, using the
+     * <code>int</code> "|" operator) two or more of those <code>SWT</code>
+     * style constants. The class description lists the style constants that are
+     * applicable to the class. Style bits are also inherited from superclasses.
+     * </p>
+     * <p>
+     * Note: Currently, null can be passed in for the display argument. This has
+     * the effect of creating the shell on the currently active display if there
+     * is one. If there is no current display, the shell is created on a
+     * "default" display. <b>Passing in null as the display argument is not
+     * considered to be good coding style, and may not be supported in a future
+     * release of SWT. </b>
+     * </p>
+     * 
+     * @param display
+     *            the display to create the shell on. Can be null.
+     * @param style
+     *            the style of control to construct
+     * 
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+     *                thread that created the receiver</li>
+     *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
+     *                allowed subclass</li>
+     *                </ul>
+     * 
+     * @see org.eclipse.swt.SWT#CLOSE
+     * @see org.eclipse.swt.SWT#TITLE
+     * @see org.eclipse.swt.SWT#NO_TRIM
+     * @see org.eclipse.swt.SWT#SHELL_TRIM
+     * @see org.eclipse.swt.SWT#DIALOG_TRIM
+     * @see org.eclipse.swt.SWT#MODELESS
+     * @see org.eclipse.swt.SWT#PRIMARY_MODAL
+     * @see org.eclipse.swt.SWT#APPLICATION_MODAL
+     * @see org.eclipse.swt.SWT#SYSTEM_MODAL
+     */
+    public MobileShell(Display display, int style) {
+        this(display, style, LARGE_STATUS_PANE);
+    }
+
+    /**
+     * Constructs a new instance of this class given the display to create it
+     * on, a style value describing its behavior and appearance, and a status
+     * style describing the appearance of a status pane.
+     * <p>
+     * The style value is either one of the style constants defined in class
+     * <code>SWT</code> which is applicable to instances of this class, or must
+     * be built by <em>bitwise OR</em> 'ing together (that is, using the
+     * <code>int</code> "|" operator) two or more of those <code>SWT</code>
+     * style constants. The class description lists the style constants that are
+     * applicable to the class. Style bits are also inherited from superclasses.
+     * </p>
+     * <p>
+     * Note: Currently, null can be passed in for the display argument. This has
+     * the effect of creating the shell on the currently active display if there
+     * is one. If there is no current display, the shell is created on a
+     * "default" display. <b>Passing in null as the display argument is not
+     * considered to be good coding style, and may not be supported in a future
+     * release of SWT. </b>
+     * </p>
+     * 
+     * @param display
+     *            the display to create the shell on. Can be null.
+     * @param style
+     *            the style of control to construct
+     * @param statusStyle
+     *            the style of the status pane
+     * 
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+     *                thread that created the parent</li>
+     *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
+     *                allowed subclass</li>
+     *                </ul>
+     * 
+     * @see org.eclipse.swt.SWT#CLOSE
+     * @see org.eclipse.swt.SWT#TITLE
+     * @see org.eclipse.swt.SWT#NO_TRIM
+     * @see org.eclipse.swt.SWT#SHELL_TRIM
+     * @see org.eclipse.swt.SWT#DIALOG_TRIM
+     * @see org.eclipse.swt.SWT#MODELESS
+     * @see org.eclipse.swt.SWT#PRIMARY_MODAL
+     * @see org.eclipse.swt.SWT#APPLICATION_MODAL
+     * @see org.eclipse.swt.SWT#SYSTEM_MODAL
+     * @see #NO_STATUS_PANE
+     * @see #SMALL_STATUS_PANE
+     * @see #LARGE_STATUS_PANE
+     */
+    public MobileShell(Display display, int style, int statusStyle) {
+        super(display, null, style, new MobileShellPackageProxy());
+        if (!Internal_PackageSupport.isValidSubclass(this)) SWT.error(SWT.ERROR_INVALID_SUBCLASS);
+        changeTrim(style, statusStyle);
+        init();
+    }
+
+    /**
+     * Report whether the key has been pressed. A return value of true indicates
+     * the key is pressed or has been pressed since the state of this key was
+     * last checked. A return value of false indicates the key has not been
+     * pressed since the state of this key was last checked. Only the active
+     * Shell can return true for this method. Calling this method on a Shell
+     * that is not the currently active Shell will always return false and will
+     * not clear the key's "has-been-pressed" state.
+     * <p>
+     * Values of keyCode that are not valid for a given platform will result in
+     * a return value of false.
+     * <p>
+     * An application gaining focus should call <code>getKeyState()</code> for
+     * each key it is nterested in polling in order to clear the key's
+     * "has-been-pressed" state.
+     * 
+     * @param keyCode
+     *            keyCode of the key to be check
+     * 
+     * @return true if this shell is the active Shell and the key is pressed or
+     *         has been pressed since the last time the state of this key was
+     *         checked. Otherwise, return false.
+     * 
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
+     *                called from the thread that created the receiver</li>
+     *                </ul>
+     */
+    public boolean getKeyState(int keyCode) {
+        checkWidget();
+        Display display = getDisplay();
+        if (display.getActiveShell() != this) return false; // Current shell is not active
+        
+        Enumeration keyCodeIterator = keyCodeVector.elements();
+        int index = 0;
+        while(keyCodeIterator.hasMoreElements()) {
+            Integer keyCodeInteger = (Integer)(keyCodeIterator.nextElement());
+            if (keyCodeInteger.intValue() == keyCode) {
+                keyCodeVector.removeElementAt(index);
+                return true;
+            }
+            index ++;
+        }   
+        return false;
+    }
+
+    /**
+     * Sets the screen mode
+     * 
+     * This method controls whether the shell is in normal or full-screen mode.
+     * If the argument is <code>true</code> it causes the shell to switch to the
+     * full-screen state, and if the argument is <code>false</code> and the
+     * shell was in full-screen state, it causes the shell to switch back to the
+     * normal state.
+     * <p>
+     * 
+     * @param mode
+     *            the boolean value
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
+     *                called from the thread that created the receiver</li>
+     *                </ul>
+     */
+    public void setFullScreenMode(boolean mode) {
+        checkWidget();
+        Internal_PackageSupport.setRestoreState(this, OS.QT_WINDOWFULLSCREEN, !mode);
+    }
+
+    /**
+     * Sets the screen mode
+     * 
+     * This method controls whether the shell is in normal or full-screen mode.
+     * If the <code>fullScreenMode</code> argument is <code>true</code>, it causes the shell 
+     * to switch to the full-screen state, and if the argument is <code>false</code> it 
+     * causes the shell to switch back to the normal state.
+     * If the <code>showVKBSelector</code> argument is <code>true</code>,
+     * the Virtual Keyboard Selector used for displaying a virtual keyboard or other input
+     * mechanism will be made visible, if the platform supports it. Otherwise, a
+     * Virtual Keyboard Selector will not be visible.
+     * If any Commands are present, the Commands can still be invoked. This means
+     * a Command menu or softkey label area may use a portion of the screen.
+     * <p>
+     * 
+     * @param fullScreenMode
+     *            whether the shell should use the full screen
+     *            
+     * @param showVKBSelector
+     *            whether the Virtual Keyboard Selector should be displayed
+     *
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li>
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+     *                thread that created the receiver</li>
+     *                </ul>
+     */
+    public void setFullScreenMode(boolean fullScreenMode, boolean showVKBSelector) {
+        // TODO: VKB
+        setFullScreenMode(fullScreenMode);
+    }
+    
+    /**
+     * Changes the window trim mode. The implementation decides how to re-layout
+     * the content if the style changes. The method will throw an
+     * IllegalArgumentException if the given style is invalid.
+     * 
+     * @param style
+     *            the trim style
+     * @param statusStyle
+     *            the status pane style
+     * 
+     * @exception IllegalArgumentException
+     *                <ul>
+     *                <li>ERROR_INVALID_ARGUMENT - if the given style is invalid
+     *                </li>
+     *                </ul>
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
+     *                called from the thread that created the receiver</li>
+     *                </ul>
+     * 
+     * @see org.eclipse.swt.SWT#CLOSE
+     * @see org.eclipse.swt.SWT#TITLE
+     * @see org.eclipse.swt.SWT#NO_TRIM
+     * @see org.eclipse.swt.SWT#SHELL_TRIM
+     * @see org.eclipse.swt.SWT#DIALOG_TRIM
+     * @see #NO_STATUS_PANE
+     * @see #SMALL_STATUS_PANE
+     * @see #LARGE_STATUS_PANE
+     */
+    public void changeTrim(int style, int statusStyle) {
+        checkWidget();
+        Internal_PackageSupport.checkStyle(style, null);
+        int validStatusStyle = ~(NO_STATUS_PANE | SMALL_STATUS_PANE | LARGE_STATUS_PANE);
+        if ((statusStyle & validStatusStyle) != 0) {
+            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+        }
+        
+        // Setting of style
+        if(OS.windowServer == OS.WS_X11) {
+            /*
+             * Setting window flags on-the-fly doesn't change the window frame. Thus,
+             * it's not supported. It's a bad idea to change the flags if they don't do
+             * anything because there are assumptions made based on the current flags
+             * about what kind of frame the window has.
+             */
+        } else {
+            // TODO: Check if this is ok for S60
+            style &= ~(SWT.SHELL_TRIM|SWT.BORDER);
+            style |= style;
+            OS.QWidget_setWindowFlags(topHandle(), Internal_PackageSupport.windowFlagsFromStyle(this));
+        }
+        
+        // TODO: Setting of statusStyle
+    }
+
+    /**
+     * 
+     * Gets the full-screen state.
+     * 
+     * Returns true if in full screen mode, false otherwise.
+     * 
+     * @return Boolean the current screen mode.
+     * 
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
+     *                called from the thread that created the receiver</li>
+     *                </ul>
+     */
+    public boolean getFullScreenMode() {
+        checkWidget();
+        return Internal_PackageSupport.hasState(this, OS.QT_WINDOWFULLSCREEN);
+    }
+
+    /**
+     * Sets the status text.
+     * 
+     * The change will take effect immediately.
+     * 
+     * @param statusText
+     *            the status string value. It can be NULL.
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
+     *                called from the thread that created the receiver</li>
+     *                </ul>
+     */
+    public void setStatusText(String statusText) {
+        checkWidget();
+        title = statusText;
+    }
+
+    /**
+     * 
+     * Returns the status text.
+     * 
+     * @return String - The current status text.
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
+     *                called from the thread that created the receiver</li>
+     *                </ul>
+     */
+    public String getStatusText() {
+        checkWidget();
+        return title;
+    }
+
+    private void init() {
+    final Display display = this.getDisplay();
+    final MobileShell mobileShell = this;
+    keyListener = new Listener() {
+
+        public void handleEvent(Event event) {
+            // Only records the key event at currently active MobileShell
+            if (display.getActiveShell() == mobileShell) { 
+                Enumeration keyCodeIterator = keyCodeVector.elements();
+                boolean hasEntry = false;
+                while (keyCodeIterator.hasMoreElements()) {
+                    Integer keyCode = (Integer) (keyCodeIterator.nextElement());
+                    if (keyCode.intValue() == event.keyCode) {
+                        hasEntry = true;
+                        break;
+                    }
+                }
+                // If the keycode doesn't exist in vector, add it
+                if (!hasEntry) { 
+                    Integer addKeycode = new Integer(event.keyCode);
+                    keyCodeVector.addElement(addKeycode);
+                }
+            }
+
+        }
+    };
+    display.addFilter(SWT.KeyDown, keyListener);
+
+    mobileShell.addDisposeListener(new DisposeListener() {
+        public void widgetDisposed(DisposeEvent e) {
+            if (mobileShell != null && !mobileShell.isDisposed()) {
+                mobileShell.getDisplay().removeFilter(SWT.KeyDown, keyListener);
+            }
+        }
+
+    });
+}
+    
+private final int topHandle() {
+    return Internal_PackageSupport.topHandle(this);
+}
+}