Menu

org.eclipse.ui.menus

3.2

Opisywany punkt rozszerzenia umożliwia programistom wtyczek definiowanie menu, separatorów, grup logicznych oraz elementów menu, które mają być wyświetlane w dowolnym miejscu w ramach aplikacji (od wierszy statusu po menu kontekstowe). Ponadto umożliwia on definiowanie zestawów tego rodzaju elementów wnoszonych przez kontrybutora (tzw. zestawów akcji), które użytkownicy mogą włączać i wyłączać. Zasadniczo punkt rozszerzenia menu zawiera wszystkie elementy prezentacji (z wyjątkiem ikon), które można wnieść do dowolnego obszaru menu lub obszaru marginesu w środowisku Eclipse.

Każdemu elementowi w ramach tego punktu rozszerzenia przydziela się unikalny identyfikator. Umożliwia to tworzenie odwołań do tych elementów w innych miejscach bez konieczności ich ponownego definiowania. Identyfikator może być potrzebny na przykład do uporządkowania lub zdefiniowania zestawu akcji. Ponadto zastosowane rozwiązanie umożliwia zewnętrznym programistom wtyczek umieszczanie elementów w nowych miejscach w ramach interfejsu (zależnie od potrzeb).

Uwaga: w wersji 3.2 wdrożona została jedynie część opisywanego mechanizmu rozszerzenia, która dotyczy elementów wnoszonych przez kontrybutora, umieszczanych w obszarze marginesu. Próba dodania elementów, menu, pasków narzędzi bądź wpisów wiersza statusu zostanie zignorowana.

<!ELEMENT extension (item* , menu* , group* , widget*)>

<!ATTLIST extension

point CDATA #REQUIRED

id    CDATA #IMPLIED

name  CDATA #IMPLIED>


<!ELEMENT item (parameter* , location* , visibleWhen?)>

<!ATTLIST item

id        CDATA #REQUIRED

commandId CDATA #REQUIRED

menuId    CDATA #IMPLIED>

Dany element może być elementem menu lub marginesu (zależnie od umiejscowienia). Tekst i obraz powiązane z tym elementem są rysowane na podstawie komendy.



<!ELEMENT menu (location* , visibleWhen?)>

<!ATTLIST menu

id    CDATA #REQUIRED

label CDATA #IMPLIED>

Wyświetlane menu może być dołączone do elementu narzędzia lub umieszczone w dowolnym miejscu w menu widoku, w menu kontekstowym lub na pasku menu najwyższego poziomu. Programista wtyczek może założyć, że w każdym widoku występuje menu i pasek narzędzi, a także że istnieje pasek menu najwyższego poziomu. Menu kontekstowe należy przed użyciem zarejestrować programowo (parz punkt Informacje o interfejsie API).

Menu może zawierać wyłącznie grupy.



<!ELEMENT group (location*)>

<!ATTLIST group

id                CDATA #REQUIRED

separatorsVisible (true | false) "true">

Grupa logiczna. Może ona być widoczna (np. przez umieszczenie przed nią i po niej separatorów) lub niewidoczna. Domyślnie grupy logiczne są widoczne.

Grupa może zawierać menu, elementy lub inne grupy.



<!ELEMENT widget (location* , class? , visibleWhen? , layout?)>

<!ATTLIST widget

id    CDATA #REQUIRED

class CDATA #REQUIRED>

Element menu lub marginesu, który ma bezpośredni dostęp do widgetów. Element ten może na przykład służyć do wyświetlania okna złożonego. Niestety oznacza to również, że wyświetlenie elementu widgetu w interfejsie użytkownika spowoduje załadowanie wtyczki. Z opisywanego elementu należy korzystać ostrożnie, ponieważ może to powodować problemy z wydajnością. Oprócz tego mogą występować utrudnienia w zakresie obsługi makr, tworzenia skryptów oraz innych mechanizmów działających w oparciu o komendy. Widget użyty w ramach marginesu powoduje załadowanie wtyczki wyłącznie w sytuacji, w której jest widoczny w interfejsie użytkownika.



<!ELEMENT layout EMPTY>

