Как стать автором
Обновить

Автоматизация OpenOffice с использованием С++, часть 0

     Доброго времени суток!
     Возникла недавно необходимость освоить API такого чуда программистской мысли, как OpenOffice (далее OO). Каково же было мое удивление, когда оказалось, что доступная справочная информация по такому солидному приложению носит довольно-таки разрозненный, а местами и противоречивый характер. Было решено в процессе обучения “скомпилировать” максимально подробное руководство по установке и основам пользования, дабы сэкономить время моим последователям. Итак, добро пожаловать под кат.

Введение


     Автоматизировать OO можно множеством разных способов. Если разработка планируется сугубо по Windows, то можно выбрать OLE-bridge. Основным плюсом такого выбора можно считать тот факт, что кроме самого OO и какого-либо C++ компилятора вам больше ничего не понадобиться. В минусы можно сразу заносить отсутствие кроссплатформенности и общую… эмм… ненативность для самого OO.
     Путем же настоящего джедая является UNO (Universal Network Objects) — разработчики обещают переносимость и мобильность, наличие привязок к Java, C++, Python, .NET и некоторым другим языкам. Для работы вам понадобятся:

     Под Windows нужен Visual Studio или C++ Builder (с MinGW вроде как существуют некоторые проблемы, по крайней мере, мне не удалось собрать простейший пример, да и видел пару жалоб по этому поводу в Интернете). Под Linux`ом, я думаю, GCC найдется, желательно, конечно, посвежее. Все работы проводились под Windows с использованием VS2008.
     Итак, скачиваем все необходимое, распаковываем и устанавливаем. Пусть будет так:
  • OO: C:\Program Files\OpenOffice.org 3\
  • OO SDK: C:\Program Files\OpenOffice.org 3\Basis\sdk\

     Открываем консоль, пишем:
cd \Program Files\OpenOffice.org 3\Basis\sdk\
setsdkenv_windows.bat

     Данный скрипт запросит с вас кучу путей, указываем соответствующие папки. Ответ на вопрос “Automatic deployment of UNO components (YES/NO)“ особого значения не имеет, но выберем стандартное “yes”. Думаете все? Да куда там! Пишем в консоли set, видим, что переменная OO_SDK_URE_HOME пуста. Идем примерно сюда: C:\Users\ UserName>\AppData\Roaming\openoffice.org3.x_sdk\, открываем единственный файл блокнотом и правим:
set OO_SDK_URE_HOME=C:\Program Files\OpenOffice.org 3\URE
     Запускаем снова в консоли C:\Program Files\OpenOffice.org 3\Basis\sdk\setsdkenv_windows.bat и при помощи команды set проверяем наличие беглянки (или беглянок. если будут еще пустые строки).

Компиляция SDK


     Следующий этап — компиляция header’ов или (для Java) классов. Сам по себе, SDK представляет собой набор компонентов с расширением .idl, которые собраны в блоки .udl, которые, в свою очередь, собраны в реестр с расширением .rdb. В таком виде, естественно, пользоваться им невозможно, целью же такого подхода является возможность писать свои компоненты, которые потом добавляются к общему дереву.
     Итак, создаем где-нибудь папку include (у меня OpenOffice.org 3\Basis\include\). Нашей целью являются 3 файла-реестра: offapi.rdb, types.rdb и services.rdb. Первый в директории C:\Program Files\OpenOffice.org 3\Basis\program, 2 последних в C:\Program Files\OpenOffice.org 3\URE\misc.
Открываем консоль, пишем:
cd \Program Files\OpenOffice.org 3\Basis\sdk\bin (рекомендую сюда и кинуть все 3 файла)
cppumaker.exe -Gc -BUCR -oC:\Program Files\OpenOffice.org 3\Basis\include -Ltypes.rdb -Lservices.rdb -Loffapi.rdb

     Ключ -Gc показывает, что если уже есть нужные файлы, их переписать, -BUCR указывает корень дерева-реестра, -o, традиционно, указывает, куда сохранять результат, -L подключает внешние файлы. Если все нормально, то в пути с ключем -o появится куча вложенных папок, содержащих искомые header’ы. Будет ругаться на отсутствующие dll (например, cppu3.dll), отшлепайте то что-то не так с переменными окружения. Как вариант, требуемые файлы можно взять в C:\Program Files\OpenOffice.org 3\URE\bin и кинуть к cppumaker.exe.

     Фух, теперь, наконец-то, можно из консоли с установленными переменными окружения вызвать VS 2008 и начать писать свою первую программу.


Настройка проекта


     Первым делом цепляем с таким трудом сгенерированные файлы:
Сервис->параметры->Проекты и решения-> Каталоги VC++->Включаемые файлы, тут добавляем следующие пути:
  • C:\Program Files\OpenOffice.org 3\Basis\include
  • C:\OpenOffice.org 3\Basis\sdk\include

Файлы библиотек:
C:\OpenOffice.org 3\Basis\sdk\lib
     После этого идем в настройки проекта (Проект – Свойства), там в настройки линкера (Компоновщик — Ввод), в дополнительные зависимости добавляем всех постояльцев из директории C:\Program Files\OpenOffice.org 3\Basis\sdk\lib\.

     И только теперь можно опробовать местный «Hello, world!»

Первый запуск


Итак, пишем следующий код:
#include &ltstdio.h>
#include &ltcppuhelper/bootstrap.hxx&gt
#include &ltcom/sun/star/bridge/XUnoUrlResolver.hpp&gt
#include &ltcom/sun/star/lang/XMultiComponentFactory.hpp&gt
#include &ltcom/sun/star/lang/XMultiServiceFactory.hpp&gt
#include &ltcom/sun/star/frame/XComponentLoader.hpp&gt

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::bridge;
using namespace com::sun::star::frame;

using namespace rtl;
using namespace cppu;

Reference &lt XComponentContext &gt setContext(void)
{
     Reference&lt XComponentContext &gt context( ::cppu::bootstrap() );
     if ( context.is() )
     {
         return context;
     }
     else
     {
         fprintf(stderr, "no component context!\n");
         return NULL;
     }
}
Reference&lt XMultiComponentFactory &gt setServiceManager(Reference &lt XComponentContext &gt xContext)
{
    Reference&lt XMultiComponentFactory &gt serviceManager( xContext-&gtgetServiceManager() );
     if ( serviceManager.is() )
    {
         return serviceManager;
     }
     else
     {
         fprintf(stderr, "no service manager!\n");
         return NULL;
     }
}

Reference &lt XComponentLoader &gt setComponentLoader( Reference&lt XMultiComponentFactory &gt xServiceManager, Reference &lt XComponentContext &gt xContext)
{
     Reference &lt XComponentLoader &gt componentLoader(xServiceManager-&gtcreateInstanceWithContext(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), xContext ), UNO_QUERY_THROW );
     return componentLoader;
}

Reference&lt XComponent &gt setComponent(Reference &lt XComponentLoader &gt xComponentLoader)
{
     Reference&lt XComponent > component( xComponentLoader->loadComponentFromURL( OUString::createFromAscii("private:factory/simpress") , OUString::createFromAscii( "_default" ), 0, Sequence < ::com::sun::star::beans::PropertyValue >() ) );
     return component;
}

int main ()
{
     try
     {
         Reference &lt XComponentContext &gt xContext = setContext();
         Reference&lt XMultiComponentFactory &gt xServiceManager = setServiceManager(xContext);
         Reference &lt XComponentLoader &gt xComponentLoader =setComponentLoader(xServiceManager,xContext);
         Reference&lt XComponent &gt xComponent = setComponent(xComponentLoader);
         if ( !xComponent.is() )
         {
             fprintf(stderr, "Opening presentation document failed!\n");
             return NULL;
         }
     }
     catch ( ::cppu::BootstrapException & e )
     {
         fprintf(stderr, "caught BootstrapException: %s\n", OUStringToOString( e.getMessage(), RTL_TEXTENCODING_ASCII_US ).getStr());
         return NULL;
     }
     catch ( Exception & e )
     {
         fprintf(stderr, "caught UNO exception: %s\n", OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
         return NULL;
     }
     return 0;
}

    Пытаемся скомпилировать… И радостно изучаем следующее:
Ошибка 1 fatal error C1189: #error: «Could not find 16-bit type, add support for your architecture» C:\Program Files\OpenOffice.org 3\Basis\sdk\include\sal\types.h 69
    Лечиться это сменой архитектуры на 16-битную следующим:
#define WNT
#define CPPU_ENV msci
перед всеми директивами #include.
    Запускаем еще раз и-и-и-и-и… Ура, перед нами открывается окошко OO Impress'а с новым файлом! Как это получилось? Это Вы узнаете в следующей серии!

    Полезности:
  • wiki.services.openoffice.org/wiki/UNO_automation_with_a_binary_(executable) Нечеловеческое спасибо французскому товарищу Serge Moutou, который пишет большое и страшное руководство по работе с OO SDK.
  • wiki.services.openoffice.org/wiki/Documentation/Wiki_Books Здесь можно скачать огромный(1700 страниц!) и исчерпывающий мануал по OO SDK на английском языке. Вот только большая часть примеров на Java и Visual Basic.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.