Skip to main content
Skip table of contents

SDK Guide (SPC UI Plugin)

Smart Print Controller v4.10.6296.0, Copyright (c) 2023 Global Graphics Software. All rights reserved.

Overview

The app automatically loads a collection of plugin DLLs upon launch. These plugins extend the application's UI and influence its runtime behavior. They allow customers to track the status of their output hardware, import jobs using custom mechanisms, display their own UI content, and more.

Plugins for the app are typically written in C# and utilize Microsoft's Managed Extensibility Framework (MEF), although most details are hidden by the app's API. Each plugin must provide a human-readable name, icon, and a main WPF UI control.

For convenience, the app includes a TemplateProject project that serves as a starting point for developing new UI plugins. See below for more details.

Getting Started

Interfaces: IBasicJobInfo, IExtendedConfigTokenSource, IJobNotifier, IPlugin, IPluginContext, IJobInfo, IOpcModel
Classes: IconOverlayUiSource, LazyImageSourceToImageSourceConverter, PluginBase, PluginLogger, SettingsKey, TemplatePlugin, TemplateViewModel, WebPlugin

Installing a Plugin

The app requires plugins to be located in the following directory:

C:\Program Files\Global Graphics Software Ltd\Smart Print Controller\UiPlugins

To install a plugin, follow these steps:

  1. Create a new folder within the UiPlugins directory with a unique name.

  2. The folder name and the prefix of the plugin DLL must match.
    For example, if your plugin DLL is named WebViewPane.UiPlugin.dll, create a folder named WebViewPane.

  3. Place your plugin DLL inside the created folder.

  4. If your plugin requires additional files, you can include them within or below the plugin folder.
    Note that the app ignores any files other than the plugin DLL itself.

Note It is recommended to install plugins using the main application installer or a plugin-specific installer. If you manually copy files into the plugin folder, Windows may block DLLs that it considers potentially downloaded from the internet. In such cases, you can unblock the DLLs using a PowerShell prompt or by right-clicking on the file, selecting Properties, and unblocking it.

Take care to ensure the proper installation of plugins to avoid any issues.

Creating a new UI Plugin

  1. Create a new Visual Studio C# Class Library (.NET Framework) project targeting .NET Framework 4.7.x

  2. Edit the project properties to set the Assembly name to include a .UiPlugin suffix. (Only DLLs of the form *.UiPlugin.dll are loaded by the app.)

  3. Reference the following system assemblies:

    • PresentationCore

    • PresentationFramework

  4. Reference the following app assemblies (found in the app installation folder):

    • MaterialDesignThemes.Wpf.dll

    • CSharp.Framework.dll

    • CSharp.OPCUAServer.dll

    • CSharp.Wpf.dll

    • CSharp.Wpf.MaterialDesign.dll

    • Spc.UiPlugin.dll This provides access to the app's IPlugin interface, which UI plugins must implement in order to be loaded by the app.

  5. In some circumstances, these assemblies may also need to be referenced:

    • CSharp.HarlequinDirect.App.dll

    • CSharp.PrinterProfile.dll

For convenience, we recommend sub-classing PluginBase which implements IPlugin and defines a sensible set of default behavior for the majority of plugins. (See the WebPlugin equivalent for HTML-based plugins.)

Here is a minimal example of a UI plugin:

CODE
using Spc.UiPlugin;
using System.ComponentModel.Composition;
using System.Windows.Controls;
using CSharp.Framework;
using CSharp.OPCUAServer.Model;
using CSharp.Wpf.MaterialDesign;

namespace Template
{
    [Export(typeof(IPlugin))]
    public class TemplatePlugin : PluginBase
    {
        private UserControl m_uiComponent;

        internal TemplateViewModel ViewModel { get; private set; }

        public override string Name => "Custom Plugin";
        public override string Icon => PackIconKind.Tune.ToString();
        public override UserControl UiComponent => m_uiComponent ??= new TemplateView();

        public override PaneLocation PaneLocation => PaneLocation.InputArea;

