Imported from Prabhu-PhD/BKT_English (
AGENTS.md). Install upstream withnpx skills add Prabhu-PhD/BKT_English. Copyright stays with the author.
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Overview
BKT (Business Kasper Toolbox) is an Office COM add-in framework for PowerPoint, Excel, Word, Outlook, and Visio. The project uses a hybrid architecture where a C# COM add-in hosts an IronPython environment that dynamically generates the Office ribbon UI and handles all callbacks.
Key Architecture Principle: The C# add-in (dotnet/bkt-addin/BKT/AddIn.cs) loads IronPython and executes bkt/bootstrap.py, which creates the Python add-in. Most functionality is implemented in Python for easier customization.
Repository Structure
bkt-framework/
dotnet/ # C# COM add-in
bkt-addin/ # Main COM add-in (builds BKT.dll)
bkt-dev-addin/ # Development add-in for runtime reload
bkt.sln # Visual Studio solution
bkt/ # Core Python framework
bootstrap.py # Entry point from C# (creates AddIn)
addin.py # Main AddIn class and callback management
ribbon.py # Ribbon control definitions
apps.py # Application-specific callbacks
context.py # Context management for callbacks
library/ # Helper libraries for Office automation
features/ # Application-specific feature modules
toolbox/ # PowerPoint toolbox (main feature)
bkt_excel/ # Excel-specific features
bkt_visio/ # Visio-specific features
devkit/ # Developer tools
bin/ # Compiled binaries and IronPython runtime
installer/ # Installation scripts
modules/ # Optional Python modules
config.txt # Main configuration file
Architecture Flow
-
Startup Sequence:
- Office loads C# COM add-in (dotnet/bkt-addin/BKT/AddIn.cs)
- C# creates IronPython engine and executes bkt/bootstrap.py
bootstrap.create_addin()returns PythonAddIninstanceAddIn.on_create()loads features fromconfig.txt- Features are loaded via
__bkt_init__.pyfiles (new) or__init__.py(legacy)
-
Feature Loading:
- Each feature folder contains
__bkt_init__.pydefining aBktFeatureclass - Features declare
relevant_apps(e.g., "Microsoft PowerPoint") - Features can declare
dependenciesandconflictswith other features - Feature loading is cached to speed up subsequent starts
- Each feature folder contains
-
UI Generation:
- Python generates CustomUI XML dynamically via bkt/ribbon.py
- C# retrieves XML via
python_delegate.get_custom_ui(ribbon_id) - XML is cached in
<root>/resources/xml/for async startup
-
Callback Flow:
- Office fires ribbon callbacks to C# methods (e.g.,
PythonOnAction) - C# delegates to Python
AddIn._callback(callback_type, control, *args) - Python resolves callback via
CallbackManagerand invokes Python method - Context is resolved (application, selection, etc.) and passed to callback
- Office fires ribbon callbacks to C# methods (e.g.,
Building and Development
Build Commands
Build C# add-in:
cd dotnet
build.bat # Build for Office 2013+
build2010.bat # Build for Office 2010
build_debug.bat # Build debug version
The build script compiles dotnet/bkt.sln and copies binaries to bin/.
Installation
Install for development:
cd installer
install.bat # Standard install
install_do_not_disable.bat # Install without disabling other add-ins
Reload add-in at runtime:
- Enable BKT Dev Plugin in Office Add-Ins dialog
- Use Dev Plugin ribbon controls to reload without restarting Office
Configuration
Main config: config.txt
Key settings:
ironpython_root: Path to IronPython binaries (usuallybin/)ipy_addin_path: Path to framework rootfeature_folders: List of feature folders to loadlog_write_file: Enable file logging (bkt-debug-py.log)log_level: Logging level (DEBUG, INFO, WARNING)async_startup: Load Python asynchronously for faster Office startshow_exception: Show exception message boxes
Testing and Debugging
Enable debug mode: Set in config.txt:
log_write_file = True
log_level = DEBUG
show_exception = True
Log files:
bkt-debug-<MMDD>.log- C# log (in framework root)bkt-debug-py.log- Python log (in framework root)
Python debugging with PyDev:
pydev_debug = True
pydev_codebase = <path-to-eclipse>/plugins/org.python.pydev_<version>/pysrc
Creating New Features
Feature Structure
Create a feature folder with this structure:
features/my_feature/
__bkt_init__.py # Required: Feature declaration
__init__.py # Optional: Legacy support
my_module.py # Feature implementation
resources/ # Optional: Images, XAML, etc.
images/
xaml/
Example bkt_init.py
class BktFeature(object):
name = "My Feature Name"
relevant_apps = ["Microsoft PowerPoint"] # or Excel, Word, etc.
dependencies = [] # Other feature names required
conflicts = [] # Conflicting feature names
@staticmethod
def contructor():
# Import and register UI elements
from . import my_module
Registering UI Elements
Features typically register ribbon tabs, groups, and controls in their modules using the BKT framework:
import bkt
from bkt.library.powerpoint import PowerPointApplication
# Define ribbon controls
my_group = bkt.ribbon.Group(
label="My Feature",
children=[
bkt.ribbon.Button(
label="My Button",
on_action=bkt.Callback(my_callback_function),
get_enabled=bkt.Callback(lambda: True)
)
]
)
# Register with app UI
bkt.powerpoint.add_tab(
bkt.ribbon.Tab(
label="My Tab",
children=[my_group]
)
)
Key Modules and Classes
Core Framework (bkt/)
- bkt/addin.py:
AddInclass - main entry point, manages callbacks and lifecycle - bkt/ribbon.py: Ribbon control classes (
Button,Group,Tab,Menu, etc.) - bkt/callbacks.py:
CallbackandCallbackTypes- callback definitions - bkt/context.py:
AppContext- provides Office application context to callbacks - bkt/apps.py:
AppCallbacks- application-specific event handling
PowerPoint Libraries
- bkt/library/powerpoint/helpers.py: PowerPoint automation helpers
- bkt/library/powerpoint/elements.py: Shape and slide abstractions
Excel Libraries
- bkt/library/excel/helpers.py: Excel automation helpers
- bkt/library/excel/model.py: Excel object model wrappers
Common Development Tasks
Adding a Ribbon Button
- Find or create appropriate module in feature folder
- Define button with callback in Python:
my_button = bkt.ribbon.Button( id="my_unique_button_id", label="My Button", supertip="Detailed description", on_action=bkt.Callback(my_function, shapes=True), get_enabled=bkt.Callback(lambda shapes: len(shapes) > 0, shapes=True) ) - Add button to group/menu in ribbon hierarchy
- Reload add-in via Dev Plugin or restart Office
Working with Office Objects
PowerPoint shapes:
def my_shape_function(shapes):
for shape in shapes:
shape.Width = 100
shape.Height = 100
Context injection: Use bkt.Callback decorators to inject Office objects:
shapes=True- Current shape selectionpresentation=True- Active presentationslide=True- Current slideapplication=True- Office Application object
Creating Dialog Windows
Use WPF XAML files with Python view models:
- Create XAML in
resources/xaml/my_dialog.xaml - Load in Python:
from bkt.ui import WpfWindowAbstract class MyDialog(WpfWindowAbstract): _xaml_path = 'my_dialog.xaml' def __init__(self): WpfWindowAbstract.__init__(self) # Initialize view model
Important Conventions
Naming
- Python modules: lowercase with underscores (e.g.,
my_module.py) - Ribbon IDs: lowercase with underscores (e.g.,
my_button_id) - Python callbacks: snake_case (e.g.,
my_callback_function) - C# methods: PascalCase (e.g.,
PythonOnAction)
Ribbon Control IDs
- Must be unique across all features
- Use prefix for feature-specific controls (e.g.,
toolbox_align_left) - Predefined Office controls use
idMsoattribute instead
Callback Context
Callbacks can request specific context via decorator parameters:
@bkt.Callback(shapes=True, presentation=True)
def my_callback(shapes, presentation):
# shapes and presentation are automatically injected
pass
Office Versions
- Office 2010: Requires special build with
OFFICE2010flag, no task pane support - Office 2013+: Full functionality including task panes
Build for Office 2010:
cd dotnet
build2010.bat
Troubleshooting
Add-in not loading
- Check Windows Event Viewer for COM errors
- Verify registry entries (see resources/registry/)
- Run
installer/register.batto re-register - Check Office Trust Center > Add-ins settings
Python errors
- Check
bkt-debug-py.logfor exceptions - Enable
show_exception = Truein config.txt for message boxes - Verify feature paths in config.txt are absolute and correct
- Clear import cache: delete cached entries or force reload
UI not updating
- Invalidate ribbon:
context.ribbon.Invalidate() - Check callback
get_enabled/get_visiblemethods - Verify control IDs are unique
- Reload add-in via Dev Plugin
Performance issues
- Disable verbose logging (
log_level = WARNING) - Enable
async_startup = Truefor faster Office start - Optimize callback
get_enabledmethods (cached frequently) - Use "fast enabled events" in C# for PowerPoint selection callbacks
Related Documentation
- GitHub Wiki: https://github.com/pyro-team/bkt-toolbox/wiki
- Office Ribbon XML Reference: https://docs.microsoft.com/en-us/office/vba/Library-Reference/Concepts/overview-of-the-office-fluent-ribbon
- IronPython Documentation: https://ironpython.net/documentation/
Language Note
Historically developed in German. Most UI labels and code comments may be in German. English documentation is being added progressively.