RCP Aktivieren/Deaktivieren von Toolbar-Items

dzim

Top Contributor
Hallo zusammen,

trotz Lars Vogels Tutorial zu Commands (Eclipse Commands Tutorial) komm ich gerade mit o.g. Thema nicht weiter.
Der Aufbau meiner Toolbar über die plugin.xml war bisher stark verinfacht wie folgt:
Command
Handler
Menu - toolbar - Item ist nur sichtbar, wenn bestimmter Editor offen ist

Ich habe am Handler jetzt noch zusätzlich die enableWhen-Kondition mit angegeben und dabei das Beispiel von LV genutzt.
Auf dem Toolbar-Item sind zwei Icons (enabled/disabled) angemeldet. Wenn jetzt die Kondition zum disablen eintritt, verschwindet das Item aber, anstatt grau zu werden.
Vielleicht hab ich ja auch nur etwas falsch verstanden...

Könnt ihr mir da Tipps geben?
 
G

Gast2

Gast
Hast du schon mal als 1. das disable Icon anzeigen lassen? Vielleicht stimmt mit dem was nicht.
Zeig mal bischen Code vielleicht.
 

dzim

Top Contributor
@SirWayne: Anzeigen in dem Sinne habe ich sie mir nicht lassen, aber auch wenn ich die icons für's enable (die ja definitv funktionieren) dafür einsetze, verschwinden diese auch...

@Wildcard:
kleines Beispiel
Code:
   <extension
         point="org.eclipse.core.expressions.definitions">
      <definition
            id="com.my_company.processing.handlers.correction-toolbar-enabled">
         <with
               variable="com.my_company.processing.handlers.correction-toolbar-enabled.state">
            <equals
                  value="ENABLED">
            </equals>
         </with>
      </definition>
   </extension>
   <extension
         point="org.eclipse.ui.services">
      <sourceProvider
            provider="com.my_company.processing.handlers.ProcessingStates">
         <variable
               name="com.my_company.processing.handlers.correction-toolbar-enabled.state"
               priorityLevel="workbench">
         </variable>
      </sourceProvider>
   </extension>
   <extension
         point="org.eclipse.ui.commands">
      <category
            description="%command.category.process.desc"
            id="com.my_comman.processing.commands"
            name="%command.category.process">
      </category>
      [...]
      <command
            categoryId="com.my_company.processing.commands"
            description="%command.auto-correct-isp.desc"
            id="com.my_company.processing.commands.auto-replacement"
            name="%command.auto-correct-isp">
      </command>
      [...]
   </extension>
    <extension
         point="org.eclipse.ui.handlers">
      [...]
      <handler
            class="com.my_company.processing.handlers.ProviderByUserIDHandler"
            commandId="com.my_company.processing.commands.auto-replacement">
         <enabledWhen>
         	<reference
                definitionId="com.my_company.processing.handlers.correction-toolbar-enabled">
         	</reference>
         </enabledWhen>
      </handler>
      [...]
   </extension>
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            locationURI="toolbar:org.eclipse.ui.main.toolbar">
         <toolbar
               id="com.my_company.processing.toolbar.correction">
            <separator
                  name="views"
                  visible="false">
            </separator>
            [...]
            <separator
                  name="tasks"
                  visible="true">
            </separator>
            <command
                  commandId="com.my_company.processing.commands.auto-replacement"
                  disabledIcon="icons/fugue_reports-stack-disabled.png"
                  icon="icons/fugue_reports-stack.png"
                  label="%command.auto-correct-isp"
                  style="push"
                  tooltip="%command.auto-correct-isp.desc">
               <visibleWhen
                     checkEnabled="true">
                  <with
                        variable="activeEditorId">
                     <equals
                           value="com.my_company.processing.ui.editor.RecordCorrectionEditor">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
         </toolbar>
      </menuContribution>
   </extension>

Die SourceServiceProvider-Klasse ist wie folgt definiert worden
Java:
public class ProcessingStates extends AbstractSourceProvider {

	public static final String CORRECTION_TOOLBAR_ENABLED_STATE = "com.my_company.processing.handlers.correction-toolbar-enabled.state";