        public override bool Init(IPluginContext pluginContext)
        {
            ViewModel = new TemplateViewModel(pluginContext.DialogService, pluginContext.OpcModel, Logger);
            UiComponent.DataContext = ViewModel;
            return true;
        }
    }
}
  • The [Export(typeof(IPlugin))] line indicates that the class represents a UI plugin that should be loaded by the app.

  • The Name property must return a user-visible plugin name.

  • The Icon property must return the name of a valid Material Design icon.

  • The UiComponent must return a WPF UserControl containing the main plugin UI.

  • PaneLocation provides a hint to the app as to where the plugin icon should be located.

  • The Init() method will be called by the app when the plugin is loaded.

In the example above, we create an MVVM view model and pass it a reference to the DialogService (allowing for the presentation of UI prompts, message boxes, and user queries), OpcModel (the OPC data model), and the Logger object (allowing plugins to add messages into the app's log). Real-world implementations will vary.

NOTE The example leaves the TemplateView and TemplateViewModel classes undefined. Implementing these is a plugin-specific task.

Once a successful build has been made, the plugin DLL must be copied under the app installation folder, as described above. Launching the app will load the new UI plugin, making it visible on the left-hand side of the application window, and the app log file will contain a line similar to: [UiPlugin:Custom Plugin] Successfully loaded.

For more details, see the IPlugin documentation.

Creating a UI Plugin from TemplateProject.

You can use the TemplateProject source code (TemplatePluginSource.zip) as a starting point for creating a UI plugin. The TemplateProject provides default values for various properties like name, icon, etc., and includes a simple UI control. It also references many of the required assemblies by default.

To create a UI plugin from the TemplateProject, follow these steps:

  1. Extract the contents of the TemplatePluginSource.zip file.

  2. Open the extracted project in Visual Studio.

  3. Modify the source code to meet your specific requirements. Customize the name, icon, and UI components of the plugin.

  4. Follow the previous section's instructions to build and install the plugin.

See Installing a Plugin, TemplatePlugin

Accessing the OPC Model

IPluginContext's OpcModel property provides access to the app's OPC model (IOpcModel) - A collection of state relating to the entire application, mirroring the data model exposed over the OPC interface.

The UI plugin can use this object to:

  • Monitor the active job.

  • Manipulate the Waiting queue.

  • Control the print run.

  • Get details about the current/available media.

  • Get details about the RIP Servers.

  • ...and more.

Each IOpcModel property is an MVVM view model, making it simple to bind WPF UI control values to the required source. Changes to state can be detected from the code by subscribing to the INotifyPropertyChanged.PropertyChanged event.

See the OPC API Documentation for more information.

API

Interfaces

IBasicJobInfo

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin.Jobs
Extends: IDisposable, IJobInfo, IJobReference, ITrackedDisposable

Description

Interface defining the properties for a single job file (Extending IJobInfo).

Properties

Name

Type

Writable

Description

HasLiLoEnabled

bool

No

Whether the job has lead in pages and/or lead out pages received from the .complete file.

IsLocked

bool

Yes

Whether modifying operations (changes to copy count, job editor, ...) are allowed or not.

JobId

string

Yes

The job ID received from the .complete file.

JobLabel

string

Yes

Property the User can use to group Jobs.

JobPartId

string

Yes

The job part ID received from the .complete file.

LeadInThumbnail

ILazyImageSource

No

A lazy-loaded lead in page thumbnail. Only created for LILO jobs.

See also: LazyImageSourceToImageSourceConverter

LeadOutThumbnail

ILazyImageSource

No

A lazy-loaded lead out page thumbnail. Only created for LILO jobs.

See also: LazyImageSourceToImageSourceConverter

TargetMediaName

string

Yes

The intended media to use when printing the job.

Thumbnail

ILazyImageSource

No

A lazy-loaded job thumbnail.

See also: LazyImageSourceToImageSourceConverter

IExtendedConfigTokenSource

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin.Commands

Description

Interface allowing UI plugins to provide token values than can be found/replaced in a config file.

Any IPlugin-based objects which implement this interface may define their own tokens in SPC's config file templates.

When SPC processes a config file template with an unknown token (E.g. $CustomToken$) UI plugins implementing IExtendedConfigTokenSource will be enumerated, allowing the Get() method to provide a plugin-specific value.

Methods

Name

Description

object Get(string name, IConfigTokens parentSource)

Called when applying settings to a config template.

name - The name of the token.
parentSource - The default IConfigTokens source. (May be null)

Returns: Implementations must return a value for the specified token, or null if not handled.

IJobNotifier

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin

Description

Allows access to job-level events as they are being processed in the Print Queue.

Made available to the UI plugin via IPluginContext.

Events

Name

Description

JobCompleted

Called when a job has completed processing in the Print Queue, regardless of the final job status.

See also: IBasicJobInfo

JobStarted

Called when a job has started processing in the Print Queue.

See also: IBasicJobInfo

IPlugin

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin
See also: PluginBase, WebPlugin

Description

The base interface for any SPC UI plugin.

SPC will load any suitable IPlugin-based classes at start-up, reporting success/failure in the application log. The Init() method will be called early in the load cycle, allowing the plugin to initialize any state it requires. Implementations which implement IDisposable will be disposed when SPC is shut down.

Consider using PluginBase as a base class for any new custom plugins (or WebPlugin for HTML-based plugins).

Properties

Name

Type

Writable

Description

CanVisitWithUnsavedSettings

bool

No

Whether the pane can be displayed when modified settings have yet to be 'Applied' by the user.

CustomSettings

Dictionary<SettingsKey,object>

Yes

A collection of non-persistent settings optionally populated with plugin-specific content. Each setting is identified by a SettingsKey. Any key defining a UI-visible name will be made visible in the Engineer pane's plugin settings tab.

EnableWithExternalControl

bool

No

Whether the pane UI should be enabled when external OPC control is active. (false by default.)

Icon

string

No

The plugin icon displayed in the SPC UI. This much match an icon name defined in PackIconKind (from MaterialDesignThemes.Wpf.dll)

Logger

IBasicLogger

Yes

Provides access the message logger, allowing plugins to add messages into SPC's log.

Name

string

No

The plugin name displayed in the SPC UI.

PaneLocation

PaneLocation

No

Implementations must return the location at which their plugin icon will appear in the SPC UI.

Values: InputArea, OutputArea, SettingsArea, AfterNative, None

PluginDir

DirectoryInfo

Yes

The directory containing this plugin (Automatically set by SPC).

UiComponent

UserControl

No

Implementations must return a UserControl for the content displayed within the plugin pane.

See also: IUiControlSource, IEngineerMediaTabSource

UiControlSources

IEnumerable<IUiControlSource>

No

A collection of objects used to inject UI content in the main application. (e.g. IconOverlayUiSource)

Methods

Name

Description

bool Init(IPluginContext pluginContext)

Called by SPC to allow the plugin to initialize any state it requires.

pluginContext - Application context.

Returns: true if the plugin has initialized and should be loaded in the UI.

void OnStoppingPrinting(bool isPrintingDetected)

Called when a request to stop the print run is triggered.

isPrintingDetected - true if anything was printed during the print run.

IPluginContext

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin

Description

Holds state which allows a UI plugin to interact with the SPC application.

Provided to the UI plugin when SPC calls its IPlugin.Init() method.

We recommend plugins use OpcModel as a source of information whenever possible.

Properties

Name

Type

Writable

Description

Branding

IBranding

No

An interface that sets the branding of the app (such as product name and colors) and provides access to commonly used directories.

DialogService

IMaterialDesignDialogService

No

Allows for the presentation of UI prompts, message boxes, and user queries.

JobNotifier

IJobNotifier

No

An interface that notifies plugins of job-level events.

MessageController

IMessageController

No

An object responsible for displaying snackbar messages at the bottom of the SPC UI.

MultiPrinterInterface

IMultiPrinterInterface

No

Allows access to the collection of RIP Servers in use by SPC.

Mutable

IMutable

No

An object allowing detection of 'pending' changes made by the user in the SPC UI.

OpcModel

IOpcModel

No

Collection of state relating to the entire application, mirroring the data model exposed over the OPC interface.

See the OPC API Documentation for more information.

PageSetupViewModel

IPageSetupViewModel

No

An interface allowing access to page setup properties.

ProfileSource

IProfileSource

No

An interface allowing access to the active printer profile.

ThumbnailDirectory

DirectoryInfo

No

The directory where thumbnails for jobs are stored.

WaitingQueueJobs

IEnumerable<IBasicJobInfo>

No

A read-only collection of jobs currently held in the Waiting Queue.

IJobInfo

Assembly: CSharp.HarlequinDirect.App.dll
Namespace: CSharp.HarlequinDirect.App
Extends: IDisposable, IJobReference, ITrackedDisposable
See also: JobInfoBase

Description

Interface defining the properties for a single job file.

Properties

Name

Type

Writable

Description

CopyCount

int

Yes

The number of copies of the job to print.

CustomPostScript

string

Yes

Property the OEM can use to pass custom PostScript to override default behavior.

EndTime

DateTime

No

The time at which the job finished printing.

ExpectedStatusCount

int

Yes

JobTag

string

Yes

Property the OEM can use to pass arbitrary job data to Harlequin Direct.

LeadInCount

int

Yes

The lead in page count received from the .complete file.

LeadOutCount

int

Yes

The lead out page count received from the .complete file.

LocalFile

FileInfo

Yes

OriginalPageHeightMm

double?

Yes

The height of the original/unprocessed job pages, if known. For multi-page jobs, this is set from the first page.

OriginalPageWidthMm

double?

Yes

The width of the original/unprocessed job pages, if known. For multi-page jobs, this is set from the first page.

PageCount

int

Yes

The number of pages in the job to print (Unaffected by CopyCount).

RemoteFiles

List<FileInfo>

No

RipAheadRemoteFileSpecs

List<string>

No

RipMode

RipMode

Yes

StartTime

DateTime

No

The time at which the job started printing.

Statistics

JobStatistics

No

Status

JobStatus

Yes

The current status of the job.

Methods

Name

Description

void SetStatus(JobStatus status)

IOpcModel

Assembly: CSharp.OPCUAServer.dll
Namespace: CSharp.OPCUAServer.Model
See also: OpcModel

Description

A representation of the SPC OPC UA data model.

See the OPC API Documentation for more information.

Properties

Name

Type

Writable

Description

ActiveJob

OpcActiveJobNode

No

State relating to the currently active job.

ActiveMedia

OpcActiveMedia

No

State relating to the currently active media.

AllJobs

OpcAllJobsNode

No

State relating to all jobs in the Waiting/Print/Completed queues. This tree dynamically includes children named from the GUID of each known job.

AllMedia

OpcAllMedia

No

State relating to all available media.

App

OpcApp

No

State relating to the entire application.

JobCosting

OpcJobCosting

No

State relating to job cost estimation.

PrintBarGroups

OpcPrintBarGroups

No

State relating to the active print bars.

PrinterProfile

OpcPrinterProfile

No

State relating to the active printer profile.

PrintRun

OpcPrintRun

No

State relating to the print run.

PrintRunConfig

OpcPrintRunConfig

No

State relating to the print configuration (Applies to both media sides).

Servers

OpcServerCollection

No

State relating to the collection of RIP Servers.

ServiceRip

OpcServiceRip

No

State relating to the offline Service RIP.

StreamlineDirect

OpcStreamline

No

State relating to Streamline Direct technology.

WaitingQueueOptions

OpcWaitingQueueOptions

No

State relating to the behavior of the Waiting queue.

Classes

IconOverlayUiSource

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin
Extends: IUiControlSource

Description

Represents a UI component that is overlaid on top of a plugin's pane icon.

Properties

Name

Type

Writable

Description

Overlay

FrameworkElement

No

The UI object to overlay over the plugin's pane icon.

LazyImageSourceToImageSourceConverter

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin.Converters

Description

A WPF IValueConverter implementation that simplifies displaying job thumbnails in the UI.

For example: <Image Source="{Binding Thumbnail, Converter={Converters:LazyImageSourceToImageSourceConverter}}"/>

See also: IBasicJobInfo

Methods

Name

Description

object Convert(object value, Type targetType, object parameter, CultureInfo culture)

Convert an ILazyImageSource to a WPF ImageSource.

PluginBase

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin
Extends: IPlugin

Description

Base class for UI plugins. Consider using this as a base class for any new custom plugins.

SPC will load any suitable IPlugin-based classes at start-up, reporting success/failure in the application log. The Init() method will be called early in the load cycle, allowing the plugin to initialize any state it requires. Implementations which implement IDisposable will be disposed when SPC is shut down.

Consider using PluginBase as a base class for any new custom plugins (or WebPlugin for HTML-based plugins).

Custom Settings Feature

Plugins can now define custom settings using the CustomSettings property, a dictionary where each setting is identified by a SettingsKey. Each SettingsKey consists of a unique key and an optional UI-visible string. This allows you to expose plugin settings directly in the application's user interface (e.g., the Engineer pane's plugin settings tab).

