2011-11-21

Harmattan. Пишем свой Control Panel Applet

Мы разобрались с тем, как писать в Event Feed. Но любое приложение нуждается в каких-либо настройках. В этой посте разберемся с тем, как интегрироваться в иерархию Settings в MeeGo Harmattan.

Есть три способа внедриться в Settings:
  1. написание xml-файла определенного формата, который потом будет преобразован в нужные виджеты;
  2. написание своего плагина на C++, где мы можем делать все что захотим;
  3. перенаправление пользователя во внешнее приложение из Settings (не очень хороший вариант, так как заставляет пользователя ждать, пока приложение загрузится).
Я остановлюсь на первом, более простом. Он хорошо подходит, когда нам не нужны динамические настройки, а вполне хватит заранее прописанных.

Для этого нам понадобится два файла (в предыдущем посте они уже прописаны в .pro-файл, поэтому приводить его здесь я не буду):
  • /usr/share/duicontrolpanel/desktops/calendarfeed.desktop
  • /usr/share/duicontrolpanel/uidescriptions/calendarfeed.xml
Рассмотрим их повнимательнее.

calendarfeed.desktop
[Desktop Entry]
Type=ControlPanelApplet
Name=Calendar Feed
X-logical-id=calendarfeed
X-translation-catalog=calendarfeedcatalog
Icon=
X-Maemo-Service=com.nokia.DuiControlPanel
X-Maemo-Method=com.nokia.DuiControlPanelIf.appletPage
X-Maemo-Object-Path=/
# this has to be identical to the value in Name
X-Maemo-Fixed-Args=Calendar Feed
[DUI]
X-DUIApplet-Applet=libdeclarative.so
[DCP]
Category=Events Feed
Order=100
Part=calendarfeed.xml

Вот такой вот стандартный .desktop-файл, с парой дополнительных параметров. В секции DUI указывается плагин libdeclarative, который, собственно, и занимается выводом на экран нашей xml'ки.

Секция DCP - вот что нас интересует сейчас больше всего. Указываем в категории что мы цепляемся в Events Feed и указываем наш xml. Вот и вся магия. Благодаря этому файлу, наши настройки появятся как в Settings->Applications, так и в Settings->Notifications->Feed on home screen (что для нас более важно, мы ведь хотим остаться максимально интегрированными в систему.

calendarfeed.xml
<settings>
<boolean key="/apps/ControlPanel/CalendarFeed/EnableFeed" title="Publish to Feed"></boolean>
<integer key="/apps/ControlPanel/CalendarFeed/FeedSize" title="Events Shown" min="1" max="15"></integer>
<boolean key="/apps/ControlPanel/CalendarFeed/FillWithFuture" title="Fill with Future Events"></boolean>
</settings>

Тут тоже все очень просто. Корневая нода settings содержит набор настроек (либо групп с настройками, но в нашем простом случае не нужна группировка, у нас всего 3 параметра). Каждая настройка описывается нодой с типом данных в названии. Поддерживаются следующие типы:
  • group - группа настроек. Может содержать в себе все остальные типы нод (вложенная группировка невозможна).
  • selection - выбор из предопределенного списка (подноды option)
  • text - обычный текстовый ввод
  • boolean - переключатель
  • integer - целое число (отображается слайдером, поэтому задается еще min и max)
Не очень много, но вполне достаточно для простых настроек. У любой настройки есть два основных параметра: key и title. Ну с title все понятно, это то, что отображается на экране (либо идентификатор для локализованных названий).

Key. Вот тут все интереснее. Все, я думаю, помнят что MeeGo построен на Qt, в качестве рекомендованного (и по сути единственного) способа реализации UI выступает QML и все такое. Но следы Maemo все еще остались. Например в настройках. Хранилищем настроек является GConf. Благо есть Qt-адаптированный класс для работы с ним. Ну и Backup Framework бекапит именно их.

Использование GConfItem
Пришло время включить использование настроек в нашем небольшом SyncFW плагине. Возьмем метод startSync и добавим в него проверку ключа EnableFeed, который в случае false будет выходить из синхронизации, в обратном же случае продолжит ее как и положено правильному плагину.
bool CalendarFeedPlugin::startSync()
{
    GConfItem enabledConfItem("/apps/ControlPanel/CalendarFeed/EnableFeed");    
    QVariant enabledVariant = enabledConfItem.value();
    if (enabledVariant.isValid()) {
        bool enabled = enabledVariant.toBool();
        if (!enabled)
            return false;
    }
    QTimer::singleShot(1, this, SLOT(updateFeed()));

    return true;
}
Все просто как топор. Получаем параметр в виде QVariant, проверяем на валидность (если параметр не задан, то QVariant будет невалидным), преобразуем в булево значение, проверяем, делаем что положено.

Послесловие
Вот такими нехитрыми манипуляциями мы добавили возможность настройки нашего плагина. И, что гораздо важнее, сделали это максимально удобным для пользователя образом - интеграцией в уже существующую иерархию Settings.
Следующая часть нашего увлекательного квеста ожидается быть более захватывающей. Скандалы, интриги, расследования. Stay tuned!

Комментариев нет:

Отправить комментарий