	public static final String ENABLED = "ENABLED";
	public static final String DISABLED = "DISABLED";

	public static Map<String, String> state_map;
	static {
		state_map = new HashMap<String, String>();
		state_map.put(CORRECTION_TOOLBAR_ENABLED_STATE, ENABLED);
	}

	private boolean correctionToolbarEnabled = true;

	@Override
	public void dispose() {
		state_map.clear();
	}

	@Override
	public String[] getProvidedSourceNames() {
		return new String[] { CORRECTION_TOOLBAR_ENABLED_STATE };
	}

	@Override
	public Map getCurrentState() {
		return state_map;
	}

	private void toggleCorrectionToolbarEnabled(boolean enabled) {
		correctionToolbarEnabled = enabled;
		state_map.put(CORRECTION_TOOLBAR_ENABLED_STATE,
				(correctionToolbarEnabled ? ENABLED : DISABLED));
		fireSourceChanged(ISources.WORKBENCH, CORRECTION_TOOLBAR_ENABLED_STATE,
				state_map.get(CORRECTION_TOOLBAR_ENABLED_STATE));
	}

	public static void toggleCorrectionToolbarEnabledState(
			boolean newEnabledState) {
		// Get the source provider service
		ISourceProviderService sourceProviderService = (ISourceProviderService) PlatformUI
				.getWorkbench().getActiveWorkbenchWindow()
				.getService(ISourceProviderService.class);
		// now retrieve the service
		RecordProcessingStates stateService = (RecordProcessingStates) sourceProviderService
				.getSourceProvider(RecordProcessingStates.CORRECTION_TOOLBAR_ENABLED_STATE);
		stateService.toggleCorrectionToolbarEnabled(newEnabledState);
	}
}

Also das wichtigste ist imho, dass oben in den extension "enabledWhen" steht.
Vielleicht liegt's ja auch am Eclipse 3.6.1... kA...
 
G

Gast2

Gast
Denk mal liegt an dem visibleWhen hier

[XML]
<command
commandId="com.my_company.processing.commands.auto-replacement"
disabledIcon="icons/fugue_reports-stack-disabled.png"
icon="icons/fugue_reports-stack.png"
label="%command.auto-correct-isp"
style="push"
tooltip="%command.auto-correct-isp.desc">
<visibleWhen
checkEnabled="true">
<with
variable="activeEditorId">
<equals
value="com.my_company.processing.ui.editor.RecordCorrectionEditor">
</equals>
</with>
</visibleWhen>
</command>

[/XML]
 

dzim

Top Contributor
Ich hab das gerade mal ausprobiert und muss mit erschrecken feststellen, dass du recht hast.
Offenbar beißt sich das wohl, wenn man die Kombination enableWhen und visibleWhen an den zwei verschiedenen Baustellen verwendet.
Leider ist es aber genau die Funktionalität, die gewollt war. Ich wollte nicht, das z.B. das musterhafte Element der Toolbar immer zu sehen ist (auch nicht disabled)...
Mist verdammter! Und das zum Freitag! :-/
 
G

Gast2

Gast
Ich weiß nicht was du genau vor hast aber so ist dein Comman nur sichtbar wenn der avtive part die id = "com.my_company.processing.ui.editor.RecordCorrectionEditor" hat sobald du draußen bist geht dieser weg.

So Sachen wie disable und enable ein Command habe ich immer über Interfaces und PropertyTester gemacht.
 

dzim

Top Contributor
Die Einträge in der Toolbar sind tatsächlich nur sichtbar, wenn der Editor gerade aktiv ist (wenn ich mich recht entsinne, spielt der Focus dabei aber keine Sache).
Offenbar aber vertägt sich das visibleWhen am command der menu-Extension nicht mit der enabledWhen in der handler-Extension...
Ich wollte, dass die Items in der Toolbar aber wirklich nur im Falle des einen Editors sichtbar sind (und dann noch bei Bedarf enabled oder disabled).

