2009 06 Macro w służbie autora [Open Office]

background image

Open Office

Macro w służbie autora

66

czerwiec 2009

Open Office

Macro w służbie autora

67

www.lpmagazine.org

lin

ux

@

so

ftw

ar

e.

co

m

.p

l

J

ęzyk Makr OpenOffice.org (OOo) powstał na bazie ję-
zyka programowania BASIC, podobnie jak język Vi-
sual BASIC stosowany jako język makropoleceń w
pakiecie MS Office, a także AppleScript w systemie

MacOS X. Pomimo iż języki te, a zwłaszcza OOo BASIC i Vi-
sual BASIC, pochodzą od tego samego przodka, to nie są one
wzajemnie kompatybilne, choć istnieją projekty pozwalające
na pewne przenoszenie makr pomiędzy tymi językami.

Cechą charakterystyczną OOo BASIC jest jego niesamo-

wita prostota, która czasami, moim zdaniem, jest największą
wadą tego języka. Jednak narzekając na ograniczenia OOo BA-
SICa, należy wziąć pod uwagę cel, dla którego powstał – budo-
wanie krótkich procedur upraszczających i automatyzujących
pracę w OOo, nie zaś do budowania skomplikowanych wie-
lowątkowych aplikacji. Aby sprostać temu drugiemu zadaniu,
OOo udostępnia IDE, które może być wykorzystane do two-
rzenia makr, nawet najbardziej rozbudowanych, w innych języ-
kach programowania: JavaScript, Python oraz JAVA. Ja w tym
artykule skupię się na wykorzystaniu OOo BASICa do automa-
tyzacji pracy w pakiecie biurowym OpenOffice.org, a zwłasz-
cza w programie OOo Writer. Opisywane w tym artykule ma-
kra były tworzone za pomocą OOo w wersji 3.0.0 w Gentoo.

Jednak w porównaniu do VisualBASICa – działającego tylko
pod Windows, mogą one być wykorzystane w każdym syste-
mie operacyjnym, w którym działa OpenOffice.org – niezależ-
nie od zainstalowanej wersji.

Trochę podstaw

Nie każdy z korzystających z OpenOffice.org, nawet w najbar-
dziej zaawansowany i profesjonalny sposób, zna język OOo
BASIC. Wynika to po prostu z jego potrzeb. Warto jednak za-
znajomić się z tym językiem, gdyż w pewnym momencie sa-
modzielnie napisane makra staną się nieodzowne w codzien-
nej pracy z tym pakietem biurowym. Zanim zaczniemy praco-
wać z makrami, należy pamiętać, iż ich stosowanie wiąże się z
zagrożeniem w postaci wirusów. Z tego też powodu domyśl-
nie obsługa makr w OpenOffice jest wyłączona. Aby to zmie-
nić, należy zmodyfikować ustawienia bezpieczeństwa. Dostęp
do tych ustawień uzyskujemy poprzez menu Narzędzia, pozy-
cję Opcje. W oknie ustawień pakietu OpenOffice wybieramy
pozycję Bezpieczeństwo, a następnie klikamy przycisk Bezpie-
czeństwo makr
. Zalecanym poziomem bezpieczeństwa jest Po-
ziom średni
. Jednak jeśli mamy pewność, że uruchamiane ma-
kra pochodzą od zaufanych dostawców (tj. są całkowicie bez-

Macro w służbie autora

Praca autora artykułów do Linux+ ma swoje blaski i cienie. W moim przekonaniu niezbyt przyjemnym
etapem pracy jest konieczność otagowania tekstu przed wysłaniem go do druku. Ja tę czynność
postanowiłem sobie uprościć, stosując zestaw makr w OpenOffice Word, które znacząco automatyzują
ten proces, zmniejszając zarówno nakład pracy, jak i uprzyjemniając tę, którą musimy wykonać.

Grzegorz Madajczak

background image

Open Office

Macro w służbie autora

66

czerwiec 2009

Open Office

Macro w służbie autora

67

www.lpmagazine.org

pieczne), możemy ustawić Niski poziom bezpie-
czeństwa
. Wtedy to wszystkie makra będą auto-
matycznie uruchamiane bez pytania się o pozwo-
lenie. Należy pamiętać, że makra takie mają bez-
graniczny dostęp do plików, zgodnie z uprawnie-
niami użytkownika, który je uruchamia. Tak więc
root, stosując makra OOo, może nawet modyfi-
kować i kasować pliki systemowe, których obec-
ność i poprawność jest krytyczna dla działania
całego systemu.

Makra OOo mogą być przechowywane na

trzech poziomach: na poziomie bieżącego doku-
mentu, w przestrzeni użytkownika (makra użyt-
kownika) oraz jako makra pakietu OpenOffi-
ce.org – dostępne dla wszystkich użytkowni-
ków pakietu na danym komputerze. Makra bie-
żącego dokumentu przechowywane są w konte-
nerze dokumentu. Przypomnę, że zarówno pliki
OOo w wersji 1.x, jak i pliki ODF (stosowane
od wersji 2.x) są skompresowanymi zipem fol-
derami o ściśle określonej strukturze. Znajduje
się tam między innymi folder

Basic

,zawierają-

cy makra zapisane w danym dokumencie. Makra
użytkownika są przechowywane w jego folderze
domowym, w katalogu

.ooo3

(lub

.ooo-2.0

dla

starszej wersji pakietu), w folderze

user/basic

.

