이클립스 워크벤치에 액션 기여하기
요약
이클립스 플랫폼은 오픈된 확장 가능한 플랫폼이다. 이 문서에서는 워크벤치가 어떻게 새로운 액션을 추가하기 위해 확장 가능한지를 알아보고 플러그인 개발자들에게 그들이 확장성 있는 디자인을 할 수 있도록 상세하게 설명한다.
October 18, 2001
January 2, 2007
목차:
소개
이클립스 플랫폼은 플러그인이 다른 플러그인을 확장할 수 있도록 하고, 잘 통합될 수 있도록 하기 때문에 사용자에게 좀 더 나은 경험을 제공한다. 이 문서에서는 다른 플러그인의 뷰나 에디터에 액션을 추가하는 방법과 다른 개발자들에게 당신이 만든 뷰나 에디터에 액션을 추가할 수 있도록 하는 방법에 대해 설명한다. 각 예제들은 액션을 추가할 수 있는 상황들에 대해 상세하게 설명한다. 한 번 이해하고 나면, 이 내용들을 뷰나 에디터에 액션을 추가하기 위해 서로 조합해서 사용할 수 있을 것이다.
이 그림은 플러그인이 액션을 추가할 수 있는 많은 영역들을 보여준다:
- 뷰나 에디터의 컨텍스트 메뉴
- 뷰의 툴바나 풀-다운(pull down) 메뉴
- 메인 툴바나 워크벤치 윈도우의 메뉴바
각각의 경우에 대해서 예를 들어 가면서 설명하도록 하겠다.
독립적인 소프트웨어 벤더(Independent Software Vendor ,ISV) 들은 다른 뷰나 에디터에 액션을 추가할 수 있도록 하기 위해 플러그인을 확장 가능하도록 만들 필요가 있다. 이 문서에서는 플러그인이 다른 플러그인으로 부터 액션 추가를 가능하도록 하기 위한 방법을 설명한다.
일단 여러분들이 플러그인을 제작하기 위한 기본적인 지식이 있다고 보겠다. 이클립스 플랫폼에서 플러그인을 개발하는 방법에 대해 알고 싶으면 Jim Amsden 이 쓴 "Your First Plug-in" 을 읽어보길 바란다.
이 문서의 예제들을 따라 하고 싶으면,"예제 실행하기" 섹션을 참고하길 바란다.
컨텍스트 메뉴에 액션 추가하기
뷰나 에디터의 컨텍스트 메뉴에 액션을 추가 하는 기능은 플러그인 간의 통합을 잘 할 수 있도록 해준다. 예를 들어, VCM(버젼과 설정 관리 플러그인)은 "네비게이터"나 "패키지 뷰"와 같이 기존의 뷰에 몇몇 액션을 추가한다. 그 액션들을 통해 사용자가 기존의 뷰에서 리소스의 버전관리를 할 수 있도록 한다. 컨텍스트 메뉴에 액션을 기여하기 위해서 워크벤치 플러그인(org.eclipse.ui)에서 확장점org.eclipse.ui.popupMenus가 제공된다. 여기 액션 기여의 두 가지 형태가 있다. 액션은 어떤 에디터나 뷰의 컨텍스트 메뉴에 기여될 수 있으며, 또는 특별한 객체의 유형에 맞추어 등록할수 있다. 다음 세가지 예제를 따라가며 잘 생각해 보자.
예제 1: 기본 텍스트 에디터에 액션 추가
워크벤치 플러그인에서 제공하는 기본 텍스트 에디터의 컨텍스트 메뉴에 하나의 액션을 추가하는 것을 살펴보자.
<extension point="org.eclipse.ui.popupMenus">
<viewerContribution
id="org.eclipse.ui.articles.action.contribution.popup.editor"
targetID="#TextEditorContext">
<action
id="org.eclipse.ui.articles.action.contribution.editor.action1"
label="Editor Action 1"
icon="icons/red_dot.gif"
menubarPath="additions"
class="org.eclipse.ui.articles.action.contribution.EditorAction1Delegate">
</action>
</viewerContribution>
</extension>
위 XML은 특정 에디터의 컨텍스트 메뉴에 기여를 정의한다. 이 확장을 뷰어 확장이라고 한다(
). 뷰어라는 용어는 뷰와 에디터 모두를 칭한다.
targetID 속성은(
) 타겟 뷰나 에디터에서의 컨텍스트 메뉴 식별자(identifier)를 가리킨다. 뷰나 에디터를 제공하는 플러그인의 문서에 사용할 수 있는 식별자들의 리스트가 있을 것이다. 만약 문서에 정의되어 있지 않다면, 외부 액션 기여가 플러그인에 의해 컨텍스트 메뉴에 등록되지 않는다. 뷰나 에디터는 하나 이상의 컨텍스트 메뉴를 가질 수 있다.
아쉽게도, 기본으로 제공되는 텍스트 에디터는플러그인 개발자를 위한 가이드라인에서 설명하는 내용을 따르지 않고 있다. 앞서 설명했던 대로 컨텍스트 메뉴 식별자가 기본 텍스트 에디터 문서에 없다. 또한, 식별자가 전체적으로 유효하지(fully qualified) 않다.
XML에서 다음으로 적혀진 action 속성(
)이 컨텍스트 메뉴에 기여한다. 첫 단계로 id 속성을 이용해 액션의 식별자를 할당한다. 컨텍스트 메뉴에서 표현될 라벨과 아이콘은 label과 icon 속성을 사용해서 정의한다. icon 속성에서의 경로는 플러그인 디렉토리를 기준으로 적어준다.
menubarPath 속성(
)은 컨텍스트 메뉴의 루트에서 시작되는 위치를 정의한다. 이 예제에서 사용된 "additions"는 org.eclipse.ui.IWorkbenchActionConstants.MB_ADDITIONS 상수로 정의된 값이다. 플러그인을 제작할 때 액션 기여를 할 수 있는 기본 위치로 그들의 컨텍스트 메뉴에 이 그룹을 한 번 제공하기를 기대한다. 플러그인에서 그들의 컨텍스트 메뉴에 액션 기여를 할 수 있는 다른 그룹을 제공할 수도 있다. 이 경우에는 플러그인 문서에 각각의 그룹에 대한 설명을 달아주길 바란다. 만약 menubarPath 속성이 정의되지 않으면, 일단 워크벤치에서 "additions" 그룹에 액션을 추가하려고 할 것이다. 만약 "additions" 그룹이 없다면, 기여되는 액션은 컨텍스트 메뉴의 제일 마지막에 추가된다.
class 속성은 사용자가 메뉴를 선택했을 때 해당 항목에 대한 액션을 수행할 자바 클래스를 정의한다. 이 클래스는 에디터의 컨텍스트에 기여되는 액션일 경우 org.eclipse.ui.IEditorActionDelegate 인터페이스를 구현해야하고, 뷰의 컨텍스트 메뉴에 기여되는 액션일 경우 org.eclipse.ui.IViewActionDelegate 인터페이스를 구현해야 한다. 대표(delegate) 클래스에 대해 이해를 할 때 한가지 중요한 점은 플러그인이 게으른 로딩(lazily loaded)이 되기 때문에 처음 메뉴 항목을 선택했을 때 워크벤치에 의해 이 클래스가 로딩된다는 점이다. 이것은 최초 사용가능 여부에 대한 로직을 XML 에서 기술해두어야 함을 의미한다. 대표 클래스가 워크벤치에 의해 한 번 로딩된 후로는, 자체적으로 액션의 enabled/disabled 상태를 바꾸어줄 수 있다.
IEditorActionDelegate 인터페이스는 활성화된 에디터에 맞게 자신의 타겟을 재조정 할 수 있게 한다. 이것은 하나의 액션이 만들어진 후에 같은 에디터 타입의 모든 인스턴스에서 공유할 수 있게 해준다. 이 대표 액션은 setActiveEditor(IAction action, IEditorPart targetEditor) 메쏘드를 구현해주어야 한다. run() 메쏘드를 통해 액션이 호출되었을 때, setActiveEditor() 메쏘드 콜을 통해 주어진 활성화 에디터에 대해 액션을 취한다.
IViewActionDelegate 인터페이스는 초기화 과정에서 액션이 동작할 뷰 인스턴스를 자신의 타겟으로 알게 해준다. 이 대표 액션은 init(IViewPart
view) 메쏘드를 구현해주어야 한다. run() 메쏘드를 통해 액션이 호출되었을 때, init() 메쏘드를 통해 주어진 뷰에 대해 액션을 취한다.
위의 그림은예제 실행하기의 결과를 보여준다. "Editor Action 1"이 에디터의 컨텍스트 메뉴에 추가된 것이다. 그림 상의 위치가 기본 텍스트 에디터의 컨텍스트 메뉴내에서 "additions" 그룹이 가리기는 위치이다.
예제 2: 네비게이터 뷰에 서브 메뉴 추가
네비게이터 뷰에 하나의 액션을 추가하고 두 개의 액션을 가지는 서브 메뉴를 추가하는 법을 살펴보자.
<extension point="org.eclipse.ui.popupMenus">
<viewerContribution
id="org.eclipse.ui.articles.action.contribution.popup.navigator"
targetID="org.eclipse.ui.views.ResourceNavigator">
<action
id="org.eclipse.ui.articles.action.contribution.navigator.action1"
label="View Action 1"
icon="icons/red_dot.gif"
menubarPath="additions"
class="org.eclipse.ui.articles.action.contribution.ViewAction1Delegate"
enablesFor="!">
</action>
<menu
id="org.eclipse.ui.articles.action.contribution.navigator.subMenu"
label="View Sub Menu"
path="additions">
<separator name="group1"/>
</menu>
<action
id="org.eclipse.ui.articles.action.contribution.navigator.action2"
label="View Action 2"
icon="icons/red_dot.gif"
menubarPath="org.eclipse.ui.articles.action.contribution.navigator.subMenu/group1"
class="org.eclipse.ui.articles.action.contribution.ViewAction2Delegate"
enablesFor="1">
</action>
<action
id="org.eclipse.ui.articles.action.contribution.navigator.action3"
label="View Action 3"
icon="icons/red_dot.gif"
menubarPath="org.eclipse.ui.articles.action.contribution.navigator.subMenu/group1"
class="org.eclipse.ui.articles.action.contribution.ViewAction3Delegate"
enablesFor="2+">
</action>
</viewerContribution>
</extension>
위의 XML은 네비게이터 뷰 (
)의 컨텍스트 메뉴에 기여를 하기 위한 것이다. 첫 액션 기여 ( )는 앞의 예제에서와 동일하게 정의한다. 이 예제에서는 새로운 속성과 기능에 대해 설명하고 앞의 예제에서 설명한 것들은 넘어가겠다.
액션 정의에 enablesFor (
) 라는 속성이 있다. 이 속성은 현재 선택된 내용에 따라 액션의 enabled/disabled 상태를 정할 수 있게 한다. 현재 선택된 내용은 플러그인 개발자에 의해 컨텍스트 메뉴가 등록될 때 주어진 셀렉션 프로바이더로 부터 얻을 수 있다. enablesFor 속성 값은 액션이 enable 되기 위해 필요한 선택된 항목의 개수를 나타낸다. 조건에 맞지 않으면 액션은 diabled 된다. 해당 속성이 없는 경우, 액션은 항상 enabled 상태가 된다. 다음은 지원되는 속성값의 형태이다:형태 설명 ! 아무것도 선택되지 않음 ? 0 이나 1 개 항목이 선택됨 + 1 개 이상의 항목이 선택됨 multiple, 2+ 2 개 이상의 항목이 선택됨 n 주어진 개수의 항목이 선택됨 (예. 4) * 선택된 항목의 개수와 상관없음
액션의 활성화 여부가 XML에 정의된 이유는 플러그인이 게으른 로딩(lazily loaded)을 하기 때문이다. 실제 사용자에 의해 액션이 호출되기 전까지는 플러그인이 로딩되지 않고 워크벤치는 XML에 정의된 로직을 가지고 활성화 여부를 판단한다. 플러그인이 한 번 로딩되고 나면, 대표 클래스는 셀렉션 체인지를 받아서 이에 따라 액션의 enabled/disabled 상태를 바꾸꿀 수 있다. 보다 자세한 정보는 org.eclipse.ui.IActionDelegate.selectionChanged(IAction action, ISelection selection) 메쏘드 문서를 참조하라.
예제에서의 menu 속성(
)은 서브 메뉴를 정의한다. label 속성은 메뉴상에 표시될 텍스트를 정의한다. path 속성은 컨텍스트 메뉴의 루트에서 부터의 경로를 정의한다. 이 속성은 처음 예제에서 이야기한 menubarPath 속성과 동일하게 동작한다.
메뉴 속성(
)과 함께 separator ( )가 정의된다. separator 속성은 액션이 추가될 수 있는 그룹 이름을 제공한다. 이 예제에서는, 마지막 두 액션이 menubarPath 속성( )에 이 separator 이름을 사용해서 정의되고 있다. 이것이 두 액션이 서브 메뉴에 위치할 수 있는 방법이다. menu separator 항목은 워크벤치 메뉴 메니저에 의해 그룹의 위나 아래에 추가된다.
위의 그림은예제 실행하기의 결과를 보여준다. 네비게이터의 컨텍스트 메뉴에 서브 메뉴가 추가되었음을 알 수 있다.
액션이 메뉴나 서브 메뉴에 추가되는 순서는 plugin.xml 파일에 나열된 것과 같은 순서로 처리된다.
예제 3: 오브젝트에 액션 추가
자바 프로젝트에 있는 .java 파일에 하나의 액션을 추가하는 법을 살펴보자.
<extension point="org.eclipse.ui.popupMenus">
<objectContribution
id="org.eclipse.ui.articles.action.contribution.popup.object"
objectClass="org.eclipse.core.resources.IFile"
nameFilter="*.java">
<filter
name="projectNature"
value="org.eclipse.jdt.core.javanature">
</filter>
<action
id="org.eclipse.ui.articles.action.contribution.object.action1"
label="Object Action 1"
icon="icons/red_dot.gif"
menubarPath="additions"
class="org.eclipse.ui.articles.action.contribution.ObjectAction1Delegate">
</action>
</objectContribution>
</extension>
위 XML은 모든 컨텍스트 메뉴(
)에 기여하지만, 선택된 오브젝트가 objectClass 속성( )에 정의된 타입과 일치할 때만 표시되도록 한다. objectClass 속성 값은 유효한 클래스 이름이나 인터페이스 이름을 가질 수 있다. 서로 다른 타입의 항목들이 선택될 경우, 선택된 항목들의 공통된 타입을 기준으로 동작 여부를 판단한다. 직접적인 매치가 불가능한 경우, 상위 클래스나 상위 인터페이스를 가지고 매치를 시도한다. 액션 기여는 선택 항목이 특정 타입의 오브젝트를 포함하는 경우에만 동작하며, 하나의 뷰나 에디터의 컨텍스트 메뉴에 제한적이지 않다.
예를 들어, 네비게이터에서 "f1.java" 파일과 "Java Project" 프로젝트를 선택하고 뷰의 컨텍스트 메뉴를 띄우면, 위 XML에서 정의한 액션 기여는 보여지지 않을 것이다. "Java Project" 가 IFile 타입이 아닌 IProject 타입이고, IFile 이 IProject의 상위 인터페이스도 아니기 때문이다. 그러나, 위 XML에서 objectClass 속성 값을 org.eclipse.core.resources.IResource 으로 설정했다면, 액션 기여가 보여질 것이다. IResource 가 IFile ("f1.java") 과 IProject ("Java Project")의 상위 인터페이스이기 때문이다.
nameFilter 속성(
) 은 선택 항목에 대한 추가 제한 속성이다. 이 예제에서는, IFile 오브젝트이면서 확장자가 .java 인 경우로 제한했다. 이 값은 선택된 오브젝트 별로 org.eclipse.ui.model.IWorkbenchAdapter.getLabel() 메쏘드 호출 결과와 비교된다. 오브젝트가 IWorkbenchAdapter 를 가지고 있지 않은 경우에는 오브젝트의 toString() 메쏘드가 사용된다. 이 속성이 없으면 오브젝트 이름에 따른 필터링을 하지 않는다.
filter 항목(
)은 액션의 활성화를 조정하는 다른 방법을 제공한다. 이 filter 항목은 선택된 오브젝트를 위한 name/value 쌍의 속성을 가진다. 이 속성은 선택 항목에 적용할 타입을 정의한다. 그렇기 때문에 워크벤치는 이 단계의 필터링을 처리한 실제 선택 항목을 전달한다(IActionFilter 의 자바독을 참조하라). 이 예제에서는, 객체 속성 이름(name)이 "projectNature"이고, 이는 IResourceActionFilter 로 정의되었고 모든 IResources에 적용할 수 있다. 따라서, 액션 기여는 선택된 각 IProject 객체가 Java nature를 가지는 경우에만 이루어진다. IActionFilter에 대한 문서와 그 하부 인터페이스들을 참조하고 다른 이름의 속성에 대한 설명을 봐두도록 하자. project natures에 대한 추가 정보는 org.eclipse.core.resources.IProjectNature 인터페이스의 문서를 참조하라.
오브젝트에 기여하기 위해서는, 액션의 class 속성(
)에 정의될 자바 클래스가 org.eclipse.ui.IObjectActionDelegate 인터페이스를 구현해야 한다. IObjectActionDelegate 인터페이스는 활성화된 파트에 따라 자신을 리타겟(retarget) 할 수 있게 해준다. 이는 하나의 대표 액션(action delegate)을 생성하고 모든 IWorkbenchPart의 인스턴스가 공유할 수 있다는 것을 의미한다. 대표 액션은 setActivePart(IAction action, IWorkbenchPart targetPart) 메쏘드를 구현해야 한다. 액션이 run() 메쏘드를 통해 호출되었을 때, 마지막에 setActivePart() 메쏘드 콜을 통해 전달된 활성화 파트에 대해 동작한다.
위의 그림은예제 실행하기의 결과를 보여준다. 자바 프로젝트 내의 .java 파일이 선택됨에 따라 네비게이터의 컨텍스트 메뉴에 오브젝트 액션 기여가 추가되었음을 알 수 있다.
개발자 가이드라인: 당신이 만든 컨텍스트 메뉴에 액션 기여 지원하기
워크벤치 상에서, 컨텍스트 메뉴에 액션을 기여할 수 있는 경우는 메뉴가 워크벤치가 알 수 있도록 만들어졌을 경우 뿐이다. 이것은 자발적인 과정이지만 플러그인은 자신의 메뉴를 노출시킴으로써 ISV들이 메뉴를 확장시키도록 할 수 있다. 이는 플랫폼의 전반적인 확장성과 통합성을 높여준다.
각각의 컨텍스트 메뉴는 워크벤치에 등록시킬 수 있다. 이는 org.eclipse.ui.IWorkbenchPartSite.registerContextMenu(MenuManager menuManager, ISelectionProvider selectionProvider) 나org.eclipse.ui.IWorkbenchPartSite.registerContextMenu(String menuId, MenuManager menuManager, ISelectionProvider selectionProvider)
를 호출함으로써 처리할 수 있다. 만약 뷰나 에디터가 노출시키고자 하는 메뉴가 하나 이상인 경우에는 각각의 메뉴를 등록해줄 필요가 있다. 컨텍스트 메뉴가 한 번 등록되고 나면, 워크벤치가 자동적으로 메뉴에 액션을 등록할 수 있다.
컨텍스트 메뉴를 등록할 때에는, 워크벤치에 등록된 컨텍스트 메뉴들 간의 혼동을 피하기 위해 유일한 식별자를 부여해주어야 한다. 전체적으로 이를 지키기 위해, 모든 플러그인이 컨텍스트 메뉴를 등록할 때 다음과 같은 방법을 사용할 수 있을 것이다:
- 뷰나 에디터에 하나의 컨텍스트 메뉴가 있다면, 뷰나 에디터의 식별자와 동일한 식별자를 줄 수 있다. 간단하게 IWorkbenchPartSite의 registerContextMenu(MenuManager, ISelectionProvider)를 호출하면 된다.
- 뷰나 에디터에 하나 이상의 컨텍스트 메뉴가 있다면, 각각의 식별자는 뷰나 에디터의 식별자를 접두사로 가지는 유일한 식별자를 부여해줄 수 있다. 예를들어, 식별자가 com.xyz.bestEditor 인 에디터가 두 개의 컨텍스트 메뉴를 가진다고 하자. 첫번째 컨텍스트 메뉴의 식별자는 org.xyz.bestEditor.menu1 이고, 두번째 컨텍스트 메뉴의 식별자는 com.xyz.bestEditor.menu2 로 하면 될 것이다. 각각의 컨텍스트 메뉴는 IWorkbenchPartSite 의 registerContextMenu(String, MenuManager, ISelectionProvider) 를 호출해서 등록한다.
모든 컨텍스트 메뉴 식별자는 뷰나 에디터의 자바독에 설명되어 있을 것이다. 이는 ISV들이 특정 부분의 메뉴 식별자를 찾고, 액션 기여를 하는데에 도움이 된다. 이 식별자들은 액션 기여의 targetID 속성값으로 사용된다.
컨텍스트 메뉴를 제공하는 경우 기본적인 추가 위치 식별자(standard insertion point identifier)인 IWorkbenchActionConstants.MB_ADDITIONS 를 포함하도록 한다. 이 참조점은 ISV들이 액션 기여를 할 때, 액션이 추가될 위치를 찾는데 사용된다. 추가 위치는 메뉴의 적절한 위치에 그룹마커(GroupMarker)를 추가함으로써 정의된다. 다른 추가 위치가 있다면 뷰의 자바독(javadoc)에 기술해주도록 한다. 이것은 ISV가 풀-다운 메뉴에 액션을 기여할 위치를 판단하는데 큰 도움이 되므로 신경써주는게 좋다.
컨텍스트 메뉴내에 선택할 수 있는 오브젝트를 만드는 플러그인 개발자는 org.eclipse.ui.IActionFilter 인터페이스를 구현할 수 있다. 이것은 name/value 쌍에 기반해서 특정 타입의 필터링을 할 수 있게해주는 방법이다. 이는 ISV에게 XML 상의 filter 항목에 name/value 쌍을 사용해서 액션 기여를 적용할 오브젝트에 대한 추가적인 제한을 할 수 있게 해준다. 워크벤치는 선택 항목에 대해 IActionFilter를 구현했는지 확인하고 필터링 처리를 할 것이다. 만약 실패한다면, 워크벤치는 IAdaptable 메커니즘을 이용해서 필터링을 하고자 할 것이다.
뷰의 메뉴나 툴바에 액션 기여하기
뷰는 자체적으로 초기화한 풀-다운 메뉴와 툴바를 가지고 있다. 다른 플러그인은 org.eclipse.ui.viewActions 확장점을 이용해서 이 메뉴나 툴바에 액션 기여를 할 수 있다.
예제 4: 네비게이터 뷰의 메뉴와 툴바에 액션 추가
네비게이터 뷰의 풀 다운 메뉴와 툴바에 다른 액션을 추가하는 법을 살펴보자.
<extension point="org.eclipse.ui.viewActions">
<viewContribution
id="org.eclipse.ui.articles.action.contribution.view"
targetID="org.eclipse.ui.views.ResourceNavigator">
<action
id="org.eclipse.ui.articles.action.contribution.view.action1"
label="View Action 1"
icon="icons/red_dot.gif"
tooltip="Tooltip for View Action 1"
menubarPath="additions"
class="org.eclipse.ui.articles.action.contribution.ViewAction1Delegate"
enablesFor="*">
</action>
<action
id="org.eclipse.ui.articles.action.contribution.view.action2"
label="View Action 2"
icon="icons/red_dot.gif"
tooltip="Tooltip for View Action 2"
toolbarPath="group1"
class="org.eclipse.ui.articles.action.contribution.ViewAction2Delegate"
enablesFor="*">
<selection
class="org.eclipse.core.resources.IFile"
name="*.java">
</selection>
</action>
</viewContribution>
</extension>
위 XML은 플러그인이 네비게이터의 풀-다운 메뉴와 툴바에 기여하고자 함을 워크벤치에게 알려준다(
). 이 예제에서는, targetID 속성( )이 네비게이터 뷰의 식별자(identifier)로 정의되었다.
첫 action 항목(
)은 이전 예제에서 보여졌던 속성들로 구성되어 있다. menubarPath 속성 값( ) 은 기본적으로 액션을 추가하는 그룹인 IWorkbenchActionConstants.MB_ADDITIONS 상수와 같다. 이 예제에서 보여주진 않지만, 간단하게 menu 항목을 정의해줌으로써 뷰의 풀-다운 메뉴의 서브 메뉴에도 액션을 추가할 수 있다. 자세한 내용은 이전컨텍스트 메뉴에 서브 메뉴 추가 하기 예제를 참조하라.
두번째 action 항목(
)은 첫번째 것과 약간 다르다. menubarPath 속성을 이용해서 풀-다운 메뉴에 액션을 추가하는 대신에, 뷰의 툴바에 액션을 추가한다( ). toolbarPath 속성은 액션을 추가하고자 하는 그룹을 나타낸다. 정의된 그룹이 없으면 툴바의 마지막에 액션이 추가되고 필요한 경우 구분자도 추가된다. 뷰는 플러그인이 툴바 내에 액션을 추가할 그룹에 대해 기술해두어야 한다. 네비게이터 뷰의 툴바는 어떠한 그룹도 기술해두지 않았다. 메뉴가 기본 IWorkbenchActionConstants.MB_ADDITIONS 그룹을 가지고 있는 것과는 달리, 툴바는 그런 것이 필요없다.
selection 항목(
)은 액션을 적용하기 위한 선택 항목에 추가적인 제약을 둘 수 있게 한다. class 속성에 정의된 타입과 선택된 객체의 타입이 일치해야지 액션이 활성화된다. 이 예제에서는, 선택된 모든 객체가 IFile 인터페이스를 구현해야지만 활성화된다. name 속성은 선택된 각각의 객체에 대해 와일드카드 매치를 정의한다. 이 속성의 값은 선택된 각각의 객체의 org.eclipse.ui.model.IWorkbenchAdapter.getLabel() 메쏘드 호출 결과와 비교된다. 이 예제에서는, 선택된 모든 객체가 .java 확장자를 가진 경우에만 활성화된다. 선택 항목은 enablesFor 속성이 정의되지 않은 경우 워크벤치에 의해 무시된다.
위의 그림은예제 실행하기의 결과를 보여준다. 네비게이터의 풀-다운 메뉴에 액션이 추가되었음을 알 수 있다. 툴바에 추가된 액션은 선택된 항목이 .java 파일이기 때문에 활성화되어 있다.
개발자 가이드라인: 당신이 만든 뷰에 액션 기여 지원하기
뷰 개발자는 뷰의 풀-다운 메뉴에 IWorkbenchActionConstants.MB_ADDITIONS 라는 기본적인 액션 추가를 위한 자리를 넣어주도록 한다. 이 참조점은 ISV들이 액션 기여를 할 때, 액션이 추가될 위치를 찾는데 사용된다. 추가 위치는 메뉴의 적절한 위치에 그룹마커(GroupMarker)를 추가함으로써 정의된다. 다른 추가 위치가 있다면 뷰의 자바독(javadoc)에 기술해주도록 한다. 이것은 ISV가 풀-다운 메뉴에 액션을 기여할 위치를 판단하는데 큰 도움이 되므로 신경써주는게 좋다.
에디터의 메뉴나 툴바에 액션 기여하기
에디터의 경우, 액션은 메인 메뉴 바나 워크벤치 윈도우의 툴바에 기여된다. 플러그인은 org.eclipse.ui.editorActions 확장점을 이용해서 특정 에디터에 액션을 기여할 수 있다. 생성된 각각의 액션 확장은 같은 에디터 타입의 모든 인스턴스에 대해 공유된다.
예제 5: 기본 텍스트 에디터의 툴바에 액션 추가
기본 텍스트 에디터의 툴바에 두 개의 액션을 추가하는 법을 살펴보자.
<extension point="org.eclipse.ui.editorActions">
<editorContribution
id="org.eclipse.ui.articles.action.contribution.editor"
targetID="org.eclipse.ui.DefaultTextEditor">
<action
id="org.eclipse.ui.articles.action.contribution.editor.action1"
label="Editor Action 1"
icon="icons/red_dot.gif"
tooltip="Tooltip for Editor Action 1"
toolbarPath="Normal/additions"
class="org.eclipse.ui.articles.action.contribution.EditorAction1Delegate">
</action>
<action
id="org.eclipse.ui.articles.action.contribution.editor.action2"
label="Editor Action 2"
icon="icons/red_dot.gif"
tooltip="Tooltip for Editor Action 2"
helpContextId="org.eclipse.ui.articles.action.contribution.editor.action2"
toolbarPath="Normal/save.ext"
class="org.eclipse.ui.articles.action.contribution.EditorAction2Delegate">
</action>
</editorContribution>
</extension>
앞의 예제에서 처럼, 처음 몇 줄은 워크벤치에게 기본 텍스트 에디터 (
and )에 액션을 기여한다는 것을 알려준다. 이 예제에서는, 두 개의 액션이 에디터의 툴바에 추가된다.
예제에서의 toolbarPath 속성 값(
and )은 서로 다르다. 처음 것은 툴바의 식별자를 의미하며, 두번째 것은 툴바 내의 그룹을 의미한다. 툴바의 식별자는 플러그인이 액션을 추가하고자 하는 툴바를 정의하는데 사용된다. 현재 워크벤치에서는 오직 하나의 툴바가 제공되며 그 식별자는 "Normal"이다. 해당 그룹이 존재하지 않으면 정의된 툴바 내에 생성되지 않고, 액션이 추가되지 않는다. IWorkbenchActionConstants 인터페이스와 타겟 에디터를 제공하는 플러그인에 관한 문서에 유효한 툴바 그룹이 나열되어 있다.
첫 액션(
)은 toolbarPath 속성( )을 사용하여 IWorkbenchActionConstants.MB_ADDITIONS 라는 기본 그룹에 추가된다. 두번째 액션( )은 toolbarPath 속성을 사용하여 IWorkbenchActionConstants.SAVE_EXT 라는 그룹에 추가된다. 워크벤치 윈도우 메인 툴바에서 제공하는 다른 그룹들을 알고 싶으면 IWorkbenchActionConstants 인터페이스를 참조하라.
위의 그림은예제 실행하기의 결과를 보여준다. 툴바의 저장(save) 항목 뒤에 액션이 추가되고 툴바의 마지막에 액션이 추가되었음을 알 수 있다.
예제 6: 기본 텍스트 에디터의 메뉴바에 액션 추가
기본 텍스트 에디터의 메뉴바에 다음과 같은 액션을 추가하는 법을 살펴보자.:
- 파일 메뉴에 하나의 액션,
- 에디트 메뉴에 두 개의 액션을 가지는 서브 메뉴,
- 하나의 액션을 가지는 새로운 최상위 레벨의 메뉴.
<extension point="org.eclipse.ui.editorActions">
targetID="org.eclipse.ui.DefaultTextEditor">
<editorContribution
id="org.eclipse.ui.articles.action.contribution.editor2"
<action
id="org.eclipse.ui.articles.action.contribution.editor.action1"
label="Editor Action 1"
icon="icons/red_dot.gif"
tooltip="Tooltip for Editor Action 1"
menubarPath="file/save.ext"
class="org.eclipse.ui.articles.action.contribution.EditorAction1Delegate">
</action>
<menu
id="org.eclipse.ui.articles.action.contribution.editor.subMenu"
label="Editor Sub Menu"
path="edit/additions">
<separator name="group1"/>
</menu>
<action
id="org.eclipse.ui.articles.action.contribution.editor.action2"
label="Editor Action 2"
icon="icons/red_dot.gif"
tooltip="Tooltip for Editor Action 2"
menubarPath="org.eclipse.ui.articles.action.contribution.editor.subMenu/group1"
class="org.eclipse.ui.articles.action.contribution.EditorAction2Delegate">
</action>
<action
id="org.eclipse.ui.articles.action.contribution.editor.action3"
label="Editor Action 3"
icon="icons/red_dot.gif"
tooltip="Tooltip for Editor Action 3"
menubarPath="org.eclipse.ui.articles.action.contribution.editor.subMenu/group1"
class="org.eclipse.ui.articles.action.contribution.EditorAction3Delegate">
</action>
<menu
id="org.eclipse.ui.articles.action.contribution.editor.topLevelMenu"
label="EditorTopLevelMenu"
path="additions">
<separator name="group1"/>
</menu>
<action
id="org.eclipse.ui.articles.action.contribution.editor.action4"
label="Editor Action 4"
icon="icons/red_dot.gif"
tooltip="Tooltip for Editor Action 4"
menubarPath="org.eclipse.ui.articles.action.contribution.editor.topLevelMenu/group1"
class="org.eclipse.ui.articles.action.contribution.EditorAction4Delegate">
</action>
</editorContribution>
</extension>
앞의 예제에서 처럼, targetID 속성 값(
)은 워크벤치에게 기본 텍스트 에디터에 액션을 추가할 것임을 알려준다. 첫 액션 정의는 menubarPath 속성( )에 붙게 했다. 이 값은 IWorkbenchActionConstants.M_FILE 이나 IWorkbenchActionConstants.SAVE_EXT 상수가 될 수 있다. 이것은 추가될 액션이 파일(File) 메뉴의 저장(save) 그룹에 위치할 것임을 말한다.
다음으로, 서브 메뉴는 편집(Edit) 메뉴(
)에 정의했다. menu 항목의 path 속성은 IWorkbenchActionConstants.M_EDIT 나 IWorkbenchActionConstants.MB_ADDITIONS 상수가 될 수 있다. 이어서 기여될 두 개의 액션은 menubarPath 속성( 와 )에 서브 메뉴의 그룹( )으로 정의했다.
워크벤치의 주 메뉴 바에서는 기여된 서브 메뉴에 액션을 기여하는데에 문제가 있다. 이 서브 메뉴 항목은 워크벤치에 의해 없어져버린다. 따라서 서브 메뉴는 아무것도 가지지 못하고 보이기는 하지만 사용할 수 없게된다. 이런 서브 메뉴의 문제점은 '편집기 메뉴 기여'와 '액션셋 기여'에서만 발생한다. 이런 이유로 편집(Edit) 메뉴에 서브 메뉴를 기여하는 것은 불가능하다.
XML의 마지막 부분에서 윈도우(Window) 메뉴의 왼쪽에 새로운 최상위 메뉴를 정의(
)하고 있다. menu 항목의 path 속성은 IWorkbenchActionConstants.MB_ADDITIONS 상수를 말한다. 이 상수가 플러그인이 메뉴 바에 붙는 최상위 메뉴를 정의할 때 기본적으로 사용하는 것이다. 새로운 메뉴는 항상 윈도우(Window) 메뉴 왼쪽에 추가된다.
마지막에 정의한 action 항목은 최상위 메뉴(
)로 만들어 놓은 그룹의 경로를 menubarPath 속성( )으로 정의했다. 이 경로가 워크벤치에 의해 액션이 추가될 위치이다.
위의 그림은예제 실행하기의 결과를 보여준다. 파일(File) 메뉴의 저장(save) 메뉴 항목 아래에 액션이 추가되고, 새로운 최상위 메뉴가 추가되었음을 알 수 있다.
퍼스펙티브나 프로젝트 메뉴에 기여하고자 할 때에는, path 이름이 menu 이름과 같지 않다. 퍼스펙티브 메뉴의 경우에는 IWorkbenchActionConstants.M_VIEW 상수를 사용하고, 프로젝트 메뉴의 경우에는 IWorkbenchActionConstants.M_WORKBENCH 상수를 사용한다. 이는 이 상수가 API로 정의되고 난후에 이 메뉴들의 이름이 바뀌었기 때문이다.
개발자 가이드라인: 당신이 만든 에디터에 액션 기여 지원하기
에디터 개발자들은 모든 최상위 메뉴에 기본적으로 액션이 기여될 수 있는 위치를 IWorkbenchActionConstants.MB_ADDITIONS 상수를 이용해서 정의해두도록 한다. 이 참조점은 ISV들이 액션 기여를 할 때, 액션이 추가될 위치를 찾는데 사용된다. 추가 위치는 메뉴의 적절한 위치에 그룹마커(GroupMarker)를 추가함으로써 정의된다. 다른 추가 위치가 있다면 뷰의 자바독(javadoc)에 기술해주도록 한다. 이것은 ISV가 메뉴 바에 액션을 기여할 위치를 판단하는데 큰 도움이 되므로 신경써주는게 좋다.
액션셋을 통한 액션 추가
액션셋은 플러그인이 워크벤치 윈도우의 메인 메뉴바나 툴바에 메뉴, 메뉴 항목 그리고 툴바 항목을 기여할 수 있게 해주는 기술이다. 액션셋을 사용한다는 것의 의미를 이해하는 것이 중요하다. 액션셋은 특정 뷰나 에디터에 종속되지 않은 일반적인 액션을 기여할 수 있도록 해준다. 대게 액션셋은 생성(creation) 액션, 전역(global) 액션을 포함한다. 이것은 뷰의 액션을 메인 메뉴바나 툴바에 "올려 붙이는" 기술은 아니다.
사용자는 어떤 액션셋이 보여질지를 결정할 수 있다. 목표는 사용자가 그들의 요구에 따라 워크벤치 환경을 커스터마이징 할 수 있도록 하고, 플러그인에서 만들어진 액션이 적절한 것이라고 믿을 수 있게 하는 것이다. 뷰나 에디터의 플러그인 개발자는 자체적으로 사용되는 중요한 액션들은 자신의 메뉴나 툴바에서만 사용될 수 있도록하며 결국 스스로가 액션셋이 보여지는 것의 여부를 결정할 수 있다.
플러그인은 org.eclipse.ui.actionSets 확장점을 사용해서 액션셋을 정의한다. 이 액션은 사용자 설정에 따라 워크벤치 윈도우에 나타난다. Perspective->Customize... 메뉴를 선택해서 퍼스펙티브 다이얼로그를 띄우고 Other 카테고리를 확장시켜보자.
예제 7: 액션셋 추가
두 개의 툴바 아이템을 가지는 액션셋을 추가하는 법을 살펴보자.
<extension point="org.eclipse.ui.actionSets">
<actionSet
id="org.eclipse.ui.articles.action.contribution.set"
label="Action Set 1"
visible="false">
<action
id="org.eclipse.ui.articles.action.contribution.set.action1"
label="Set Action 1"
icon="icons/red_dot.gif"
tooltip="Tooltip for Set Action 1"
toolbarPath="Normal/additions"
class="org.eclipse.ui.articles.action.contribution.SetAction1Delegate">
</action>
<action
id="org.eclipse.ui.articles.action.contribution.set.action2"
label="Set Action 2"
icon="icons/red_dot.gif"
tooltip="Tooltip for Set Action 2"
toolbarPath="Normal/additions"
style="pulldown"
class="org.eclipse.ui.articles.action.contribution.SetAction2Delegate">
</action>
</actionSet>
</extension>
label 속성(
)은 액션 그룹의 이름을 정의한다. 이 텍스트는 퍼스펙티브 다이얼로그(Perspective->Customize...)에서 "Other"를 펼치면 나온다.
visible 속성(
)은 옵션항목이며 퍼스펙티브가 열렸을 때 기본적으로 보여질지 말지를 정한다. 이 옵션은 사용자가 커스터마이즈 되지 않은 새로운 퍼스펙티브를 열 때에만 적용된다. 사용자는 이 설정을 퍼스펙티브의 커스터마이징을 통해서 바꿀 수 있다. 기본적으로, 이 속성값은 false이다. 이 속성을 활성화 시킬때에는 잘못 사용하지 않도록 주의하자. 만약 모든 플러그인이 이 속성을 활성화하면, 모든 퍼스펙티브는 이 액션셋으로 인해 난잡해져버릴 것이다. 좀 더 좋은 접근은 org.eclipse.ui.perspectiveExtensions 확장점을 사용해서 어떤 퍼스펙티브에서 액션셋을 보여줄지 정하는 것이다. 추가 정보는 Dave Springgay의 아티클 "이클립스 UI에서 퍼스펙티브 사용하기 (Using Perspectives in the Eclipse UI"에서 "기존 퍼스펙티브 확장하기 (Extending an Existing Perspective)"를 살펴보자.
앞의 예제에서는 각 액션의 정의가 똑같아 보인다. 그러나, toolbarPath 속성(
와 ) 값이 다르다. 처음 것은 툴바 식별자이고, 두번째 것은 툴바 내의 그룹을 가리킨다. 툴바 식별자는 플러그인이 어떤 툴바에 액션을 추가할지 알려준다. 현재 워크벤치에서는 하나의 툴바만이 지원되고 이것의 식별자는 "Normal"이다. 만약 툴바 내의 그룹이 없으면, 지정된 툴바에 해당 그룹을 생성한다.
두번째 액션 정의에서 style 속성(
)이 있는데, 이것도 옵션항목이다. "pulldown"으로 설정하면 툴바 항목은 풀-다운 메뉴 형태로 표시된다. 툴바 항목의 모양은 워크벤치 윈도에서 제공하는 "새로운 마법사 열기 (Open The New Wizard)"와 동일한 모양이다. 이 속성은 메뉴 항목으로 기여될 때에는 무시된다.
class 속성(
)은 사용자가 항목을 선택했을 때 실제 액션을 수행하기 위한 자바 클래스를 정의한다. 여기에 정의되는 클래스는 style 속성이 "push", "radio" 혹은 "toggle"인 경우 org.eclipse.ui.IWorkbenchWindowActionDelegate 인터페이스를 구현해야 한다; 그리고 "pulldown" 인 경우 org.eclipse.ui.IWorkbenchWindowPulldownDelegate 인터페이스를 구현해야 한다. 이 대표 클래스에서는 셀렉션 체인지(selection changes)에 따라 액션의 활성화/비활성화 상태를 설정할 수 있다. 다만 플러그인이 로드된 후부터 가능하다. 그전까지는 액션의 활성화/비활성화 상태는 enablesFor나 selection 같은 XML 속성에 따라 설정된다.
위의 그림은예제 실행하기의 결과를 보여준다. 두 가지 액션이 툴바의 마지막에 추가되었음을 알 수 있다. 하나는 드롭 다운 메뉴 형태이다. 이 액션셋을 현재 퍼스펙티브에서 볼 수 있게 하려면 메뉴 항목에서 "Perspective->Customize..."을 선택하고, "Other" 항목를 확장해서 "Action Set 1" 옵션을 체크하도록 한다.
예제 8: 일반적인 에디터와 뷰에 액션 추가
당신이 만든 에디터나 뷰의 컨텍스트 메뉴에 하나의 액션을 추가하는 법을 살펴보자.
<extension point="org.eclipse.ui.popupMenus">
<viewerContribution
id="org.eclipse.ui.articles.action.contribution.popup.xmleditor"
targetID="org.eclipse.articles.xmleditor.editors.XMLEditor.context">
<action
id="org.eclipse.ui.articles.action.contribution.editor.xmltextaction1"
label="XML Text Editor Action"
icon="icons/red_dot.gif"
menubarPath="additions"
class="org.eclipse.ui.articles.action.contribution.EditorAction1Delegate">
</action>
</viewerContribution>
</extension>
이것은 앞서 이야기 했던예제 1과 매우 흡사하다; 다만 여기서 하이라이트된 부분만 예제 1과 차이가 있다. 이 예제는 기본 이클립스 마법사를 사용해서 만든 XML 에디터를 사용하고 있다:
- 파일 > 새로 만들기 > 프로젝트 > 플러그인 프로젝트
- 프로젝트 이름: org.eclipse.articles.xmlEditor 을 입력하고, "다음" 클릭
- "Templates page"에서 "Plug-in with an editor"를 선택 (이것은 예제 XML 에디터를 만들어준다.)
- 기본 설정을 유지하고, '마침'을 클릭
targetID 속성(
)은 뷰나 에디터의 컨텍스트 메뉴 식별자(XMLEditor.EDITOR_CONTEXT
)를 정의한다. 뷰나 에디터를 제공하는 플러그인의 문서에는 사용 가능한 식별자의 목록이 있을 것이다. 만약 문서상에 아무것도 정의되어 있지 않다면, 그 플러그인의 컨텍스트 메뉴에는 외부 액션 기여를 할 수 없다. 대게 뷰나 에디터는 하나 이상의 컨텍스트 메뉴를 가지고 있다.
아래 코드는 기본 템플릿을 사용해서 만들게 되는 XMLEditor를 보여주고 있다.
public class XMLEditor extends TextEditor {
/** The ID of this editor as defined in plugin.xml */
public static final String EDITOR_ID = "org.eclipse.articles.xmleditor.editors.XMLEditor";
/** The ID of the editor context menu */
public static final String EDITOR_CONTEXT = EDITOR_ID + ".context";
/** The ID of the editor ruler context menu */
public static final String RULER_CONTEXT = EDITOR_CONTEXT + ".ruler";
protected void initializeEditor() {
super.initializeEditor();
setEditorContextMenuId(EDITOR_CONTEXT);
setRulerContextMenuId(RULER_CONTEXT);
}
...
}
위의 그림은예제 실행하기의 결과를 보여준다. "XML Text Editor Action"이 XML 에디터의 컨텍스트 메뉴에 추가되었음을 알 수 있다. 추가된 위치는 기본적인 텍스트 에디터 컨텍스트 메뉴의 "additions" 그룹이 가리키는 곳이다.
결론
이 문서에서는 플러그인이 워크벤치에 액션을 기여할 때 사용할 수 있는 확장점(extension points)들을 다루었다. 액션 기여에 대해 좀 더 알고 싶으면 예제를 받아서 한 번씩 돌려보길 바란다. 플러그인 개발자들은 ISV들이 액션을 기여할 수 있도록 하기 위해 그리고 더 멋진 통합을 이룰 수 있도록, 특별히 이곳에 있는 내용들에 대해 신경을 써야 할 것이다. 많은 정보들이 도움말 퍼스펙티브의 "플랫폼 플러그인 개발 가이드"에 있다. "플랫폼 플러그인 개발 가이드" 도움말에서 Reference->Extension Points Reference->Workbench 를 보면 org.eclipse.ui 확장점들에 대한 문서가 있다.
예제 실행하기
파일 "action_contribution_examples.zip" 은 이 문서에 나와있는 모든 예제들의 소스 코드를 포함하고 있다. 액션 추가 예제 플러그인을 설치하기 위해서는 이클립스의 "plugings" 디렉토리에 압축을 풀면 된다. 그리고 나서 plugin.xml 파일의 주석을 예제를 실행할 수 있다.
Notices
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
'Eclipse' 카테고리의 다른 글
SWT Ribbon Control (0) | 2008.11.30 |
---|---|
Eclipse Forms로 애플리케이션에 새로운 활력을 (한글) (0) | 2007.12.01 |
GMF: Beyond the Wizards (0) | 2007.08.03 |