Elvio Basello, 22-06-2010
hell at hellvis69 dot netsons dot org

SUMMARY
=======
1. PREFACE
2. INSTALLATION
3. A TYPICAL ADDON LAYOUT
4. SOME EXAMPLES
5. HINTS
6. WHERE TO START


1. PREFACE

Starting from the release 4.0.0 KVIrc supports the addon packaging system.

A KVIrc addon is basically a zip package containing a subset of user-defined icons,
aliases, functions, classes and all stuff needed to implement a new KVIrc feature.
It might be a simple automatic-away subsystem, a GUI newsticker or a complex file
sharing service (commonly called "fserve"). Addons are sometimes called "scripts".
In fact a KVIrc addon is usually made of more than one KVS script.

KVIrc has a builtin addon management system that allows the users to create, install,
configure and uninstall features with a nice graphical interface. The management
system allows the addons to have documentation integrated in the KVIrc help and to
be translated in several languages.


2. INSTALLATION

The addons are usually shipped in compressed archives (.kva). A simple double
click on the *.kva file should be sufficient to install the addon for the current user.

Another way to install the package is to use the /addon.install command.
Under the hood, the double click will just invoke kvirc by passing the *.kva file
name as parameter. KVirc will recognize it as being an addon package and will
automatically invoke "/addon.install <filename>" on it.


3. A TYPICAL ADDON LAYOUT

As stated above, the addons are usually shipped in a compressed archive. The
/addon.install command will uncompress it to a temporary directory.
The uncompressed tree is substantially the same directory tree that you have
to create in order to package your addon and it usually looks like this:

    name-version/
     +- install.kvs
     +- src/
     |    +- source1.kvs
     |    +- source2.kvs
     |    \- ...
     +- locale/
     |    +- name_it.mo
     |    +- name_de.mo
     |    \- ...
     +- config/
     |    +- config1.kvc
     |    +- config2.kvc
     |    \- ...
     +- audio/
     |    +- audio1.wav
     |    +- audio2.wav
     |    \- ...
     +- pics/
     |    +- pic1.png
     |    +- pic2.png
     |    \- ...
     +- help/
          +- en/
          |   +- index.html
          |   +- hints.html
          |   \- ...
          +- it/
              +- index.html
              +- hints.html
              \- ...

The entries with a slash (/) at the end are directories while the other are files.

The toplevel directory should be named with your addon name and version. Use no spaces
in the directory entries: this will make the things simpler for people that want to
use your addon.

The install.kvs is the mandatory initialization script which must contain all the
procedures required to register your addon inside the KVIrc subsystems and install
all your addon data files.

