Acciones de editor redirigibles

Recuerde que la herramienta readme define un editor propio que suministra acciones a la barra de menús del entorno de trabajo utilizando el correspondiente objeto ReadmeEditorActionBarContributor.  

<extension
    point = "org.eclipse.ui.editors">
	<editor
  	   id = "org.eclipse.ui.examples.readmetool.ReadmeEditor"
  	   name="%Editors.ReadmeEditor"
      	   icon="icons/obj16/editor.png"
      	   class="org.eclipse.ui.examples.readmetool.ReadmeEditor"
	   extensions="readme"
           contributorClass="org.eclipse.ui.examples.readmetool.ReadmeEditorActionBarContributor">
	</editor>
   </extension>

Veamos con más detalle lo que sucede en la clase del contribuyente.

public ReadmeEditorActionBarContributor() {
	...
	action2 = new RetargetAction(IReadmeConstants.RETARGET2, MessageUtil.getString("Editor_Action2"));
	action2.setToolTipText(MessageUtil.getString("Readme_Editor_Action2"));
	action2.setDisabledImageDescriptor(ReadmeImages.EDITOR_ACTION2_IMAGE_DISABLE);
	action2.setImageDescriptor(ReadmeImages.EDITOR_ACTION2_IMAGE_ENABLE);
	...
	action3 = new LabelRetargetAction(IReadmeConstants.LABELRETARGET3, MessageUtil.getString("Editor_Action3"));
	action3.setDisabledImageDescriptor(ReadmeImages.EDITOR_ACTION3_IMAGE_DISABLE);
	action3.setImageDescriptor(ReadmeImages.EDITOR_ACTION3_IMAGE_ENABLE);
	...  
	handler2 = new EditorAction(MessageUtil.getString("Editor_Action2")); 
	...
	handler3 = new EditorAction(MessageUtil.getString("Editor_Action3")); 
	...

Al crearse el contribuyente, este crea dos acciones redirigibles (una que permite la actualización de la etiqueta y otra que no la permite).  Para crear acciones se emplea la misma técnica que la que utiliza el entorno de trabajo.  El contribuyente también crea dos manejadores que se utilizarán para las acciones cuando el editor sea el componente activo.  

Pero, ¿dónde se registran los manejadores de las acciones?  La operación de definir los manejadores globales se realiza de forma algo distinta cuando el editor define las acciones redirigidas.  ¿Por qué?  Porque el contribuyente se encarga de realizar el seguimiento de la vista activa y de colgar los diversos manejadores a medida que se activan vistas diferentes o el propio editor.  (El entorno de trabajo realiza esta operación automáticamente cuando el usuario establece un manejador para una de sus acciones globales).  Esta es la configuración que efectúa ReadmeEditorActionBarContributor:

public void init(IActionBars bars, IWorkbenchPage page) {
	super.init(bars, page);
	bars.setGlobalActionHandler(IReadmeConstants.RETARGET2, handler2);
	bars.setGlobalActionHandler(IReadmeConstants.LABELRETARGET3, handler3);
	...

En primer lugar, el contribuyente registra sus manejadores para las acciones redirigidas.  Esto garantiza que las acciones del contribuyente se ejecutarán cuando esté activo el propio editor.  El siguiente paso consiste en registrar cada acción RetargetAction como escuchador de componente en la página.

	...
	// Enganchar acciones de redirección como escuchas de página
	page.addPartListener(action2);
	page.addPartListener(action3);
	IWorkbenchPart activePart = page.getActivePart();
	if (activePart != null) {
		action2.partActivated(activePart);
		action3.partActivated(activePart);
	}
}

La adición de cada acción RetargetAction en forma de escuchador de componente implica que esta acción recibirá una notificación cuando cambie un componente activo.  La acción puede obtener el manejador global correcto a partir del componente recién activado.  (Encontrará todos los detalles en la implementación de la acción RetargetAction.  Observe que, para empezar, la acción tiene como valor generador el componente activo actualmente.

Cuando llega el momento de desecharlo (método dispose), el contribuyente del editor debe desenganchar las acciones redirigibles como escuchas de página.

public void dispose() {
	// Eliminar las acciones de redirección como escuchas de página
	getPage().removePartListener(action2);
	getPage().removePartListener(action3);
}

Finalmente, recuerde que los contribuyentes de barra de acciones se comparten entre las distintas instancias de una misma clase de editor.  Por esta razón, hay que informar a los manejadores cuando cambia el editor activo para que puedan conectarse con la instancia adecuada del editor.

public void setActiveEditor(IEditorPart editor) {
	...
	handler2.setActiveEditor(editor);
	handler3.setActiveEditor(editor);
	...
}

Con esto se completa la configuración del lado del editor.  Cuando el editor está abierto y activo, los manejadores (y sus etiquetas) tal como los define el objeto ReadmeEditorActionBarContributor aparecerán en la barra de menús del entorno de trabajo.

Menú Readme con tres acciones de editor en la barra de menús del entorno de trabajo

Ahora que ya están colocadas las contribuciones del editor, ¿qué hace una vista para registrar un manejador?  El código del lado del cliente es similar al utilizado para registrar un manejador para una acción del entorno de trabajo, salvo que el ID de la acción es el definido por el editor del conector.  La página Esquema de contenido del readme (ReadmeContentOutlinePage) registra un manejador para estas acciones.

    public void createControl(Composite parent) {
	super.createControl(parent);
	...
	getSite().getActionBars().setGlobalActionHandler(
		IReadmeConstants.RETARGET2, 
		new OutlineAction(MessageUtil.getString("Outline_Action2")));  

	OutlineAction action = new OutlineAction(MessageUtil.getString("Outline_Action3")); 
	action.setToolTipText(MessageUtil.getString("Readme_Outline_Action3")); 
	getSite().getActionBars().setGlobalActionHandler(
		IReadmeConstants.LABELRETARGET3, 
		action);  
	...

Observe que el esquematizador establece texto de ayuda flotante y una etiqueta en la segunda acción, porque permite el reetiquetado.  Cuando la vista del esquematizador del readme pase a estar activa, sus manejadores (junto con sus etiquetas) figurarán en la barra de menús del entorno de trabajo.

Menú Readme con una acción de editor renombrada

Fíjese en que la acción reetiquetada presenta la nueva etiqueta.