Files
create/src/Gui/SDK/SDKRegistry.cpp
forbes 60c0489d73 feat(sdk): migrate editing context API to kcsdk (#351)
Add context/overlay registration, injection, query, and refresh to the
KCSDK C++ library and kcsdk pybind11 module.

New files:
- src/Gui/SDK/Types.h — ContextDef, OverlayDef, ContextSnapshot structs
  (plain C++, no Qt in public API)

Modified:
- src/Gui/SDK/SDKRegistry.h/.cpp — register_context/overlay, unregister,
  inject_commands, current_context, refresh (delegates to
  EditingContextResolver with std↔Qt conversion)
- src/Gui/SDK/CMakeLists.txt — add Types.h, link FreeCADGui
- src/Gui/SDK/bindings/kcsdk_py.cpp — bind all context functions with
  GIL-safe match callable wrapping and dict-based snapshot return
- mods/sdk/kindred_sdk/context.py — try kcsdk first, fall back to
  FreeCADGui for backwards compatibility
2026-03-01 14:42:00 -06:00

158 lines
5.0 KiB
C++

// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2025 Kindred Systems <development@kindred-systems.com> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "SDKRegistry.h"
#include <QString>
#include <QStringList>
#include <Base/Console.h>
#include <Gui/EditingContext.h>
namespace KCSDK
{
// -- Helpers: std ↔ Qt conversion (internal) --------------------------------
namespace
{
QString toQString(const std::string& s)
{
return QString::fromUtf8(s.data(), static_cast<int>(s.size()));
}
std::string fromQString(const QString& s)
{
QByteArray utf8 = s.toUtf8();
return std::string(utf8.constData(), utf8.size());
}
QStringList toQStringList(const std::vector<std::string>& v)
{
QStringList out;
out.reserve(static_cast<int>(v.size()));
for (const auto& s : v) {
out.append(toQString(s));
}
return out;
}
std::vector<std::string> fromQStringList(const QStringList& list)
{
std::vector<std::string> out;
out.reserve(list.size());
for (const auto& s : list) {
out.push_back(fromQString(s));
}
return out;
}
} // anonymous namespace
// -- Singleton --------------------------------------------------------------
SDKRegistry& SDKRegistry::instance()
{
static SDKRegistry reg;
return reg;
}
SDKRegistry::SDKRegistry()
{
Base::Console().log("KCSDK: registry initialized (API v%d)\n", API_VERSION_MAJOR);
}
SDKRegistry::~SDKRegistry() = default;
std::vector<std::string> SDKRegistry::available() const
{
std::lock_guard<std::mutex> lock(mutex_);
return {};
}
// -- Editing context API ----------------------------------------------------
void SDKRegistry::registerContext(const ContextDef& def)
{
Gui::ContextDefinition guiDef;
guiDef.id = toQString(def.id);
guiDef.labelTemplate = toQString(def.labelTemplate);
guiDef.color = toQString(def.color);
guiDef.toolbars = toQStringList(def.toolbars);
guiDef.priority = def.priority;
guiDef.match = def.match;
Gui::EditingContextResolver::instance()->registerContext(guiDef);
}
void SDKRegistry::unregisterContext(const std::string& id)
{
Gui::EditingContextResolver::instance()->unregisterContext(toQString(id));
}
void SDKRegistry::registerOverlay(const OverlayDef& def)
{
Gui::OverlayDefinition guiDef;
guiDef.id = toQString(def.id);
guiDef.toolbars = toQStringList(def.toolbars);
guiDef.match = def.match;
Gui::EditingContextResolver::instance()->registerOverlay(guiDef);
}
void SDKRegistry::unregisterOverlay(const std::string& id)
{
Gui::EditingContextResolver::instance()->unregisterOverlay(toQString(id));
}
void SDKRegistry::injectCommands(const std::string& contextId,
const std::string& toolbarName,
const std::vector<std::string>& commands)
{
Gui::EditingContextResolver::instance()->injectCommands(
toQString(contextId), toQString(toolbarName), toQStringList(commands));
}
ContextSnapshot SDKRegistry::currentContext() const
{
Gui::EditingContext ctx =
Gui::EditingContextResolver::instance()->currentContext();
ContextSnapshot snap;
snap.id = fromQString(ctx.id);
snap.label = fromQString(ctx.label);
snap.color = fromQString(ctx.color);
snap.toolbars = fromQStringList(ctx.toolbars);
snap.breadcrumb = fromQStringList(ctx.breadcrumb);
snap.breadcrumbColors = fromQStringList(ctx.breadcrumbColors);
return snap;
}
void SDKRegistry::refresh()
{
Gui::EditingContextResolver::instance()->refresh();
}
} // namespace KCSDK