2010-08-06 14 views
1

Ce que j'essaie de réaliser consiste à ajouter une action au menu déroulant IProject. L'action est défini comme celui-ci dans mon plugin.xml:Comment définir l'état initial d'une contribution d'action Eclipse

<extension 
     point="org.eclipse.ui.popupMenus"> 
     <objectContribution 
      adaptable="true" 
      objectClass="org.eclipse.core.resources.IProject" 
      nameFilter="*" 
      id="RemoteSync.contribution1"> 
     <action 
       label="Enable RemoteSync" 
       class="remotesync.builder.ToggleNatureAction" 
       menubarPath="additions" 
       enablesFor="1" 
       id="RemoteSync.addRemoveNatureAction" 
       style="toggle"> 
     </action> 
     </objectContribution> 
    </extension> 

Sur run() je setPersistentProperty() afin de sauvegarder l'état de bascule de menu et je veux restaurer plus tard lorsque la fiche de mises en chantier ou chaque fois que le menu contextuel est affiché sur setActivePart().

Voici les éléments pertinents de code:

public void run(IAction action) { 
    if (selection instanceof IStructuredSelection) { 
     for (Iterator it = ((IStructuredSelection) selection).iterator(); it 
       .hasNext();) { 
      Object element = it.next(); 
      IProject project = null; 
      if (element instanceof IProject) { 
       project = (IProject) element; 
      } else if (element instanceof IAdaptable) { 
       project = (IProject) ((IAdaptable) element) 
         .getAdapter(IProject.class); 
      } 
      if (project != null) { 
       toggleNature(project); 
       try { 
        ((IResource) project).setPersistentProperty(
          new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString()); 
       } catch (CoreException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 


public void setActivePart(IAction action, IWorkbenchPart targetPart) { 
    if (selection instanceof IStructuredSelection) { 
     for (Iterator it = ((IStructuredSelection) selection).iterator(); it 
       .hasNext();) { 
      Object element = it.next(); 
      IProject project = null; 
      if (element instanceof IProject) { 
       project = (IProject) element; 
      } else if (element instanceof IAdaptable) { 
       project = (IProject) ((IAdaptable) element) 
         .getAdapter(IProject.class); 
      } 
      if (project != null) { 
       toggleNature(project); 
       try { 
        String status = ((IResource) project).getPersistentProperty(
          new QualifiedName("", ENABLED_PROPERTY)); 
        action.setChecked(new Boolean(status)); 
       } catch (CoreException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

Tout fonctionne comme prévu, mais une chose - lorsque le menu contextuel iProject est d'abord activée, elle ne reflète pas l'état enregistré, mais si je vous apporte le menu encore une fois, il montre l'état enregistré comme prévu. Ensuite, si j'apporte le menu pour un autre projet, il montre encore une fois avec un état incorrect, mais la deuxième fois fonctionne très bien.

Répondre

0

Eh bien, il semble qu'il y ait soit un problème avec mon code ou bug/fonctionnalité dans Eclipse 3.6 I20100608-0911 qui empêche selectionChanged() de tirer correctement la première fois que vous cliquez sur la ressource (iProject dans mon cas):

public void selectionChanged(IAction action, ISelection selection) { 
    this.selection = selection; 
} 

Comme je l'ai découvert événements sont déclenchés dans cet ordre lors de la mise en place dans le menu contextuel pour la première fois:

  1. selectionChanged()
  2. setActivePart()
  3. selectionChanged()

La sélection IS transmise à selectionChanged() la première fois est toujours "sélection vide".

Après la première fois, ce qui porte le menu contextuel cède l'ordre suivant dans lequel les événements sont tirés:

  1. setActivePart()
  2. selectionChanged()

C'est la raison pour laquelle nous devrions tirer selectionChanged() chaque fois à l'intérieur de setActivePart() afin de nous assurer que nous obtenons la sélection la plus récente:

public void setActivePart(IAction action, IWorkbenchPart targetPart) { 
    selectionChanged(action, targetPart.getSite().getPage().getSelection()); 
    ... 
} 

J'espère que cela aide quelqu'un;)

0

bien, jetez un oeil à ces lignes

  String status = ((IResource) project).getPersistentProperty(
         new QualifiedName("", ENABLED_PROPERTY)); 

     ((IResource) project).setPersistentProperty(
         new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString()); 

La variable « projet » souligne le projet sélectionné et donc l'état ne sont stockées dans ses méta-données. Si vous souhaitez stocker l'état indépendamment du projet, il est possible qu'une solution les stocke dans les métadonnées de l'espace de travail.

+0

Je veux stocker l'état de basculement de menu sur par projet. Le problème est que lorsque le menu contextuel IProject est activé pour la première fois, il ne reflète pas l'état enregistré, mais si je remonte le menu, il affiche l'état enregistré comme prévu. Ensuite, si j'apporte le menu pour un autre projet, il montre encore une fois avec un état incorrect, mais la deuxième fois fonctionne très bien. – blablacio