To define a Custom Setting:

  • Use the CustomSettings dictionary to define your plugin's settings during initialization or runtime.

  • For example: CustomSettings[new SettingsKey("_EnableFeature", "Enable Feature")] = true;

Events

Name

Description

CustomSettingsChanged

Properties

Name

Type

Writable

Description

CanVisitWithUnsavedSettings

bool

No

Whether the pane can be displayed when modified settings have yet to be 'Applied' by the user.

CustomSettings

Dictionary<SettingsKey,object>

Yes

A collection of non-persistent settings optionally populated with plugin-specific content. Each setting is identified by a SettingsKey. Any key defining a UI-visible name will be made visible in the Engineer pane's plugin settings tab.

EnableWithExternalControl

bool

No

Whether the pane UI should be enabled when external OPC control is active. (false by default.)

Icon

string

No

The plugin icon displayed in the SPC UI. This much match an icon name defined in PackIconKind (from MaterialDesignThemes.Wpf.dll)

Logger

IBasicLogger

Yes

Provides access the message logger, allowing plugins to add messages into SPC's log.

Name

string

No

The plugin name displayed in the SPC UI.

PaneLocation

PaneLocation

No

Implementations must return the location at which their plugin icon will appear in the SPC UI.

Values: InputArea, OutputArea, SettingsArea, AfterNative, None