Tam zlokalizowane są foldery odpowiadające bi-
bliotekom (np. domyślny folder

Standard

od-

powiadający bibliotece Standard. Przechowy-
wane tam pliki z rozszerzeniami

*.xlb

,

*.xba

są zwykłymi plikami XML, które można edyto-
wać w każdym edytorze tekstu. Jednak nie zaleca
się tego robić, gdyż błędna składnia tak wprowa-
dzonego kodu uniemożliwi jego otwarcie w IDE
OOo, a także korzystanie z tychże makr.

OpenOffice dostarcza bowiem wygodne w

użyciu środowisko programistyczne służące do
pisania i debugowania makr napisanych w OOo
BASICu. Uruchamiamy je poprzez menu Narzę-
dzia | Makra | Zarządzaj makrami | Makro
. W
otwartym w ten sposób oknie (Rysunek 1) moż-
na wybrać bibliotekę oraz moduł. Jeśli dokument
nie posiada makr, przycisk Nowy służy do utwo-
rzenia biblioteki, jak i modułu. W głównej części
tak otwartego IDE wyświetlony jest kod makr w
danym module.

Najszybszym sposobem uruchomienia ma-

kra jest skorzystanie z menadżera makr, wybie-
rając pozycję Wykonaj makro z menu Narzędzia
| Makra
. Z otwartego w ten sposób okna nale-
ży wybrać makro, które chcemy uruchomić. Je-
śli jednak dane makro będziemy wykorzystywa-
li wielokrotnie, przedzieranie się przez poszcze-
gólne pozycje menu będzie na dłuższą metę mę-
czące. Można tego uniknąć tworząc na pasku na-
rzędziowym skrót do wybranego makro. W tym
celu z menu paska narzędziowego należy wy-
brać pozycję Dostosuj pasek narzędzi. W otwar-
tym oknie Dostosuj należy kliknąć przycisk Do-

daj, następnie w kolejnym oknie z pola Kate-
gorie
należy wybrać pozycję Makra OpenOffi-
ce.org
, a następnie właściwą bibliotekę i moduł
zawierający makro, do którego chcemy utworzyć
skrót. Po wybraniu modułu w prawym polu Pole-
cenia
pojawią się wszystkie makra w danym mo-
dule. Wybór właściwego makra należy potwier-
dzić klikając przycisk Dodaj. Spowoduje to do-
danie skrótu do makra na modyfikowanym pa-
sku narzędziowym.

Jak wygląda makro w OOo BASIC

Każde makro stanowi podprogram (Subrouti-
nes
), którego klamrą są dwa polecenia:

Sub na-

zwa_makro

oraz

End Sub

. Nazwa makro musi

być jednym wyrazem, najlepiej bez polskich zna-
ków. W OOo Basic możliwe jest również tworze-
nie funkcji (Function), czyli poleceń (podprogra-
mów), których zasadniczym celem jest zwróce-
nie jakiejś wartości.

Podstawy OOo BASIC

OOo BASIC charakteryzuje się łatwą do zrozu-
mienia składnią, dość swobodnym podejściem
do sposobu pisania poleceń (np. brak zróżnico-
wania na małe i duże litery). Dość typową ce-
chą dla BASIC jest to, że ten język interpretowa-
ny (nie kompilowany, jak np. Java) wykonywa-
ny jest linia po linii – jedna linia poleceń jedno-
razowo. Oznacza to, że nie można dłuższych po-
leceń przenosić do nowej linijki. Jeśli polecenie
nie mieści się na ekranie, można na końcu dodać
znak _, który oznacza kontynuację polecenia w
następnym wierszu.

Ograniczeniem powyższej zasady jest zakaz

łamania linii wewnątrz bloku tekstu objętego cu-
dzysłowem. Znacznym udogodnieniem w pisa-
niu, poprawiającym czytelność kodu OOo Basic,
jest możliwość definiowania wielu zmiennych w
jednej linii przez rozdzielanie ich dwukropkiem.

Do wstawiania pojedynczej linii komentarza

służy polecenie

REM

, przy czym, jak wcześniej

zaznaczyłem, nie ma znaczenia wielkość uży-
tych znaków, czyli napisanie

rem

,

REM

, a nawet

rEm

, będzie tak samo interpretowane. Dla czytel-

ności kodu i tak zwanej dobrej maniery progra-
mistycznej proponuję nie mieszać małych i du-
żych znaków w ostatni sposób.

Tradycyjnie we wszystkich językach progra-

mowania, pierwszym programem, skryptem, jaki
uczymy się pisać, jest wyświetlenie tekstu Hel-
lo World
. Nie będę odbiegał od rutyny i zapro-
ponuję to samo.

W pierwszej linii utworzyliśmy makro o na-

zwie helloworld. Drugą linię zajmuje komentarz.
Trzecia linia makra jest najważniejsza. W niej
znajduje się polecenie

Print

wyświetlające okno

dialogowe z tekstem zawartym w cudzysłowie.
Ostatni wiersz zamyka makro.

Oficjalnie nazwy zmiennych mogą mieć dłu-

gość do 255 znaków, lecz nie wydają mi się być
uzasadnione tak długie nazwy. Jak już wielokrot-
nie zaznaczałem, nazwy zmiennych nie różnicu-
ją małych i dużych liter, więc

zmienna

oznacza

dokładnie to samo co

ZMIENNA

. Nazwy zmien-

nych nie powinny zawierać spacji, a jeśli już, to
nazwę zmiennej należy zamknąć w nawiasach
kwadratowych, co jednak nie jest dobra praktyką
i z pewnością nie poprawia czytelności kodu. Za-
miast spacji z powodzeniem można użyć znaku
dolnego podkreślenia. Nazwy zmiennych mogą
zawierać cyfry, lecz nie na początku nazwy, nie
mogą natomiast zawierać znaków specjalnych
(np. kropka, przecinek, ukośnik, myślnik itd).

Do lokalnego deklarowania zmiennych w

OOo BASICc służy polecenie

DIM

. Domyślnie

brak jest deklaracji typu zmiennej, co można zro-
bić poprzez polecenie

AS nazwa_typu

, Domyśl-

na zmienna jest typu Variant, co oznacza dowol-
ny typ danych. W jednym poleceniu Dim moż-
na zadeklarować kilka zmiennych, dla każdej z
osobna ustanawiając ten sam lub inny typ. Jed-
norazowe podanie typu zmiennej nie nadaje te-
go typu wszystkim zmiennym zadeklarowanym
w danej linii. Brak deklaracji typu zmiennej trak-
towane jest jako deklaracja typu Variant. W przy-
padku zmiennych typu String, możliwe jest wsta-
wianie znaku $ bezpośrednio po nazwie zmien-
nej zamiast

As String

. Obie formy są równo-

znaczne. W przypadku zmiennych typu Double,
w podobny sposób używamy znaku #. Znaki dla
innych typów danych podane zostały w Tabeli 1.

Listing 1.

Wygląd makro w OOo BASIC

Sub

moje_makro

print

''

Witaj

!''

End

Sub

Function

nazwa_funkcji

(

dbl

)

As

Double

nazwa_funkcji

=

dbl

*

2

End

Function

Listing 2.

Przenoszenie polecenia do kolejne-

go wiersza

Sub

Main

Dim

d1

,

d2

,

d3

,

d4

,

d5

,

d6

,

d7

,

_

d8

,

d9

,

d10

,

d11

,

d12

,

d13

End

Sub

Listing 3.

Deklarowanie zmiennych przy użyciu

dwukropka

Sub

Main

Dim

d1

,

d2

,

d3

,

d4

,

d5

,

d6

,

d7

,

_

d8

,

d9

,

d10

,

d11

,

d12

,

d13

d1

=

1

:

d2

=

2

:

d3

=

3

:

d4

=

4

:

d5

=

5

:

d6

=

6

End

Sub

background image

68

Open Office

Macro w służbie autora

czerwiec 2009

69

Open Office

Macro w służbie autora

www.lpmagazine.org

Istnieje jeszcze możliwość krótkiego deklarowa-
nia niektórych typów zmiennych za pomocą jed-
nego polecenia

Def <typ zmiennej>

.

W OOo Basic sterować możemy również

zasięgiem zmiennych, to znaczy, na jakim po-
ziomie one obowiązują. Polecenie

Dim

deklaru-

je zmienną, która obowiązuje w obrębie modu-
łu i biblioteki, w której została zadeklarowana,
lecz zgodnie z jej lokalnym zasięgiem (np. dzia-
ła tylko w obrębie funkcji, pętli for – zgodnie z
powszechnie przyjętymi zasadami). Szerszy za-
sięg ma polecenie

Global

, przy użyciu którego

utworzymy zmienną, z której będzie można ko-
rzystać we wszystkich modułach i bibliotekach.
Przeciwieństwem deklaracji zmiennej global-
nej jest zmienna utworzona za pomocą polece-
nia

Private

. Jest ona widoczna tylko w obrębie

modułu, w którym została utworzona. Inicjaliza-
cja zmiennej

Global

następuje wraz z kompilo-

waniem makra, natomiast zmiennej utworzonej
przy użyciu poleceń

Dim

i

Private

– w trakcie

uruchomienia makra.

Napisałem, że zmienna zadeklarowana bez

typu jest domyślnie zmienną typu Variant z do-
wolnym typem danych. Co w sytuacji, gdy chce-
my przekształcać dane różnych typów? Otóż ję-
zyk OOo BASIC jest w tym względzie bardzo
elastyczny, do czego trudno jest się przyzwycza-
ić programistom Java czy C++ (nawiązuje do
tych dwóch języków, ponieważ akurat te znam).
W OOo BASIC w bardzo łatwy sposób można
rzutować jedne typy danych na drugie za pomocą
odpowiednich funkcji przekształcających. Funk-
cje te mają znaczenie zwłaszcza w przypadku ob-
sługi formularzy. Dane pochodzące z takiego po-
la są zawsze typu tekstowego. Sumowanie za-
wartości tych pól będzie się odbywało w ten spo-
sób, że będą połączone w jeden łańcuch teksto-
wy. Np. zawartość pola 1 to 10, pola nr 2 to 10,
a wynik sumowania zawartości tych pól to 1010,

nie zaś 20. Aby przekształcić dane tekstowe na
dane typu liczbowego, należy użyć jednej z funk-
cji opisanej w Tabeli 1.

Siła makr dla OOo tkwi w tych trzech liter-

kach. UNO (Uniwersalne Obiekty Sieciowe) to
niezależny od języka programowania interfejs,
pozwalający między innymi na dostęp do obiek-
tów występujących w dokumentach OpenOffi-
ce.org. OOo BASIC oczywiście również korzy-
sta z UNO, lecz ze względu na swą prostotę je-
dynie w ograniczonym stopniu. Jednak dla prze-
ciętnego programisty, chcącego napisać makro
dla OOo – dostępne funkcje są wystarczające.
Dzięki UNO programista OOo BASIC ma moż-
liwość korzystania ze wszelkich elementów ak-
tualnie edytowanego dokumentu, np. tekstu czy
komórek tabeli.

Okna dialogowe w OOo

Wraz z OOo Basic do dyspozycji dostajemy bar-
dzo funkcjonalne narzędzie do tworzenia okien
dialogowych, które mogą być później wykorzy-
stywane w tworzeniu własnych makr. Okna dia-
logowe w OOo można tworzyć za pomocą gra-
ficznego edytora, dostępnego w menu Narzędzia
| Makra | Zarządzaj oknami dialogowymi. Wy-
wołanie tej funkcji sprawi, że otwarte zostanie
znane już nam okno zarządzania makrami, lecz
tym razem z aktywną zakładką Okna dialogowe.
Jak poprzednio, w oknie tym będziemy mieli do-
stęp do wszystkich okien dialogowych, które zo-
stały utworzone w systemie. Również tutaj są one
podzielone na kategorie odpowiadające katego-
riom makr. Naciśnięcie przycisku Nowy lub Edy-
tuj
(jeśli wybierzemy już istniejące okno dialogo-
we) otworzy okno edycji okna dialogowego. W
rzeczywistości do okna edycji makr została do-
dana zakładka z nazwą utworzonego lub wybra-
nego do edycji okna dialogowego. Rozwiązanie
takie pozwala nam w łatwy sposób przełączać się
pomiędzy edycją okien a edycją kodu makra. Do
tworzenia okna dialogowego wykorzystywane są
standardowe elementy formularza OOo.

Dokument OpenOffice.org

API OOo BASIC w prosty sposób umożliwia do-
stęp użytkownikowi do aktywnego dokumentu
poprzez obiekt będący referencją interfejsu UNO
::com::sun::star::lang::XComponent. Wywoła-
nie aktywnego obiektu, bez znaczenia, czy jest to
dokument Writera, czy arkusz Calca, odbywa się
poprzez polecenie

ThisComponent.Current-

Controler

. W opisywanych poniżej makrach

obiekt ten, będący reprezentacją dokumentu, bę-
dzie wykorzystywany wielokrotnie. W przypad-
ku dokumentu tekstowego programu OOo Wri-
ter obiekt ten posiada właściwość

Text

będącą

odzwierciedleniem samego tekstu w opisywa-
nym dokumencie.

tekst_dokumentu = ThisComponent.Cur-

rentControler.Text

Należy dodać, iż powyższy obiekt nie ma
właściwości łańcucha znaków (obiektu typu
String). Obiekt ten możemy rzutować na obiekt
typu String za pomocą polecenia

getString()

.

Należy jednak bardzo uważać ze stosowaniem
tej metody ze względu na ograniczenie co do
maksymalnej długości łańcucha znaków. Li-
mit ten narzucony przez ograniczenia standar-
du UNICODE wynosi nieco ponad 65 tysięcy
znaków. Przy standardzie czterech i pół tysię-
cy znaków na stronę (tekstu w postaci jedne-
go akapitu na całą stronę, czcionki Times New
Roman, 12pt, odstęp 1 wiersz) stanowi to oko-
ło czternaście stron tekstu, co nie jest znaczącą
ilością. Jak więc widać, obiekt typu String nie
jest najlepszą formą przechowywania długiego
tekstu. Ponadto właściwość

Text

ma tę prze-

wagę nad obiektem typu String, iż przechowuje
więcej informacji – na przykład o stosowanym
formatowaniu czy też implementuje nasłuch na
zdarzenia oraz obsługuje obecność kursora.

Przybornik autora

Nadszedł czas, aby po pobieżnym zaznajomieniu
się z językiem OOo BASIC zabrać się do praw-
dziwej pracy – pisania makr. Ja stworzyłem bi-
bliotekę makr, które przydadzą się wszystkim
osobom piszącym artykuły do Linux+. Pozwala-
ją one na zautomatyzowanie procesu wstawiania
znaczników (tagów) do tekstu. Całość składa się
z kilkunastu makr, z czego dziewięć wywoływa-
nych jest bezpośrednio. Korzystać można z nich
w dwojaki sposób. Przede wszystkim wszyst-
kie makra zebrałem w postaci okna dialogowe-
go (Rysunek 1), z którego można wywołać każdą
z dostępnych funkcji. Wadą takiego rozwiązania
jest fakt, iż okna dialogowe w OOo obligatoryj-
nie mają charakter modalny, co oznacza, iż akty-
wacja takiego okna blokuje dostęp do głównego
okna programu (jest ono nieaktywne).

Przyznaję, że jest to mało komfortowa sytu-

acja. Z konsultacji na forach dyskusyjnych do-
wiedziałem się, że problem ten miał być rozwią-
zany w OOo 3.0, co jednak się nie stało. Dewelo-
perzy projektu tłumaczą, iż na razie nie jest moż-
liwe jest stworzenie okien dialogowych nie-mo-
dalnych, gdyż może zachwiać to stabilnością
programu. W zamian, niezależni deweloperzy na
stronach forum OpenOffice.org proponują dość
karkołomne rozwiązanie – stworzenie kontene-
ra w języku JAVA, a następnie umieszczenie w
nim widgetów (pól formularza, elementów gra-
ficznych, itd.) komunikujących się z dokumen-
tem OOo za pomocą wspomnianego wyżej me-
chanizmu UNO. Powyższy dyskomfort używa-
nia okien dialogowych może być usunięty po-

Listing 4.

Komentarze w OOo BASIC

Sub

Main

REM

To

jest

komentarze

rem

To

r

ó

wnie

ż

jest

komentarz

End

Sub

Listing 5.

Pierwsze makro w OOo BASIC

Sub

helloworld

REM

To

jest

komentarz

Print

"Hello World!"

End

Sub

Listing 6.

Deklarowanie zmiennej

Sub

Main

Dim

[

nazwa

zmiennej

ze

spacjami

]

[

nazwa

zmiennej

ze

spacjami

]

=

1

End

Sub

background image

68

Open Office

Macro w służbie autora

czerwiec 2009

69

Open Office

Macro w służbie autora

www.lpmagazine.org

przez zastosowanie opisanego uprzednio sposo-
bu dodawania do paska narzędziowego skrótów
do makr. Ja w tym celu utworzyłem osobny pa-
sek narzędziowy, do którego dodałem skróty do
odpowiednich makr, a następnie, aby było ładniej
i wygodniej – przypisałem do nich ikonki. Roz-
wiązanie to prezentuje Rysunek 2. Tak przygoto-
wane skróty do makropoleceń działają niezawod-
nie i wygodnie – jest to zdecydowanie lepsze roz-
wiązanie, niż modalne okno dialogowe.

Wstawianie sekcji

Pierwszymi makrami, które chciałbym opisać są
polecenia wstawiające sekcje oraz . W zasadzie
oba te makra działają w bardzo podobny spo-
sób. Przed ich wywołaniem wymagają zaznacze-
nia fragmentu tekstu, który zostanie poprzedzo-
ny znacznikiem otwierającym i zamykającym.
Makra

setTitleSection

oraz

setLeadSection

odwołują się do innego makra

setTag

, którego

zadaniem jest wstawianie na początku i na końcu
zaznaczenia znaczników początku i końca sekcji.
To zaś makro wykorzystuje z kolei trzy inne ma-
kra –

isAnythingSelected

,

GetLeftMostCur-

sor

oraz

GetRightMostCursor

. Pierwsze z tych

makr sprawdza, czy w tekście został zaznaczony
fragment tesktu. Makro to wykorzystuje metodę

getCurrentSelection()

interfejsu com::sun::

star::lang::XComponent, zwracającą obiekt bę-
dący tablicą aktualnych zaznaczeń w tekście.

allSelections = ThisComponent.Current
Controller.getCurrentSelection()

Jeśli w danym dokumencie znajduje się tyl-
ko jedno zaznaczenie, to powyższe polecenie
zwróci jednoelementową tablicę – zawierają-
cą dane zaznaczenie. Odwołanie do niego wy-
korzystuje metodę

getByIndex()

, której para-

metr będzie miał oczywiście wartość 0.

oSelection = allSelections.getByIndex(0)

Wspomniane makro setTags wykorzystuje po-
nadto dwa inne makra, które określają początek
zaznaczenia i jego koniec, co wcale nie jest ta-
ką prostą sprawą, jakby się wydawało. Obydwa
te makra działają bardzo podobnie. Tworzą one
obiekt Zakres (Range) na podstawie przekaza-
nego przy wywoływaniu parametru – konkret-
nego zaznaczenia. Ten z kolei służy do utwo-
rzenia innego obiektu – kursora tekstowego
– odwzorowania interfejsu UNO ::com::sun:
:star::text::XTextCursor
. Kursor ten zwracany
jest w zależności od makra – jako skrajny pra-
wy lub skrajny lewy kursor.

Przy tej okazji nie sposób jest nie wspomnieć

o idei kursorów w API OpenOffice.org. Najważ-
niejszą kwestią konieczną do zrozumienia me-

chanizmu obsługi kursorów w OOo jest rozróż-
nienie dwóch jego typów. Oprócz wspomniane-
go w poprzednim akapicie kursora tekstowego,
API OOo dostarcza jeszcze kursor widoczny – in-
terfejs UNO com::sun::star::text::XViewCursor.
Jaka jest różnica pomiędzy obydwoma interfej-
sami? Kursor widoczny, jak sama nazwa wska-
zuje, jest odzwierciedleniem kursora migające-
go (na przykład) gdzieś w tekście, gdzie aktual-
nie wstawimy go kliknięciem myszki. Kursor ten
jest więc jedynie punktem, którego współrzędne
można określić za pomocą długości łańcucha po-
przedzającego kursor czy długości łańcucha za
kursorem. W przeciwieństwie do niego kursor
tekstowy jest kursorem niewidocznym, będącym
niczym innym jak wspomnianym uprzednio za-
kresem tekstu. Nie należy jednak mylić kursora
tekstowego z omówionym uprzednio zaznacze-
niem, gdyż ono jest właśnie zakresem, na pod-
stawie którego możemy utworzyć kursor tek-
stowy. Właśnie ta metoda – createTextCursor-
ByRange() została wykorzystana w omawia-

nych makrach GetLeftMostCursor oraz GetRi-
ghtMostCursor.

We wspomnianym makrze

setTags

do

wstawienia tekstu – tu znacznika otwierającego
lub zamykającego sekcję – wykorzystana została
metoda

insertString(XTextRange, String,

boolean)

. Metoda ta wymaga trzech argumen-

tów. Pierwszy z nich to zakres tekstu (interfejs
UNO ::com::sun:: star :: text::XTextRange), któ-
ry w opisywanym makro został zwrócony z me-
tody

getStart()

określającej początek kursora

tekstowego. Zakres ten jest odzwierciedleniem
pozycji, w której będzie wstawiony tekst. Dru-
gim parametrem jest łańcuch tekstowy, który ma
być wstawiony. Trzecim parametrem jest war-
tość logiczna (wartość typu boolean), która okre-
śla, czy wstawiany łańcuch tekstowy ma zastą-
pić zakres tekstu (true), czy poprzedzony tymże
tekstem (false). Należy wspomnieć, iż wstawiany
łańcuch tekstowy może zawierać oprócz znaków
drukowanych także znaki typu Whitespaces, np.
spację lub tabulator, a także znak łamania wiersza

Tabela. 1

Funkcje konwertujące różnego rodzaju dane

Funkcja

Opis

CDbl(txt)

Przekształca dane tekstowe

txt

na dane typu Double

CInt(txt)

Przekształca dane tekstowe

txt

na dane typu Integer

CLng(txt)

Przekształca dane tekstowe

txt

na dane typu Long

CSng(txt) Przekształca dane tekstowe

txt

na dane typu Single

Int(licz-
ba)

Przekształca wartość liczbową

liczba

na wartość typu Integer

Val(txt)

Przekształca dane tekstowe

txt

na dane typu Double. Funkcja bardzo tolerancyjna w sto-

sunku do wartości nienumerycznych.

CStr(obj)

Przekształca obiekt

obj

na dane typu String

Tabela 2.

Znaki specjalne

Znak specjalny

Opis

PARAGRAPH_BREAK

Znak łamania paragrafu

LINE_BREAK

Znak łamania wiersza

HARD_HYPHEN

Znak twardego łącznika

SOFT_HYPHEN

Ten znak kontrolny określa punkt dzielenia wyrazów. Stosowany,
jeśli słowa zawierające muszą być rozdzielone na końcu wiersza.

HARD_SPACE

Wstawia twardą spację (spacja ta nie zmienia rozmiaru podczas ju-
stowania wiersza oraz łączy ze sobą dwa wyrazy przy przenosze-
niu do nowego wiersza)

APPEND_PARAGRAPH

Wstawia nowy akapit

Tabela 3.

Znaki specjalne wyrażeń regularnych zastosowane w opisywanych makrach

Znak

Opis

*

Dowolna liczba znaków, np. a*b odpowiada aab, jak i abbcccb

[abc123]

Wyszukuje dowolny ze znaków zapisanych pomiędzy nawiasami kwadratowymi

a-z

Myślnik oznacza zakres, tu wszystkie litery alfabetu od a do z, lecz 0-9 oznacza wszystkie
cyfry

(abc)

Wyszukuje sekwencji abc

/>

Koniec wyrazu

[:space:]

Wyszukuje dowolny znak typu Whitespace

background image

70

Open Office

Macro w służbie autora

czerwiec 2009

71

Open Office

Macro w służbie autora

www.lpmagazine.org

(lf), jak i łamania paragrafu(cr). Makro to zawiera
również bardzo podobną metodę –

insertCon-

trolCharacter(XTextRange,ControlCha-
racter,boolean)

, która różni się od omawianej

uprzednio tym, iż wstawia znak specjalny – jeden
z przedstawionych w Tabeli 2.

Omawiane makra

setTitleSection

oraz

setLeadSection

zawierają dodatkowo bardzo

użyteczną funkcję liczenia tekstu, który ma być
wprowadzony do danej sekcji. Jak wiadomo, re-
dakcja Linux+ narzuca limit dla tytułu 45 zna-
ków, a dla wprowadzenia – 700 znaków. Oby-
dwa wspomniane makra poinformują nas, jeśli
limity te zostaną przekroczone. W tym momen-
cie z pomocą przyjdzie nam opracowany prze-
ze mnie bardzo prosty edytor tekstu w postaci
okienka dialogowego uruchamianego makrem

TextEditor

.

Zaletą tego prostego edytora jest stały na-

słuch co do zmian we wprowadzanym tekście.
Za każdą zmianą w polu tekstowym pod polem
do edycji pojawia się informacja na temat ak-
tualnej liczby znaków. Przyciskiem Wklej tekst
można wkleić poprawiony tekst do dokumentu
– w miejscu wstawienia kursora. Warto zwrócić
uwagę na kod tego makra, gdyż po raz pierw-
szy w tym artykule wykorzystane zostaną in-
terfejsy: UNO XTextListener i XActionListe-
ner
będące pochodnymi interfejsu ::com::sun:
:star::lang::XEventListener
. Zasada stosowa-
nia nasłuchu zdarzeń w OOo jest bardzo pro-
sta. Do danej kontrolki okna dialogowego (czy
też innego obiektu UNO) należy przypisać me-
todę typu add_Listener – różną w zależności od
typu obsługiwanego zdarzenia. Parametrem tej

metody jest obiekt powstały na bazie interfejsu
obsługującego konkretne zdarzenie. Konstruk-
tor takiego obiektu nasłuchu wymaga podania
dwóch parametrów. Pierwszy z nich to przed-
rostek metod implementujących daną obsłu-
gę zdarzeń, drugi zaś to klasa danego zdarze-
nia. Na koniec należy dodać makra obsługujące
zdarzenia – z konkretnymi ustalonymi w kon-
struktorze przedrostkami. Niesamowitą zaletą
obsługi zdarzeń w OOo BASIC jest łatwość,
z jaką uzyskujemy dostęp do kontrolki wywo-
łującej zdarzenie – poprzez właściwość

Source

obiektu zdarzenia (jednej z klas implementują-
cych interfejs ::com::sun::star::lang::XEven-
tListener
). Z podobną łatwością uzyskuje się
dostęp do kontenera, na którym umieszczona
jest dana kontrolka, to jest na przykład do okna
dialogowego, gdzie się znajduje. Służy do tego
właściwość

Context

.

Nieco bardziej skomplikowana sytuacja ma

miejsce w przypadku sekcji <<LISTING>> i
<<TABELA>>. W tych to sekcjach wymaga-
ne jest podanie dodatkowych informacji – ta-
kich jak numer tabeli/listingu czy też tytuł. In-
teraktywność makra setTags została rozwiązana
poprzez zastosowanie okna dialogowego

setTe-

xtDialog

oraz funkcji

getDialog()

, zwracają-

cej wprowadzony łańcuch znakowy. Okno dialo-
gowe

setTextDialog

jest zastąpieniem brakują-

cego w API OOo gotowego okna dialogowego
typu INPUT, zwracającego wprowadzony tekst.
Na całe szczęście tworzenie okien dialogowych
w IDE OOo oraz ich obsługa są tak proste, że nie
należy specjalnie płakać nad tą stratą.

Spis ilustracji

Najbardziej skomplikowanym przykładem okna
dialogowego i zestawu makr je obsługujących
jest okno, które wprowadza spis ilustracji uży-
tych w artykule. Podstawowym makrem wywo-
ływanym jako pierwsze w tym celu jest makro

ChoosePictureFiles

. Makro to tworzy okno

dialogowe wyboru plików będące instancją ser-
wisu UNO ::com::sun::star::ui::dialogs::XFi-
lePicker
. Instancja ta ma dwie odmiany – klasę
OfficeFilePicker oraz SystemFilePicker. Pierw-
sza tworzy okno wyboru plików o GUI jak w ca-
łym pakiecie OpenOffice.org, druga zaś korzysta
z systemowego okna wyboru. Zasadniczo nie po-
winno być różnicy pomiędzy obydwoma klasa-
mi, ale... Ja osobiście zauważyłem na MacOS X
10.5.6 Leopard problemy ze stabilnością System-
FilePicker
. Nic się nie działo natomiast z Office-
FilePicker
.

Tworzone przeze mnie okno wyboru plików

ma włączoną właściwość wielokrotnego wybo-
ru (

setMultiSelectionMode(True)

). Dodat-

kowo, aby ułatwić pracę z tym oknem, ustawi-
łem filtr plików zezwalających na wyświetla-

nie jedynie plików zakwalifikowanych za po-
mocą rozszerzenia jako pliki graficzne. Innym
istotnym elementem omawianego makra jest
serwis ::com::sun::star::ucb::SimpleFileAccess
zezwalający na pewne proste operacje na pli-
kach. W naszym przypadku operacją tą będzie
sprawdzenie, czy dany plik jest rzeczywiście pli-
kiem, czy też katalogiem (folderem). Służy do
tego metoda

isFolder(File)

, która jako para-

metr przyjmuje obiekt typu File. W przypadku,
gdy ma do czynienia z folderem (katalogiem),
zwracana jest wartość True. Przyznaję w tym
momencie, że obsługa okna dialogowego wy-
boru plików początkowo nastręczyła mi pewne
trudności, łatwe do pokonania, jeśli ma się wie-
dzę, którą chcę przekazać teraz. Otóż domyślnie
okno dialogowe wyboru plików zwraca tablicę
zawierającą wybrane pliki. Nawet jeżeli pozo-
stawimy domyślną możliwość wyboru pojedyn-
czego pliku – nadal zwracana będzie tablica, ty-
le że jednoelementowa. Tablica ta zwracana jest
jako efekt wywołania metody

getFiles()

dla

obiektu okna dialogowego. Tutaj następuje pew-
na nieścisłość. W przypadku okna z wielokrot-
nym wyborem, jak w omawianym przykładzie,
pierwszym elementem tablicy jest folder, a na-
stępnie nazwy wybranych plików w obrębie da-
nego folderu. Jeśli chcemy mieć pełną ścieżkę
dostępu do wybranych plików, musimy ręcz-
nie skleić sobie jedno z drugim – istna głupo-
ta! Tak też robię w omawianym makrze. Posia-
dając już tablicę z plikami obrazków, utworzo-
na jest pętla for, która kolejno wywołuje funk-
cję

openPictureDialog

, która jako argumen-

ty wymaga podania URL rysunku, nazwy pliku
oraz kolejnego numeru rysunku (wartość indek-
su pętli for). Funkcja ta uruchamia okno dialo-
gowe, w którym wyświetlona zostaje miniaturka
ilustracji oraz pola tekstowe z kolejnym (propo-
nowanym) numerem ilustracji, nazwą pliku ilu-
stracji i polem do wprowadzenia podpisu do ilu-
stracji. Po zatwierdzeniu przyciskiem Zatwierdź,
uruchamiane jest kolejne makro –

AddPicture-

Section

, które odpowiedzialne jest za wstawia-

nie sekcji opisującej rysunek z danymi podany-
mi uprzednio w oknie dialogowym.

Sekcja w sieci

Wstawienie tej sekcji do edytowanego artykułu
potraktowałem na dwie możliwości. Pierwsza z
nich wykorzystuje mechanizm wyszukiwania
użytych w tekście adresów internetowych, druga
zaś wstawia adresy na podstawie podanych da-
nych w oknie dialogowym.

W przypadku przeszukiwania tekstu pod

kątem adresów internetowych należy uruchomić
makro SearchHTTP. Makro to jako podstawowy
mechanizm wykorzystuje obiekt

oDescriptor

będący implementacją interfejsu UNO ::com:

Rysunek 1.

Okno dialogowe Przybornik autora

Rysunek 2.

Pasek narzędziowy ze skrótami do opi-

sywanych makropoleceń

background image

70

Open Office

Macro w służbie autora

czerwiec 2009

71

Open Office

Macro w służbie autora

www.lpmagazine.org

:sun::star::util::SearchDescriptor. Obiekt ten
przeszukuje tekst dokumentu pod kątem wystę-
powania łańcucha znakowego zdefiniowanego
we właściwości

SearchString

(tu przy pomocy

polecenia

Witch

). Inną właściwością tego obiek-

tu jest

SearchRegularExpression

, której war-

tość True oznacza, że szukany łańcuch jest wy-
rażeniem regularnym. Jeśli ktoś do tej pory nie
spotkał się z pojęciem wyrażenia regularnego
– nadszedł najwyższy czas, aby to zrobić. Wy-
rażenie regularne jest zapisem sekwencji znako-
wej za pomocą specjalnie zdefiniowanych sym-
boli, w ten sposób, aby istniała możliwość przy-
najmniej jednokrotnego odnalezienia sekwencji
spełniającej założone warunki, co jednak nie jest
konieczne (wyrażenie regularne może nie zostać
odnalezione w przeszukiwanym łańcuchu zna-
kowym). Zastosowane przeze mnie wyrażenie
regularne opiera się na zasadzie, iż adres inter-
netowy rozpoczyna się (przynajmniej powinien)
od znaków http:// lub https://, po których nastę-
puje sekwencja liter, cyfr i/lub innych znaków.
Wyrażenie regularne odnajdujące adresy inter-
netowe wygląda następująco: (http[s]*://)[a-z0-
9._%+-/]*\>
. Szczegółowe wyjaśnianie znacze-
nia poszczególnych znaków specjalnych stoso-
wanych w wyrażeniach regularnych przekroczy-
łoby zakres tego artykułu, skoncentruję się więc
jedynie na znakach użytych w danym wyraże-
niu. Znaczenie poszczególnych znaków przed-
stawia Tabela 3.

Aby przeszukać dokument pod kątem wy-

stępowania zadanej frazy, należy wywołać dla
obiektu

ThisComponent

jedną z metod, z któ-

rych każda, jako parametr, wymaga podania zde-
finiowanego obiektu interfejsu SearchDescrip-
tor
. Metody te są następujące:

findFirst()

– wy-

szukująca pierwsze napotkane wyrażenie,

find-

Next()

- wyszukująca sekwencyjnie kolejne od-

powiadające wyrażenia, oraz

findAll()

– zwra-

cająca tablicę odpowiadających wyrażeń. W opi-
sywanym makrze została zastosowana ostatnia z
metod – której iterator wykorzystywany jest na-

stępnie w pętli for, wstawiającej adres wraz z opi-
sem podanym w oknie dialogowym.

Zupełnie inne podejście stosuje makro I

n-

WebSection

. Ono bowiem wyświetla na samym

początku małe okno dialogowe, w którym za po-
mocą suwaka ustala się liczbę adresów, które ma-
ją się znaleźć w sekcji <<W_SIECI>>. W kodzie
tego makro należy zwrócić szczególną uwagę na
zaimplementowany nasłuch zdarzenia – zmiany
wartości suwaka (XChangeEvent). Wadą kon-
trolki suwaka w OOo jest fakt, iż poza warto-
ścią maksymalną i minimalną niewiele więcej
(poza wyglądem graficznym) da się z nim zro-
bić. Nie ma na przykład możliwości wyświetla-
nia aktualnej pozycji (wartości suwaka). Z tego
też powodu zaimplementowany nasłuch wpro-
wadza dynamicznie odczytaną aktualną wartość
suwaka do pola tekstowego. Wciśnięcie przyci-
sku Zatwierdź uruchamia kolejne makro – Cre-
ateDialog
. Makro to służy dynamicznemu zbu-
dowaniu okna dialogowego – bez użycia kreatora
– bezpośrednio z kodu OOo BASIC. Jak widać,
nie jest to specjalnie trudne, a daje dużo większe
możliwości obsługi tak zbudowanego okna dia-
logowego. Okno to zawiera odpowiednią liczbę
powtórzeń par pól tekstowych – do których na-
leży wprowadzić adres i opis pola. Zatwierdze-
nie wpisanych wartości powoduje wstawienie do
tekstu adresów wraz z opisami, z wykorzysta-
niem tych samych metod, jak opisane uprzednio.

Podwójne spacje,

usuwanie cudzysłowów

Mechanizm wyszukiwania za pomocą wyra-
żenia regularnego stosuje również inne makro

FindDoubleSpaces

– wyszukujące w tekście

podwójnych spacji. Makro to jednak wykorzy-
stuje interfejs UNO ::com::sun::star::util::Re-
placeDescriptor
. W tym konkretnym przypad-
ku szukamy podwójnych spacji, które przez wy-
rażenie regularne zapisane jest w postaci [:spa-
ce:][:space:]. Właściwość tego deskryptora Re-
placeString
stosuje znak specjalny & oznacza-

jący tę samą wartość, co wyszukiwana. Jedyną
zmianą jaką się tutaj wprowadza jest formatowa-
nie – wstawienie czerwonego tła w miejscu po-
dwójnej spacji. Błąd ten należy usunąć już oso-
biście. Do ustawienia czerwonego koloru tła zna-
ków służy właściwość

CharBackColor

, przypi-

sana do deskryptora zastępującego.

Ostatnim makrem wykorzystującym wyra-

żenia regularne jest makro wyszukujące cudzy-
słowy drukarskie i adresy http:// i formatujące te
łańcuchy na kursywę.

Inspektor akapitów

Ostatnim makrem, które chciałbym przybliżyć
na łamach tego artykułu jest inspektor akapitów.
Makro to przegląda akapit za akapitem, wyświe-
tla w oknie dialogowym, jaki styl został zastoso-
wany dla niego oraz umożliwia zmianę tego sty-
lu na jeden z trzech: Domyślny, Nagłówek 1 i Na-
główek 2
. Makro akapity w swojej konstrukcji
wykorzystuje metodę createEnumeration(), któ-
ra zwraca kolejne tablice kolejnych akapitów.
Dostęp do poszczególnych akapitów odbywa się
za pomocą

nextElement()

, zwracającego para-

graf. Wadą metody createEnumeration() jest nie-
możliwość bezpośredniego odwołania się do ko-
lejnego akapitu poprzez index (brak takiej funk-
cji w API OOo).

Podsumowanie

Mam nadzieję, iż wszyscy piszący artykuły do
Linux+ zaczną stosować napisane przeze mnie
makra. Choć z pewnością nie są one doskonałe,
to i tak stanowią wyśmienite ułatwienie pracy. In-
ne osoby, które nie skorzystają z tych makr bez-
pośrednio, z opisanych przeze mnie przykładów
będą mogły czerpać wiedzę w zakresie stosowa-
nia makr w pracy z OpenOffice Writer. Na sam
koniec dodam, iż powyższy tekst przygotowałem
przy zastosowaniu opisywanych makr.

Listing 7.

Deklarowanie zmiennych różnych typów

Sub

Main

Dim

zmienna

Dim

zmienna1

As

String

,

zmienna2

$

Dim

zmienna4

As

Single

,

zmienna5

As

Double

DefInt

zmienna6

End

Sub

Listing 8.

Zmienne o różnym zasięgu

Global

oForm

Sub

Main

oForm

=

thisComponent

.

getDrawPage

().

getForms

().

getByName

(

"Standard"

)

Private

component

=

oForm

.

getByName

(

"poletxt"

)

End

Sub

Grzegorz Madajczak jest z wykształcenia le-
karzem weterynarii i mikrobiologiem. Linuk-
sem i ogólnym oprogramowaniem Open-
Source
pasjonuje się od 2001 roku. Na co
dzień używa Linuksa zarówno w pracy, jak
i w domu. Jego ulubione dystrybucje to Gen-
too i Slackware.
Kontakt z autorem: madajczak@gmail.com

O autorze

http://www.madajczak.eu/download/

przybornik_autora.odt – plik ODT z
opisywanymi makrami.

W Sieci


Wyszukiwarka

Podobne podstrony:
2009 06 15 21;42;51
Elektroinstalator 2009 06 koordynacja ochronników klasy I [B] i II [C]
2009 06 BO Egzamin
Makroekonomia I 11 Cykl koniunkturalny (2009 06 02)
Ćwiczenia do powtórzenia w klasach piątych o Grecji Rzymie nowe(Open Office), Dla klas piątych
2009 06 09 Kolokwium 2
Pierwsze powtórzenie w klasach piątych od ludzi pierwotnych do Egiptu można otwierać programem Open
2009 06 29 Caritas In Veritate
Open office Ćwiczenia
2009 06 26 20;05;26
22c - Przepisy - Zupy (open office), Kuchnia
2009 06 Szkoła konstruktorów klasa II
Lubie Gotowac 2009 06
2007 08 OpenOffice–narzędzie do konwersji [Open Office]
2 Omowienie pakietu MS Office i Open Office Ogolne wlasciwosci edytora tekstu
2009 06 03 POZ 11id 26815 ppt
bd w3 (aga's conflicted copy 2009 06 10)

więcej podobnych podstron