Макросы, диалоги и библиотеки (Basic)

OOo: создадим конвертер валют Печать
Автор chkur   
05.09.2010 г.

Возможности офисного пакета OpenOffice.org легко расширить, написав макрос, реализующий недостающий функционал. Это можно сделать, вооружившись API OpenOffice.org и выбрав язык программирования: OOBasic (встроенный в OOo), Java, JavaScript или Python. В случае, если написанный код будет использоваться на одной машине, можно добавить пункт меню или панель инструментов вручную. Если же необходимо установить макрос на нескольких компьютерах, лучшим способом его распространения будет упаковка в расширение. В этом случае нужны инструменты для удобного создания расширений. Для OOBasic это, например, BasicAddonBuilder. Для Java можно использовать Eclipse или NetBeans - дополнения к ним для работы с OOo уже давно и успешно используются. Расширение на Python ранее нужно было собирать вручную, выискивая документацию по разным сайтам. Сегодня нам на помощь приходит молодой продукт - EuroOffice Extension Creator (EOEC). Он прост в использовании, хорошо документирован, содержит несколько интересных примеров в виде готовых расширений, и распространяется под свободной лицензией.

Для ознакомления с EOEC создадим расширение «Конвертер валют», загружающее с сайта Центробанка РФ курсы валют на текущую дату и переводящее суммы из одной валюты в другую. Также расширение будет пытаться брать сумму из текущего документа и вставлять результат обратно в документ.

О EuroOffice Extension Creator

Это конструктор расширений на Python, распространяемый под лицензией GNU GPL. Продукт был представлен в ноябре 2008 года на OpenOffice.org Conference (OOoCon 2008).

Так как расширения, создаваемые при помощи EOEC, включают его исходный код, они также должны быть лицензированы по GPL v3. Для создания коммерческих продуктов на сайте разработчика предлагается коммерческая версия.

Разработчик EuroOffice Extension Creator - венгерская компания MultiRacio Ltd. Фирма выпускает собственную сборку OpenOffice.org - EuroOffice и множество расширений: клипарты, словари, пакет Solver для Calc и много других интересных решений, которые можно найти на сайте расширений. Продукты доступны под GNU/GPL или коммерческой лицензией.

Подготовка к работе

Чтобы разработать расширение с помощью EuroOffice Extension Creator, необходимы: хорошая ОС, свежий OpenOffice.org, интерпретатор языка Python и архив с EOEC. Также крайне желательна удобная IDE для Python.

Первому требованию удовлетворяет практически любой современный дистрибутив Linux (в моем случае - Debian Lenny). Последний официальный русскоязычный выпуск OpenOffice.org доступен на сайте ru.openoffice.org; при написании статьи использовалась «ванильная» версия 3.1. Интерпретатор Python можно взять системный или же тот, что идет в комплекте с OOo. В OOo 3.1 это Python 2.6.1, в более ранних версиях - Python 2.3. В случае, если Python отсутствует в вашей системе, для более удобного использования сборки из состава OpenOffice.org можно создать символьную ссылку в каталоге /usr/bin (целевой файл - путь_к_ooo/program/python). Если у вас установлен OOo без Python, можно попробовать настроить его на использование внешнего интерпретатора. В качестве IDE я буду использовать Geany.

Идем на страницу EOEC:  и скачиваем последнюю версию (на момент написания статьи - 0.3). Распаковав полученный архив, вы увидите каталог с тремя папками, тремя скриптами и PDF-файлом с документацией. Версия 0.3 заметно увеличилась по сравнению с предыдущими - в архиве теперь содержится шесть расширений, созданных с помощью EOEC. Находятся они в каталоге examples. Настоятельно рекомендую ознакомиться с их исходным кодом после изучения документации. В расширениях Lookup и Sharpen использованы функции встраивания в контекстное меню OOo и назначения комбинаций клавиш.  

Новое расширение