PluginDir

DirectoryInfo

Yes

The directory containing this plugin (Automatically set by SPC).

UiComponent

UserControl

No

Implementations must return a UserControl for the content displayed within the plugin pane.

See also: IUiControlSource, IEngineerMediaTabSource

UiControlSources

IEnumerable<IUiControlSource>

No

A collection of objects used to inject UI content in the main application. (e.g. IconOverlayUiSource)

Methods

Name

Description

bool Init(IPluginContext pluginContext)

Called by SPC to allow the plugin to initialize any state it requires.

pluginContext - Application context.

Returns: true if the plugin has initialized and should be loaded in the UI.

void OnStoppingPrinting(bool isPrintingDetected)

Called when a request to stop the print run is triggered.

isPrintingDetected - true if anything was printed during the print run.

void RaiseCustomSettingsChanged(string key)

PluginLogger

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin
Extends: IBasicLogger

Description

Allows UI plugins to log application messages.

Made available to the UI plugin via IPluginContext.

Methods

Name

Description

void Error(string message)

Write an error-level message to the SPC log.

void Exception(Exception ex)

Write a formatted C# exception message to the SPC log.

void Info(string message)

Write an information-level message to the SPC log.

void Warn(string message)

Write a warning-level message to the SPC log.

SettingsKey

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin

Description

Represents a unique key for plugin settings, with optional support for user-visible names.

Properties

Name

Type

Writable

Description

Key

string

No

The internal dictionary key name.

UiString

string

No

The optional user interface string associated with the key.

Methods

Name

Description

bool Equals(object obj)

int GetHashCode()

string ToString()

TemplatePlugin

Assembly: Template.UiPlugin.dll
Namespace: Template
Extends: IDisposable, IPlugin

Description

An example implementation of a 'starting point' UI plugin.

SPC will load any suitable IPlugin-based classes at start-up, reporting success/failure in the application log. The Init() method will be called early in the load cycle, allowing the plugin to initialize any state it requires. Implementations which implement IDisposable will be disposed when SPC is shut down.

Consider using PluginBase as a base class for any new custom plugins (or WebPlugin for HTML-based plugins).

Custom Settings Feature

Plugins can now define custom settings using the CustomSettings property, a dictionary where each setting is identified by a SettingsKey. Each SettingsKey consists of a unique key and an optional UI-visible string. This allows you to expose plugin settings directly in the application's user interface (e.g., the Engineer pane's plugin settings tab).

To define a Custom Setting:

  • Use the CustomSettings dictionary to define your plugin's settings during initialization or runtime.

  • For example: CustomSettings[new SettingsKey("_EnableFeature", "Enable Feature")] = true;

