0

I would like to add an item to the eclipse context menu only if a text is marked as selected
below is my XML relevant snippet:

<menuContribution
    allPopups="false"
    locationURI="popup:org.eclipse.ui.popup.any">
  <command
      commandId="com.test.ide.menu.commands.sampleCommand"
      icon="icons/sample.png"
      id="com.test.ide.menu.toolbars.sampleCommand"
      tooltip="Popup test">
    <visibleWhen>
        <with variable="selection">
            <instanceof value="org.eclipse.jface.text.ITextSelection"/>
        </with>
    </visibleWhen>
  </command>
</menuContribution>

I tried the solution in How do you contribute a command to an editor context menu in Eclipse which does not resolve the issue

What am i missing?
Can you help?

Thanks
Avner

Excuse my detailed question, I am a newb to eclipse programming
i tried:

<extension
         point="org.eclipse.core.expressions.propertyTesters">
      <propertyTester
            class="com.test.ide.TextSelectedPropertyTester"
            id="com.test.ide.propertyTester1"
            namespace="tested"
            properties="textSelected"
            type="org.eclipse.jface.text.ITextSelection">
      </propertyTester>
</extension>

<menuContribution
    allPopups="false"
    locationURI="popup:org.eclipse.ui.popup.any">
  <command
      commandId="com.test.ide.menu.commands.sampleCommand"
      icon="icons/sample.png"
      id="com.test.ide.menu.toolbars.sampleCommand"
      tooltip="Popup test">
    <visibleWhen>
        <with variable="selection">
            <adapt type="org.eclipse.jface.text.ITextSelection">
                <test
                    property="tested.textSelected">
                </test>
            </adapt>
        </with>
    </visibleWhen>
  </command>
</menuContribution>

created a new package - com.test.ide in it created a new class TextSelectedPropertyTester
however the class is never invoked

package com.test.ide;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.jface.text.ITextSelection;


public class TextSelectedPropertyTester extends PropertyTester
{
    
    
    
  @Override
  public boolean test(Object receiver, String property, Object [] args, Object expectedValue)
  {
      System.out.println("testing");
      if (receiver instanceof ITextSelection) {
          return ((ITextSelection)receiver).getLength() > 0;
      }

    return false;
  }
}

however the class is never used

what am I missing?

Avner
  • 1
  • 3
  • The problem is that editors normally always have a text selection set - it will just be zero length if no characters are selected. – greg-449 Dec 05 '21 at 08:56
  • thanks so is there a way to check its length? – Avner Dec 05 '21 at 09:17
  • i tried using public void setEnabled(Object context) however looks like this takes affect only after first time the new menu item is used – Avner Dec 05 '21 at 09:47
  • Are you specifying `-clean` on the Eclipse startup to make sure it always looks for changed plugin.xml details? The property tester will only be run if the current selection is a text selection - which will only be the case in a text editor. – greg-449 Dec 06 '21 at 10:44
  • I am using the Eclipse Committer package (version 2021-06 (4.20)) for developing, and restarting the eclipse by Right click -> Debug as -> Eclipse Application, this is how i did the entire developing of my feature and never had any problems with it. The right click is done while mouse is in text editor or java editor, in the newly opened eclipse. The context menu is shown regardless if a string is marked – Avner Dec 06 '21 at 11:12
  • The -clean goes in the Run Configuration (in the Run menu) which will have been created for the application. In the "Program arguments" on the "Arguments" tab. The code I posted works for me. – greg-449 Dec 06 '21 at 11:25

1 Answers1

0

The problem is that editors normally always have a text selection set - it will just be zero length if no characters are selected.

I can't see a way to test this using existing expressions so it may be necessary to define your own property tester using the org.eclipse.core.expressions.propertyTester extension point.

 <extension
         point="org.eclipse.core.expressions.propertyTesters">
      <propertyTester
            class="tested.TextSelectedPropertyTester"
            id="tested.propertyTester1"
            namespace="tested"
            properties="textSelected"
            type="org.eclipse.jface.text.ITextSelection">
      </propertyTester>
</extension>

use like this:

<visibleWhen>
    <with variable="selection">
        <adapt type="org.eclipse.jface.text.ITextSelection">
            <test
                property="tested.textSelected"
                forcePluginActivation="true">
            </test>
       </adapt>
    </with>
</visibleWhen>

The property tester is very simple:

public class TextSelectedPropertyTester extends PropertyTester
{
  @Override
  public boolean test(Object receiver, String property, Object [] args, Object expectedValue)
  {
    if (receiver instanceof ITextSelection textSel) {
      return textSel.getLength() > 0;
    }

    return false;
  }
}

Note as shown the if statement uses a Java 16 instanceof type pattern, if you need to run with an older Java use:

    if (receiver instanceof ITextSelection) {
      return ((ITextSelection)receiver).getLength() > 0;
    }

greg-449
  • 109,219
  • 232
  • 102
  • 145
  • my apologies, edited my quested as you instructed – Avner Dec 06 '21 at 10:33
  • You might need `forcePluginActivation` on the `test` if the plug-in containing the property tester has not already been activated - see updated answer. – greg-449 Dec 06 '21 at 13:49
  • `forcePluginActivation` resolved the problem, thanks! your help is much appreciated – Avner Dec 07 '21 at 08:15