All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.swt.accessibility.Relation Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2009, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.accessibility;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.internal.ole.win32.*;

class Relation {
	Accessible accessible;
	COMObject objIAccessibleRelation;
	int refCount;
	int type;
	Accessible[] targets;
	static final String[] relationTypeString = {
		"controlledBy",		//$NON-NLS-1$
		"controllerFor",	//$NON-NLS-1$
		"describedBy",		//$NON-NLS-1$
		"descriptionFor",	//$NON-NLS-1$
		"embeddedBy",		//$NON-NLS-1$
		"embeds",			//$NON-NLS-1$
		"flowsFrom",		//$NON-NLS-1$
		"flowsTo",			//$NON-NLS-1$
		"labelFor",			//$NON-NLS-1$
		"labelledBy",		//$NON-NLS-1$
		"memberOf",			//$NON-NLS-1$
		"nodeChildOf",		//$NON-NLS-1$
		"parentWindowOf",	//$NON-NLS-1$
		"popupFor",			//$NON-NLS-1$
		"subwindowOf",		//$NON-NLS-1$
	};
	static final String[] localizedRelationTypeString = {
		SWT.getMessage("SWT_Controlled_By"),	//$NON-NLS-1$
		SWT.getMessage("SWT_Controller_For"),	//$NON-NLS-1$
		SWT.getMessage("SWT_Described_By"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Description_For"),	//$NON-NLS-1$
		SWT.getMessage("SWT_Embedded_By"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Embeds"),			//$NON-NLS-1$
		SWT.getMessage("SWT_Flows_From"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Flows_To"),			//$NON-NLS-1$
		SWT.getMessage("SWT_Label_For"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Labelled_By"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Member_Of"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Node_Child_Of"),	//$NON-NLS-1$
		SWT.getMessage("SWT_Parent_Window_Of"),	//$NON-NLS-1$
		SWT.getMessage("SWT_Popup_For"),		//$NON-NLS-1$
		SWT.getMessage("SWT_Subwindow_Of"),		//$NON-NLS-1$
	};

	Relation(Accessible accessible, int type) {
		this.accessible = accessible;
		this.type = type;
		this.targets = new Accessible[0];
		AddRef();
	}
	
	int /*long*/ getAddress() {
		/* The address of a Relation is the address of its IAccessibleRelation COMObject. */
		if (objIAccessibleRelation == null) createIAccessibleRelation();
		return objIAccessibleRelation.getAddress();
	}
	
	void createIAccessibleRelation() {
		objIAccessibleRelation = new COMObject(new int[] {2,0,0,1,1,1,2,3}) {
			public int /*long*/ method0(int /*long*/[] args) {return QueryInterface(args[0], args[1]);}
			public int /*long*/ method1(int /*long*/[] args) {return AddRef();}
			public int /*long*/ method2(int /*long*/[] args) {return Release();}
			public int /*long*/ method3(int /*long*/[] args) {return get_relationType(args[0]);}
			public int /*long*/ method4(int /*long*/[] args) {return get_localizedRelationType(args[0]);}
			public int /*long*/ method5(int /*long*/[] args) {return get_nTargets(args[0]);}
			public int /*long*/ method6(int /*long*/[] args) {return get_target((int)/*64*/args[0], args[1]);}
			public int /*long*/ method7(int /*long*/[] args) {return get_targets((int)/*64*/args[0], args[1], args[2]);}
		};
	}

	/* QueryInterface([in] iid, [out] ppvObject)
	 * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject 
	 * must be incremented before returning.  Caller is responsible for releasing ppvObject.
	 */
	int QueryInterface(int /*long*/ iid, int /*long*/ ppvObject) {
		GUID guid = new GUID();
		COM.MoveMemory(guid, iid, GUID.sizeof);

		if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIAccessibleRelation)) {
			COM.MoveMemory(ppvObject, new int /*long*/[] { getAddress() }, OS.PTR_SIZEOF);
			AddRef();
			return COM.S_OK;
		}

		return COM.E_NOINTERFACE;
	}

	int AddRef() {
		refCount++;
		return refCount;
	}

	int Release() {
		refCount--;

		if (refCount == 0) {
			if (objIAccessibleRelation != null)
				objIAccessibleRelation.dispose();
			objIAccessibleRelation = null;
		}
		return refCount;
	}

	/* IAccessibleRelation::get_relationType([out] pbstrRelationType) */
	int get_relationType(int /*long*/ pbstrRelationType) {
		setString(pbstrRelationType, relationTypeString[type]);
		return COM.S_OK;
	}

	/* IAccessibleRelation::get_localizedRelationType([out] pbstrLocalizedRelationType) */
	int get_localizedRelationType(int /*long*/ pbstrLocalizedRelationType) {
		setString(pbstrLocalizedRelationType, localizedRelationTypeString[type]);
		return COM.S_OK;
	}

	/* IAccessibleRelation::get_nTargets([out] pNTargets) */
	int get_nTargets(int /*long*/ pNTargets) {
		COM.MoveMemory(pNTargets, new int [] { targets.length }, 4);
		return COM.S_OK;
	}

	/* IAccessibleRelation::get_target([in] targetIndex, [out] ppTarget) */
	int get_target(int targetIndex, int /*long*/ ppTarget) {
		if (targetIndex < 0 || targetIndex >= targets.length) return COM.E_INVALIDARG;
		Accessible target = targets[targetIndex];
		target.AddRef();
		COM.MoveMemory(ppTarget, new int /*long*/[] { target.getAddress() }, OS.PTR_SIZEOF);
		return COM.S_OK;
	}

	/* IAccessibleRelation::get_targets([in] maxTargets, [out] ppTargets, [out] pNTargets) */
	int get_targets(int maxTargets, int /*long*/ ppTargets, int /*long*/ pNTargets) {
		int count = Math.min(targets.length, maxTargets);
		for (int i = 0; i < count; i++) {
			Accessible target = targets[i];
			target.AddRef();
			COM.MoveMemory(ppTargets + i * OS.PTR_SIZEOF, new int /*long*/[] { target.getAddress() }, OS.PTR_SIZEOF);
		}
		COM.MoveMemory(pNTargets, new int [] { count }, 4);
		return COM.S_OK;
	}

	void addTarget(Accessible target) {
		if (containsTarget(target)) return;
		Accessible[] newTargets = new Accessible[targets.length + 1];
		System.arraycopy(targets, 0, newTargets, 0, targets.length);
		newTargets[targets.length] = target;
		targets = newTargets;
	}

	boolean containsTarget(Accessible target) {
		for (int i = 0; i < targets.length; i++) {
			if (targets[i] == target) return true;
		}
		return false;
	}

	void removeTarget(Accessible target) {
		if (!containsTarget(target)) return;
		Accessible[] newTargets = new Accessible[targets.length - 1];
		int j = 0;
		for (int i = 0; i < targets.length; i++) {
			if (targets[i] != target) {
				newTargets[j++] = targets[i];
			}
		}
		targets = newTargets;
	}

	boolean hasTargets() {
		return targets.length > 0;
	}

	// setString copied from Accessible class
	void setString(int /*long*/ psz, String string) {
		char[] data = (string + "\0").toCharArray();
		int /*long*/ ptr = COM.SysAllocString(data);
		COM.MoveMemory(psz, new int /*long*/ [] { ptr }, OS.PTR_SIZEOF);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy