Gå til innhold

Å skrive et innebygd programtillegg

Et minimalt innebygd programtillegg er én klasse, én fabrikkmakro, én JSON-fil og en kort CMakeLists.txt. Du kan skrive det helt utenfor arkivet mot programtillegg-SDK-et — det kreves ingen utsjekk av MTEs kildekode.

Innebygd eller Python?

Denne siden handler om innebygde C++-programtillegg (kompilert til en .dll/.so/.dylib og lastet inn av Qt-innlasteren). Vil du heller levere en mappe med .py-filer som redigereren starter som en underprosess, så se Python-programtillegg — samme PluginApi-flate, annen backend, ingen kompilator nødvendig.

Utkast

Denne gjennomgangen bygger på PLUGIN_ARCHITECTURE.md; kontroller det nøyaktige navnet på SDK-pakken og argumentene til mte_add_plugin() mot det leverte SDK-et før du bygger videre på dem.

1. Implementer IPlugin

#include <PluginApi/IPlugin.h>
#include <PluginApi/IPluginContext.h>

class HelloWorldPlugin : public MTE::plugin::IPlugin {
public:
    MTE::plugin::PluginInfo info() const override {
        return { "org.mte.helloworld", "Hello World", "1.0.0",
                 "Example Vendor", "Says hi.", MTE_PLUGIN_API_VERSION };
    }

    bool initialize(MTE::plugin::IPluginContext& ctx) override {
        m_cmd = ctx.commands().registerCommand(
            { "helloworld.sayHi", "Say Hi", "Ctrl+Alt+H", "Hello" },
            [&ctx] { ctx.log().log(MTE::plugin::LogLevel::Info, "Hi!"); });
        m_menu = ctx.menus().addItem("Plugins/Say Hi", "helloworld.sayHi");
        return true;
    }

    void shutdown() noexcept override {}   // tokens tear down automatically

private:
    MTE::plugin::CommandToken m_cmd;
    MTE::plugin::MenuToken    m_menu;
};

2. Eksporter fabrikken (den innebygde Qt-backenden)

#include <PluginApi/Qt/PluginQtGlue.h>

class HelloWorldFactory : public QObject, public MTE::plugin::IPluginFactory {
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.mte.IPluginFactory/1" FILE "plugin.json")
    Q_INTERFACES(MTE::plugin::IPluginFactory)
public:
    std::unique_ptr<MTE::plugin::IPlugin> create() override {
        return std::make_unique<HelloWorldPlugin>();
    }
};

3. Beskriv det i plugin.json

{
  "id":         "org.mte.helloworld",
  "name":       "Hello World",
  "version":    "1.0.0",
  "apiVersion": 1,
  "entry":      "native",
  "requires":   [],
  "order":      600,
  "menus": [
    { "title": "Plugins", "barPriority": 570, "itemPriority": 100 }
  ]
}

apiVersion her og den info() gir tilbake, må begge være lik MTE_PLUGIN_API_VERSION, ellers nekter verten å laste inn programtillegget.

To valgfrie nøkler hører med:

  • apiMinorVersion (standard 0) — den laveste minor-versjonen av vertens API som programtillegget ditt trenger. En vert med lavere MTE_PLUGIN_API_MINOR_VERSION viser programtillegget med «Krever en nyere versjon av OctoEdit» og laster det ikke inn. Verten sjekker denne manifestverdien før den laster inn noe, og deretter PluginInfo::apiMinorVersion fra info() én gang til — den er som standard minor-versjonen til headerfilene du kompilerte mot, så la den være med mindre du vet at du ikke bruker noe nyere. Se Versjonering.
  • requires (standard []) — ID-ene til programtillegg som ditt ikke kan virke uten, for eksempel ["org.mte.lsp"]. Bare ID-er: det finnes ikke noe versjonsområde og ingen valgfri form — et programtillegg ditt bare virker bedre sammen med, hører ikke hjemme her; snakk med det under kjøring gjennom hendelser og leverandørregistre. Redigeringsprogrammet initialiserer avhengighetene dine før deg, uansett hva order sier, og avslutter dem etter deg. Mangler en av dem, er den slått av, trenger den en lisens som ikke er aktiv, eller ble den ikke lastet inn, blir programtillegget ditt ikke lastet inn i det hele tatt, og Innstillinger ▸ Programtillegg sier hvilket programtillegg det trenger og hvorfor («Krever programtillegget LSP Provider, som er slått av»). En syklus blokkerer hvert programtillegg i den. Den samme nøkkelen betyr det samme i plugin.json for et Python-programtillegg.

Å kreditere medfølgende biblioteker — thirdParty

Leverer eller lenker programtillegget ditt en tredjepartskomponent, så erklær den i en valgfri thirdParty-tabell, så redigereren kan innfri kravene sine om kreditering:

"thirdParty": [
  { "name": "Qt WebEngine", "license": "LGPL-3.0",
    "url": "https://doc.qt.io/qt-6/qtwebengine-index.html",
    "file": "QtWebEngine-LGPLv3.txt" }
]

Hver post trenger et name (poster uten blir droppet); license, url og file er valgfrie. Programtillegget ditt eier lisenstekstene — lever dem ved siden av programtillegget under Plugins/Licenses/<your-plugin-id>/, der file er filnavnet. Vinduet Om viser thirdParty-komponentene til hvert installerte programtillegg og peker brukerne mot den mappen; kjernen bærer aldri et programtilleggs tredjepartstekster for det. (Det medfølgende HtmlPreviewPlugin, som legger inn QtWebEngine og Chromium, er referanseeksempelet.)

4. Bygg det

Bruk SDK-ets CMake-hjelper:

find_package(MTEPluginSDK REQUIRED)
mte_add_plugin(NAME HelloWorldPlugin
    SOURCES Src/HelloWorldPlugin.cpp
    # TRANSLATIONS Translations/HelloWorld_en.ts ...
)

Byggekrav

Et innebygd programtillegg lastes inn i redigererens prosess, så det må bygges med en verktøykjede som er binært forenlig med det redigererbygget det retter seg mot. Dette er kravene for den gjeldende utgaven (bygget med Qt 6.11.2):

Windows macOS
Kompilator Visual Studio 2022, MSVC-verktøysett 14.44 eller et eldre 14.x (VS 2015–2022 deler én C++-ABI); clang-cl virker også. Bygg med MinGW eller GCC kan ikke lastes inn. Apple clang fra Xcode (Xcode 27, Apple clang 21.0.0); bare arm64
Byggeoppsett Release, dynamisk kjøretidsbibliotek (/MD, CMakes standard). Et Debug-programtillegg avvises av innlasteren; et programtillegg med statisk kjøretidsbibliotek (/MT) krasjer når minne krysser programtilleggsgrensen Release; distribusjonsmål 14.4 (samme som redigereren)
Qt Qt 6.11, settet msvc2022_64. Et programtillegg som er bygget mot en eldre 6.x-underversjon, lastes inn; et som er bygget mot en nyere underversjon, gjør det kanskje ikke Qt 6.11, samme arkitektur
C++-standard C++20 (API-ets hodefiler bruker std::span og konsepter) C++20
CMake 3.16+ 3.16+
Programtillegg-API den MTE_PLUGIN_API_VERSION som fulgte med SDK-et for den redigererversjonen du retter deg mot samme

To følger er verdt å kjenne til på Windows:

  • Den Visual C++ Redistributable som er installert på brukerens maskin, må være minst like ny som det nyeste MSVC-verktøysettet som redigereren eller et innlastet programtillegg er bygget med. Bygger du programtillegget ditt med et verktøysett som er nyere enn redigererens, hever du det kravet for brukerne dine; bygger du med redigererens verktøysett eller et eldre, gjør du ikke det.
  • Den versjonen av Windows SDK du kompilerer mot, påvirker ikke foreneligheten med redigereren; den avgjør bare hvilke Windows-API-er programtillegget ditt kan kalle, og redigereren støtter Windows 10 1809 og senere.

Og på macOS:

  • Redigereren leveres bare som arm64; et programtillegg som bare er x86_64, kan ikke lastes inn (et universelt binærprogram er greit). Hold distribusjonsmålet på 14.4: et programtillegg som er bygget for en nyere laveste macOS, avvises av systemets innlaster på eldre Mac-er, og operativsystemets egen libc++ er kjøretidsmiljøet, så spørsmålet om et videredistribuerbart bibliotek oppstår ikke.
  • Vis til Qt-rammeverkene gjennom @rpath, så programtillegget bruker de kopiene som er lagt inn i OctoEdit.app. Qt-sett der rammeverkene bærer absolutte installasjonsnavn (Homebrews, for eksempel), krever install_name_tool på det bygde programtillegget før det leveres; ellers leter programtillegget etter Qt på byggemaskinens sti.

Ingenting av dette gjelder Python-programtillegg: de kjører i en egen prosess og deler ingen binær grenseflate med redigereren.

5. Installer og kjør

Enten pakker du det bygde biblioteket og plugin.json som en zip ved navn <name>.mteplugin og installerer den via Innstillinger ▸ Programtillegg ▸ Installer programtillegg... (pakken kontrolleres — manifestet, arkivets sikkerhet og programfilens innebygde metadata — før noe som helst røres), eller så legger du filene i en oppdaget programtilleggsmappe for hånd (se Arkitekturoversikt). Start redigereren på nytt, og slå programtillegget på under Innstillinger ▸ Programtillegg om nødvendig.

Videre herfra