javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Decorations.java
changeset 21 2a9601315dfc
child 35 85266cc22c7f
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2000, 2007 IBM Corporation and others.
       
     3  * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     4  * All rights reserved. This program and the accompanying materials
       
     5  * are made available under the terms of the Eclipse Public License v1.0
       
     6  * which accompanies this distribution, and is available at
       
     7  * http://www.eclipse.org/legal/epl-v10.html
       
     8  *
       
     9  * Contributors:
       
    10  *     IBM Corporation - initial API and implementation
       
    11  *     Nokia Corporation - Qt implementation
       
    12  *******************************************************************************/
       
    13 package org.eclipse.swt.widgets;
       
    14 
       
    15 import org.eclipse.swt.SWT;
       
    16 import org.eclipse.swt.graphics.Image;
       
    17 import org.eclipse.swt.graphics.Internal_GfxPackageSupport;
       
    18 import org.eclipse.swt.graphics.Point;
       
    19 import org.eclipse.swt.graphics.Rectangle;
       
    20 import org.eclipse.swt.internal.qt.OS;
       
    21 import org.eclipse.swt.internal.qt.QObjectDeleteWrapper;
       
    22 import org.eclipse.swt.internal.qt.WidgetState;
       
    23 
       
    24 /**
       
    25  * Instances of this class provide the appearance and
       
    26  * behavior of <code>Shells</code>, but are not top
       
    27  * level shells or dialogs. Class <code>Shell</code>
       
    28  * shares a significant amount of code with this class,
       
    29  * and is a subclass.
       
    30  * <p>
       
    31  * IMPORTANT: This class was intended to be abstract and
       
    32  * should <em>never</em> be referenced or instantiated.
       
    33  * Instead, the class <code>Shell</code> should be used.
       
    34  * </p>
       
    35  * <p>
       
    36  * Instances are always displayed in one of the maximized,
       
    37  * minimized or normal states:
       
    38  * <ul>
       
    39  * <li>
       
    40  * When an instance is marked as <em>maximized</em>, the
       
    41  * window manager will typically resize it to fill the
       
    42  * entire visible area of the display, and the instance
       
    43  * is usually put in a state where it can not be resized
       
    44  * (even if it has style <code>RESIZE</code>) until it is
       
    45  * no longer maximized.
       
    46  * </li><li>
       
    47  * When an instance is in the <em>normal</em> state (neither
       
    48  * maximized or minimized), its appearance is controlled by
       
    49  * the style constants which were specified when it was created
       
    50  * and the restrictions of the window manager (see below).
       
    51  * </li><li>
       
    52  * When an instance has been marked as <em>minimized</em>,
       
    53  * its contents (client area) will usually not be visible,
       
    54  * and depending on the window manager, it may be
       
    55  * "iconified" (that is, replaced on the desktop by a small
       
    56  * simplified representation of itself), relocated to a
       
    57  * distinguished area of the screen, or hidden. Combinations
       
    58  * of these changes are also possible.
       
    59  * </li>
       
    60  * </ul>
       
    61  * </p>
       
    62  * Note: The styles supported by this class must be treated
       
    63  * as <em>HINT</em>s, since the window manager for the
       
    64  * desktop on which the instance is visible has ultimate
       
    65  * control over the appearance and behavior of decorations.
       
    66  * For example, some window managers only support resizable
       
    67  * windows and will always assume the RESIZE style, even if
       
    68  * it is not set.
       
    69  * <dl>
       
    70  * <dt><b>Styles:</b></dt>
       
    71  * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP</dd>
       
    72  * <dt><b>Events:</b></dt>
       
    73  * <dd>(none)</dd>
       
    74  * </dl>
       
    75  * Class <code>SWT</code> provides two "convenience constants"
       
    76  * for the most commonly required style combinations:
       
    77  * <dl>
       
    78  * <dt><code>SHELL_TRIM</code></dt>
       
    79  * <dd>
       
    80  * the result of combining the constants which are required
       
    81  * to produce a typical application top level shell: (that
       
    82  * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
       
    83  * </dd>
       
    84  * <dt><code>DIALOG_TRIM</code></dt>
       
    85  * <dd>
       
    86  * the result of combining the constants which are required
       
    87  * to produce a typical application dialog shell: (that
       
    88  * is, <code>TITLE | CLOSE | BORDER</code>)
       
    89  * </dd>
       
    90  * </dl>
       
    91  * <p>
       
    92  * IMPORTANT: This class is intended to be subclassed <em>only</em>
       
    93  * within the SWT implementation.
       
    94  * </p>
       
    95  *
       
    96  * @see #getMinimized
       
    97  * @see #getMaximized
       
    98  * @see Shell
       
    99  * @see SWT
       
   100  */
       
   101 public class Decorations extends Canvas {
       
   102     Image image;
       
   103     Menu menuBar;
       
   104     Menu [] menus;
       
   105     Control savedFocus;
       
   106     Button defaultButton, saveDefault;
       
   107 
       
   108     // Window state information for restoring the previous state
       
   109     int restoreState;
       
   110     Point fixedSize;
       
   111 
       
   112     // Holds the handle to the internal menu bar
       
   113     private int ownMenuBar;
       
   114 
       
   115     // Learned dimensions of normal window trim with title bar
       
   116     static int topTitleFrame = -1;
       
   117     static int leftTitleFrame = -1;
       
   118     static int rightTitleFrame = -1;
       
   119     static int bottomTitleFrame = -1;
       
   120 
       
   121     // Learned dimensions of thin window trim without title bar
       
   122     static int topThinFrame = -1;
       
   123     static int leftThinFrame = -1;
       
   124     static int rightThinFrame = -1;
       
   125     static int bottomThinFrame = -1;
       
   126 
       
   127 Decorations () {
       
   128     /* Do nothing */
       
   129 }
       
   130 
       
   131 /**
       
   132  * Constructs a new instance of this class given its parent
       
   133  * and a style value describing its behavior and appearance.
       
   134  * <p>
       
   135  * The style value is either one of the style constants defined in
       
   136  * class <code>SWT</code> which is applicable to instances of this
       
   137  * class, or must be built by <em>bitwise OR</em>'ing together
       
   138  * (that is, using the <code>int</code> "|" operator) two or more
       
   139  * of those <code>SWT</code> style constants. The class description
       
   140  * lists the style constants that are applicable to the class.
       
   141  * Style bits are also inherited from superclasses.
       
   142  * </p>
       
   143  *
       
   144  * @param parent a composite control which will be the parent of the new instance (cannot be null)
       
   145  * @param style the style of control to construct
       
   146  *
       
   147  * @exception IllegalArgumentException <ul>
       
   148  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
       
   149  * </ul>
       
   150  * @exception SWTException <ul>
       
   151  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
       
   152  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
       
   153  * </ul>
       
   154  *
       
   155  * @see SWT#BORDER
       
   156  * @see SWT#CLOSE
       
   157  * @see SWT#MIN
       
   158  * @see SWT#MAX
       
   159  * @see SWT#RESIZE
       
   160  * @see SWT#TITLE
       
   161  * @see SWT#NO_TRIM
       
   162  * @see SWT#SHELL_TRIM
       
   163  * @see SWT#DIALOG_TRIM
       
   164  * @see SWT#ON_TOP
       
   165  * @see Widget#checkSubclass
       
   166  * @see Widget#getStyle
       
   167  */
       
   168 public Decorations (Composite parent, int style) {
       
   169     super (parent, checkStyle (style, parent));
       
   170 }
       
   171 
       
   172 static int checkStyle (int style, Composite parent) {
       
   173     if ((style & SWT.NO_TRIM) != 0) {
       
   174         style &= ~(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.BORDER);
       
   175     }
       
   176     if ((style & (SWT.MENU | SWT.MIN | SWT.MAX | SWT.CLOSE)) != 0) {
       
   177         style |= SWT.TITLE;
       
   178     }
       
   179     return style;
       
   180 }
       
   181 
       
   182 protected void checkSubclass () {
       
   183     if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
       
   184 }
       
   185 
       
   186 void checkBorder_pp() {
       
   187     // For Shells SWT.BORDER means dialog window border. Not QFrame border.
       
   188     if ((state & WidgetState.CANVAS) != 0) {
       
   189         if(frameHandle != 0) {
       
   190             OS.QFrame_setFrameStyle(frameHandle, OS.QT_NOFRAME);
       
   191         }
       
   192     } else {
       
   193         super.checkBorder_pp ();
       
   194     }
       
   195 }
       
   196 
       
   197 void addMenu (Menu menu) {
       
   198     if (menus == null) menus = new Menu [4];
       
   199     for (int i=0; i<menus.length; i++) {
       
   200         if (menus [i] == null) {
       
   201             menus [i] = menu;
       
   202             return;
       
   203         }
       
   204     }
       
   205     Menu [] newMenus = new Menu [menus.length + 4];
       
   206     newMenus [menus.length] = menu;
       
   207     System.arraycopy (menus, 0, newMenus, 0, menus.length);
       
   208     menus = newMenus;
       
   209 }
       
   210 
       
   211 Control computeTabGroup () {
       
   212     return this;
       
   213 }
       
   214 
       
   215 Control computeTabRoot () {
       
   216     return this;
       
   217 }
       
   218 
       
   219 public void dispose () {
       
   220     if (isDisposed()) return;
       
   221     if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
       
   222     super.dispose ();
       
   223 }
       
   224 
       
   225 /**
       
   226  * Returns the receiver's default button if one had
       
   227  * previously been set, otherwise returns null.
       
   228  *
       
   229  * @return the default button or null
       
   230  *
       
   231  * @exception SWTException <ul>
       
   232  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   233  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   234  * </ul>
       
   235  *
       
   236  * @see #setDefaultButton(Button)
       
   237  */
       
   238 public Button getDefaultButton () {
       
   239     checkWidget();
       
   240     return defaultButton;
       
   241 }
       
   242 
       
   243 /**
       
   244  * Returns the receiver's image if it had previously been
       
   245  * set using <code>setImage()</code>. The image is typically
       
   246  * displayed by the window manager when the instance is
       
   247  * marked as iconified, and may also be displayed somewhere
       
   248  * in the trim when the instance is in normal or maximized
       
   249  * states.
       
   250  * <p>
       
   251  * Note: This method will return null if called before
       
   252  * <code>setImage()</code> is called. It does not provide
       
   253  * access to a window manager provided, "default" image
       
   254  * even if one exists.
       
   255  * </p>
       
   256  *
       
   257  * @return the image
       
   258  *
       
   259  * @exception SWTException <ul>
       
   260  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   261  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   262  * </ul>
       
   263  */
       
   264 public Image getImage () {
       
   265     checkWidget ();
       
   266     return image;
       
   267 }
       
   268 
       
   269 /**
       
   270  * Returns <code>true</code> if the receiver is currently
       
   271  * maximized, and false otherwise.
       
   272  * <p>
       
   273  *
       
   274  * @return the maximized state
       
   275  *
       
   276  * @exception SWTException <ul>
       
   277  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   278  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   279  * </ul>
       
   280  *
       
   281  * @see #setMaximized
       
   282  */
       
   283 public boolean getMaximized () {
       
   284     checkWidget();
       
   285     return hasState(OS.QT_WINDOWMAXIMIZED);
       
   286 }
       
   287 
       
   288 /**
       
   289  * Returns the receiver's menu bar if one had previously
       
   290  * been set, otherwise returns null.
       
   291  *
       
   292  * @return the menu bar or null
       
   293  *
       
   294  * @exception SWTException <ul>
       
   295  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   296  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   297  * </ul>
       
   298  */
       
   299 public Menu getMenuBar () {
       
   300     checkWidget();
       
   301     return menuBar;
       
   302 }
       
   303 
       
   304 /*
       
   305  *  Returns the handle to the menu bar. Creates an internal
       
   306  *  Menu bar if there is no menu bar set. If there is already
       
   307  *  a menu bar it returns the handle for that.
       
   308  */
       
   309 public int internal_getOwnMenuBar(){
       
   310     if( menuBar != null && !menuBar.isDisposed() ){
       
   311         return menuBar.handle;
       
   312     }
       
   313     if ( ownMenuBar == 0 ){
       
   314         ownMenuBar = OS.QMenuBar_new(topHandle);
       
   315         if (parent == null ){
       
   316             OS.QMainWindow_setMenuBar(topHandle, ownMenuBar);
       
   317         }
       
   318         else{
       
   319             int layout = OS.QWidget_layout(topHandle);
       
   320             OS.QLayout_setMenuBar( layout,  ownMenuBar );
       
   321         }
       
   322 
       
   323     }
       
   324     return ownMenuBar;
       
   325 }
       
   326 
       
   327 /*
       
   328  * Destroys the own menu bar if there is one.
       
   329  */
       
   330 public void internal_destroyOwnMenuBar(){
       
   331     if (ownMenuBar != 0 ){
       
   332         QObjectDeleteWrapper.deleteSafely( ownMenuBar );
       
   333         ownMenuBar = 0;
       
   334     }
       
   335 }
       
   336 
       
   337 
       
   338 /**
       
   339  * Returns <code>true</code> if the receiver is currently
       
   340  * minimized, and false otherwise.
       
   341  * <p>
       
   342  *
       
   343  * @return the minimized state
       
   344  *
       
   345  * @exception SWTException <ul>
       
   346  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   347  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   348  * </ul>
       
   349  *
       
   350  * @see #setMinimized
       
   351  */
       
   352 public boolean getMinimized () {
       
   353     checkWidget();
       
   354     return hasState(OS.QT_WINDOWMINIMIZED);
       
   355 }
       
   356 
       
   357 String getNameText () {
       
   358     return getText ();
       
   359 }
       
   360 
       
   361 /**
       
   362  * Returns the receiver's text, which is the string that the
       
   363  * window manager will typically display as the receiver's
       
   364  * <em>title</em>. If the text has not previously been set,
       
   365  * returns an empty string.
       
   366  *
       
   367  * @return the text
       
   368  *
       
   369  * @exception SWTException <ul>
       
   370  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   371  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   372  * </ul>
       
   373  */
       
   374 public String getText () {
       
   375     checkWidget();
       
   376     return OS.QWidget_windowTitle(topHandle);
       
   377 }
       
   378 
       
   379 public boolean isReparentable () {
       
   380     checkWidget ();
       
   381     return false;
       
   382 }
       
   383 
       
   384 boolean isTabGroup () {
       
   385     return true;
       
   386 }
       
   387 
       
   388 boolean isTabItem () {
       
   389     return false;
       
   390 }
       
   391 
       
   392 Decorations menuShell () {
       
   393     return this;
       
   394 }
       
   395 
       
   396 void removeMenu (Menu menu) {
       
   397     if (menus == null) return;
       
   398     for (int i=0; i<menus.length; i++) {
       
   399         if (menus [i] == menu) {
       
   400             menus [i] = null;
       
   401             return;
       
   402         }
       
   403     }
       
   404 }
       
   405 
       
   406 void releaseChildren_pp (boolean destroy) {
       
   407     if (menuBar != null) {
       
   408         menuBar.release (false);
       
   409         menuBar = null;
       
   410     }
       
   411     internal_destroyOwnMenuBar();
       
   412     super.releaseChildren_pp (destroy);
       
   413     if (menus != null) {
       
   414         for (int i=0; i<menus.length; i++) {
       
   415             Menu menu = menus [i];
       
   416             if (menu != null && !menu.isDisposed ()) {
       
   417                 menu.dispose ();
       
   418             }
       
   419         }
       
   420         menus = null;
       
   421     }
       
   422 }
       
   423 
       
   424 void releaseWidget_pp () {
       
   425     super.releaseWidget_pp ();
       
   426     image = null;
       
   427     savedFocus = null;
       
   428     defaultButton = saveDefault = null;
       
   429 }
       
   430 
       
   431 boolean restoreFocus () {
       
   432     if (savedFocus != null && savedFocus.isDisposed ()) savedFocus = null;
       
   433     boolean restored = savedFocus != null && savedFocus.setFocus (OS.QT_OTHERFOCUSREASON);
       
   434     /*
       
   435     * This code is intentionally commented.  When no widget
       
   436     * has been given focus, some platforms give focus to the
       
   437     * default button. We don't do this.
       
   438     */
       
   439 //  if (restored) return true;
       
   440 //  if (defaultButton != null && !defaultButton.isDisposed ()) {
       
   441 //      if (defaultButton.setFocus ()) return true;
       
   442 //  }
       
   443     return restored;
       
   444 }
       
   445 
       
   446 /**
       
   447  * If the argument is not null, sets the receiver's default
       
   448  * button to the argument, and if the argument is null, sets
       
   449  * the receiver's default button to the first button which
       
   450  * was set as the receiver's default button (called the
       
   451  * <em>saved default button</em>). If no default button had
       
   452  * previously been set, or the saved default button was
       
   453  * disposed, the receiver's default button will be set to
       
   454  * null.
       
   455  * <p>
       
   456  * The default button is the button that is selected when
       
   457  * the receiver is active and the user presses ENTER.
       
   458  * </p>
       
   459  *
       
   460  * @param button the new default button
       
   461  *
       
   462  * @exception IllegalArgumentException <ul>
       
   463  *    <li>ERROR_INVALID_ARGUMENT - if the button has been disposed</li>
       
   464  *    <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
       
   465  * </ul>
       
   466  * @exception SWTException <ul>
       
   467  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   468  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   469  * </ul>
       
   470  */
       
   471 public void setDefaultButton (Button button) {
       
   472     checkWidget ();
       
   473     if (button != null) {
       
   474         if (button.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
       
   475         if (button.menuShell () != this) error(SWT.ERROR_INVALID_PARENT);
       
   476     }
       
   477     setDefaultButton (button, true);
       
   478 }
       
   479 
       
   480 void setDefaultButton (Button button, boolean save) {
       
   481     if (button == null) {
       
   482         if (defaultButton == saveDefault) {
       
   483             if (save) saveDefault = null;
       
   484             return;
       
   485         }
       
   486     } else {
       
   487         if ((button.style & SWT.PUSH) == 0) return;
       
   488         if (button == defaultButton) return;
       
   489     }
       
   490     if (defaultButton != null) {
       
   491         if (!defaultButton.isDisposed ()) defaultButton.setDefault (false);
       
   492     }
       
   493     if ((defaultButton = button) == null) defaultButton = saveDefault;
       
   494     if (defaultButton != null) {
       
   495         if (!defaultButton.isDisposed ()) defaultButton.setDefault (true);
       
   496     }
       
   497     if (save) saveDefault = defaultButton;
       
   498     if (saveDefault != null && saveDefault.isDisposed ()) saveDefault = null;
       
   499 }
       
   500 
       
   501 /**
       
   502  * Sets the receiver's image to the argument, which may
       
   503  * be null. The image is typically displayed by the window
       
   504  * manager when the instance is marked as iconified, and
       
   505  * may also be displayed somewhere in the trim when the
       
   506  * instance is in normal or maximized states.
       
   507  *
       
   508  * @param image the new image (or null)
       
   509  *
       
   510  * @exception IllegalArgumentException <ul>
       
   511  *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
       
   512  * </ul>
       
   513  * @exception SWTException <ul>
       
   514  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   515  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   516  * </ul>
       
   517  */
       
   518 public void setImage (Image image) {
       
   519     checkWidget ();
       
   520     if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
       
   521     this.image = image;
       
   522     int icon = (image != null ? Internal_GfxPackageSupport.getIconHandle(image) :
       
   523         Internal_GfxPackageSupport.getNullIconHandle());
       
   524     OS.QWidget_setWindowIcon(topHandle, icon);
       
   525 }
       
   526 
       
   527 /**
       
   528  * Sets the maximized state of the receiver.
       
   529  * If the argument is <code>true</code> causes the receiver
       
   530  * to switch to the maximized state, and if the argument is
       
   531  * <code>false</code> and the receiver was previously maximized,
       
   532  * causes the receiver to switch back to either the minimized
       
   533  * or normal states.
       
   534  * <p>
       
   535  * Note: The result of intermixing calls to <code>setMaximized(true)</code>
       
   536  * and <code>setMinimized(true)</code> will vary by platform. Typically,
       
   537  * the behavior will match the platform user's expectations, but not
       
   538  * always. This should be avoided if possible.
       
   539  * </p>
       
   540  *
       
   541  * @param maximized the new maximized state
       
   542  *
       
   543  * @exception SWTException <ul>
       
   544  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   545  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   546  * </ul>
       
   547  *
       
   548  * @see #setMinimized
       
   549  */
       
   550 public void setMaximized (boolean maximized) {
       
   551     checkWidget();
       
   552     // On Symbian platform top-level Shells are not resizeable.
       
   553     if(OS.windowServer == OS.WS_SYMBIAN_S60 && parent == null) {
       
   554         // If canceling maximized state then it must be to return to maximized
       
   555         // or minimized. It should not be possible to clear the maximized state
       
   556         // because then automatic resizing won't happen anymore.
       
   557         if(!maximized &&
       
   558                 (restoreState != OS.QT_WINDOWMAXIMIZED) &&
       
   559                 (restoreState != OS.QT_WINDOWMINIMIZED))
       
   560             return;
       
   561     }
       
   562     setRestoreState(OS.QT_WINDOWMAXIMIZED, !maximized);
       
   563 }
       
   564 
       
   565 final void storeState(int state) {
       
   566     if((state & OS.QT_WINDOWMINIMIZED) != 0) {
       
   567         restoreState = OS.QT_WINDOWMINIMIZED;
       
   568     } else if((state & OS.QT_WINDOWMAXIMIZED) != 0) {
       
   569         restoreState = OS.QT_WINDOWMAXIMIZED;
       
   570     } else {
       
   571         restoreState = 0;
       
   572     }
       
   573 }
       
   574 
       
   575 final boolean hasState(int state) {
       
   576     int bits = OS.QWidget_windowState(topHandle);
       
   577     return (bits & state) != 0;
       
   578 }
       
   579 
       
   580 final boolean sizeFixed() {
       
   581     return OS.QWidget_minimumSize(topHandle).equals(OS.QWidget_maximumSize(topHandle));
       
   582 }
       
   583 
       
   584 final void unlockSize() {
       
   585     OS.QWidget_setMaximumSize(topHandle, OS.QWIDGETSIZE_MAX, OS.QWIDGETSIZE_MAX);
       
   586     OS.QWidget_setMinimumSize(topHandle, 0, 0);
       
   587 }
       
   588 
       
   589 final void setState(final int state) {
       
   590     final int oldState = OS.QWidget_windowState(topHandle);
       
   591     if((oldState & state) != 0) return;
       
   592     storeState(oldState);
       
   593     int newState = oldState;
       
   594     int statesToRemove = (OS.QT_WINDOWFULLSCREEN|OS.QT_WINDOWMAXIMIZED|OS.QT_WINDOWMINIMIZED) & ~state;
       
   595     newState &= ~statesToRemove;
       
   596     newState |= state;
       
   597 
       
   598     // Full screen and maximize won't work if size is fixed. The fixed size
       
   599     // needs to be stored and then restored when going back to normal state.
       
   600     if (((newState & (OS.QT_WINDOWFULLSCREEN|OS.QT_WINDOWMAXIMIZED)) != 0) &&
       
   601             ((oldState & (OS.QT_WINDOWFULLSCREEN|OS.QT_WINDOWMAXIMIZED)) == 0)) {
       
   602         if (sizeFixed()) {
       
   603             fixedSize = OS.QWidget_minimumSize(topHandle);
       
   604             style |= SWT.Resize;
       
   605             unlockSize();
       
   606         }
       
   607     }
       
   608 
       
   609     // Going directly from full screen to maximized doesn't work. Need to go normal first.
       
   610     if((newState & OS.QT_WINDOWMAXIMIZED)!= 0 && (oldState & OS.QT_WINDOWFULLSCREEN)!= 0) {
       
   611         OS.QWidget_setWindowState(topHandle, 0);
       
   612     }
       
   613 
       
   614     OS.QWidget_setWindowState(topHandle, newState);
       
   615 
       
   616     // Restore the fixed size if back to normal
       
   617     if (((newState & (OS.QT_WINDOWFULLSCREEN|OS.QT_WINDOWMAXIMIZED)) == 0)) {
       
   618         if (fixedSize != null) {
       
   619             OS.QWidget_setFixedSize(topHandle, fixedSize.x, fixedSize.y);
       
   620             style &= ~SWT.Resize;
       
   621             fixedSize = null;
       
   622         }
       
   623     }
       
   624 }
       
   625 
       
   626 final void restoreState() {
       
   627     // This might not restore it from minimized if wm doesn't allow it.
       
   628     // It might e.g. blink in the task bar to indicate to the user
       
   629     // that the window wants to become active.
       
   630     if(restoreState == OS.QT_WINDOWMINIMIZED) {
       
   631         setState(OS.QT_WINDOWMINIMIZED);
       
   632     } else if(restoreState == OS.QT_WINDOWMAXIMIZED) {
       
   633         setState(OS.QT_WINDOWMAXIMIZED);
       
   634         bringToTop(false);
       
   635     } else {
       
   636         setState(OS.QT_WINDOWNOSTATE);
       
   637         bringToTop(false);
       
   638     }
       
   639     restoreState = 0;
       
   640 }
       
   641 
       
   642 void bringToTop (boolean force) {
       
   643     if(isDisposed()) return;
       
   644     OS.QWidget_activateWindow(topHandle);
       
   645     OS.QWidget_raise(topHandle);
       
   646 }
       
   647 
       
   648 /**
       
   649  * Sets the receiver's menu bar to the argument, which
       
   650  * may be null.
       
   651  *
       
   652  * @param menu the new menu bar
       
   653  *
       
   654  * @exception IllegalArgumentException <ul>
       
   655  *    <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
       
   656  *    <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
       
   657  * </ul>
       
   658  * @exception SWTException <ul>
       
   659  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   660  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   661  * </ul>
       
   662  */
       
   663 public void setMenuBar (Menu menu) {
       
   664     checkWidget();
       
   665     if (menuBar == menu) return;
       
   666 
       
   667     if (menu != null) {
       
   668         if (menu.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
       
   669         if ((menu.style & SWT.BAR) == 0) error (SWT.ERROR_MENU_NOT_BAR);
       
   670         if (menu.parent != this) error (SWT.ERROR_INVALID_PARENT);
       
   671         // Feature on Qt: Setting a new menu bar causes deletion of the old menu bar.
       
   672         // in order to adjust shell disposes the menu.
       
   673         if ( menuBar !=null ) menuBar.dispose();
       
   674         if (parent == null ){
       
   675         OS.QMainWindow_setMenuBar(topHandle, menu.handle);
       
   676         }else{
       
   677             int layout = OS.QWidget_layout(topHandle);
       
   678             OS.QLayout_setMenuBar( layout,  menu.handle );
       
   679         }
       
   680 
       
   681         menuBar = menu;
       
   682         ownMenuBar = 0;
       
   683         //Inform CommandArranger
       
   684         display.commandArranger.menuBarChanged( this );
       
   685     }
       
   686 }
       
   687 
       
   688 /**
       
   689  * Sets the minimized stated of the receiver.
       
   690  * If the argument is <code>true</code> causes the receiver
       
   691  * to switch to the minimized state, and if the argument is
       
   692  * <code>false</code> and the receiver was previously minimized,
       
   693  * causes the receiver to switch back to either the maximized
       
   694  * or normal states.
       
   695  * <p>
       
   696  * Note: The result of intermixing calls to <code>setMaximized(true)</code>
       
   697  * and <code>setMinimized(true)</code> will vary by platform. Typically,
       
   698  * the behavior will match the platform user's expectations, but not
       
   699  * always. This should be avoided if possible.
       
   700  * </p>
       
   701  *
       
   702  * @param minimized the new maximized state
       
   703  *
       
   704  * @exception SWTException <ul>
       
   705  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   706  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   707  * </ul>
       
   708  *
       
   709  * @see #setMaximized
       
   710  */
       
   711 public void setMinimized (boolean minimized) {
       
   712     checkWidget();
       
   713     setRestoreState(OS.QT_WINDOWMINIMIZED, !minimized);
       
   714 }
       
   715 
       
   716 final void setRestoreState(int state, boolean restore) {
       
   717     int oldState = OS.QWidget_windowState(topHandle);
       
   718     if(!restore) {
       
   719         setState(state);
       
   720     } else {
       
   721         if((oldState & state) == 0) return;
       
   722         restoreState();
       
   723     }
       
   724 
       
   725 }
       
   726 
       
   727 void setSavedFocus (Control control) {
       
   728     savedFocus = control;
       
   729 }
       
   730 
       
   731 /**
       
   732  * Sets the receiver's text, which is the string that the
       
   733  * window manager will typically display as the receiver's
       
   734  * <em>title</em>, to the argument, which must not be null.
       
   735  *
       
   736  * @param string the new text
       
   737  *
       
   738  * @exception IllegalArgumentException <ul>
       
   739  *    <li>ERROR_NULL_ARGUMENT - if the text is null</li>
       
   740  * </ul>
       
   741  * @exception SWTException <ul>
       
   742  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   743  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   744  * </ul>
       
   745  */
       
   746 public void setText (String string) {
       
   747     checkWidget();
       
   748     if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
       
   749     OS.QWidget_setWindowTitle(topHandle, string);
       
   750     OS.QWidget_setWindowIconText(topHandle, string);
       
   751 }
       
   752 
       
   753 boolean traverseItem (boolean next) {
       
   754     return false;
       
   755 }
       
   756 
       
   757 boolean invokeDefaultButton() {
       
   758     if (defaultButton != null && !defaultButton.isDisposed()) {
       
   759         int dbHandle = defaultButton.handle;
       
   760         if (OS.QPushButton_isDefault(dbHandle) && defaultButton.isVisible()
       
   761                 && defaultButton.isEnabled()) {
       
   762             OS.QAbstractButton_click(dbHandle);
       
   763             return true; // success
       
   764         }
       
   765     }
       
   766     return false; // failure
       
   767 }
       
   768 
       
   769 void saveFocus () {
       
   770     Control control = display._getFocusControl ();
       
   771     if (control != null && control != this && this == control.menuShell ()) {
       
   772         setSavedFocus (control);
       
   773     }
       
   774 }
       
   775 
       
   776 // If the window will get decoration eventually
       
   777 boolean willBeDecorated() {
       
   778     if(OS.windowServer == OS.WS_SYMBIAN_S60) return false;
       
   779     int flags = OS.QWidget_windowFlags(topHandle);
       
   780     if((flags & OS.QT_WINDOWFLAGS_FRAMELESSWINDOWHINT) != 0)
       
   781         return false;
       
   782     return true;
       
   783 }
       
   784 
       
   785 // If the window will get the normal thick decoration (title bar, buttons, etc.)
       
   786 boolean thickFrame() {
       
   787     return willBeDecorated() && !thinFrame();
       
   788 }
       
   789 
       
   790 // If the window will get the thin decoration
       
   791 boolean thinFrame() {
       
   792     if(OS.windowServer == OS.WS_SYMBIAN_S60) return false;
       
   793     if((style & SWT.RESIZE) != 0) return false;
       
   794     int flags = OS.QWidget_windowFlags(topHandle);
       
   795     if((flags &
       
   796             (OS.QT_WINDOWFLAGS_WINDOWMAXIMIZEBUTTONHINT|
       
   797             OS.QT_WINDOWFLAGS_WINDOWMINIMIZEBUTTONHINT|
       
   798             OS.QT_WINDOWFLAGS_WINDOWSYSTEMMENUHINT|
       
   799             OS.QT_WINDOWFLAGS_WINDOWTITLEHINT)) == 0) {
       
   800         return true;
       
   801     }
       
   802     return false;
       
   803 }
       
   804 
       
   805 // The window trim around the left/bottom/right edges
       
   806 int windowFrameTrim() {
       
   807     if(!willBeDecorated())
       
   808         return 0;
       
   809 
       
   810     if(thinFrame()) {
       
   811         return leftThinFrame != -1 ? leftThinFrame : 4;
       
   812     } else {
       
   813         return leftTitleFrame != -1 ? leftTitleFrame : 5;
       
   814     }
       
   815 }
       
   816 
       
   817 // The window trim above the top edge
       
   818 int windowTitleTrim() {
       
   819     if(!willBeDecorated())
       
   820         return 0;
       
   821 
       
   822     if(thinFrame()) {
       
   823         return topThinFrame > -1 ? topThinFrame : 4;
       
   824     } else {
       
   825         return topTitleFrame > -1 ? topTitleFrame : 24;
       
   826     }
       
   827 }
       
   828 
       
   829 boolean verifyTrim(int topTrim, int leftTrim, int rightTrim, int bottomTrim) {
       
   830     if(willBeDecorated() && (topTrim == 0 || leftTrim == 0 || rightTrim == 0 || bottomTrim == 0))
       
   831         return false;
       
   832     if(!willBeDecorated() && (topTrim != 0 || leftTrim != 0 || rightTrim != 0 || bottomTrim != 0))
       
   833         return false;
       
   834     if(leftTrim < 0 || topTrim < 0 || bottomTrim < 0 || rightTrim < 0)
       
   835         return false;
       
   836     if(leftTrim != rightTrim)
       
   837         return false;
       
   838     if(thickFrame() && (topTrim == bottomTrim))
       
   839         return false;
       
   840     return true;
       
   841 }
       
   842 
       
   843 void learnTrim() {
       
   844     if(!willBeDecorated()) return;
       
   845 
       
   846     int state = OS.QWidget_windowState(topHandle);
       
   847     if((state & OS.QT_WINDOWMINIMIZED) != 0) return;
       
   848     if((state & OS.QT_WINDOWFULLSCREEN) != 0) return;
       
   849 
       
   850     // Try to measure the window frame from the current state of the widget.
       
   851     // This doesn't return correctly if window manager has not decorated the
       
   852     // window yet.
       
   853     Rectangle frameRect = OS.QWidget_frameGeometry(topHandle);
       
   854     Rectangle rect = OS.QWidget_geometry(topHandle);
       
   855     int leftTrim = rect.x - frameRect.x;
       
   856     int topTrim = rect.y - frameRect.y;
       
   857     int bottomTrim = frameRect.height - rect.height - topTrim;
       
   858     int rightTrim = frameRect.width - rect.width - leftTrim;
       
   859 
       
   860     // Ignore wrong results
       
   861     if(!verifyTrim(topTrim, leftTrim, rightTrim, bottomTrim)) return;
       
   862 
       
   863     // Learn the normal frame
       
   864     if(thickFrame()) {
       
   865         if(topTrim > topTitleFrame) topTitleFrame = topTrim;
       
   866         if(leftTrim > leftTitleFrame) leftTitleFrame = leftTrim;
       
   867         if(rightTrim > rightTitleFrame) rightTitleFrame = rightTrim;
       
   868         if(bottomTrim > bottomTitleFrame) bottomTitleFrame = bottomTrim;
       
   869     }
       
   870     // Learn the thin frame
       
   871     else if (thinFrame()) {
       
   872         if(topTrim > topThinFrame) topThinFrame = topTrim;
       
   873         if(leftTrim > leftThinFrame) leftThinFrame = leftTrim;
       
   874         if(rightTrim > rightThinFrame) rightThinFrame = rightTrim;
       
   875         if(bottomTrim > bottomThinFrame) bottomThinFrame = bottomTrim;
       
   876     }
       
   877 }
       
   878 
       
   879 boolean qt_event_focusOut(int reason) {
       
   880     boolean result = super.qt_event_focusOut(reason);
       
   881     saveFocus ();
       
   882     return result;
       
   883 }
       
   884 
       
   885 
       
   886 void qt_swt_event_focusWasGained() {
       
   887     super.qt_swt_event_focusWasGained();
       
   888     if (savedFocus != this) restoreFocus ();
       
   889 }
       
   890 
       
   891 void closeWidget () {
       
   892     Event event = new Event ();
       
   893     sendEvent (SWT.Close, event);
       
   894     if (event.doit && !isDisposed ()) dispose ();
       
   895 }
       
   896 
       
   897 
       
   898 boolean qt_event_close() {
       
   899     if (isEnabled()) closeWidget ();
       
   900     return true;
       
   901 }
       
   902 
       
   903 boolean qt_event_windowActivate(int widgetHandle) {
       
   904     if(widgetHandle == topHandle) {
       
   905         sendEvent(SWT.Activate);
       
   906     }
       
   907     return false;
       
   908 }
       
   909 
       
   910 boolean qt_event_windowDeactivate(int widgetHandle) {
       
   911     if(widgetHandle == topHandle) {
       
   912         sendEvent(SWT.Deactivate);
       
   913         saveFocus();
       
   914     }
       
   915     return false;
       
   916 }
       
   917 
       
   918 boolean qt_event_windowStateChange(int widgetHandle, int oldState) {
       
   919     int newState = OS.QWidget_windowState(topHandle);
       
   920     if((oldState & OS.QT_WINDOWMINIMIZED) != 0 && (newState & OS.QT_WINDOWMINIMIZED) == 0) {
       
   921         sendEvent(SWT.Deiconify);
       
   922         return false;
       
   923     }
       
   924     if((oldState & OS.QT_WINDOWMINIMIZED) == 0 && (newState & OS.QT_WINDOWMINIMIZED) != 0) {
       
   925         sendEvent(SWT.Iconify);
       
   926         /* Save the focus widget when the shell is minimized */
       
   927         menuShell ().saveFocus ();
       
   928         return false;
       
   929     }
       
   930     return false;
       
   931 }
       
   932 }