Kannst du mir ein kleines Beispiel geben, wie du das mit dem PropertyTester meinst? Das ist doch das with-Element in der plugin.xml, oder? Kommst du da allein mit den gegebenen Props klar, oder definierst du eigene über neue PropertyTester?
Ich hab mir das zwar alles schon mal überflogen, aber mich nicht tief genug damit beschäftigt...
Danke für Anregungen ;-)
 
G

Gast2

Gast
Ja ich hab in den Forum mal ein Beispiel gemacht muss mal suchen^^...
Ja klar hat es etwas mit dem Focus zu tun und zwar wenn der Editor den blauen Rahmen hat, hat das Composite den Focus und deine Toolbar ändert sich...
 
G

Gast2

Gast
Okay ich hab dir mal ein plugin Projekt gemacht mit dem du ein wenig herum spielen kannst.
Und hier ist noch ein Tutorial:
Rezepte

Zum Beispiel funktioniert so ähnlich wie das saveCommand

Java:
public interface IDeletable {

	boolean isDeletable();
	void delete();
}

Handler

Java:
public class DeleteHandler extends AbstractHandler{

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		IWorkbenchPart edi = HandlerUtil.getActivePart(event);
		if (edi != null) {
			IDeletable deletable = (IDeletable) edi;
			deletable.delete();
		}
		return null;
	}

}

PropertyTester

Java:
public class DeleteProperyTester extends PropertyTester {

	@Override
	public boolean test(Object receiver, String property, Object[] args,
			Object expectedValue) {
			return ((IDeletable) receiver).isDeletable();
	}

}

Also wenn ein Aktiver Part IDeleteable implementiert UND isDeletable true zurückliefert dann wird der Command aktiv...

Plugin.xml

Der Tester...
type gibt an welches Interface oder von welcher Klasse der Tester ausgeführt werden soll.

[XML]
<extension
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
class="a.property.DeleteProperyTester"
id="A.propertyTester1"
namespace="test.delete"
properties="isDeleteable"
type="a.IDeletable">
</propertyTester>
</extension>
[/XML]

Der Handler der sagen soll aktiv wird sobald der PropertyTester true zurückliefert.
das property ist nameaspace + properties des PropertyTester
[XML]
<extension
point="org.eclipse.ui.handlers">
<handler
class="a.handler.DeleteHandler"
commandId="Delete">
<activeWhen>
<with
variable="activePart">
<test
forcePluginActivation="true"
property="test.delete.isDeleteable">
</test>
</with>
</activeWhen>
</handler>
</extension>
[/XML]

Nun wird der PropertyTester anschlagen wenn man den aktivenPart wechselt. Und der neue aktive Part IDeletable implementiert wird isDeleteable geprüft.

Falls man den PropertyTester innerhalb einen aktiven Part nochmal ausführen will so wie das fireProperty isDirty ...
Kann man das folgender maßen machen
Java:
		final IEvaluationService evaluationService = (IEvaluationService) getSite()
				.getWorkbenchWindow().getWorkbench().getService(
				IEvaluationService.class);
// hier wieder namespace+properties
				evaluationService.requestEvaluation("test.delete.isDeleteable");


PS: sorry für die schreibfehler ;)...
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
Was bei dir aber auch das Problerm sein könnte
[XML]
<visibleWhen
checkEnabled="true">

[/XML]

mach das hier mal auf false vielleicht klappt es dann schon...
 

Cage Hunter

Aktives Mitglied
checkEnabled : "If this attribute is set to true, then there should be no sub-elements. This just checks the enabled state of the command, and makes the corresponding element visible if the command is enabled."

Übersetzt : SirWayne hat Recht ;)
 

dzim

Top Contributor
Danke Jungs!

Das Flag war, wie ihr vermutet/gewusst habt, schuld an dem Problem.
Danke auch die Sir wegen dem PropertyTester - den werde ich zukünftig auch mal verwenden (dann spar ich mir diese Statusklasse, die ich mir gebaut hab...)

Danke nochmal vielmals für die Hilfe!
 
Ähnliche Java Themen

Ähnliche Java Themen


Oben