воскресенье, 23 декабря 2007 г.

Eclipse.PlatformPluginDeveloperGuide.navigatorContent

Вольный перевод раздела руководства разаботчика plug-in'ов для Eclipse.
Выполнен - Флоров Евгений.
Будет пополняться постепенно.


...



suppressedExtensionId CDATA #REQUIRED
policy (InvokeOnlyIfSuppressedExtAlsoVisibleAndActive|InvokeAlwaysRegardlessOfSuppressedExt) "InvokeAlwaysRegardlessOfSuppressedExt">

В случае, если для данного элемента срабатывает как выражение triggerPoints у подавляемого расширения, так и у объявляемого расширения, то данное расширение будет вызвано, а подавленное им расширение - нет. Клиенты, которые указывают перекрываемый элемент должны также предоставлять поставщика содержания (content provider) реализующего org.eclipse.ui.navigator.IPipelinedTreeContentProvider, который предоставляет методы для перехвата (intercept) запросов на дочерние узлы (children), родительские узлы (parents), и непосредственые обновления представления (viewer).
  • suppressedExtensionId - Идентификатор подавляемого (если расширение в котором пределяется override видимо и активно) расширения.
  • policy - Политика - объявляет, как расширение должно вызываться со стороны движка/каркаса (framework). Если политика не указана, то используется значение по-умолчанию InvokeAlwaysRegardlessOfSuppressedExt. Доступны следующие политики:
    • InvokeOnlyIfSuppressedExtAlsoVisibleAndActive: Данный компонент является безусловно перекрывающим компонентом. За исключением того, когда подавленное им расширение видимо и доступно представлению, определяемому расширению не должна предоставляться возможность участвовать в процессе предоставления содержания. Если используется эта политика, данный компонент будет вызван только тогда, когда выражение triggerPoints для подавляемого расширения и выражение triggerPoints данного расширения доступны (срабатывают) для текущего элемента содержания. Поэтому, выражения triggerPoints и possibleChildren для данного расширения должны быть подмножеством соотвественно выражений triggerPoints и possibleChildren подавляемого им расширения. Другими словами, данная политика позволяет подавить (переопределить) предоставление провайдером suppressedExtensionId содержания для некоторого подмножества обрабатываемых им элементов.
    • InvokeAlwaysRegardlessOfSuppressedExt (default): Показывает, что данное расширение является первоклассным (first class) расширением; ему должна быть предоставлена возможность предоставлять содержание независимо от того активно-ли или видимо-ли для представления подавляемое расширение suppressedExtensionId. Таким образом, расширение является первоклассным и перекрывающим. Оно будет вызываться всегда, когда его выражение triggerPoints срабатывает. Когда подавляемое расширение и его выражение triggerPoints срабатывает, наше расширение будет вызвано вместо подавляемого расширения для данных элементов; подавленное расширение не получит возможность непосредственного участия в процессе.
...

понедельник, 3 декабря 2007 г.

Создание представлений на основе Common Navigator. Часть IV: Сборка объектов

Обзор

В предыдущем разделе, мы обсуждали как конфигурировать всплывающие меню для экземпляра Common Navigator. Как вы видели, Common Navigator может декларировать все его точки включения меню через точку расширения org.eclipse.ui.navigator.viewer и показывать все-ли привязки к точке расширения org.eclipse.ui.popupMenus должны быть учтены. Декларативная конфигурация меню предназначена для исключения программирования струткуры меню, и документирования структуры меню для потенциальных расширителей.

Мы также кратко говорили о двух способах, с помощью которых конфигураторы могут встроиться в меню:
  1. через org.eclipse.ui.popupMenus, который позволяет вам добавить меню через workbench;
  2. через org.eclipse.ui.navigator.navigatorContent, который специфичен для каркаса Common Navigator.
Мы рассмотрим ...popupMenus в данном разделе, и ...navigatorContent в следующем.

Как всегда, вы можете найти полные исходные тексты для этого примера в org.eclipse.ui.navigator.examples модуле из Eclipse CVS репозитория.

Добавление операции "Delete Property" с помощью org.eclipse.ui.popupMenus

Напоминаю, что для данной серии статей мы отображаем простую модель файла свойств.



Теперь мы добавим действие "Delete Property", которое позволяет пользователю выделить свойство из списка и удалить его.



Откройте редактор Plug-in Manifest двойным щелчком на файле plugin.xml в вашем проекте модуля. Если вы не не уверены в точ, что это означает, прочитайте еще раз раздел I данной серии.