For example:

    ...
    addon.register("MyAddon", \
                    "1.0.0", \
                    "My First Addon", \
                    "An addon that is really cool but does
                    simply nothing", \
                    "4.0.0", \
                    "MyAddon_32.png" \
         )
    {
    }

    addon.installfiles "MyAddon" "pics" "pics/*.png"
    addon.installfiles "MyAddon" "locale" "locale/*.mo"
    addon.installfiles "MyAddon" "config" "config/*.kvc"
    addon.installfiles "MyAddon" "audio" "audio/*.wav"
    addon.installfiles "MyAddon" "help/en" "help/en/*.html"
    addon.installfiles "MyAddon" "help/it" "help/it/*.html"

    # Register classes
    MyAddon::classes::register

    # Initialize events
    MyAddon::events::init

    # Load configuration
    MyAddon::config::load

    # Setup popups
    defpopup("MyAddon")
    {
        item($tr("Something","MyAddon"),110)
        {
            ...
        }
    }

    # Set options
    option boolAutoAcceptDccSend 1
    option boolShowMinimizedDebugWindow 1

    # Invoke sources
    include "src/mystuff.kvs"
    ...


The install.kvs is the only really mandatory piece of an addon. Most real-world addons,
however, will be split over several kvs source files. Canonically these
source files are placed in the src/ subdirectory and the install.kvs must invoke them
them in the right order. More about the install.kvs script in section 4.

If your addon is translated in different languages then the "locale" directory should
contain the *.mo catalogue files for your translations. The localization process of a
script is explained in the KVIrc documentation. Your *.mo filenames should be prefixed
by your addon name.

If your addon needs an initial configuration then your config files should be placed
in the "config" subdirectory and should have *.kvs as extension.

The "pics" and "audio" (if relevant) directories should contain your multimedia files.
It's a good idea to have your pics file in PNG format and sound files in WAV format.

The "help" directory should contain subdirectories for each language your help files
are written in. The languages dirs should be named with the language code also used for
the translation files (like "en", "it" etc...).

Please note that English is the default language and KVIrc will fallback to the "en"
subdirectory when no other language is found around...


4. THE INIT FILE

The smallest addon that you can write is the one that does nothing.

    addon.register("MyAddon", \
                    "1.0.0", \
                    $tr("My First Addon","myaddon"), \
                    $tr("An addon that is really cool but does
                    simply nothing","myaddon"), \
                    "4.0.0", \
                    "MyAddon_32.png")
    {
    }


The code above does nothing but registers the "MyAddon" addon.


The first parameter is the internal addon id which can be used to identify your addon
inside KVIrc. The id must be unique: two addons that share the same name cannot be
installed.
The second parameter is the addon version. It should be expressed in the classic format
[major].[minor].[pathlevel] or something really similar (in fact KVIrc just expects the
version to be a string composed of numbers separated by dots). The version is compared
when an addon is installed and KVIrc complains if the user tries to downgrade an addon
(that is to install a less recent version over a more recent one).
The third parameter is the visible name of your addon: it will be displayed to the user
in the addon management dialog. It can contain the $tr function so you can have it
translated to several languages: in this case, our string will be translated in the
catalogue myaddon.
The fourth parameter is a short description of the feature that the addon implements;
it can contain the $tr() function too.
The fifth parameter is the minimal KVIrc version required to run the addon.
The sixth parameter is the icon to show in the manager: it has to be 32x32 pixel big.
There are also some switches that can be used to fiddle a little bit more :)


5. THE HELP AND CONFIGURATION CALLBACKS

Each addon can have a help and a configuration callback. These are set respectively by
addon.sethelpcallback and addon.setconfigurecallback.
The help callback will be invoked by KVIrc when the user will ask help for your addon
(mainly from the addon management dialog, but not necessarily). It should call help.open
with the name of your documentation index html file (it should be relative to the help
language directory.

Hint: help.open myaddon/index.html will automatically lookup the right language

If you provide no help callback, the button for requesting help will be simply disabled.
A good and relatively complex addon *should* have at least a minimal help file explaining
the features.

The configuration callback will be invoked when the user will try to configure your addon
from the addon management dialog. This callback is useful mainly for more complex graphical
scripts that can show up a dialog that allows configuring all of the addon features.
To use this callback you will probably need some object scripting.


6. THE REAL WORK

The real addon work is done by the scripts contained in the source directory. They will
likely add aliases (maybe in a nice namespace named against your addon), register event
handlers, create actions, timers, toolbars and object classes. You should install all of
this stuff from your addon source files.

Remember that your source files will NOT be parsed every time KVIrc starts up: your stuff
must be registered in KVIrc and be able to startup itself, if needed. You must clean up
everything in your uninstallation callback. This means that you must remove the aliases,
unregister the event handlers, destroy the actions, kill the timers and the object classes
you've created. Be a clean coder :)


7. SOME EXAMPLES

The code below is just an example of how to write a useful initalizazion of your own addon.
The name of the classes refer to the ones described above.

    # Register the classes
    alias(MyAddon::classes::register)
    {
        # Create an array with all the classes of our addon.
        # In this way it's easy to add or remove classes in the registering routine
        %classes[] = $array( \
            MyAddon::classes::database, \
            MyAddon::classes::gui::options, \
            ...
            )

        # Scan the array and register the classes
        for(%i=0; %i < $length(%classes[]); %i++)
        {
            if($classDefined("%classes[%i]"))
            {
                objects.killClass %classes[%i]
            }
            eval %classes[%i]
        }
    }

    # Initialize events
    alias(MyAddon::events::init)
    {
        event(OnKVIrcStartup,"MyAddon")
        {
            ...
            # Load the catalogue (translation) file "myaddon" from the path provided
            trload myaddon $file.localdir("locale/MyAddon")
            MyAddon::config::load
            ...
        }
        event(OnChannelMessage,"MyAddon_something")
        {
            ...
        }
    }

    # Load configuration
    alias(MyAddon::config::load)
    {
        # If the class ConfHandler is not defined, register all classes we have
        if(!$classDefined(MyAddon::classes::ConfHandler))
        {
            MyAddon::classes::register
        }

        # Set some variables
        %MyAddonConfig = $new(MyAddon::classes::ConfHandler)
        %MyAddonConfigPath = $file.localdir(config/scripts/MyAddon)

        # Open the configuration file and move to the section "general"
        %c = $config.open(%MyAddonConfigPath/MyAddon.kvc,"r")
        config.setsection %c general

        # Store the value of the key "Key" in the global variable %Key
        %Key = $config.read(%c,"Key",2)
        ...
    }


8. HINTS

- Use namespaces for your aliases and your classes. This will help avoiding
  collisions with other scripts and addons.

- Remember that your addon is going to be installed on different platforms (at
  least Linux, macOS and Windows based). The poor Windows' notepad has serious problems
  with reading text files that contain only linefeeds as line separators.
  You could consider using a proper editor like e.g. Notepad++


9. WHERE TO START

It is a good idea to start on the KVIrc web site. There are surely several addons to
look at. Pick one that seems simple and analyze its layout and code (wow... the free
software!). It will be easier to do than it was to explain it :D

Another great resource place is the IRC channel #kvirc located on irc.freenode.org
network. There you can find many people able to code and help you.

Have fun! :)

Elvio Basello