Для создания собственного расширения необходимо открыть терминал и запустить скрипт create.py, находящийся в каталоге EOEC, с аргументами:

python create.py --vendor=VENDOR project-name

Здесь project-name - название нашего нового расширения, VENDOR - имя его разработчика. Справку по использованию скриптов create.py, pack.py и update.py можно получить, запустив их из терминала с ключом --help.
Выполним команду:

python create.py --vendor=OOoCoder CurConverter

В результате скрипт create.py создаст каталог нового расширения CurConverter на основе директории template с использованием введенных вами данных.
Теперь нужно создать версию расширения для разработки. Для этого нам потребуется скрипт pack.py с ключом -D. Синтаксис таков:

python pack.py -D project-name

В нашем случае это значит:

python pack.py -D CurConverter

В результате получим версию расширения CurConverter_Debug.oxt «для разработчика». Она не предназначена для распространения конечным пользователям! Скопированное на другой компьютер, такое расширение не будет работать.
Давайте добавим CurConverter к OOo через меню Сервис > Управление расширениями. Он появится в списке установленных расширений.

Иконку расширения можно изменить на свою, переписав соответствующие графические файлы в каталоге расширения. Текст описания изменяется в файле description.txt.
Перезапустите OpenOffice.org: в третьей версии OOo это необходимо делать после установки любого расширения. Войдите в меню Справка > About CurConverter > Debug и посмотрите на поле под меткой Debug output. Если вы увидите такой же текст, как на рисунке 2, значит в вашей системе сообщения отладчика идут в стандартный вывод (в противном случае их следует искать в окне Debug, которое вы сейчас видите). Оно и к лучшему - терминал (в отличие от диалога Debug) всегда у вас перед глазами. Закройте OOo и запустите его из терминала - теперь вы будете видеть в нем все отладочные сообщения.

Третий скрипт, update.py, предназначен для обновления ранее созданного расширения при выходе новой версии EOEC. Предварительно прочтите документацию - разработчики предупреждают о возможной потере данных. Старая, как мир, истина: не забывайте регулярно делать резервные копии каталога расширения!

Пункт в меню

Перед тем, как приступать к написанию собственного расширения, необходимо ознакомиться с главами 3 и 5 документации EOEC для понимания файловой структуры расширения и методов EOEC. Желательно также просмотреть примеры расширений, идущих в составе EOEC, и документацию по API OpenOffice.org. Скачать OpenOffice.org SDK можно со специальной страницы.

Для начала обеспечим интернационализацию расширения. Откройте Сервис > Макросы > Управление диалогами, перейдите на вкладку Библиотеки, выберите OOoCoderCurConverterDialogs, и нажмите на кнопку Изменить

В открытом окне на панели нажмите кнопку Управление языками > Добавить > Русский > Закрыть (при необходимости сделайте языковую панель видимой через меню Вид). Сохраните изменения.
Для более удобного перевода элементов управления и пунктов меню воспользуемся расширением Extension Translator. Установите его, перезапустите OOo и вызовите Сервис > Extension Translator. Выберите в списке CurConverter и в Calc откроются имеющиеся локализации - en и ru. Здесь будут перечислены все элементы форм и названия пунктов меню, используемые нашим расширением. Переведите все, что нужно, на родной язык. Придумайте название для пункта меню, который будет запускать наше расширение. Пусть поле с названием пункта меню (первый столбец) имеет имя title. По-английски им будет «CurConverter», а по-русски - «Конвертер валют». Нажмите Сервис > Save Localizations и закройте файл с локализациями, не сохраняя его. Перейдите в меню Справка > About CurConverter > Debug > Save Dialogs. Изменения в диалогах будут скопированы из профиля OOo (каталога с пользовательскими настройками, шаблонами и скриптами - ~/.openoffice.org) в рабочую директорию расширения. Эту кнопку необходимо использовать каждый раз после изменений диалогов. Для того, чтобы в русскоязычном диалоге, вызываемом при выборе пункта меню Справка > About CurConverter, отображался логотип CurConverter, создадим файл logo_ru.gif в каталоге расширения. Для каждого языка можно создать отдельный логотип, сохранив его в файле с именем logo_<двухбуквенный_код_языка>.gif.