На закладке Extensions, выберите Add... и затем org.eclipse.ui.popupMenus. Если вы не видете эту опции в списке, снимите метку с "Show only extension points from the required plugins". Если у вас org.eclipse.ui не добавлен в проект как модуль от которого зависит наш модуль, то сделайте это.

Теперь выберите элемент созданные в списке ("org.eclipse.ui.popupMenus"), нажмите правую кнопку и выберете "objectContribution". Затем, нажмите правую кнопку еще раз и выберите "action".



Любой objectContribution может объявить меню (поднемю расширения для всплывающего меню) и действия. Расширение довольно многословно для облегчения оптимизации загрузки модуля. Это означает, что расширение объявляет достаточно информации, для того, чтобы реальный класс (и следовательно модулю) не потребуется загружаться для отрисовки меню. Если пользователь не выбрал действие, то это означает, что модуль не был загружен.

На практике, расширение объявляет ярлыки меню, иконку меню, и контекстное окно для остальных типов. Расширение также объявляет путь панели меню (напоминаю, что мы описали значения для точек вставки в разделе III).

Используйте значения из следующей диаграммы для конфигурирования элементов действия. Вы можете ввести значения на странице Extensions, или перейти на закладку plugin.xml и заполнить его вручную.



Есть несколько вещей, которые мы должны обсудить здесь.

Первое - это objectClass, который объявляет, что именно нам интересно в ...PropertiesTreeData. Напоминаю, что мы уже определили простую модель объектов для представления name=value пар в файле свойств. Для удаления этих элементов, мы хотим, чтобы наши операции были доступны на экземпляре нашей модели.

Атрибут class указывает подкласс org.eclipse.ui.actions.ActionDelegate. Реализация DeletePropertyAction.run(IAction) имеет некоторый шаблон для robustness, но важная часть такова:



ActionDelegate объявляет метод selectionChanged(IAction, ISelection), который обновляется, когда меняется выбор в представлении. Мы перекрываем этот метод для запоминания выбора так, что когда приходит сообщение, что пользователь выбрал опцию меню мы знаем на каком элементе он кликнул.

Итого

Теперь вы должны чуствовать себя комфортно в экспериментах с добавлением большего числа действий во всплывающее меню, а так же при добавлении подменю. Убедитесь, что проверили элемент меню (accessible in the same way you found action earlier). Если вы используете закладку Extensions, все доступные атрибуты будут доступны вам и помните, что вы можете использовать правый щелчёк для создания подменю.

воскресенье, 2 декабря 2007 г.

Создание представлений на основе Common Navigator. Часть III: Конфигурирование меню

Автор оригинальной статьи : Michael D. Elder
Перевод: Евгений Флоров

В предыдущих разделах мы узнали как конструироватьCommon Navigator Framework (CNF) представление и базовое расшиерние для отображения файлов свойств. Теперь мы разберёмся с тем как конфигурировать меню для CNF представления и как добавить действия в наше представление для манипулирования его содержанием.

Обзор

Существует две основные возможности для добавления действий в Common Navigator Framework (CNF) представление:
  • Собрать действия используея org.eclipse.ui.popupMenus как objectContributions или viewerContributions. Точка расширения ...popupMenus позволит вам собрать индивидуальные делегаты действий через Eclipse Workbench. CNF представление может быть сконфигурировано с учётом условий (contributions) (это вариант по-умолчанию) или игнорируя их. В случае, когда Project Explorer contributed by Platform/UI, object and viewer contributions are honored. (Будет затронуто в разделе IV.)
  • Сборка действий используя org.eclipse.ui.navigator.navigatorContent как actionProvider'ы. Иногда, клиенты требуют больше программного управления тем, какие действия собраны в данное меню в конкретном контексте, а также какие retargetable действия сконфгурированы на основе текущего выбора (элемента).
Конфигурирование структуры меню

В Разделе I, мы определили элемент viewer нашего примера, и всплывающее меню там было кратко упомянуто.
Напоминаю, что есть два способа конфигурирования всплывающего меню. Первая возможность - это простое указание значения для popupMenuId элемента viewer в org.eclipse.ui.navigator.viewer. Вторая возможность - это выполнить более активную роль в конфигурировании точек включения (insertion points) поддержки меню.

Подсказка: Случай, когда указывается (определяется) и popupMenuId и элемент popupMenu - является ошибкой.

Если мы установили popupMenuId, мы должны иметь что-то похожее на это:



Идентификатор может быть использован расширителями (extenders) org.eclipse.ui.popupMenus для добавления viewerContributions особенностей к представлению, однако не требуются идентификаторы для objectContributions.

Когда указан только атрибут popupMenuId, набор по-умолчанию точек вставки автоматически конфигурируется во всплывающем меню. Это документируется в schema
reference для org.eclipse.ui.navigator.viewer, но продублировано здесь для удобства:

"group.new" separator="true"
"group.goto"
"group.open" separator="true"
"group.openWith"
"group.edit" separator="true"
"group.show" separator="true"
"group.reorganize"
"group.port" separator="true"
"group.generate" separator="true"
"group.search" separator="true"
"group.build" separator="true"
"additions" separator="true"
"group.properties" separator="true"

Эти значения могут быть использованы атрибутом menubarPath элементов в org.eclipse.ui.popupMenus.

Эти значения могут быть также использованы тогда, когда программно используются или ищутся элементы меню (смотри org.eclipse.jface.action.IContributionManager, конкретно insertAfter(), insertBefore(), и appendToGroup().

Все строковые константы ("group.*") описаны в org.eclipse.ui.navigator.ICommonMenuConstants и доступны для программного использования.

С другой стороны, мы можем определить элемент popupMenu как дочку для viewer, где затем мы можем определить наш mix точек включения. Запомните, что вы можете использовать закладку Extensions редактора Plug-in Manifest для создания элементов расширения из меню.



Для нашего примера, мы можем использовать такую же конфигурацию меню, как и в Project Explorer:



Каждый элемент insertionPoint показывает GroupMarker'у, что является доступным через IContributionMenu API. Везде, где атрибут separator устанавливается в "истина", меню отобразит горизонтальную линию. Меню в Eclipse достаточно разумны, чтобы отображать лии по-необходимости, так две линии расположенные вплотную отображаются как одна горизонтальная линия.

Также, необходимо принять во внимание атрибут allowsPlatformContributions="true" для элемента popupMenu. По-умолчанию, CNF представления учитывают сборки ..popupMenus. Установка данного атрибута в "ложь" ограничит меню только учётом Action Provider'ов.

Пример выше не делает что-либо фанастического, но в вашем CNF представлении, мы можете определить ваши точки включения меню ("group.example") где сделать их чуствительными для ваших сценариев. Рекомендуемым соглашением именования является "group.*", как верхняя точка включения, с исключением для специальных дополнительных групп.

Несколько комментариев на счет расширения или управления набором точек включения в меню CNF. Невозможно декларативно управлять или расширять набор точек включения для уже сконфигурированных представлений. Возможно программно добавить новые GroupMarker'ы или Separators через Action Provider'ов, но эта правктика должна использоваться аккуратно. Мы получим подробности о том как это может быть в разделе V, но на данный момент просто примите во внимание предупреждение о том, что эта практика должна применяться с осторожностью и только используя в своих интересах атрибут dependsOn элемента actionProvider , где значение показывает идентификатор Action Provider, который добавляет к меню дополнительные точки включения. Точки включения не должны программно удаляться, так как другие расширения могут зависить от них. Если ваше представление не использует конкретную точку включения, то вы можете пропустить ее, когда определяете ваш элемент popupElement.

четверг, 29 ноября 2007 г.

Создание представлений на основе Common Navigator. Часть II: Добавление содержания

Автор оригинальной статьи : Michael D. Elder
Перевод: Евгений Флоров

В данном разделе, мы выполним добавление простого расширения содержания в представление созданное в последнем примере. Для исключения возможности завязнуть в сложных провайдерах контента (content provider) и ярлыков (label provider), мы сконцентрируемся на файловой структуре с очень простой моделью, в этом случае - плоские старые *.properties файлы. По-завершению, наше расширение контента позволит нам раскрыть любой *.properties файл в Example viewer и отобразить данные файла в представлении.

Вы можете также загрузить полный пример в том виде, в котором он будет в конце данного раздела.

Во-первых, давайте посмотрим на что будет похоже расширение в plugin.xml файле. Если вы читали предыдущий раздел, вы знаете, что вы можете строить расширение (подобное последующему примеру) используя закладку Extensions в Plug-in Manifest Editor. Сначала путем выбора Add... на странице Extensions, выберите org.eclipse.ui.navigator.navigatorContent, затем в меню по правой кнопке выберите New > navigatorContent. Другой способ - это создание этого расширения в закладке plugin.xml того-же редактора. Оба варианта хороши, но первая возможность использует меню New из Extension Point Schema так, что вы увидете другие опции, которые довтупны в закладке plugin.xml.


Расширение объявляет расширение содержания с id - "org.eclipse.ui.examples.navigator.propertiesContent", с отображаемым именем "Properties File Contents". Имя - это текстовая строка используемая в закладке "Available Extensions" диалогах Filters. Мы разберемся с кодом для провайдеров содержимого и ярлыков позднее, а на данный момент запомните только, что каждый из них должен быть специфицирован; вы не можете описать только один или другой.

В итоге мы устанавливаем некоторые атрибуты для того, чтобы сказать каркасу как нам хотелось бы, чтобы наше расширение отображалось в представлении.
  • activeByDefault определяет должно ли расширение быть активным в конфигурации по-умолчанию (то есть в новом workspace).
  • icon определяет какая исонка должна быть использована, когда ссылаются на расширение в пользовательском интерфейсе
  • priority используется в нескольких различных случаях. Наиболее известным является определение относительного порядка элементов в представлении (высокоприоритетные элементы подымаются вверх представления, низкоприоритетные - опускаются вниз). В основном, вариантов "normal"или "high" должно быть достаточно для большинства расширений, показывая, что они должны смешиваться с ресурсными расширениями (когда приоритеты одинаковы, то для сортировки элементов используется алфавтная сортировка их ярлыков) или поместить их выше ресурсов под проектами.
Внутри каждого элемента, мы можем указать множество типов расширений, но до того, как расширить пример, мы должны описать каркасу - когда наше расширение должно быть вызвано. Мы должны описать когда мы можем предоставить дочерние, родительские узлы или ярлыки и иконки узлов дерева. Мы делаем это используя Eclipse Core Expressions. Пока я предложу вам обратиться к документации по org.eclipse.core.expressions для изучения подробностей об этом или вы можете использовать New > ...меню в закладке Extensions для простого создания их.

Для расширений содержания существует два важных выражения: triggerPoints и possibleChildren.

Выражение triggerPoints показывает какие типы узлов в дереве моглибы быть интересными для нашего расширения. Когда каркас находит узел соотвествующий выражению triggerPoints, наше расширение будет вызвано для обеспечения элементов или подузлов для данного узла. Наше расширение может быть не единственным кто предоставит подузлы, поэтому каркас скомпонует все собранные дочерние узлы под каждым узлом.



Выражение possibleChildren показывает для каких типов узлов дерева наше расширение может предоставить ярлыки или родителя. Для ваших сценариев, которые могут поддерживать связь с редактором, или setSelection() на представлении, данное выражение должно быть аккуратным и полным.



После того, как мы определили расширение, мы должны связать (bind) его к представлению с которым мы хотим это расширение ассоциировать. Данная спецификация показывает, что любое расширение которое соотвествует шаблону included является видимым любому представлению с указанным в элементе viewerId. Напоминаю, что мы видели это в предыдущем разделе.

Например, мы привяжем наше расширение содержания свойств (с id "org.eclipse.ui.examples.navigator.propertiesContent") к нашему Example View (с id "org.eclipse.ui.examples.navigator.view").



Теперь, когда мы настроили наше расширение, посмотрим на код, который фактически выполнит жесткую привязку.

Во-первых нам нужна модель. Файл свойств имеет черезвычайно простую структуру и мы смоделируем это используя только один тип объекта модели, называемый PropertiesTreeData, который будет иметь три поля: name (имя свойства), значение (значение свойства), и container (файл содержащий модель свойств). Один из этих элементов модели будет создан для каждого свойства в *.properties файле.

В нашем примере, модель свойств будет загружена только когда она будет запрошена через поставщика содержания (content provider). Поставщик содержания используется каркасом для определения дочек каждого элемента в дереве, или для указанного элемента, определение их родителя (или родителей, так как их может быть потенциально больше чем один).

Поставщик содержания в нашем примере реализует implements org.eclipse.jface.viewers.ITreeContentProvider для предоставления информации о структуре дерева. Каркас Common Navigator также поддерживает реализации новых org.eclipse.jface.viewers.ITreePathContentProvider, но это уже выходит за рамки этого примера.

PropertiesContentProvider также обрабатывает некоторые другие функции требуемые нашему расширению, такие как отслеживание (listening) изменений ресурсов и соответственно обновление модели (и представления). Мы не будем смотреть это в текущем разделе, но вы можете смотреть как это работает в полных исходниках.

Теперь, мы сконцентрируемся на интеграционных методах представления, определенных в ITreeContentProvider.


ITreeContentProvider должен релизовать getElements(Object input), getChildren(Object parent), hasChildren(Object element) и getParent(Object element).

Метод getElements() запрашивается для элементов в корне представления. Многие реализации просто перенаправляют этот вызов в getChildren(), и это то, что мы сделаем.



getChildren() принимает объект (в нашем случае либо *.properties IFile либо экземпляр объекта нашей модели PropertiesTreeData так как мы описали это в нашем расширении.

В последующей реализации, мы выполняем проверку на то является ли переданный элемент экземпляром org.eclipse.core.resources.IFile и если да, то имеет ли файл расширение - *.properties. Если переданные элемент удовлетворяет этим условиям, то мы проверяем наш кэш загруженной модели или пытаемся загрузить модель, если она не кеширована. Метод updateModel() будет создавать объект PropertiesTreeData для каждого свойства и кэшировать то, что найдет в cachedModelMap. Загрузите полный текст исходного кода для того, чтобы посмотреть как реализован updateModel().



Метод hasChildren() оптимизирован для того, чтобы вернуть "истина" если он вызван с IFile с расширением *.properties. Другой альтернативой является ранняя загрузка содержимого для выполнения вычислений, но эта возможность привносит с собой дополнительные накладные расходы.

При вызове с элементом модели PropertiesTreeData - hasChildren() вернет "ложь", что означает, что наши элементы модели не могут иметь детей (свойства не могут иметь детей, но остальные модели могут).



Метод getParent() вернет IFile, который содержит элемент PropertiesTreeData или null если вызывается для любого другого элемента. Каркас Common Navigator продолжит опрос остальных расширений пока не обнаружится не нулевой родитель или пока все связанные расширения не будут опрошены. Запомните, что некоторое расширение может быть запрошено на предоставление родителя для некоторого элемента, если этот элемент соотвествует его выражению.



В конце концов, поставщик ярлыков (label provider) нашего расширения содержания скажет представлению как отобразить иконку и ярлык для наших элементов модели (PropertiesTreeData). Так как мы только начали изучение этих элементов, мы не должны беспокоиться о предоставлении иконок и ярлыков для любых других элементов. Другие расширения предоставят ярлыки и иконки для других элементов в дереве.

PropertiesLabelProvider реализует org.eclipse.jface.viewers.ILabelProvider и также org.eclipse.ui.navigator.IDescriptionProvider.

ILabelProvider является интерфейсом по-умолчанию требуемым JFace для предоставления ярлыков и иконок.

IDescriptionProvider специфичен для каркаса Common Navigator и используется для предоставления текста для стори состояния в левом нижнем углу окна Eclipse.

Методы требуемые ILabelProvider - это getText() и getImage(). Мы отобразим ярлык для наших элементов модели как строку "name= value"для свойства (быз кавычек). Для иконки, мы просто используем одну из доступных иконок предоставляемых Platform/UI.



Поставщик ярлыков будет запрашиваться для ярлыков, иконок, описаний для каждого элемента предоставленного непосредственно расширением или для любого элемента, который соответствует выражению для этого расширения. Если null возвращен для иконки или ярлыка, каркас продолжит работать с другими доступными расширениями основываясь на их выражениях и связывании представления. Если ваши расширения хотят не хотят использовать свою возможность предоставлять ярлык или иконку, они всегда должны возвращать null.

Финальный вид отображающий файлы свойств доступен в нашем Example View.

вторник, 27 ноября 2007 г.

Создание представлений на основе Common Navigator. Часть I: Определение представления

Автор оригинальной статьи : Michael D. Elder
Перевод: Евгений Флоров

Я начал принимать вопросы о Common Navigator в eclipse.platform newsgroup и сообщения из сообщества показывали, что недостаточно примеров. С целью помочь сообществу понять Common Navigator framework, я размещу некоторые примеры (в репозитории Eclipse по адресу dev.eclipse.org:/home/eclipse, куда вы можете зайти как "anonymous"; смотрите wiki для пояснений. Я буду документировать эти примеры в этом блоге. Возможно я вставлю созданную здесь документацию в Platform SDK, но я хочу организовать обсуждение, где потенциальные пользователи могли-бы высказать свое мнение максимально простым способом и непосредственно в первоисточник (то есть данный блог).

Детальная документация о точках расширения и API доступна в помощи платформы Eclipse (Help > Help Content) в разделе Platform Plug-in Developer's Guide > Reference > API Reference | Extension Points Reference.
К данной теме имеют отношения org.eclipse.ui.navigator.viewer и org.eclipse.ui.navigator.navigatorContent, а также пакет org.eclipse.ui.navigator. Если вам потребуются дополнительные детали по каким-либо моментам данного документа, пожалуйста воспользуйтесь этими ссылками.

Итак, с чего начнем? Во-первых мы должны сконфигурировать плюгин, который будет содержать представление (view), а именно добавить в его зависимости
org.eclipse.ui.navigator. Затем мы определим view part используя точку расширения org.eclipse.ui.views и укажем класс org.eclipse.ui.navigator.CommonNavigator как нашу реализацию view part, который обеспечит окружение (cradle) для нашего представления. Затем мы определим расширение org.eclipse.ui.navigator.viewer для конфигурирования представления как Common Navigator. В заключение, мы можем определить расширение org.eclipse.ui.navigator.navigatorContent вместе с связываниями (bindings) (org.eclipse.ui.navigator.viewer/viewerContentBinding) для того, чтобы ассоциировать расширения с нашим представлением.

Вы не должны использовать org.eclipse.ui.navigator.CommonNavigator как framework в своих целях; вместо этого вы можете вставлять свой контент используя org.eclipse.ui.navigator.INavigatorContentService виртуально куда угодно - от диалогов до редакторов или определить ваш viewer и view part класс, но в этом примере, мы будем придерживаться основ.

Основная настройка.

Common Navigator Framework появился в Eclipse 3.2. Следовательно, вы должны иметь окружение обновленное до Eclipse 3.2. Тема этого документа не будет касаться вопросов настройки Eclipse для self-hosting разработки. I assume that you have Eclipse 3.2 setup and are either self-hosting against a target of your own choice or the default.

Перед тем, как мы будем делать что-нибудь, мы должны убедиться, что наш plugin сконфигурирован со всеми необходимыми зависимостями. Либо создайте новый Plugin (File> New> Project: Plug-in Development> Plug-in Project: Введите имя и примите все по-умолчанию), или откойте Редактор манифеста plugin'а (выберите "plugin.xml"файл в вашем представлении (Project Explorer, Package Explorer, Navigator, и т.д.) и двойным щелчком или правой кнопкой и выберите Open With> Plug-in Manifest Editor. На закладке Dependencies, нажмите Add... и начинайте печатать org.eclipse.ui.navigator и выберете этот пункт, когда он подстветится или вы его увидите в списке.

Теперь выберите закладку Extensions редактора.

Определение view part

Для использования Common Navigator в вашем представлении, при его определении вы должны зарегистрировать реальный view part. Eclipse view parts определяются точкой расширения org.eclipse.ui.views. View part - контейнер для нашего представления; он имеет именованные закладки, место для меню представления (маленький треугольник в правом верхнем углу view part), и может содержать любой widget, который мы должны показать конечному пользователю. View parts не являются особенностью Common Navigators, мы просто используем их как окружение для хранения нашего представления.

Вы можете определить представлени через закладку Extensions путём выбора Add... и начиная печатать org.eclipse.ui.views до момента, когда вы его увидите в списке. Затем правый щелчёк на элементе, созданном под деревом "All Extensions" и имеющим имя org.eclipse.ui.views и выбрать New > view. Это приведет к созданию элемента в файле plugin.xml.

Когда вы выберете элемент view, то доступные для данного элемента атрибуты должны появиться как поля редактирования и widgets справа. Мы введём следующие значения (без кавычек):

id: "org.eclipse.ui.examples.navigator.view"
name: "Example View"
class: "org.eclipse.ui.navigator.CommonNavigator"
icon: "icons/filenav_nav.gif" (or your own)
allowMultiple: false

Теперь выберите закладку "plugin.xml" редактора. Вы должны увидеть что-нибудь похожее на это.



Вы можете создать категорию как на рисунке, но убедитесь, что указали категорию, с которой должен быть ассоциирован ваш viewer. Это делается определением атрибута "category". В противном случае, ваш viewer появится в категории Other в Show View dialog (Window > Show View > Other...).

Определение конфигурации viewer

Сразу мосле определения view part, нам необходимо определить конфигурацию расширений для нашего view part (org.eclipse.ui.navigator.viewer) которые скажут framework'у некоторые основные моменты, такие как то, что view part является Common Navigator, какая структура всплывающего меню должна быть, дополнительно к свойствам определяющим поведение viewer по-умолчанию.

Откройте опять закладку Extensions и нажмите Add...; когда появится диалог начинайте печатать org.eclipse.ui.navigator.viewer до тех пор, пока вы не увидите этот пункт в списке и выберите его. Клик правой кнопкой на новом элементе org.eclipse.ui.navigator.viewer в дереве "All Extensions" и выберите New > viewer. Этот элемент позволит нам ассоциировать абстрактный Common Navigator viewer с конкретным view part. Абстрактный viewer - это тот, с которым ассоциированы расширения, вне зависимости встроен он в view part или как-либо еще. Так для данного примера, мы будем использовать id, который использовали выше в нашем расширении org.eclipse.ui.views (org.eclipse.ui.examples.navigator.view"). Выберите элемент во view (который будет по-умолчанию обозначен name-of-you-plugin.viewer) и измените viewerId в поле редактирования, которое появится справа на "org.eclipse.ui.examples.navigator.view" без кавычек.

Некоторые комментарии о всплывающих меню.

Каркас Common Navigatorпредлгает два способа позволяющих viewer'ам адаптироватьэто меню.
  • Первый путь - это определение popupMenuId viewer'а для принятия разделителей и идентификаторов маркеров групп для меню. Значения по-умолчанию описаны в точке расширения org.eclipse.ui.navigator.viewer, но для удобства, повторены ниже.
  • С другой стороны, вы можете не определять popupMenuId и вместо этого указать элемент как дочерний для элемента. В этом случае, вы также можете определить ваши разделители и маркеры групп для ваших downstream клиентов.
Если вы предполагаете привязывать содержание или действия предоставляемые Платформой (Resource, Java(tm)), то рекомендуется использовать группировку по-умолчанию.

"group.new" separator="true"
"group.
goto"
"group.open" separator="true"
"group.openWith"
"group.edit" separator="true"
"group.show" separator="true"

"group.reorganize"

"group.port"
"group.generate" separator="true"
"group.search" separator="true"
"group.build" separator="true"
"additions" separator="true"
"group.properties" separator="true"

Некторые пояснения по поводу опций.
Элемент <> под элементом <> позволяет вам указывать строковые пары имя=значение. Существуют опции используемые базовым каркасом (описанные в разделе Примеры для org.eclipse.ui.navigator.viewer), но этот механизм может быть использован для ваших представлений или расширений для обеспечения дополнительного конфигурирования границ расширения представления. Обратитесь к org.eclipse.ui.navigator.INavigatorViewerDescriptor для ознакомления с API чтения свойст указанных в элементе. Вы можете получить описатель представления через org.eclipse.ui.navigator.INavigatorContentService представления Common Navigator viewer.

После того, как вы установили viewerId, вы можете выбрать закладку "plugin.xml" для просмотра определений следующих элементов.


После определения представления, нам необходимо добавить расширения содержания и привязать их к представлению. Я буду описывать этот процесс более детально в следующей части. Для примера мы просто привяжем содержание ресурсов по-умолчанию (определенные модулем org.eclipse.ui.navigator.resources) к нашему представлению.


Вернитесь обратно на закладку Extensions, нажмите правой кнопкой на расширении org.eclipse.ui.navigator.viewer и выберите New > viewerContentBinding. Выберите элемент viewerContentBinding и установите viewerId в то значение идентификатора, которое мы использовали для нашего представления ("org.eclipse.ui.navigator.examples.view").
Нажмите правой кнопкой на новом элементе viewerContentBinding и выберите New > includes. В завершение, нажмите правой кнопкой на новом элементе includes и выберите New > contentExtension. Для атрибута pattern в contentExtension мы укажем "org.eclipse.ui.navigator.resourceContent" без кавычек. Этот идентификатор используется модулем org.eclipse.ui.navigator.resources для идентификации расширения Resource.

На закладке "plugin.xml", мы должны иметь что-то похожее на вот это:

Теперь вы можете запустить верстак (workbench) - (Run... > New Eclipse Application) и посмотреть представление в работе. Мы пока не определили каких-либо действий для него, поэтому вам потребуется использовать либо Resource Navigator, либо Package Explorer для создания проекта, который вы хотите увидеть в представлении. Мы будем добавлять действия Resource и фильтры далее, но на данный момент, обратите внимание на поведение по-умолчанию ассоциированное с представлением: кнопки Collapse All, Link with Editor, Filters (вместе с закладкой Filters ("Available Filters") и Extensions ("Available Content")).

Для привязки фильтров ресурсов, нам необходимо добавить другой элемент contentExtension к нашему includes. Укажите "org.eclipse.ui.navigator.resources.filters.*" как идентификатор. Это подцепит все фильтры определенные org.eclipse.ui.navigator.resources. С другой стороны, вы можете выбрать отдельные фильтры, которые хотите видеть в plugin.xml этого модуля и указать идентификаторы.

Выберите Run... опять и проверьте, что вам теперь доступны несколько фильтров ресурсов в вашей закладке "Available Filters" диалога Filters.

Далее мы будем привязывать действия с ресурсами по-умолчанию. Для привязывания действий нам необходимо добавить viewerActionBinding в корень точки расширения. Нажмите правой кнопкой на org.eclipse.ui.navigator.viewer и выберите New > viewerActionBinding. Убедитесь в правильности viewerId и затем добавьте эелемент includes, который имеет элемент actionExtension. Для атрибута pattern укажите "org.eclipse.ui.navigator.resources.*". Теперь когда вы запустите верстак, вы по-умолчанию увидите New, Import, Export, и Refresh в пустом представлении, а также другие действия соотвествующие Resource Navigator при выделении элементов в представлении.

Ваш plugin.xml в этот момент должен выглядеть так:

"Откуда он знает все правельные идентификаторы? Это просто "магические числа для меня!" Для определения идертификаторов расширений содержания которые вы хотите привязать к вашему представлению, вы можете просмотреть файлы plugin.xml модулей определяющих расширения. Вы можете использовать представления Plug-ins для того, чтобы сделать это проще всего (Window > Show View > Other...: PDE > Plug-ins) или вы можете открыть plugin.xml файл для org.eclipse.ui.navigator.navigatorContent (используя опять представление Plug-ins) и закладку Extension Points, выберите navigatorContent. Затем нажмите Find References для обнаружения всех расширений в вашем workspace определяющих расширения содержания или действий, которые мы можете захотеть использовать в вашем представлении. Расширения содержания определяются элементом navigatorContent, так что используйте атрибут id расширений navigatorContent при привязывании когда вы определяете элементы contentExtension под viewerContentBindings для вышего представления. Расширения действий определяются элементом actionProvider, так, что используйте атрибут id расширений actionProvider при привязывании, когда определяете элементы actionExtension под viewerActionBindings для вашего представления. Имейте ввиду, что actionProvider который вложен в расширение navigatorContent привязывается автоматически, когда охватывающее его расширение содержания привязано к представлению.

Определение фильтров
Последнее, что мы сделаем сегодня - это определение фильтра для нашего представления используя Eclipse Core Expressions. Документация на каркас Core Expressions доступна с модулем org.eclipse.core.expressions. Мы используем проверки свойств (property testers) определенные org.eclipse.core.resources для проверки типа (вида) проекта, и скроем все проекты, которые не имеют этот тип проекта.

Итак, вернитесь на закладку Extensions редактора манифеста модуля, затем нажмите Add... и выберите org.eclipse.ui.navigator.navigatorContent. Затем добавьте новый элемент commonFilter в это расширение (также как до этого: правый щелчек на элементе org.eclipse.ui.navigator.navigatorContent, выбрать New > commonFilter). Измените предлагаемый id на "org.eclipse.ui.examples.navigator.filters.hideNonJavaProjects", и измените имя на "Hide non-Java projects". Вместо указания класса-реализации, мы только определим выражение в виде XML. Нажмите правой кнопкой на элементе commonFilter и выберите New > filterExpression. Здесь мы можем продолжить использование меню по правой кнопке для создания выражения, подобного следующему:

Вы также можете установить атрибут activeByDefault в выражении для определения будет ли фильтр активен в конфигурации по-умолчанию.

В завершение, нам необходимо определить contentExtension как чать нашего viewerContentBinding для данного представления. Убедитесь в использовании id нашего нового фильтра или общего шаблона (например "org.eclipse.ui.examples.navigator.filters.*") для привязывания этого фильтра и всех будущих фильтров, которые мы (или наши подчиненные сушности) определим как соотвествующие этому id. Ваш итоговый plugin.xml должен выглядеть похожим на следующее:


Теперь запустите верстак последний раз. Создайте несколько Simple проектов и несколько Java проектов. Когда фильтр "Hide non-Java Projects" включен, Simple проекты должны пропадать из представления.