Properties

Name

Type

Writable

Description

Icon

string

No

The plugin icon displayed in the SPC UI. This much match an icon name defined in PackIconKind (from MaterialDesignThemes.Wpf.dll)

Name

string

No

The plugin name displayed in the SPC UI.

PaneLocation

PaneLocation

No

Implementations must return the location at which their plugin icon will appear in the SPC UI.

Values: InputArea, OutputArea, SettingsArea, AfterNative, None

UiComponent

UserControl

No

Implementations must return a UserControl for the content displayed within the plugin pane.

See also: IUiControlSource, IEngineerMediaTabSource

Methods

Name

Description

void Dispose()

Performs cleanup when the plugin is disposed.

bool Init(IPluginContext pluginContext)

Called by SPC to allow the plugin to initialize any state it requires.

pluginContext - Application context.

Returns: true if the plugin has initialized and should be loaded in the UI.

TemplateViewModel

Assembly: Template.UiPlugin.dll
Namespace: Template.ViewModels

Description

The MVVM view model backing the main UI control (TemplateView).

Properties

Name

Type

Writable

Description

ExampleText

string

No

WebPlugin

Assembly: Spc.UiPlugin.dll
Namespace: Spc.UiPlugin
Extends: IPlugin

Description

Base class for web-based UI plugins. Consider using this as a base class for any new HTML-based plugins.

A web-based UI plugin is one where the entire view is filled with a single control displaying the content of a web address.

The plugin Icon, Name, PaneLocation, and Url properties are obtained by parsing a JSON config file which must exist alongside the plugin DLL, with a name of the format <PluginName>.UiPlugin.json

For example:

CODE
	{
		"URL": ["https://globalgraphics.com", "ja:https://globalgraphics.com"],
		"Name": [ "Web View", "ja:Web View", "zh:网络视图" ],
		"Icon": ["Web"],
		"PaneLocation": "OutputArea"
	}

NOTE Locale-specific values can be specified using an array element with a valid prefix.

Properties

Name

Type

Writable

Description

CanVisitWithUnsavedSettings

bool

No

Whether the pane can be displayed when modified settings have yet to be 'Applied' by the user.

CustomSettings

Dictionary<SettingsKey,object>

Yes

A collection of non-persistent settings optionally populated with plugin-specific content. Each setting is identified by a SettingsKey. Any key defining a UI-visible name will be made visible in the Engineer pane's plugin settings tab.

EnableWithExternalControl

bool

No

Whether the pane UI should be enabled when external OPC control is active. (false by default.)

Icon

string

Yes

The plugin icon displayed in the SPC UI. This much match an icon name defined in PackIconKind (from MaterialDesignThemes.Wpf.dll)

Logger

IBasicLogger

Yes

Provides access the message logger, allowing plugins to add messages into SPC's log.

Name

string

Yes

The plugin name displayed in the SPC UI.

PaneLocation

PaneLocation

No

Implementations must return the location at which their plugin icon will appear in the SPC UI.

Values: InputArea, OutputArea, SettingsArea, AfterNative, None

PluginDir

DirectoryInfo

Yes

The directory containing this plugin (Automatically set by SPC).

UiComponent

UserControl

No

Implementations must return a UserControl for the content displayed within the plugin pane.

See also: IUiControlSource, IEngineerMediaTabSource

UiControlSources

IEnumerable<IUiControlSource>

No

A collection of objects used to inject UI content in the main application. (e.g. IconOverlayUiSource)

Url

string

Yes

Methods

Name

Description

bool Init(IPluginContext pluginContext)

Called by SPC to allow the plugin to initialize any state it requires.

pluginContext - Application context.

Returns: true if the plugin has initialized and should be loaded in the UI.

void OnStoppingPrinting(bool isPrintingDetected)

Called when a request to stop the print run is triggered.

isPrintingDetected - true if anything was printed during the print run.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.