Mechanizm modułów

Kadu

Wstęp

Mechanizm modułów umożliwia rozszerzanie funkcjonalności komunikatora Kadu za pomocą pakietów nazywanych modułami składających się z dodatkowego, zewnętrznego kodu i plików z danymi. Moduł może być dynamicznie ładowany i wyładowywany z Kadu w trakcie pracy komunikatora lub też może być wkompilowany statycznie.

Pliki modułu

Każdy moduł Kadu ma swój podkatalog w katalogu "modules" w źródłach komunikatora. Tam też powinny być umieszczane dodatkowe moduły, które chcemy skompilować wraz z Kadu. Nazwa podkatalogu modułu jest dość istotną rzeczą, ponieważ informuje komunikator pod jaką nazwą moduł będzie obecny w okienku menadżera modułów. W dalszej części dokumentu podkatalog modułu będzie reprezentowany przez wyrażenie $MODULE.

Nazwa modułu

Nazwa modułu powinna się składać z małych angielskich liter alfabetu. Oprócz tego na chwilę obecną przyjętych jest kilka specjalnych przyrostków (suffixów): "_sound" dla modułów dźwiękowych, "_scripting" dla modułów obsługujących języki skryptowe, "_notify" dla modułów powiadomień, "_sms" dla modułów obsługi bramek smsowych oraz "_docking" dla modułów dokujących. Moduły kwalifikujące się do wyżej wymienionych kategorii powinny mieć wymagany przyrostek. Przykłady nazw modułów: autoresponder, alsa_sound, tcl_scripting.

Katalog modułu

W katalogu $MODULE umieszczamy źródła modułu (pliki .cpp i .h), plik "README" i "ChangeLog" i tym podobne oraz plik "spec". Przyjmujemy dodatkowo standardowe podkatalogi: "translations" - z plikami tłumaczeń, jeśli moduł takie posiada, "doc" - jeśli moduł posiada dokumentację, data - z dodatkowymi plikami danych (obrazki itp), które mają zostać zainstalowane wraz z modułem oraz bin z dodatkowymi programami. W ramach potrzeb dopuszczalne sa również inne, nie wymienione.

Translacje napisów

W stałych znakowych w kodzie modułu (w komunikatach, opisach menu i innych) używamy języka angielskiego. Używamy funkcji tr() i pochodnych z biblioteki Qt - http://doc.trolltech.com/3.3/linguist-manual.html. W katalogu modułu robimy podkatalog translations i wrzucamy tam pliki .qm .ts w postaci: <nazwa_modułu>_<dwuliterowy_kod_kraju>.qm i to samo z .ts, np. autoresponder_pl.ts i autoresponder_pl.qm

Translacje napisów w ConfigDialog

przy używaniu ConfigDialog'a nie używamy tłumaczeń tr() tzn błędne jest użycie

  ConfigDialog::addVGroupBox(tr("Notify"), tr("Notify"), tr("Notify options"));

natomiast używamy sposobu:

  ConfigDialog::addTab(QT_TRANSLATE_NOOP("@default", "Notify"));
  ConfigDialog::addVGroupBox("Notify", "Notify",
  QT_TRANSLATE_NOOP("@default", "Notify options"));

może wydaje sie to bezsensowne i nienaturalne ale dla uproszczenia zapisu w ConfigDialog'u podaje się wersje nietłumaczone np. "Notify options", a ConfigDialog sam przetłumaczy ten napis jeśli posiada odpowiednie tłumaczenie (*.qm).

Opis modułu - plik spec

