Skip to main content

Overview

Every OpenTrack plugin must provide metadata through the Metadata class. This includes the plugin’s display name and icon that appear in the user interface.

Interface Definition

class Metadata : public TR, public Metadata_
{
    Q_OBJECT
public:
    Metadata();
    ~Metadata() override;
    
    virtual QString name() = 0;  // Plugin display name
    virtual QIcon icon() = 0;    // Plugin icon
};

Base Classes

Metadata_

class OTR_API_EXPORT Metadata_
{
public:
    Metadata_();
    virtual ~Metadata_();
    
    virtual QString name() = 0;
    virtual QIcon icon() = 0;
};
The base interface that defines the required methods.

TR

Provides translation support through Qt’s internationalization system. Inherit from this to enable tr() function for translatable strings.

Methods

name()

virtual QString name() = 0;
Returns the human-readable name of the plugin.
return
QString
The plugin name displayed in the UI dropdown menus
Guidelines:
  • Use descriptive, user-friendly names
  • Keep names concise (prefer “Easy Tracker” over “Easy Tracker Version 1.1”)
  • Use tr() for internationalization support
  • Include version numbers only if multiple versions exist
Examples:
QString Metadata::name() 
{ 
    return tr("Easy Tracker 1.1"); 
}

icon()

virtual QIcon icon() = 0;
Returns the plugin’s icon for display in the UI.
return
QIcon
A QIcon object, or empty icon if none available
Guidelines:
  • Use 16x16 or 32x32 PNG images for best results
  • Store icons in Qt resource files (.qrc)
  • Return QIcon() (empty) if no icon available
  • Use consistent icon style within plugin family
Icon resource setup:
  1. Create resource file (plugin.qrc):
<RCC>
    <qresource prefix="/">
        <file>Resources/icon.png</file>
    </qresource>
</RCC>
  1. Add to CMakeLists.txt:
opentrack_boilerplate(
    opentrack-tracker-myplugin
    SOURCES tracker.cpp tracker.h
    RESOURCES plugin.qrc
)
  1. Reference in code:
QIcon icon() override 
{ 
    return QIcon(":/Resources/icon.png"); 
}
Examples:
QIcon icon() override
{
    return QIcon(":/images/filter-16.png");
}

Complete Implementation

#pragma once
#include "api/plugin-api.hpp"

class MyTrackerMetadata : public Metadata
{
    Q_OBJECT
public:
    QString name() override { return tr("My Tracker"); }
    QIcon icon() override { return QIcon(":/images/mytracker.png"); }
};

Plugin Registration

The metadata class is used in plugin registration macros:

Tracker Registration

OPENTRACK_DECLARE_TRACKER(tracker_class, dialog_class, metadata_class)
Example:
OPENTRACK_DECLARE_TRACKER(EasyTracker::Tracker, 
                          EasyTracker::Dialog, 
                          EasyTracker::Metadata)

Protocol Registration

OPENTRACK_DECLARE_PROTOCOL(protocol_class, dialog_class, metadata_class)
Example:
OPENTRACK_DECLARE_PROTOCOL(freetrack, 
                           FTControls, 
                           freetrackDll)

Filter Registration

OPENTRACK_DECLARE_FILTER(filter_class, dialog_class, metadata_class)
Example:
OPENTRACK_DECLARE_FILTER(accela, 
                         dialog_accela, 
                         accelaDll)

Registration Macro Details

What the Macros Do

The registration macros expand to export three C functions:
extern "C"
{
    OTR_PLUGIN_EXPORT ITracker* GetConstructor(void);
    OTR_PLUGIN_EXPORT Metadata_* GetMetadata(void);
    OTR_PLUGIN_EXPORT ITrackerDialog* GetDialog(void);
}
These functions are called by OpenTrack to:
  1. GetMetadata(): Query plugin name/icon for UI display
  2. GetConstructor(): Create plugin instance when selected
  3. GetDialog(): Create settings dialog when configured