Здесь и далее мы будем работать с модулем CurConverter/curconverter/curconverter.py. Добавим поддержку русского языка

#-*- coding:utf-8 -*-

и в строке

SUPPORTED_LANGUAGES = ('en','ru')

Определим расширению место для запуска - поместим его в меню Сервис за пунктом Рассылка писем. Для этого нам нужно узнать идентификатор последнего пункта. Вызовите диалог Справка > About CurConverter и нажмите кнопку Debug. В открывшемся окне введите следующий текст:

self.dumpMenus('com.sun.star.text.TextDocument')

и посмотрите вывод в терминале. Необходимые нам имена пунктов меню находятся после «(u'- CommandURL:». При минимальном знании английского языка найти необходимую позицию не составит большого труда, в нашем случае это '.uno:MailMergeWizard'. Введите в окне отладки

self.addMenuItem( 'com.sun.star.text.TextDocument', '.uno:MailMergeWizard', self.localize( 'title' ), 'curconverter' )

и нажмите кнопку Execute code. Эту же строку надо добавить в метод firstrun класса CurConverter.

Несмотря на то, что при добавлении расширений в OpenOffice.org все файлы устанавливаются в профиль OOo в домашнем каталоге пользователя (для версии 3.x это ~/.openoffice.org/3/user/uno_packages/cache/uno_packages), мы будем вносить изменения в файл curconverter.py, расположенный в директории EOEC. Иными словами, при запуске расширения из OpenOffice.org будет выполняться код, расположенный в каталоге EOEC.
Для удаления пункта меню в метод uninstall после try: добавляем строку

self.removeMenuItem( 'com.sun.star.text.TextDocument', 'curconverter' )

С установкой/удалением пунктов меню определились, самое время «оживить» их. В коде метода firstrun мы указали, что при выборе пункта меню будет вызван метод curconverter. Создадим его:

def curconverter( self ):
       self.box(u'Работает!')

Сохраните код и попробуйте выбрать пункт меню Сервис > Конвертер валют. Как можно видеть, все действительно работает.

Добавим интерфейс

При написании расширений для OOo с помощью EOEC не нужно подключать сторонние графические библиотеки - можно использовать «родные» интерфейсные элементы OpenOffice.org. EOEC по умолчанию создает два диалога - окна About и Debug.
Выберите в меню Сервис > Макросы > Управление диалогами, выделите OOoCoderCurConverterDialogs и нажмите кнопку Новый диалог. Придумайте имя - скажем, Main, и нажмите Правка. Откроется новый пустой диалог. Добавим в него следующие виджеты:

  • Два элемента «Числовое поле» ValuteNum1 и ValuteNum2 - для отображения сумм.
  • Два элемента «Список» ValuteName1 и ValuteName2 - для выбора валют. Свойство «Раскрываемый» установим в «Да».
  • Флажок chkInsert с надписью «Вставить результат в текст документа».
  • Кнопку btnCalculate с надписью «Рассчитать».
  • Кнопку btnClear с надписью «Очистить».
  • Кнопку btnClose с надписью «Закрыть», тип кнопки - «Отмена»

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

Через свойства элементов можно выставить их размеры, положение и т. д.; затем нажмите кнопку Сохранить. Вид и текст диалога About CurConverter изменяется здесь же, во вкладке About. Теперь необходимо перейти из оболочки OOBasic в другой элемент ООо, например, Writer (по умолчанию расширение встраивается в меню Справка всех компонентов, кроме среды программирования). Выберите Справка > About CurConverter > Debug > Save Dialogs

Время кодировать

Создайте конфигурационный файл settings, в котором будет храниться URL сервиса, предоставляющего курсы валют. Пусть его содержимое будет таким:

[Global]
URL = http://www.cbr.ru/scripts/XML_daily.asp

Скопируйте файл настроек в каталог расширения. Внимание! В случае, если в расширение нужно добавить какие-либо файлы, например, изображения, настройки и т. д., необходимо делать это одновременно в два места: в рабочий каталог расширения и его папку в профиле. Все критические изменения в них вносятся синхронно, так как в профиле OOo лежат файлы, которые запускаются при отладке нашего dev-расширения, а в рабочем каталоге - файлы, которые будут упакованы для отправки пользователям.
Откройте curconverter.py (в рабочем каталоге) и добавьте импорт модулей:

from xml.dom import minidom
from urlparse import urlparse
import urllib
import os, ConfigParser

Видоизмените метод curconverter:

def curconverter( self ):
    self.dlgMain = dlgMain = self.createdialog( 'Main' )
    dlgMain.execute()

Сохраните файл и запустите расширение через меню. Должен появиться созданный нами диалог. Кнопки еще не работают, но вскоре мы это исправим.
В каталоге util EOEC содержаться несколько модулей с некоторыми полезными функциями. Во writer.py это функция getWord(). Воспользуемся ею для считывания суммы из документа.

import util.writer
...
self.summa=util.writer.getWord(self.getcontroller()).String
self.cursor=self.getcontroller().getViewCursor()
Заполним поле ValuteNum1
try:
    eval(self.summa)
    self.dlgMain.ValuteNum1.Value=self.summa
except:
    self.dlgMain.ValuteNum1.Value=100.00

Как видно, обращение к элементам управления диалога происходит как к объектам, являющимся атрибутами self.dlgMain, по именам.
Далее, обработаем конфигурационный файл, считав из него URL:

self.config = ConfigParser.ConfigParser()
self.config.read(os.path.join(self.path, 'settings'))
if not(self.config.has_option('Global','URL')):
    self.config.set('Global','URL',
'http://www.cbr.ru/scripts/XML_daily.asp')
    self.BANK_URL = self.config.get('Global','URL')

self.path - свойство, содержащее путь к установленному расширению. Вызываем метод получения курса валют:

self.getKurs()

который определятся следующим образом:

def getKurs(self):
    dom=minidom.parse(urllib.urlopen(self.BANK_URL))
    self.kurses=[]
    for node in dom.getElementsByTagName('Valute'):
self.kurses.append({'CharCode':
   node.getElementsByTagName('CharCode')[0].childNodes[0].nodeValue,
    'Nominal': node.getElementsByTagName('Nominal')
[0].childNodes[0].nodeValue,
    'Name': node.getElementsByTagName('Name')
[0].childNodes[0].nodeValue,
    'Value': node.getElementsByTagName('Value')
[0].childNodes[0].nodeValue})
    self.kurses.append({'CharCode': 'RUR',
      'Nominal': '1',
      'Name': u'Российских рублей',
      'Value': '1'})

В итоге получаем курсы валют в виде списка словарей и список наименований валют для подстановки в выпадающие меню ValuteName1 и ValuteName2.
Добавляем «слушателей» нажатий на кнопки:

self.dlgMain.btnCalculate.addActionListener( self )
self.dlgMain.btnClear.addActionListener( self )

Осталось создать обработчики нажатий - методы, которые вызываются при активации соответствующих элементов управления. Именуются они следующим образом: on_action_<имя_элемента>.
Кнопка btnClear сбрасывает значения элементов управления на начальные:

def on_action_btnClear(self):
    self.dlgMain.ValuteNum1.Value=100.00
    self.dlgMain.ValuteNum2.Value=0
    self.dlgMain.ValuteName1.selectItemPos(4,True)
    self.dlgMain.ValuteName2.selectItemPos(self.dlgMain.ValuteName2.ItemCount-1,True)

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

def on_action_btnCalculate(self):
    if (self.dlgMain.ValuteName1.getSelectedItemPos()>-1) and
(self.dlgMain.ValuteName2.getSelectedItemPos()>-1):
    valuteID1=self.dlgMain.ValuteName1.getSelectedItemPos()
    valuteID2=self.dlgMain.ValuteName2.getSelectedItemPos()
    self.kursnode1=self.kurses[valuteID1]
    self.kursnode2=self.kurses[valuteID2]
    v1=eval(self.kursnode1['Value'].replace(',','.'))
/eval(self.kursnode1['Nominal'])
    v2=eval(self.kursnode2['Value'].replace(',','.'))
/eval(self.kursnode2['Nominal'])
    sum1=self.dlgMain.ValuteNum1.Value
    val1to2=v1/v2
    self.dlgMain.ValuteNum2.Value=sum1*val1to2
    if (self.dlgMain.chkInsert.State):
      if self.cursor.isCollapsed():
        self.cursor.String=round(self.dlgMain.ValuteNum2.Value,2)
      else:
        self.cursor.collapseToEnd()
        self.cursor.String=round(self.dlgMain.ValuteNum2.Value,2)

 Для кнопки Закрыть обработчик не нужен.
Наконец, добавим метод заполнения списков наименований валют и добьемся, чтобы пункты «Доллар США»(на момент написания статьи - позиция №4) и «Российских рублей» были выбраны по умолчанию:

self.fillList()
self.dlgMain.ValuteName1.selectItemPos(4,True)
self.dlgMain.ValuteName2.selectItemPos(self.dlgMain.ValuteName2.ItemCount-1,True)

Метод fillList выглядит так:

def fillList(self):
    for i in range(0, len(self.kurses)):
      self.dlgMain.ValuteName1.addItem(self.kurses[i]['Name'],i)
         self.dlgMain.ValuteName2.addItem(self.kurses[i]['Name'],i)

В итоге у нас должен получиться такой метод curconverter:

def curconverter( self ):
    self.summa=util.writer.getWord(self.getcontroller()).String
    self.cursor=self.getcontroller().getViewCursor()
    self.dlgMain = dlgMain = self.createdialog( 'Main' )
    self.dlgMain.btnCalculate.addActionListener( self )
    self.dlgMain.btnClear.addActionListener( self )
    try:
       eval(self.summa)
       self.dlgMain.ValuteNum1.Value=self.summa
    except:
       self.dlgMain.ValuteNum1.Value=100.00
    self.config = ConfigParser.ConfigParser()
    self.config.read(os.path.join(self.path, 'settings'))
    if not(self.config.has_option('Global','URL')):
       self.config.set('Global','URL', 'http://www.cbr.ru/scripts/XML_daily.asp')
    self.BANK_URL = self.config.get('Global','URL')
    self.getKurs()
    self.fillList()
    self.dlgMain.ValuteName1.selectItemPos(4,True)
    self.dlgMain.ValuteName2.selectItemPos(self.dlgMain.ValuteName2.ItemCount-1,True)
    dlgMain.execute()

Результаты наших трудов можно видеть на рисунке 5.

Финальный штрих

Наше расширение готово. На всякий случай еще раз сохраним диалоги через окно О расширении. Затем войдите в каталог EOEC и соберите готовое расширение.

python pack.py CurConverter

Для того, чтобы изменить номер версии расширения, необходимо отредактировать файл description.xml. В строке

<version value="1.0"></version>

вместо 1.0 нужно установить требуемый номер. 

Появившееся в каталоге расширение CurConverter.oxt версии 1.0 готово для распространения. Разместить его для общего доступа можно на сайте расширений для OpenOffice.org.

 

Обсудить на форуме

Последнее обновление ( 10.08.2012 г. )
 
« Пред.   След. »

Главная arrow Макросы, диалоги и библиотеки (Basic) arrow OOo: создадим конвертер валют

MyOOo.ru, 2008 — 2024. Хостинг предоставлен компанией Netangels