Plik spec zawiera wszystkie informacje o module potrzebne do zbudowania go przez zawarty w źródłach Kadu kompilator modułów. Plik jest skryptem bash'owym, który interpretowany jest zarówno w trakcie wykonywania polecenia configure jak i make. W skrypcie tym powinniśmy (nie wszystkie są obowiązkowe) ustawić następujące zmienne:

  • MODULE_SOURCES - lista plików źródłowych (*.cpp) które będą kompilowane i zlinkowane do biblioteki so.
  • MODULE_MOC_HEADERS - lista plików nagłówkowych (*.h) które najpierw są kompilowane meta-kompilatorem moc do plików "*_moc.cpp", a następnie również kompilowane i linkowane do biblioteki so modułu.
  • MODULE_HEADERS - pozostałe nagłówki występujące w module i używane przez pliki "*.cpp".
  • MODULE_CXXFLAGS - flagi kompilatora przekazywane do gcc przy kompilacji źródeł modułu.
  • MODULE_LDFLAGS - flagi kompilatora przekazywane do gcc podczas procesu konsolidacji biblioteki so modułu.
  • MODULE_LIBS - lista wymaganych przez moduł bibliotek zewnętrznych, innych niż standardowo wymagane przez Kadu. Lista powinna zawierać same nazwy, bez przedrostka "lib" i rozszerzenia ".so". Skrypt configure próbuje odnaleźć podane biblioteki w systemie i ustawia wszystkie potrzebne flagi kompilatora. W razie niepowodzenia odmawia kompilacji.
  • MODULE_INCLUDES - lista wymaganych przez moduł nagłówków zewnętrznych. Zasada ta sama co przy poprzednim punkcie, ale lista zawiera pełne nazwy plików.
  • MODULE_LIBS_PATH - lista dodatkowych ścieżek, w których należy szukać wymaganych bibliotek.
  • MODULE_INCLUDES_PATH - lista dodatkowych ścieżek, w których należy szukać wymaganych plików nagłówkowych.
  • MODULE_TOOLS - lista wymaganych przez moduł poleceń zewnętrznych, innych niż standardowo wymagane przez Kadu.
  • MODULE_CONFIGURE_CMD - komenda powłoki (lub lista komend, jeśli używamy separatorów takich jak ";" lub "&&"), która zostanie wykonana podczas działania polecenia configure. jeśli polecenie zwróci status inny od zera to zostanie to zinterpretowane jako błąd.
  • MODULE_MAKE_CMD - komenda powłoki (lub lista komend, jeśli używamy separatorów takich jak ";" lub "&&") która zostanie wykonana po zakończeniu kompilowania modułu. jeśli polecenie zwróci status inny od zera to zostanie to zinterpretowane jako błąd.
  • MODULE_3RDPARTY - lista nazw podkatalogów zawierających dodatkowe biblioteki, które będą kompilowane przed kompilacją modułu; w każdym z tym katalogów zostanie wykonane polecenie make.

Współpraca modułu z Kadu

Moduł w którymś z plików źródłowych, z których powstaje biblioteka so, powinien zawierać następujące funkcje, zadeklarowane dokładnie tak jak to napisane poniżej:

  extern "C" int <nazwa_modulu>_init()
  {
     // inicjalizacja modulu
     // ...
     return 0;
  }
  extern "C" void <nazwa_modulu>_close()
  {
     // zamknięcie modulu, porządki
     // ...
  }

Po załadowaniu modułu do pamięci Kadu uruchamia funkcję inicjalizującą "<nazwa_modułu>_init", która powinna przygotować moduł do dalszej pracy i zwrócić kod błędu (jeszcze nie są ustalone, narazie używamy liczby 1) lub liczbę 0 jeśli inicjalizacja przebiegła pomyślnie. Przed wyładowywaniem modułu przez Kadu uruchamiana jest funkcja "<nazwa_modułu>_close", która powinna przygotować moduł do usunięcia z pamięci, pozwalniać zaalokowaną pamięć i tym podobne. W funkcjach tych istnieje możliwość korzystania z translacji ponieważ translator dla modułu tworzony jest przed wywołaniem funkcji "init" i usuwany po powrocie z funkcji "close".

Aby skorzystać w module z funkcjonalności oferowanych przez Kadu dołączamy nagłówki programu i używamy odpowiednich klas, obiektów, funkcji. Informację o różnego typu wydarzeniach (np. otrzymanie nowej wiadomości) możemy otrzymać podłączając się pod odpowiednie sygnały - http://doc.trolltech.com/3.3/signalsandslots.html.

Co zrobić z napisanym modułem?

Jeśli uważasz, że napisany przez Ciebie moduł oferuje ciekawą funkcjonalność skompresuj katalog z modułem do postaci tar.gz lub tar.bz2 (usuń pliki cxxflags, ldflags i pliki tymczasowe), upublicznij gdzieś w internecie i napisz jakąś informację o tym na forum Kadu w dziale "Moduły - Informacje".

Jeśli moduł będzie miał pozytywną opinię użytkowników, będzie należycie wspierany przez autora (poprawianie błędów, odpowiadanie na pytania, wyjaśnianie problemów) to zostanie umieszczony na liście oficjalnych modułów Kadu - http://www.kadu.net/w/Modu%C5%82y.

Bardzo popularne lub z innych przyczyn istotne moduły mają szanse wylądować bezpośrednio w źródłach aplikacji.


Osobiste