javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/org/eclipse/swt/internal/qt/CommandArranger.java
changeset 78 71ad690e91f5
parent 35 85266cc22c7f
child 80 d6dafc5d983f
equal deleted inserted replaced
72:1f0034e370aa 78:71ad690e91f5
     9  *     Nokia Corporation - initial implementation
     9  *     Nokia Corporation - initial implementation
    10  *******************************************************************************/
    10  *******************************************************************************/
    11 package org.eclipse.swt.internal.qt;
    11 package org.eclipse.swt.internal.qt;
    12 
    12 
    13 import org.eclipse.ercp.swt.mobile.Command;
    13 import org.eclipse.ercp.swt.mobile.Command;
    14 import org.eclipse.swt.internal.CommandPresentationStrategyWrapper;
       
    15 import org.eclipse.swt.widgets.Control;
    14 import org.eclipse.swt.widgets.Control;
    16 import org.eclipse.swt.widgets.Decorations;
    15 import org.eclipse.swt.widgets.Decorations;
    17 import org.eclipse.swt.widgets.Display;
    16 import org.eclipse.swt.widgets.Display;
       
    17 import org.eclipse.swt.widgets.Internal_PackageSupport;
    18 import org.eclipse.swt.widgets.Menu;
    18 import org.eclipse.swt.widgets.Menu;
    19 import org.eclipse.swt.widgets.Shell;
    19 import org.eclipse.swt.widgets.Shell;
       
    20 import org.eclipse.swt.widgets.Widget;
       
    21 
    20 /**
    22 /**
    21  * Manages the Command presentation cycle. This is a singleton object that gets
    23  * Manages the Command presentation cycle. This is a singleton object that gets
    22  * notified about the events that can have an effect on the way the Commands are
    24  * notified about the events that can have an effect on the way the Commands are
    23  * represented. It maintains an ordered list of Commands on the current focus
    25  * represented. It maintains an ordered list of Commands on the current focus
    24  * context with the help of {@link CommandCollection}. It also notifies the
    26  * context with the help of {@link CommandCollection}. It also notifies the
    25  * currently active {@link CommandPresentationStrategy} so that the presentation
    27  * currently active {@link CommandPresentationStrategy} so that the presentation
    26  * is updated if necessary.
    28  * is updated if necessary.
    27  *
    29  * 
    28  * @see Command
    30  * @see Command
    29  * @see CommandCollection
    31  * @see CommandCollection
    30  * @see CommandPresentationStrategy
    32  * @see CommandPresentationStrategy
    31  */
    33  */
    32 public class CommandArranger {
    34 public class CommandArranger {
    33     Control focusedControl;
    35 
    34 
    36 /**
    35     /**
    37  * A helper for keeping an ordered list of {@link Command}s in the current focus
    36      * A helper for keeping an ordered list of {@link Command}s in the current focus context.
    38  * context. The Commands are ordered according to their proximity to the
    37      * The Commands are ordered according to their proximity to the currently focused control.
    39  * currently focused control. The ordered list starts with Commands from the
    38      * The ordered list starts with Commands from the currently focused Control if any and ends with
    40  * currently focused Control if any and ends with the active Shell and includes
    39      * the active Shell and includes all the Commands in between. If a Control has more
    41  * all the Commands in between. If a Control has more than one Command they are
    40      * than one Command they are ordered among themselves according to creation order.
    42  * ordered among themselves according to creation order.
    41      */
    43  */
    42     public class CommandCollection{
    44 public class CommandCollection {
    43 
    45 
    44         private Command[] fCommands;
    46 private Command[] fCommands;
    45 
    47 
    46         CommandCollection(){
    48 CommandCollection() {
    47             super();
    49     super();
    48         }
    50 }
    49 
    51 
    50         /**
    52 /**
    51          * Adds the command to the collection.
    53  * Adds the command to the collection. Warning: This does not make duplicate
    52          * Warning: This does not make duplicate control.
    54  * control.
    53          * @param command
    55  * 
    54          */
    56  * @param command
    55         void addCommand(Command command) {
    57  */
    56             if (command == null)
    58 void addCommand(Command command) {
    57                 return;
    59     if (command == null)
    58             if (fCommands == null) {
    60         return;
    59                 fCommands = new Command[1];
    61     if (fCommands == null) {
    60                 fCommands[0] = command;
    62         fCommands = new Command[1];
    61                 return;
    63         fCommands[0] = command;
       
    64         return;
       
    65     }
       
    66     int size = fCommands.length + 1;
       
    67     Command[] newList = new Command[size];
       
    68     // find the insertion point so that the order is correct
       
    69     int insertPoint = 0;
       
    70     Shell activeShell = display.getActiveShell();
       
    71     Control ctrl = display.getFocusControl();
       
    72     while (ctrl != null && ctrl != activeShell) {
       
    73         if (ctrl == command.control) {
       
    74             // Adding a command to focused control increment by one.
       
    75             // adding Command.internal_getCommands(ctrl).length will
       
    76             // just duplicate the count for Commands already in array.
       
    77             insertPoint++;
       
    78             break;
       
    79         }
       
    80         insertPoint += Command.internal_getCommands(ctrl).length;
       
    81         ctrl = ctrl.getParent();
       
    82     }
       
    83     System.arraycopy(fCommands, 0, newList, 0, insertPoint);
       
    84     System.arraycopy(fCommands, insertPoint, newList, insertPoint + 1, fCommands.length
       
    85         - insertPoint);
       
    86     newList[insertPoint] = command;
       
    87     fCommands = newList;
       
    88 }
       
    89 
       
    90 /**
       
    91  * Adds the list of Commands to the collection.
       
    92  * 
       
    93  * @param commands
       
    94  */
       
    95 void addCommand(Command[] commands) {
       
    96     if (commands == null || commands.length == 0)
       
    97         return;
       
    98     if (fCommands == null) {
       
    99         fCommands = new Command[commands.length];
       
   100         System.arraycopy(commands, 0, fCommands, 0, commands.length);
       
   101         return;
       
   102     }
       
   103     int size = commands.length + fCommands.length;
       
   104     Command[] newList = new Command[size];
       
   105     System.arraycopy(fCommands, 0, newList, 0, fCommands.length);
       
   106     System.arraycopy(commands, 0, newList, fCommands.length, commands.length);
       
   107     fCommands = newList;
       
   108 }
       
   109 
       
   110 /**
       
   111  * Removes the command from the list.
       
   112  * 
       
   113  * @param command
       
   114  */
       
   115 void removeCommand(Command command) {
       
   116     if (command == null)
       
   117         return;
       
   118     if (fCommands == null || fCommands.length == 0)
       
   119         return;
       
   120     int removeIndex = -1;
       
   121     for (int i = 0; i < fCommands.length; i++) {
       
   122         if (fCommands[i] == command) {
       
   123             removeIndex = i;
       
   124         }
       
   125     }
       
   126     if (removeIndex == -1)
       
   127         return;
       
   128     Command[] newList = new Command[fCommands.length - 1];
       
   129     System.arraycopy(fCommands, 0, newList, 0, removeIndex);
       
   130     System.arraycopy(fCommands, removeIndex + 1, newList, removeIndex, (fCommands.length
       
   131         - removeIndex - 1));
       
   132     fCommands = newList;
       
   133 }
       
   134 
       
   135 /**
       
   136  * Returns the number of the Commands
       
   137  * 
       
   138  * @return boolean
       
   139  */
       
   140 int getSize() {
       
   141     int size = 0;
       
   142     if (fCommands != null)
       
   143         size = fCommands.length;
       
   144     return size;
       
   145 }
       
   146 
       
   147 /**
       
   148  * Retrieves the Commands of the types indicated by the commandTypes array. The
       
   149  * order of the commandTypes array has no significance. Passing a null parameter
       
   150  * or an empty array retrieves all the available Commands.
       
   151  * 
       
   152  * @param commandTypes
       
   153  * @return Command list
       
   154  */
       
   155 Command[] getCommands(int[] commandTypes) {
       
   156     if (commandTypes == null || commandTypes.length == 0) {
       
   157         return fCommands;
       
   158     }
       
   159     int size = getSize();
       
   160     Command[] filteredCommands = new Command[size];
       
   161     int index = 0;
       
   162     for (int i = 0; i < fCommands.length; i++) {
       
   163         for (int j = 0; j < commandTypes.length; j++) {
       
   164             if (fCommands[i].type == commandTypes[j]) {
       
   165                 filteredCommands[index] = fCommands[i];
       
   166                 index++;
       
   167                 break;
    62             }
   168             }
    63             int size = fCommands.length + 1;
   169         }
    64             Command[] newList = new Command[size];
   170     }
    65             // find the insertion point so that the order is correct
   171     if (size > (index)) {// Some commands filtered resize the Array
    66             int insertPoint = 0;
   172         Command[] shrunk = new Command[index];
    67             Shell activeShell = display.getActiveShell();
   173         System.arraycopy(filteredCommands, 0, shrunk, 0, index);
    68             Control ctrl = display.getFocusControl();
   174         return shrunk;
    69             while (ctrl != null && ctrl != activeShell) {
   175     }
    70                 if (ctrl == command.control) {
   176     return filteredCommands;
    71                     // Adding a command to focused control increment by one.
   177 }
    72                     // adding Command.internal_getCommands(ctrl).length will
   178 
    73                     // just duplicate the count for Commands already in array.
   179 }// CommandCollection
    74                     insertPoint++;
   180 
    75                     break;
   181 private CommandCollection currentCommands;
    76                 }
   182 private Command defaultCommand;
    77                 insertPoint += Command.internal_getCommands(ctrl).length;
   183 private Display display;
    78                 ctrl = ctrl.getParent();
   184 Control focusedControl;
       
   185 Shell lastKnownActiveShell;
       
   186 private Command[] positiveKeyCommands;
       
   187 private Command negativeKeyCommand;
       
   188 
       
   189 
       
   190 public CommandArranger(Display display) {
       
   191     super();
       
   192     this.display = display;
       
   193     currentCommands = new CommandCollection();
       
   194 }
       
   195 
       
   196 /**
       
   197  * Called when the application changes the QMenuBar. This method does not handle
       
   198  * the cases when the QMenuBar may change when the active top-level Shell
       
   199  * changes. Since this does not cause a menu bar change on all platforms.
       
   200  * 
       
   201  * @see org.eclipse.swt.widgets.Decorations#setMenuBar(Menu)
       
   202  * 
       
   203  **/
       
   204 public void menuBarChanged(Decorations decorations) {
       
   205     if (currentCommands == null || currentCommands.getSize() < 1)
       
   206         return;
       
   207     // if the changed menu bar is not on the active shell ignore and leave
       
   208     // it to focus change.
       
   209     if (decorations.getShell() != decorations.getDisplay().getActiveShell())
       
   210         return;
       
   211     // Call internal_getOwnMenuBar because the menu bar can be set to null
       
   212     // in Decorations and
       
   213     // we may need to create the internal one.
       
   214     int menuBarHandle = decorations.internal_getOwnMenuBar();
       
   215 
       
   216     handleMenuBarChanged(menuBarHandle, currentCommands);
       
   217 }
       
   218 
       
   219 /**
       
   220  * Called when a new Shell becomes active.
       
   221  * 
       
   222  * @see Control#qt_swt_event_focusWasGained() //TODO
       
   223  */
       
   224 public void shellActivityChanged() {
       
   225     if (display == null) {
       
   226         return;
       
   227     }
       
   228 
       
   229     Shell activeShell = display.getActiveShell();
       
   230     
       
   231     if (activeShell == lastKnownActiveShell) {
       
   232         return;
       
   233     }
       
   234     lastKnownActiveShell = activeShell;
       
   235     
       
   236     cleanPositiveCommands();
       
   237     cleanNegativeCommand();
       
   238     
       
   239     currentCommands = new CommandCollection();
       
   240 
       
   241     if (activeShell != null && Command.internal_getCommands(activeShell).length > 0) {
       
   242         currentCommands.addCommand(Command.internal_getCommands(activeShell));
       
   243     }
       
   244 
       
   245     // Determine where the commands go
       
   246     if (currentCommands.getSize() > 0) {
       
   247         Command[] add = currentCommands.getCommands(null);
       
   248         updateCommandPositions(add);
       
   249         placePositiveCommands();
       
   250         placeNegativeCommand();
       
   251     }
       
   252 }
       
   253 
       
   254 /**
       
   255  * Called when a new Command is created
       
   256  * 
       
   257  * @param command
       
   258  */
       
   259 public void commandAdded(Command command) {
       
   260     if (isInFocusContext(command.control)) {
       
   261         currentCommands.addCommand(command);
       
   262         handleCommandListChange(command, null, currentCommands);
       
   263     }
       
   264 }
       
   265 
       
   266 /**
       
   267  * Called when a Command is disposed
       
   268  * 
       
   269  * @param command
       
   270  */
       
   271 public void commandRemoved(Command command) {
       
   272     if (command == defaultCommand)
       
   273         defaultCommand = null;
       
   274     if (isInFocusContext(command.control)) {
       
   275         currentCommands.removeCommand(command);
       
   276         handleCommandListChange(null, command, currentCommands);
       
   277     }
       
   278 }
       
   279 
       
   280 /**
       
   281  * Called when the Display is getting disposed.
       
   282  */
       
   283 public void dispose() {
       
   284     currentCommands = null;
       
   285     display = null;
       
   286     positiveKeyCommands = null;
       
   287     negativeKeyCommand = null;
       
   288     defaultCommand = null;
       
   289     lastKnownActiveShell = null;
       
   290 }
       
   291 
       
   292 /**
       
   293  * Called when a Command is set default
       
   294  * 
       
   295  * @param command
       
   296  * @see Command#setDefaultCommand();
       
   297  */
       
   298 public void setDefaultCommand(Command command) {
       
   299     defaultCommand = command;
       
   300     if (isInFocusContext(command.control)) {
       
   301         handleDefaultCommandChange(command);
       
   302     }
       
   303 }
       
   304 
       
   305 /**
       
   306  * Returns the default command or null if there is none.
       
   307  * 
       
   308  * @return
       
   309  * @see Command#isDefaultCommand()
       
   310  */
       
   311 public Command getDefaultCommand() {
       
   312     return defaultCommand;
       
   313 }
       
   314 
       
   315 
       
   316 private boolean isInFocusContext(Control control) {
       
   317     Display display = control.getDisplay();
       
   318     Shell activeShell = display.getActiveShell();
       
   319     return control == activeShell;
       
   320 }
       
   321 
       
   322 private void handleCommandListChange(Command added, Command removed, CommandCollection commands) {
       
   323     cleanNegativeCommand();
       
   324     cleanPositiveCommands();
       
   325     updateCommandPositions(commands.getCommands(null));
       
   326     placeNegativeCommand();
       
   327     placePositiveCommands();
       
   328 }
       
   329 
       
   330 private void handleDefaultCommandChange(Command defaultCommand) {
       
   331     this.defaultCommand = defaultCommand;
       
   332     cleanPositiveCommands();
       
   333     placePositiveCommands();
       
   334 }
       
   335 
       
   336 private void updateCommandPositions(Command[] commands) {
       
   337     positiveKeyCommands = new Command[commands.length];
       
   338     int positiveKeyIndex = 0;
       
   339     for (int i = 0; i < commands.length; i++) {
       
   340         Command cmd = commands[i];
       
   341         if (cmd.isDefaultCommand()) {
       
   342             defaultCommand = cmd;
       
   343             continue;
       
   344         }
       
   345         if (CommandUtils.isNegativeType(cmd.type)) {
       
   346             if (negativeKeyCommand == null || negativeKeyCommand.isDisposed()) {
       
   347                 negativeKeyCommand = cmd;
       
   348             } else if (negativeKeyCommand.getPriority() <= cmd.getPriority()) {
       
   349                 positiveKeyCommands[positiveKeyIndex] = negativeKeyCommand;
       
   350                 positiveKeyIndex++;
       
   351                 negativeKeyCommand = cmd;
       
   352             } else {
       
   353                 positiveKeyCommands[positiveKeyIndex] = cmd;
       
   354                 positiveKeyIndex++;
    79             }
   355             }
    80             System.arraycopy(fCommands, 0, newList, 0, insertPoint);
   356             continue;
    81             System.arraycopy(fCommands, insertPoint, newList, insertPoint + 1,
   357         }
    82                     fCommands.length - insertPoint);
   358         positiveKeyCommands[positiveKeyIndex] = cmd;
    83             newList[insertPoint] = command;
   359         positiveKeyIndex++;
    84             fCommands = newList;
   360     }
    85         }
   361     if ((positiveKeyIndex) < positiveKeyCommands.length) {// needs to shrink
    86 
   362         Command[] rightSized = new Command[positiveKeyIndex];
    87         /**
   363         System.arraycopy(positiveKeyCommands, 0, rightSized, 0, rightSized.length);
    88          * Adds the list of Commands to the collection.
   364         positiveKeyCommands = rightSized;
    89          * @param commands
   365     }
    90          */
   366 }
    91         void addCommand( Command[] commands ){
   367 
    92             if (commands == null || commands.length == 0 ) return;
   368 private void cleanPositiveCommands() {
    93             if (fCommands == null ){
   369     boolean useBar = false;
    94                 fCommands = new Command[ commands.length ];
   370     if ((positiveKeyCommands != null && positiveKeyCommands.length > 1)
    95                 System.arraycopy(commands, 0, fCommands, 0, commands.length );
   371         || (defaultCommand != null && positiveKeyCommands != null)) {
    96                 return;
   372         useBar = true;
       
   373     }
       
   374     if (defaultCommand != null && !defaultCommand.isDisposed()
       
   375         && !defaultCommand.control.isDisposed()) {
       
   376         if (useBar) {
       
   377             OS.QWidget_removeAction(defaultCommand.control.getShell().internal_getOwnMenuBar(),
       
   378                 topHandle(defaultCommand));
       
   379         } else {
       
   380             OS.QWidget_removeAction(topHandle(defaultCommand.control), topHandle(defaultCommand));
       
   381         }
       
   382     }
       
   383     if (positiveKeyCommands != null) {
       
   384         for (int i = 0; i < positiveKeyCommands.length; i++) {
       
   385             Command cmd = positiveKeyCommands[i];
       
   386             if (cmd == null || cmd.isDisposed() || cmd.control.isDisposed()) {
       
   387                 continue;
    97             }
   388             }
    98             int size = commands.length + fCommands.length;
   389             int handle = 0;
    99             Command[] newList = new Command[ size ];
   390             if (useBar) {
   100             System.arraycopy(fCommands, 0, newList, 0, fCommands.length);
   391                 handle = cmd.control.getShell().internal_getOwnMenuBar();
   101             System.arraycopy(commands, 0, newList, fCommands.length , commands.length );
   392             } else {
   102             fCommands = newList;
   393                 handle = topHandle(positiveKeyCommands[0].control);
   103         }
       
   104 
       
   105         /**
       
   106          * Removes the command from the list.
       
   107          * @param command
       
   108          */
       
   109         void removeCommand( Command command ){
       
   110             if ( command == null ) return;
       
   111             if (fCommands == null || fCommands.length == 0 ) return;
       
   112             int removeIndex = -1;
       
   113             for (int i = 0; i < fCommands.length; i++) {
       
   114                 if(fCommands[i] == command ){
       
   115                     removeIndex = i;
       
   116                 }
       
   117             }
   394             }
   118             if ( removeIndex == -1 ) return;
   395             OS.QWidget_removeAction(handle, topHandle(cmd));
   119             Command[] newList = new Command[ fCommands.length -1 ];
   396 
   120             System.arraycopy( fCommands, 0, newList, 0, removeIndex);
   397         }
   121             System.arraycopy( fCommands, removeIndex + 1, newList, removeIndex, (fCommands.length - removeIndex -1) );
   398     }
   122             fCommands = newList;
   399 }
   123         }
   400 
   124 
   401 private void cleanNegativeCommand() {
   125         /**
   402     if (negativeKeyCommand != null && !negativeKeyCommand.isDisposed()
   126          * Returns the number of the Commands
   403         && !negativeKeyCommand.control.isDisposed()) {
   127          *
   404         OS.QWidget_removeAction(topHandle(negativeKeyCommand.control),
   128          * @return boolean
   405             topHandle(negativeKeyCommand));
   129          */
   406     }
   130         public int getSize(){
   407 }
   131             int size = 0;
   408 
   132             if (fCommands != null ) size = fCommands.length;
   409 private void placeNegativeCommand() {
   133             return size;
   410     if (negativeKeyCommand != null) {
   134         }
   411         OS.QWidget_addAction(Internal_PackageSupport.topHandle(negativeKeyCommand.control),
   135 
   412             topHandle(negativeKeyCommand));
   136         /**
   413     }
   137          * Retrieves the Commands of the types indicated by the commandTypes array.
   414 }
   138          * The order of the commandTypes array has no significance. Passing a null parameter
   415 
   139          * or an empty array retrieves all the available Commands.
   416 private void placePositiveCommands() {
   140          *
   417     if (defaultCommand != null) {
   141          * @param commandTypes
   418         int defaultCmdHandle = topHandle(defaultCommand);
   142          * @return Command list
   419         if (positiveKeyCommands != null) {
   143          */
   420             OS.QMenuBar_addAction(defaultCommand.control.getShell().internal_getOwnMenuBar(),
   144         public Command[] getCommands( int[] commandTypes ){
   421                 defaultCmdHandle);
   145             if ( commandTypes == null || commandTypes.length == 0 ){
   422         } else {
   146                 return fCommands;
   423             OS.QWidget_addAction(Internal_PackageSupport.topHandle(defaultCommand.control),
       
   424                 defaultCmdHandle);
       
   425         }
       
   426     }
       
   427     if (positiveKeyCommands != null) {
       
   428         if (positiveKeyCommands.length == 1 && defaultCommand == null) {
       
   429             OS.QWidget_addAction(Internal_PackageSupport.topHandle(positiveKeyCommands[0].control),
       
   430                 topHandle(positiveKeyCommands[0]));
       
   431         } else {
       
   432             CommandUtils.sort(positiveKeyCommands);
       
   433             for (int i = 0; i < positiveKeyCommands.length; i++) {
       
   434                 OS.QMenuBar_addAction(positiveKeyCommands[i].control.getShell()
       
   435                     .internal_getOwnMenuBar(), topHandle(positiveKeyCommands[i]));
   147             }
   436             }
   148             int size = getSize();
   437         }
   149             Command[] filteredCommands = new Command[size];
   438     }
   150             int index = 0;
   439 }
   151             for (int i = 0; i < fCommands.length ; i++) {
   440 
   152                 for(int j = 0; j<commandTypes.length; j++){
   441 private void handleMenuBarChanged(int newMenuBar, CommandCollection commands) {
   153                     if ( fCommands[i].type == commandTypes[j] ){
   442     placePositiveCommands();
   154                         filteredCommands[index]=fCommands[i];
   443 }
   155                         index++;
   444 
   156                         break;
   445 private static final int topHandle(Widget w) {
   157                     }
   446     return Internal_PackageSupport.topHandle(w);
   158                 }
   447 }
   159             }
   448 
   160             if( size > (index) ){// Some commands filtered resize the Array
   449 }
   161                 Command[] shrunk = new Command[index];
       
   162                 System.arraycopy( filteredCommands, 0, shrunk, 0, index);
       
   163                 return shrunk;
       
   164             }
       
   165             return filteredCommands;
       
   166         }
       
   167     }// CommandCollection
       
   168 
       
   169     private CommandCollection currentCommands;
       
   170     private CommandPresentationStrategy strategy;
       
   171     private Command defaultCommand;
       
   172     private Display display;
       
   173 
       
   174     public CommandArranger(Display display){
       
   175         super();
       
   176         this.display = display;
       
   177         currentCommands = new CommandCollection();
       
   178         strategy = CommandPresentationStrategyWrapper.createStrategy();
       
   179     }
       
   180 
       
   181 
       
   182 
       
   183     /**
       
   184      * Called when the application changes the QMenuBar.
       
   185      * This method does not handle the cases when the QMenuBar
       
   186      * may change when the active top-level Shell changes. Since
       
   187      * this does not cause a menu bar change on all platforms.
       
   188      *
       
   189      * @see org.eclipse.swt.widgets.Decorations#setMenuBar(Menu)
       
   190      *
       
   191      **/
       
   192     public void menuBarChanged( Decorations decorations ){
       
   193 
       
   194         if ( currentCommands == null || currentCommands.getSize() < 1 ) return;
       
   195         // if the changed menu bar is not on the active shell ignore and leave it to focus change.
       
   196         if (decorations.getShell() != decorations.getDisplay().getActiveShell() )return;
       
   197         // Call internal_getOwnMenuBar because the menu bar can be set to null in Decorations and
       
   198         // we may need to create the internal one.
       
   199         int menuBarHandle = decorations.internal_getOwnMenuBar();
       
   200 
       
   201         strategy.handleMenuBarChanged( menuBarHandle, currentCommands );
       
   202     }
       
   203 
       
   204     /**
       
   205      * Called when a new Control gains focus.
       
   206      *
       
   207      * @see Control#qt_swt_event_focusWasGained()
       
   208      */
       
   209     public void focusedControlChanged(){
       
   210         Control focusControl = display.getFocusControl();
       
   211         if (focusControl == focusedControl) {
       
   212             return;
       
   213         }
       
   214         focusedControl = focusControl;
       
   215 
       
   216         Shell activeShell = display.getActiveShell();
       
   217         CommandCollection oldCollection = currentCommands;
       
   218         currentCommands = new CommandCollection();
       
   219 
       
   220         Control ctrl = focusControl;
       
   221         while ( ctrl!= null && ctrl != activeShell ){
       
   222             if ( Command.internal_getCommands(ctrl).length > 0 ){
       
   223                 currentCommands.addCommand( Command.internal_getCommands(ctrl) );
       
   224             }
       
   225             ctrl = ctrl.getParent();
       
   226         }
       
   227         if (activeShell != null && Command.internal_getCommands(activeShell).length > 0 ){
       
   228             currentCommands.addCommand( Command.internal_getCommands(activeShell) );
       
   229         }
       
   230 
       
   231         if (strategy != null) {
       
   232             strategy.handleFocusChange(focusControl, oldCollection, currentCommands);
       
   233         }
       
   234     }
       
   235 
       
   236     /**
       
   237      * Called when a new Command is created
       
   238      * @param command
       
   239      */
       
   240     public void commandAdded( Command command ){
       
   241         if( isInFocusContext(command.control)){
       
   242             currentCommands.addCommand(command);
       
   243             strategy.handleCommandListChange(command, null, currentCommands);
       
   244         }
       
   245     }
       
   246 
       
   247     /**
       
   248      * Called when a Command is disposed
       
   249      * @param command
       
   250      */
       
   251     public void commandRemoved( Command command ){
       
   252         if ( command == defaultCommand ) defaultCommand = null;
       
   253         if (isInFocusContext(command.control)){
       
   254             currentCommands.removeCommand( command );
       
   255             strategy.handleCommandListChange(null, command, currentCommands);
       
   256         }
       
   257     }
       
   258 
       
   259     /**
       
   260      * Called when the Display is getting disposed.
       
   261      */
       
   262     public void dispose(){
       
   263         strategy.dispose();
       
   264         strategy = null;
       
   265         currentCommands = null;
       
   266         display = null;
       
   267     }
       
   268     /**
       
   269      * Called when a Command is set default
       
   270      *
       
   271      * @param command
       
   272      * @see Command#setDefaultCommand();
       
   273      */
       
   274     public void setDefaultCommand(Command command ){
       
   275         defaultCommand = command;
       
   276         if(isInFocusContext(command.control)){
       
   277             strategy.handleDefaultCommandChange(command);
       
   278         }
       
   279     }
       
   280 
       
   281     /**
       
   282      * Returns the default command or null if there is none.
       
   283      *
       
   284      * @return
       
   285      * @see Command#isDefaultCommand()
       
   286      */
       
   287     public Command getDefaultCommand(){
       
   288         return defaultCommand;
       
   289     }
       
   290 
       
   291     /**
       
   292      * Sets a new {@link CommandPresentationStrategy}. It also disposes to old one.
       
   293      *
       
   294      * @param commandPresentationStrategy
       
   295      */
       
   296     public void setPresentationStrategy( CommandPresentationStrategy commandPresentationStrategy ){
       
   297         CommandPresentationStrategy oldStrategy = strategy;
       
   298         strategy = commandPresentationStrategy;
       
   299         if (oldStrategy != null ){
       
   300             oldStrategy.dispose();
       
   301         }
       
   302     }
       
   303 
       
   304     private boolean isInFocusContext(Control control){
       
   305         Display display = control.getDisplay();
       
   306         Shell activeShell = display.getActiveShell();
       
   307         Control focused = display.getFocusControl();
       
   308         if( focused == null )return false;
       
   309         if(control.getShell() != activeShell) return false;
       
   310         if( control == focused ) return true;
       
   311         return isFocusAncestor(focused, control);
       
   312     }
       
   313 
       
   314     private boolean isFocusAncestor(Control node, Control parent){
       
   315         Control nodeParent = node.getParent();
       
   316         if( nodeParent == parent )return true;
       
   317         if (nodeParent == null || nodeParent == node.getShell() )return false;
       
   318         return isFocusAncestor(nodeParent, parent);
       
   319     }
       
   320 
       
   321 }