<!ATTLIST layout

fillMajor (true | false)

fillMinor (true | false) >

Element ten może służyć do określania różnych opcji układu elementów dodawanych w miejscach oznaczonych atrybutem trim.



<!ELEMENT location (order? , (bar | part | popup))>

<!ATTLIST location

mnemonic   CDATA #IMPLIED

imageStyle CDATA #IMPLIED>

Położenie, w którym można wyświetlić menu, grupę, element lub widget. Wartość ta służy do sterowania informacjami zależnymi od położenia.



<!ELEMENT bar EMPTY>

<!ATTLIST bar

type (menu|trim)

path CDATA #IMPLIED>

Element podrzędny w ramach położenia. Może to być pasek menu lub obszar marginesu. Brak informacji kwalifikujących oznacza, że element dotyczy paska menu lub marginesu najwyższego poziomu. Informacja kwalifikująca w postaci elementu part oznacza, że dotyczy on menu lub marginesu danej części.



<!ELEMENT class (parameter*)>

<!ATTLIST class

class CDATA #REQUIRED>

Element klasy umożliwiający obsługę składni analizy rozszerzenia kodu wykonywalnego w odniesieniu do elementów widget i dynamic.



<!ELEMENT visibleWhen (not | or | and | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>

<!ATTLIST visibleWhen

checkEnabled (true | false) "false">

Atrybut sterujący widocznością danego elementu.



<!ELEMENT part (popup | bar)>

<!ATTLIST part

id    CDATA #IMPLIED

class CDATA #IMPLIED>

Element w ramach położenia. Za pomocą tego elementu położenie jest kwalifikowane, a tym samym odnoszone do określonej części środowiska roboczego. Może to być widok lub edytor. Informacje kwalifikujące mogą zawierać nazwę klasy danej części (łącznie z dziedziczeniem) lub mogą odnosić się do identyfikatora widoku bądź edytora.

Określić można tylko jedną wartość atrybutów id i class.



<!ELEMENT parameter EMPTY>

<!ATTLIST parameter

name  CDATA #REQUIRED

value CDATA #REQUIRED>

Parametr rozszerzenia kodu wykonywalnego lub komendy (zależnie od miejsca, w którym występuje w ramach rozszerzenia).



<!ELEMENT order EMPTY>

<!ATTLIST order

position   (start|end|before|after)

relativeTo CDATA #IMPLIED>

Element ten steruje pozycją menu, grupy, elementu lub widgetu w ramach danego położenia.



<!ELEMENT popup EMPTY>

<!ATTLIST popup

id   CDATA #IMPLIED

path CDATA #IMPLIED>

Część położenia wskazująca, czy dane menu, grupa, element lub widget mają być wyświetlane w menu podręcznym.



<!ELEMENT enablement (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

Ogólny element główny. Element ten może być stosowany w ramach punktu rozszerzenia do zdefiniowania jego wyrażenia włączającego. Elementy potomne wyrażenia włączającego łączy się za pomocą operatora and.



<!ELEMENT not (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>

Element ten odpowiada operacji NOT wykonywanej na wynikach wartościowania wyrażenia podelementu.



<!ELEMENT and (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

Element ten odpowiada operacji AND wykonywanej na wynikach wartościowania wszystkich wyrażeń podelementów.



<!ELEMENT or (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

Element ten odpowiada operacji OR wykonywanej na wynikach wartościowania wszystkich wyrażeń podelementów.



<!ELEMENT instanceof EMPTY>

<!ATTLIST instanceof

value CDATA #REQUIRED>

Element ten służy do wykonywania sprawdzenia instanceof obiektu aktywnego. Wyrażenie zwraca wartość EvaluationResult.TRUE, jeśli typ obiektu jest podtypem typu określonego atrybutem value. W przeciwnym razie zwracana jest wartość EvaluationResult.FALSE.



<!ELEMENT test EMPTY>

<!ATTLIST test

property CDATA #REQUIRED

args     CDATA #IMPLIED

value    CDATA #IMPLIED>

Element ten służy do wartościowania stanu właściwości obiektu aktywnego. Zbiór właściwości objętych testowaniem można rozszerzyć za pomocą punktu rozszerzenia testera właściwości. Wyrażenie testowe zwraca wartość EvaluationResult.NOT_LOADED, jeśli nie załadowano jeszcze testera właściwości wykonującego faktyczne testowanie.



<!ELEMENT systemTest EMPTY>

<!ATTLIST systemTest

property CDATA #REQUIRED

value    CDATA #REQUIRED>

Testuje właściwość systemową, wywołując metodę System.getProperty i porównując wynik z wartością określoną za pomocą atrybutu value.



<!ELEMENT equals EMPTY>

<!ATTLIST equals

value CDATA #REQUIRED>

Element ten służy do wykonywania sprawdzenia equals obiektu aktywnego. Wyrażenie zwraca wartość EvaluationResult.TRUE, jeśli obiekt jest równy wartości określonej atrybutem value. W przeciwnym razie zwracana jest wartość EvaluationResult.FALSE.



<!ELEMENT count EMPTY>

<!ATTLIST count

value CDATA #REQUIRED>

Element ten służy do sprawdzania liczby elementów w ramach kolekcji.



<!ELEMENT with (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST with

variable CDATA #REQUIRED>

Element ten zamienia obiekt, który ma być sprawdzany w odniesieniu do wszystkich elementów potomnych, na obiekt, do którego odwołuje się dana zmienna. Jeśli zmiennej nie można zinterpretować, podczas wartościowania wyrażenie zgłasza wyjątek ExpressionException. Elementy potomne wyrażenia with łączy się za pomocą operatora and.



<!ELEMENT resolve (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST resolve

variable CDATA #REQUIRED

args     CDATA #IMPLIED>

Element ten zamienia obiekt, który ma być sprawdzany w odniesieniu do wszystkich elementów potomnych, na obiekt, do którego odwołuje się dana zmienna. Jeśli zmiennej nie można zinterpretować, podczas wartościowania wyrażenie zgłasza wyjątek ExpressionException. Elementy potomne wyrażenia with łączy się za pomocą operatora and.



<!ELEMENT adapt (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST adapt

type CDATA #REQUIRED>

Element ten służy do dostosowywania obiektu aktywnego do typu określonego atrybutem type. Wyrażenie zwraca wartość not loaded, jeśli nie załadowano jeszcze adaptera lub typu, którego dotyczy odwołanie. Jeśli nazwa typu w ogóle nie istnieje, podczas wartościowania zgłaszany jest wyjątek ExpressionException. Elementy potomne wyrażenia adapt łączy się za pomocą operatora and.



<!ELEMENT iterate (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST iterate

operator (or|and) >

Element ten służy do iteracji zmiennej typu java.util.Collection. Jeśli obiekt aktywny nie jest obiektem typu java.util.Collection, podczas wartościowania wyrażenia zgłaszany jest wyjątek ExpressionException.



W poniższym przykładzie przedstawiono podstawową definicję menu.

<menu id=

"com.mycompany.myplugin.projection"

label=

"%Folding.label"

>

<location mnemonic=

"%Folding.label.mnemonic"

>

<part id=

"AntEditor"

>

<popup id=

"#RulerContext"

path=

"rest"

/>

</part>

</location>

</menu>

W powyższym przykładzie programista wtyczki wnosi elementy do wszystkich części, które zawierają dany typ jako podklasę lub są wykorzystywane do jego implementacji. Umożliwia to na przykład wnoszenie niektórych elementów do wszystkich edytorów tekstu.

<menu id=

"com.mycompany.myplugin.textEditorMenu"

label=

"Komendy tekstowe"

>

<location mnemonic=

"X"

>

<part class=

"AbstractTextEditor"

>

<popup id=

"#RulerContext"

path=

"rest"

/>

</part>

</location>

</menu>

Z menu można powiązać pomoc.

<menu id=

"com.mycompany.myplugin.RunWithConfigurationAction"

label=

"Uruchamianie wraz z konfiguracją"

helpContextId=

"run_with_configuration_context"

>

<location>

<bar />

</location>

</menu>

W ramach menu można zdefiniować grupy logiczne. Grupy te mogą być widoczne (np. przez umieszczenie przed nimi i po nich separatorów) lub niewidoczne. Domyślnie grupy logiczne są widoczne.

<group id=

"com.mycompany.myplugin.stepGroup"

>

<location>

<bar path=

"org.eclipse.ui.run"

/>

</location>

</group>

<group id=

"com.mycompany.myplugin.stepIntoGroup"

separatorsVisible=

"false"

>

<location>

<bar path=

"org.eclipse.ui.run"

/>

</location>

</group>

Menu, grupy, elementy i widgety można umieszczać w wielu położeniach.

<item id=

"com.mycompany.myplugin.ToggleStepFilters"

commandId=

"com.mycompany.myplugin.ToggleStepFilters"

>

<location mnemonic=

"%mnemonic"

>

<bar path=

"org.eclipse.ui.run/emptyStepGroup"

/>

</location>

<location>

<part id=

"org.eclipse.debug.ui.DebugView"

>

<bar type=

"trim"

path=

"renderGroup"

/>

</part>

</location>

<location mnemonic=

"%mnemonic"

>

<part id=

"org.eclipse.debug.ui.DebugView"

>

<popup path=

"renderGroup"

/>

</part>

</location>

</item>

Jeśli element podręczny został określony bez identyfikatora i elementu nadrzędnego części, ma on zastosowanie do każdego menu kontekstowego zarejestrowanego w środowisku roboczym. Sposób działania jest podobny jak w przypadku wcześniejszych obiektów wnoszonych. Podobnie element podręczny najwyższego poziomu z identyfikatorem wpływa na każde menu kontekstowe zarejestrowane pod daną nazwą.

<item id=

"com.mycompany.myplugin.ObjectContribution"

commandId=

"com.mycompany.myplugin.ObjectContribution"

>

<location>

<popup path=

"additions"

/>

</location>

</item>

W niektórych przypadkach może zajść potrzeba sterowania widocznością elementu. Standardowo zaleca się utrzymywanie stabilnego układu menu i pasków narzędzi, jednak w pewnych sytuacjach można ukryć elementy, które nie są w danym momencie niezbędne. Dotyczy to w szczególności menu kontekstowych, w których ilość miejsca jest ograniczona. W takim przypadku definiuje się element visibleWhen. Jest on niemal identyczny z elementami activeWhen i enabledWhen definiowanymi w punkcie rozszerzenia procedur obsługi.

<item id=

"com.mycompany.myplugin.ConvertToWatchExpression"

commandId=

"com.mycompany.myplugin.ConvertToWatchExpression"

>

<location mnemonic=

"%mnemonic"

>

<part id=

"org.eclipse.debug.ui.DebugView"

>

<popup path=

"additions"

/>

</part>

</location>

<visibleWhen>

<with variable=

"Wybór"

>

<iterate operator=

"and"

>

<not>

<instanceof value=

"IWatchExpression"

/>

</not>

<instanceof value=

"IExpression"

/>

</iterate>

</with>

</visibleWhen>

</item>

Najczęstszym przypadkiem jest po prostu uwidocznianie elementów, których procedury obsługi są włączone. Wymaga to zastosowania dodatkowych elementów składni. Element visibleWhen jest opatrywany atrybutem checkEnabled.

<item id=

"com.mycompany.myplugin.compareWithPatch"

commandId=

"com.mycompany.myplugin.compareWithPatch"

>

<location mnemonic=

"%mnemonic"

>

<part id=

"MyPart"

>

<popup path=

"additions"

/>

</part>

</location>

<visibleWhen checkEnabled=

"true"

/>

</item>

Każdy element powiązany z komendą może zawierać wartości parametrów. Jeśli parametr danego identyfikatora nie został zdefiniowany, występuje błąd. Brak powiązania między elementem a komendą także oznacza błąd.

<item id=

"com.mycompany.myplugin.RunHistory"

commandId=

"com.mycompany.myplugin.RunHistory"

>

<location>

<bar path=

"org.eclipse.ui.run"

/>

</location>

<parameter name=

"index"

value=

"1"

/>

</item>

Istnieje również możliwość określania kolejności względnej. Służy do tego atrybut kolejności dotyczący elementu położenia. Atrybut kolejności może mieć następujące wartości: start (element jest umieszczany na początku kontenera), end (element jest umieszczany na końcu kontenera), after (element jest umieszczany po elemencie równorzędnym o identyfikatorze odpowiadającym atrybutowi ref) oraz before (element jest umieszczany przed elementem równorzędnym o identyfikatorze odpowiadającym atrybutowi ref). Kolejność względną można stosować w odniesieniu do dowolnego typu elementu menu.

<item id=

"com.mycompany.myplugin.MyFirstItem"

commandId=

"com.mycompany.myplugin.MyFirstCommand"

>

<location>

<order position=

"start"

/>

<bar path=

"org.eclipse.ui.run"

/>

</location>

</item>

<item id=

"com.mycompany.myplugin.MySecondItem"

commandId=

"com.mycompany.myplugin.MySecondCommand"

>

<location>

<order position=

"after"

relativeTo=

"com.mycompany.myplugin.MyFirstItem"

/>

<bar path=

"org.eclipse.ui.run"

/>

</location>

</item>

Aby uzyskać bezpośredni dostęp do widgetów (np. w celu wyświetlenia okna złożonego), można zastosować element widget. Niestety oznacza to również, że wyświetlenie elementu widgetu w interfejsie użytkownika spowoduje załadowanie wtyczki.

<widget id=

"com.mycompany.myplugin.MyComboBoxSimple"

class=

"com.mycompany.myplugin.MyComboBox"

>

<location>

<bar type=

"trim"

path=

"myGroup"

/>

</location>

</widget>

<widget id=

"com.mycompany.myplugin.MyComboBoxParameterized1"

class=

"com.mycompany.myplugin.MyComboBox:a,b,c"

>

<location>

<bar type=

"trim"

path=

"myGroup"

/>

</location>

</widget>

<widget id=

"com.mycompany.myplugin.MyComboBoxParameterized2"

>

<class class=

"com.mycompany.myplugin.MyComboBox"

>

<parameter name=

"list"

value=

"a,b,c"

/>

<parameter name=

"selected"

value=

"c"

/>

<parameter name=

"editable"

value=

"false"

/>

</class>

<location>

<bar type=

"trim"

path=

"myGroup"

/>

</location>

</widget>

Widgety można także wykorzystywać do wnoszenia elementów na margines środowiska roboczego. W poniższym przykładzie przedstawiono definicję nowego widgetu pod nazwą "HeapStatus", który powinien domyślnie zostać umieszczony po marginesie wiersza statusu (tj. w dolnej części okna środowiska roboczego). Więcej informacji na temat predefiniowanych grup zawiera opis elementu bar.

Grupy umieszczane na marginesie można przenosić do innych obszarów marginesu. W odniesieniu do elementu relativeTo dotyczącego położenia zakłada się, że grupa, której dotyczy odwołanie, znajduje się w pozycji domyślnej podczas określania nowego położenia na marginesie. Zasadniczo oczekuje się, aby tego rodzaju kontrybutory tworzyły własne grupy służące do udostępniania nowego widgetu, co umożliwia przemieszczanie danego elementu marginesu niezależnie od innych elementów marginesu. Wyjątek stanowi grupa status.

   

<extension point=

"org.eclipse.ui.menus"

>

<group id=

"TestTrimAPI.heapStatusGroup"

separatorsVisible=

"true"

>

<location>

<bar type=

"trim"

/>

<order position=

"after"

relativeTo=

"status"

/>

</location>

</group>

<widget class=

"HeapStatusWidget"

id=

"TestTrimAPI.HeapStatus"

>

<location>

<bar path=

"heapStatusGroup"

type=

"trim"

/>

</location>

<layout fillMajor=

"false"

fillMinor=

"true"

/>

</widget>

</extension>

Aby zarejestrować menu kontekstowe, należy skorzystać z metod interfejsu IWorkbenchPartSite.registerContextMenu.