Macro Definition

#define OPENTRACK_DECLARE_PLUGIN_INTERNAL(ctor_class, ctor_ret_class, \
                                          metadata_class, dialog_class, \
                                          dialog_ret_class) \
    extern "C" \
    { \
        OTR_PLUGIN_EXPORT ctor_ret_class* GetConstructor(void) \
        { \
            return new ctor_class; \
        } \
        OTR_PLUGIN_EXPORT Metadata_* GetMetadata(void) \
        { \
            return new metadata_class; \
        } \
        OTR_PLUGIN_EXPORT dialog_ret_class* GetDialog(void) \
        { \
            return new dialog_class; \
        } \
    }

Example Metadata Classes

namespace EasyTracker
{
    class Metadata : public ::Metadata
    {
        Q_OBJECT
    public:
        QString name() override 
        { 
            return tr("Easy Tracker 1.1"); 
        }
        
        QIcon icon() override 
        { 
            return QIcon(":/Resources/easy-tracker-logo.png"); 
        }
    };
}

OPENTRACK_DECLARE_TRACKER(EasyTracker::Tracker,
                          EasyTracker::Dialog,
                          EasyTracker::Metadata)

Translation Support

To support multiple languages, use Qt’s translation system:

1. Mark Strings for Translation

QString name() override
{
    return tr("My Plugin");  // Translatable
}

2. Create Translation Files

Create .ts files for each language:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
    <context>
        <name>MyPluginMetadata</name>
        <message>
            <source>My Plugin</source>
            <translation>Mein Plugin</translation>
        </message>
    </context>
</TS>

3. Add to Build System

opentrack_boilerplate(
    opentrack-tracker-myplugin
    SOURCES tracker.cpp
    TRANSLATIONS lang/de_DE.ts lang/fr_FR.ts
)

Best Practices

  • Be descriptive: “Point Tracker” not “PT”
  • User-friendly: “Easy Tracker” not “tracker-easy”
  • Consistent: Match naming style of existing plugins
  • Versioned: Include version if multiple versions exist
// Good
return tr("Easy Tracker 1.1");
return tr("Accela");

// Less good
return tr("tracker_easy_v1");
return tr("ACCELA_FILTER");
  • Size: 16x16 or 32x32 pixels
  • Format: PNG with transparency
  • Style: Simple, recognizable shapes
  • Color: Match OpenTrack’s color scheme
  • Fallback: Return empty QIcon() if none available
// Prefer embedded resources
QIcon icon() override
{
    return QIcon(":/images/icon.png");
}

// OK to have no icon
QIcon icon() override
{
    return QIcon();
}
  • Metadata class can have any name
  • Common patterns:
    • <PluginName>Metadata
    • <PluginName>Dll (legacy)
    • Metadata in plugin namespace
// Pattern 1: Suffixed
class MyTrackerMetadata : public Metadata { };

// Pattern 2: Legacy style
class myTrackerDll : public Metadata { };

// Pattern 3: Namespaced
namespace MyTracker {
    class Metadata : public ::Metadata { };
}

Common Issues

Common pitfalls when implementing metadata:

Missing Q_OBJECT Macro

// WRONG: Missing Q_OBJECT
class MyMetadata : public Metadata
{
public:
    QString name() override { return "My Plugin"; }
};

// CORRECT: Includes Q_OBJECT
class MyMetadata : public Metadata
{
    Q_OBJECT  // Required for Qt meta-object system
public:
    QString name() override { return "My Plugin"; }
};

Not Using tr() for Translation

// WRONG: Hard-coded string
QString name() override { return "My Plugin"; }

// CORRECT: Translatable string
QString name() override { return tr("My Plugin"); }

Invalid Icon Path

// WRONG: File path instead of resource path
QIcon icon() override { return QIcon("images/icon.png"); }

// CORRECT: Qt resource path
QIcon icon() override { return QIcon(":/images/icon.png"); }

See Also