diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ae90886eff..7459bac1b3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: VisualStudioEdition: 'Microsoft Visual Studio 2022' PluginPackedPath : '%AppData%\Trados\Trados Studio\19\Plugins\Packages\' PluginUnpackedPath: '%AppData%\Trados\Trados Studio\19\Plugins\Unpacked\' - InstallationFolder: 'C:\Program Files (x86)\Trados\Trados Studio\Studio19' + InstallationFolder: 'C:\Program Files\Trados\Trados Studio\Studio19' DefaultProjectsFolder: 'C:\Users\UserName\Documents\Studio 2026 Release\Projects' StudioDocumentsFolderName: 'Studio 2026 Release' AppSigningEmail : app-signing@sdl.com diff --git a/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.yml b/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.yml index 8fc9188363..749a3322ad 100644 --- a/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.yml +++ b/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.yml @@ -320,7 +320,10 @@ items: summary: Creates a new instance of the preview application with the specified name. example: [] syntax: - content: public virtual IAbstractPreviewApplication BuildPreviewApplication(string name) + content: >- + [Obsolete("No longer used in Studio 2026 and later, preview UI was moved inside Studio.")] + + public virtual IAbstractPreviewApplication BuildPreviewApplication(string name) parameters: - id: name type: System.String @@ -328,10 +331,19 @@ items: return: type: Sdl.FileTypeSupport.Framework.IntegrationApi.IAbstractPreviewApplication description: '' - content.vb: Public Overridable Function BuildPreviewApplication(name As String) As IAbstractPreviewApplication + content.vb: >- + + + Public Overridable Function BuildPreviewApplication(name As String) As IAbstractPreviewApplication overload: Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.BuildPreviewApplication* implements: - Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.BuildPreviewApplication(System.String) + attributes: + - type: System.ObsoleteAttribute + ctor: System.ObsoleteAttribute.#ctor(System.String) + arguments: + - type: System.String + value: No longer used in Studio 2026 and later, preview UI was moved inside Studio. nameWithType.vb: DynamicFilterComponentBuilder.BuildPreviewApplication(String) fullName.vb: Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.BuildPreviewApplication(String) name.vb: BuildPreviewApplication(String) @@ -351,16 +363,28 @@ items: namespace: Sdl.FileTypeSupport.Framework.IntegrationApi example: [] syntax: - content: public virtual IAbstractPreviewControl BuildPreviewControl(string name) + content: >- + [Obsolete("No longer used in Studio 2026 and later, preview UI was moved inside Studio.")] + + public virtual IAbstractPreviewControl BuildPreviewControl(string name) parameters: - id: name type: System.String return: type: Sdl.FileTypeSupport.Framework.IntegrationApi.IAbstractPreviewControl - content.vb: Public Overridable Function BuildPreviewControl(name As String) As IAbstractPreviewControl + content.vb: >- + + + Public Overridable Function BuildPreviewControl(name As String) As IAbstractPreviewControl overload: Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.BuildPreviewControl* implements: - Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.BuildPreviewControl(System.String) + attributes: + - type: System.ObsoleteAttribute + ctor: System.ObsoleteAttribute.#ctor(System.String) + arguments: + - type: System.String + value: No longer used in Studio 2026 and later, preview UI was moved inside Studio. nameWithType.vb: DynamicFilterComponentBuilder.BuildPreviewControl(String) fullName.vb: Sdl.FileTypeSupport.Framework.IntegrationApi.DynamicFilterComponentBuilder.BuildPreviewControl(String) name.vb: BuildPreviewControl(String) diff --git a/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.yml b/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.yml index 2deb0dcfa8..0b09a8d59f 100644 --- a/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.yml +++ b/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.yml @@ -303,14 +303,26 @@ items: - Sdl.FileTypeSupport.Framework.Core namespace: Sdl.FileTypeSupport.Framework.IntegrationApi syntax: - content: IAbstractPreviewControl BuildPreviewControl(string name) + content: >- + [Obsolete("No longer used in Studio 2026 and later, preview UI was moved inside Studio.")] + + IAbstractPreviewControl BuildPreviewControl(string name) parameters: - id: name type: System.String return: type: Sdl.FileTypeSupport.Framework.IntegrationApi.IAbstractPreviewControl - content.vb: Function BuildPreviewControl(name As String) As IAbstractPreviewControl + content.vb: >- + + + Function BuildPreviewControl(name As String) As IAbstractPreviewControl overload: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.BuildPreviewControl* + attributes: + - type: System.ObsoleteAttribute + ctor: System.ObsoleteAttribute.#ctor(System.String) + arguments: + - type: System.String + value: No longer used in Studio 2026 and later, preview UI was moved inside Studio. nameWithType.vb: IFileTypeComponentBuilder.BuildPreviewControl(String) fullName.vb: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.BuildPreviewControl(String) name.vb: BuildPreviewControl(String) @@ -331,7 +343,10 @@ items: summary: Creates a new instance of the preview application with the specified name. example: [] syntax: - content: IAbstractPreviewApplication BuildPreviewApplication(string name) + content: >- + [Obsolete("No longer used in Studio 2026 and later, preview UI was moved inside Studio.")] + + IAbstractPreviewApplication BuildPreviewApplication(string name) parameters: - id: name type: System.String @@ -339,8 +354,17 @@ items: return: type: Sdl.FileTypeSupport.Framework.IntegrationApi.IAbstractPreviewApplication description: '' - content.vb: Function BuildPreviewApplication(name As String) As IAbstractPreviewApplication + content.vb: >- + + + Function BuildPreviewApplication(name As String) As IAbstractPreviewApplication overload: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.BuildPreviewApplication* + attributes: + - type: System.ObsoleteAttribute + ctor: System.ObsoleteAttribute.#ctor(System.String) + arguments: + - type: System.String + value: No longer used in Studio 2026 and later, preview UI was moved inside Studio. nameWithType.vb: IFileTypeComponentBuilder.BuildPreviewApplication(String) fullName.vb: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeComponentBuilder.BuildPreviewApplication(String) name.vb: BuildPreviewApplication(String) diff --git a/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.yml b/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.yml index b9111674d6..20a044d57c 100644 --- a/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.yml +++ b/api/filetypesupport/Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.yml @@ -357,14 +357,26 @@ items: - Sdl.FileTypeSupport.Framework.Core namespace: Sdl.FileTypeSupport.Framework.IntegrationApi syntax: - content: IAbstractPreviewControl BuildPreviewControl(PreviewControlId previewControlId) + content: >- + [Obsolete("No longer used in Studio 2026 and later, preview UI was moved inside Studio.")] + + IAbstractPreviewControl BuildPreviewControl(PreviewControlId previewControlId) parameters: - id: previewControlId type: Sdl.FileTypeSupport.Framework.IntegrationApi.PreviewControlId return: type: Sdl.FileTypeSupport.Framework.IntegrationApi.IAbstractPreviewControl - content.vb: Function BuildPreviewControl(previewControlId As PreviewControlId) As IAbstractPreviewControl + content.vb: >- + + + Function BuildPreviewControl(previewControlId As PreviewControlId) As IAbstractPreviewControl overload: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.BuildPreviewControl* + attributes: + - type: System.ObsoleteAttribute + ctor: System.ObsoleteAttribute.#ctor(System.String) + arguments: + - type: System.String + value: No longer used in Studio 2026 and later, preview UI was moved inside Studio. - uid: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.BuildPreviewApplication(Sdl.FileTypeSupport.Framework.IntegrationApi.PreviewApplicationId) commentId: M:Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.BuildPreviewApplication(Sdl.FileTypeSupport.Framework.IntegrationApi.PreviewApplicationId) id: BuildPreviewApplication(Sdl.FileTypeSupport.Framework.IntegrationApi.PreviewApplicationId) @@ -382,7 +394,10 @@ items: summary: Instantiate a preview application of the specified type. example: [] syntax: - content: IAbstractPreviewApplication BuildPreviewApplication(PreviewApplicationId previewApplicationId) + content: >- + [Obsolete("No longer used in Studio 2026 and later, preview UI was moved inside Studio.")] + + IAbstractPreviewApplication BuildPreviewApplication(PreviewApplicationId previewApplicationId) parameters: - id: previewApplicationId type: Sdl.FileTypeSupport.Framework.IntegrationApi.PreviewApplicationId @@ -392,8 +407,17 @@ items: return: type: Sdl.FileTypeSupport.Framework.IntegrationApi.IAbstractPreviewApplication description: '' - content.vb: Function BuildPreviewApplication(previewApplicationId As PreviewApplicationId) As IAbstractPreviewApplication + content.vb: >- + + + Function BuildPreviewApplication(previewApplicationId As PreviewApplicationId) As IAbstractPreviewApplication overload: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.BuildPreviewApplication* + attributes: + - type: System.ObsoleteAttribute + ctor: System.ObsoleteAttribute.#ctor(System.String) + arguments: + - type: System.String + value: No longer used in Studio 2026 and later, preview UI was moved inside Studio. - uid: Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.BuildVerifierCollection commentId: M:Sdl.FileTypeSupport.Framework.IntegrationApi.IFileTypeDefinition.BuildVerifierCollection id: BuildVerifierCollection diff --git a/apiconcepts/integration/adding_custom_wizard_steps.md b/apiconcepts/integration/adding_custom_wizard_steps.md index ea87620151..33546c89ef 100644 --- a/apiconcepts/integration/adding_custom_wizard_steps.md +++ b/apiconcepts/integration/adding_custom_wizard_steps.md @@ -1,74 +1,82 @@ -# Adding custom steps to wizards -Var:ProductName Integration API provides support for third-party developers to add custom pages to certain wizards within the Var:ProductName desktop application. You can add custom pages using WPF views and view-models. +# Adding Custom Steps to Wizards -*For the moment, only the __Open Package wizard__ supports this functionality. Support for other wizards may come in the future.* +The Var:ProductName Integration API allows third-party developers to add custom pages to certain wizards in the Var:ProductName desktop application. You can add custom pages using WPF views and view-models. -Creating pages to use as wizard steps ----- -In order to create a view that can be used as a wizard step, a third-party developer needs to: +> [!NOTE] +> +> Currently, only the **Open Package wizard** supports this functionality. Support for other wizards may be added in the future. + +## Creating Pages for Wizard Steps + +To create a view that can be used as a wizard step, complete the following: + +* Create a WPF view file (for example, a `UserControl`) with custom XAML and/or code behind +* Create a ViewModel for the view, if necessary +* Create a class that inherits from the abstract [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) + * Implement the required abstract properties + +## StudioWizardPage Base Class + +The [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) abstract class provides default implementations for some methods and properties required to define a custom wizard page. You can override these methods and properties to provide custom logic. -* Create a WPF view file, e.g. `UserControl`, with custom XAML and/or code behind. -* Create a ViewModel for the view, if necessary. -* Create a new class representing the custom page. - * This class needs to inherit from the abstract [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml). - * Implement the required abstract properties. -## StudioWizardPage base class -The [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) abstract class comes with a default implementation for some of the methods and properties required to define a custom wizard page. You can further override these methods and properties to provide your own custom logic. -## StudioWizardPage properties -Some of the properties are represented on the user interface directly, as shown below: - +The following properties display directly on the user interface: ### ViewType -* Set the `ViewType` property to the actual type of the WPF view file. Var:ProductName's infrastructure uses the type to inject the view into the wizard's user interface. You can use the `typeof` C# keyword (`GetType` in VB) to obtain the view type needed here. + +Set the `ViewType` property to the actual type of the WPF view file. Var:ProductName uses the type to inject the view into the wizard's user interface. Use the `typeof` C# keyword (`GetType` in VB.NET) to obtain the view type. ### ViewModel -* The wizard infrastructure automatically assigns the `ViewModel` as DataContext to the view, so you can use `Binding` from the view to the ViewModel properties. If you don't need a ViewModel just assign `null` here. -* For the `ViewModel` you can use any INotifyPropertyChanged implementation suits you best, such as providing your own or using an MVVM framework. + +The wizard infrastructure automatically assigns the `ViewModel` as the DataContext to the view. You can use `Binding` from the view to the ViewModel properties. If you don't need a ViewModel, assign `null` here. + +You can use any `INotifyPropertyChanged` implementation, such as your own implementation or an MVVM framework. ### IsAvailable -* This property is used by the wizard framework when navigating to other pages to determine if a page should be displayed. -* When the user clicks **Next** the wizard checks through the subsequent pages and displays the first one that is available. The **Next** button is disabled when there are no more pages for which `IsAvailable` returns `true`. -* When the user clicks **Back** the wizard checks through the previous pages and displays the first one that is available. The **Back** button is disabled when there are no more pages for which `IsAvailable` returns `true`. + +The wizard framework uses this property to determine whether a page should display when navigating to other pages. + +- When the user clicks **Next**, the wizard steps through subsequent pages and displays the first one where `IsAvailable` returns `true`. The **Next** button is disabled when no more pages are available. +- When the user clicks **Back**, the wizard steps through previous pages and displays the first one where `IsAvailable` returns `true`. The **Back** button is disabled when no more pages are available. ### Data -* You can define custom data for your pages using the `Data` property on the [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) object. -* The Data property is a `Dictionary` that is common to all wizard pages. -* Once a dictionary key is set from a page, it becomes available to any pages that are displayed after it. This includes pages that are navigated to via the **Back** button. -* You can use the Page's `OnShow` method to query for the most recent key values that may have been updated/inserted by previously shown pages. -* The `Data` property is initialized for all pages before the wizard is displayed. + +Define custom data for your pages using the `Data` property on the [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) object. + +- The `Data` property is a `Dictionary` that is shared across all wizard pages +- Once you set a dictionary key from a page, it becomes available to any subsequently displayed pages, including pages accessed via the **Back** button +- Use the page's `OnShow` method to query for the most recent key values that may have been updated by previously displayed pages +- The `Data` property is initialized for all pages before the wizard displays ### Icon -* Set this property to display an icon in the top-right area of the page. -* Set this property to `null` if you don't want an icon displayed. + +Set this property to display an icon in the top-right area of the page. Set to `null` if you don't want an icon displayed. ### Id -* This property is used by the wizard framework to uniquely identify the pages. - -# Integrating pages as steps into Var:ProductName wizards -Custom pages are injected into the wizard via the `firstPages` argument of the event object corresponding to the respective wizard. Keep in mind that the `firstPages` argument is available only for some wizard event objects. - -To inject the custom pages as steps into a Var:ProductName wizard: +The wizard framework uses this property to uniquely identify pages. +## Integrating Pages as Wizard Steps + +Custom pages integrate into wizards via the `firstPages` argument of the wizard's event object. The `firstPages` argument is available only for some wizard event objects. + +To inject custom pages into a Var:ProductName wizard, complete the following steps: + +* Determine or define a place in your code to launch the wizard (with custom steps), for example, from an [Action](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractAction.yml)'s `Execute` method +* Determine the appropriate event (for example, [OpenProjectPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.OpenProjectPackageEvent.yml)) that corresponds to the wizard you want to open +* Create a `List` of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) instances representing the custom pages to insert into the wizard +* Create the event, passing the `firstPages` list as an argument +* Use the event aggregator to raise the event, which launches the wizard -* Determine or define a place in your code to launch the wizard (with custom steps) from; for example, from an [Action](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractAction.yml)'s `Execute` method. -* Determine the appropriate event (e.g. [OpenProjectPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.OpenProjectPackageEvent.yml)) to be raised, that corresponds to the wizard you want to open. -* Set up a `List` of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) instances, which represent the custom pages you want to insert in the wizard -* Create the event, passing in `firstPages` list as an argument. -* Use the event aggregator to raise the event. This will launch the wizard. +The custom pages appear at the beginning of the wizard, before any standard pages. Custom pages display in the same order they are defined in the list. -Notes: -* The custom pages appear in the wizard at the beginning, before any other standard pages. -* The custom pages appear in the wizard in the same order they are defined in the list configured in the event object. +## Wizard Execution Flow -Wizard conceptual execution flow ----- -The diagram below briefly describes the wizard's execution sequence, and shows the order in which `StudioWizardPage` properties and methods are called by the framework at runtime. +The following diagram describes the wizard's execution sequence and shows the order in which `StudioWizardPage` properties and methods execute at runtime. -See also: [Full sample application with source code](https://github.com/RWS/trados-studio-api-samples/tree/master/TranslationStudioAutomation/Sdl.CustomWizardSteps.Sample) (on GitHub). +See also: [Full sample application with source code](https://github.com/RWS/trados-studio-api-samples/tree/master/TranslationStudioAutomation/Sdl.CustomWizardSteps.Sample) on GitHub. diff --git a/apiconcepts/integration/bilingual_api.md b/apiconcepts/integration/bilingual_api.md index e6d8c13cff..06c4f92b4d 100644 --- a/apiconcepts/integration/bilingual_api.md +++ b/apiconcepts/integration/bilingual_api.md @@ -1,49 +1,61 @@ -Overview -===== -This section contains a quick overview of the Bilingual API. For detailed documentation on individual interfaces, properties, methods etc., see the reference documentation. +# Bilingual API Overview -Bilingual processor components implement the [IBilingualContentProcessor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentProcessor.yml) interface, which the framework calls to let the component process content in a bilingual object model one paragraph unit at a time. +This section provides a quick overview of the Bilingual API. For detailed documentation on interfaces, properties, and methods, see the reference documentation. + +Bilingual processor components implement the [IBilingualContentProcessor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentProcessor.yml) interface. The framework calls this interface to process content in a bilingual object model, one paragraph unit at a time. -The content is delivered to the components through calls to [ProcessParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_ProcessParagraphUnit_Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_). The Initialize method is invoked before any content is passed through the component, and it communicates the document properties which are common for all files in the document. For each native file in the bilingual document, the framework calls [SetFileProperties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_SetFileProperties_Sdl_FileTypeSupport_Framework_BilingualApi_IFileProperties_) before the content of the file is processed. When all content in a file has been processed, the framework calls [FileComplete](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_FileComplete) and when all files in a document have been processed, the framework calls [Complete](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_Complete). +The content flows to components through [ProcessParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_ProcessParagraphUnit_Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_) calls. The framework invokes `Initialize` before processing any content to communicate document properties common to all files. For each native file, the framework calls [SetFileProperties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_SetFileProperties_Sdl_FileTypeSupport_Framework_BilingualApi_IFileProperties_) before processing file content. When file processing completes, the framework calls [FileComplete](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_FileComplete), and after all files finish processing, it calls [Complete](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_Complete). -The file properties passed through the [SetFileProperties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_SetFileProperties_Sdl_FileTypeSupport_Framework_BilingualApi_IFileProperties_) call can be used to retrieve the persistant file conversion settings, where components can store and retrieve important settings related to the data being processed. +The file properties from the [SetFileProperties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_SetFileProperties_Sdl_FileTypeSupport_Framework_BilingualApi_IFileProperties_) call provide access to persistent file conversion settings where components can store and retrieve settings related to the processed data. -The `EventFiringBilingualProcessor` is an implementation of the [IBilingualContentProcessor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentProcessor.yml) interface that is convenient to use when you are only interested in processing one or two of these calls. That implementation simply fires events for each of the calls and you can hook up your event handler to the one you are interested in. (This is very handy, especially when writing unit tests.) +The `EventFiringBilingualProcessor` implements [IBilingualContentProcessor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentProcessor.yml) and provides a convenient way to process only specific calls. This implementation fires events for each call, and you can subscribe to the events you need. This approach works especially well for unit tests. -Paragraph units can be divided into two types: structure paragraph units and localizable paragraph units. Structure paragraph units contain only structural data (i.e. structure tags), they have no directly localizable content. Localizable paragraph units contain text and tags that are modified during translation. Both types of paragraph units are processed in the [ProcessParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_ProcessParagraphUnit_Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_) call, the implementation must check the [IsStructure](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_IsStructure) property to determine which type each is. +## Paragraph units + +Paragraph units fall into two categories: structure paragraph units and localizable paragraph units. Structure paragraph units contain only structural data (structure tags) with no directly localizable content. Localizable paragraph units contain text and tags modified during translation. Your implementation processes both types in [ProcessParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_ProcessParagraphUnit_Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_) by checking the [IsStructure](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_IsStructure) property to distinguish between them. -A localizable paragraph unit can have the following main properties: +A localizable paragraph unit has the following main properties: -The source and target language content in a paragraph is comprised of objects that implement [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml) derived interfaces: +## Paragraph content + +Paragraph source and target language content consists of objects that implement [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml) derived interfaces: -Below is a diagram with some more details on the inline tags: +## Markup + +Inline tags provide additional details: -Tags and text inside a paragraph can be annotated with different types of markup, represented with [IAbstractMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarker.yml) as base interface: +Tags and text within a paragraph can carry different types of markup, represented by [IAbstractMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarker.yml) as the base interface: -The most important type of markup is segments. A segment is uniquely identified within the paragraph unit through its segment ID. As segment in a localized paragraph unit always has a source/target language counterpart. The source and target language segments reference the same [ISegmentPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegmentPair.yml) object, and thus implicitly will always have the same segment ID. The corresponding source/target segment can be easily retrieved through the [GetSourceSegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_GetSourceSegment_Sdl_FileTypeSupport_Framework_NativeApi_SegmentId_) and [GetTargetSegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_GetTargetSegment_Sdl_FileTypeSupport_Framework_NativeApi_SegmentId_) methods, which take the segment ID as parameter and returns the corresponding object. +### Segments -Navigation and iteration through the bilingual content in a paragraph or other markup data container can be achieved in a number of different ways. Perhaps the most intuitive is to use the `Parent`, `IndexInParent` and `Items` properties to directly access related nodes, or by iterating over all items in an [IAbstractMarkupDataContainer](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarkupDataContainer.yml), either directly or through the [AllSubItems](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarkupDataContainer.yml##Sdl_FileTypeSupport_Framework_BilingualApi_IAbstractMarkupDataContainer_AllSubItems) property of the container, or by calling the [ForEachSubItem](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarkupDataContainer.yml##Sdl_FileTypeSupport_Framework_BilingualApi_IAbstractMarkupDataContainer_ForEachSubItem_System_Action_Sdl_FileTypeSupport_Framework_BilingualApi_IAbstractMarkupData__) method passing in an action object. +Segments are the most important markup type. Each segment has a unique ID within its paragraph unit. In a localized paragraph unit, every segment has a source/target language counterpart. Both source and target segments reference the same [ISegmentPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegmentPair.yml) object, so they always share the same segment ID. Retrieve the corresponding source or target segment using [GetSourceSegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_GetSourceSegment_Sdl_FileTypeSupport_Framework_NativeApi_SegmentId_) or [GetTargetSegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_GetTargetSegment_Sdl_FileTypeSupport_Framework_NativeApi_SegmentId_) with the segment ID as a parameter. -The [Location](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.Location.yml) class provides another flexible way of iterating through and working with the localizable content in a paragraph: +## Navigation and iteration + +Navigate and iterate through bilingual content in multiple ways. The most intuitive approach uses the `Parent`, `IndexInParent`, and `Items` properties to directly access related nodes. Alternatively, iterate over all items in an [IAbstractMarkupDataContainer](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarkupDataContainer.yml) directly, through the [AllSubItems](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarkupDataContainer.yml##Sdl_FileTypeSupport_Framework_BilingualApi_IAbstractMarkupDataContainer_AllSubItems) property, or by calling [ForEachSubItem](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IAbstractMarkupDataContainer.yml##Sdl_FileTypeSupport_Framework_BilingualApi_IAbstractMarkupDataContainer_ForEachSubItem_System_Action_Sdl_FileTypeSupport_Framework_BilingualApi_IAbstractMarkupData__) with an action object. + +The [Location](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.Location.yml) class provides another flexible option for iterating through and working with localizable content in a paragraph: -Localizable content can also be processed through a visitor pattern. This is often useful when dealing with collections of objects (e.g. in markup data containers), as the use of a visitor avoids having to construct awkward and difficult to maintain switch/if statements to test for different object types. Simply call AcceptVisitor on the object, and the object will call back to its corresponding method on the visitor. For more information about the Visitor pattern, see Design Patters by the “Gang of Four” (Gamma, Helm, Johnson, Vlissides), a book that should be on every developer's desk. +## Visitor pattern + +Process localizable content through a visitor pattern, which works especially well for collections of objects (for example, markup data containers). This approach avoids writing complex and hard-to-maintain switch/if statements for different object types. Call `AcceptVisitor` on the object, and it calls back to the corresponding method on your visitor. For more information on the Visitor pattern, see *Design Patterns: Elements of Reusable Object-Oriented Software* by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. - + \ No newline at end of file diff --git a/apiconcepts/integration/code_samples/CreatingRibbonGroupActions.cs b/apiconcepts/integration/code_samples/CreatingRibbonGroupActions.cs index 9119fe057e..6b4315073c 100644 --- a/apiconcepts/integration/code_samples/CreatingRibbonGroupActions.cs +++ b/apiconcepts/integration/code_samples/CreatingRibbonGroupActions.cs @@ -12,8 +12,6 @@ namespace Actions.Sample { - #region General action - [Action("MyMainIconAction", Icon = "MyAction_Icon")] [ActionLayout(typeof(MySampleRibbonGroup), 10, DisplayType.Large)] [Shortcut(Keys.Alt | Keys.F8)] @@ -25,10 +23,6 @@ protected override void Execute() } } - #endregion - - #region Controller specific actions - [Action("MyNormalSizeAction")] [ActionLayout(typeof (MySampleRibbonGroup), DisplayType = DisplayType.Normal)] public class MyNormalSizeAction : AbstractViewControllerAction @@ -50,7 +44,4 @@ protected override void Execute() Controller.GetDocuments().Count())); } } - - #endregion - } diff --git a/apiconcepts/integration/content_connector.md b/apiconcepts/integration/content_connector.md index becf7cbe9e..4eace0d625 100644 --- a/apiconcepts/integration/content_connector.md +++ b/apiconcepts/integration/content_connector.md @@ -1,12 +1,10 @@ -Content Connector -== +# Content Connector -The Content Connector sits at the heart of this extension. Its main classes are ContentConnector, ContentConnectorViewRibbonGroup, ContentConncetorViewController and ContentConnectorViewControl. +The Content Connector sits at the heart of this extension. Its main classes are ContentConnector, ContentConnectorViewRibbonGroup, ContentConnectorViewController, and ContentConnectorViewControl. -Content Connector --- +## The ContentConnector Class -The ContentConnector class simply reads the file names in the IncomingRequests folder and wraps them in a ProjectRequest object. +The ContentConnector class reads file names in the IncomingRequests folder and wraps them in a ProjectRequest object. # [C#](#tab/tabid-1) ```cs @@ -68,10 +66,9 @@ namespace StudioIntegrationApiSample ``` *** -Content Connector View Ribbon Group --- +## Content Connector View Ribbon Group -This class illustrates how a CreateProjectAction is defined and how a custom RibbonGroup on the Add-Ins ribbon tab is created and also how the action is added to it. +This class demonstrates how to define a CreateProjectAction and create a custom RibbonGroup on the Add-Ins ribbon tab. It also shows how to add the action to the group. # [C#](#tab/tabid-2) ```cs @@ -125,10 +122,9 @@ namespace StudioIntegrationApiSample ``` *** -Content Connector ViewController --- +## Content Connector ViewController -The Var:ProductName> Integration API is built in accordance with the MVC pattern. The View Controller is used to add new views to Var:ProductName> - the code sample below illustrates how this is achieved using the View attribute. The controller is also responsible for providing the View UI element. Additionally this sample has a ```CreateProjects()``` method which the controller uses to create new projects from the files in the IncomingRequests folder. +The Var:ProductName Integration API follows the MVC pattern. The View Controller adds new views to Var:ProductName using the View attribute. The controller also provides the View UI element. This sample includes a `CreateProjects()` method that the controller uses to create new projects from files in the IncomingRequests folder. # [C#](#tab/tabid-3) ```cs @@ -156,12 +152,10 @@ namespace StudioIntegrationApiSample LocationByType = typeof(TranslationStudioDefaultViews.TradosStudioViewsLocation))] public class ContentConnectorViewController : AbstractViewController, INotifyPropertyChanged { - #region private fields private readonly Lazy _control = new Lazy(() => new ContentConnectorViewControl()); private ProjectTemplateInfo _selectedProjectTemplate; private List _projectRequests; private int _percentComplete; - #endregion private fields public event EventHandler ProjectRequestsChanged; @@ -316,10 +310,9 @@ namespace StudioIntegrationApiSample ``` *** -Content Connector ViewControl --- +## Content Connector ViewControl -This class is responsible for rendering the UI and interacts with the controller described above for data retrieval. +This class renders the UI and interacts with the controller for data retrieval. # [C#](#tab/tabid-4) ```cs @@ -436,44 +429,31 @@ namespace StudioIntegrationApiSample } } - void _controller_ProjectRequestsChanged(object sender, EventArgs e) + private void _controller_ProjectRequestsChanged(object sender, EventArgs e) { LoadProjectRequests(); } - void _projectsListBox_SelectedIndexChanged(object sender, EventArgs e) + private void _projectsListBox_SelectedIndexChanged(object sender, EventArgs e) { LoadFileList(); } - - private void _projectTemplatesComboBox_SelectedIndexChanged(object sender, EventArgs e) { _controller.SelectedProjectTemplate = _projectTemplatesComboBox.SelectedItem as ProjectTemplateInfo; } - - } } ``` *** -See Also --- - - - -[Reference Sample](reference_sample.md) - -[Project Creator](project_creator.md) - -[Wikipedia Search](wikipedia_search.md) - -[Integrating actions](integrating_actions.md) - -[Integrating ribbon groups](integrating_ribbon_groups.md) - -[Integrating viewparts](integrating_viewparts.md) +## See Also -[Integrating views](integrating_views.md) +- [Reference Sample](reference_sample.md) +- [Project Creator](project_creator.md) +- [Wikipedia Search](wikipedia_search.md) +- [Integrating actions](integrating_actions.md) +- [Integrating ribbon groups](integrating_ribbon_groups.md) +- [Integrating viewparts](integrating_viewparts.md) +- [Integrating views](integrating_views.md) diff --git a/apiconcepts/integration/create_a_trados_studio_application_initializer.md b/apiconcepts/integration/create_a_trados_studio_application_initializer.md index 2dcc73391c..eec0acbd27 100644 --- a/apiconcepts/integration/create_a_trados_studio_application_initializer.md +++ b/apiconcepts/integration/create_a_trados_studio_application_initializer.md @@ -1,14 +1,71 @@ -Create a Var:ProductName application initializer -==== +# Create a Var:ProductName Application Initializer -Var:ProductName Integration API provides support for third-party developers to add specific initializations or functionalities at Var:ProductName application startup. +The Var:ProductName Integration API enables third-party developers to add custom initializations or functionalities when Var:ProductName starts. -Creating a Var:ProductName application initializer ----- -In order to create a Var:ProductName application initializer, a third-party developer will require the following steps: +## Creating an Application Initializer -* Create an initialization class which implements the [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml) interface. -* Decorate the initialization class with the [ApplicationInitializerAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ApplicationInitializerAttribute.yml) attribute +To create a Var:ProductName application initializer, follow these steps: +- Implement the [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml) interface in an initialization class. +- Decorate the initialization class with the [ApplicationInitializerAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ApplicationInitializerAttribute.yml) attribute. -[Creating a Var:ProductName application initializer Sample](trados_studio_application_initializers.md) +If you fail to implement [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml), an exception will be thrown. If you omit the [ApplicationInitializerAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ApplicationInitializerAttribute.yml), your plugin will simply be ignored when Var:ProductName starts. + +## Example + +The following example demonstrates a simple plugin data initialization. This plugin measures the time since Var:ProductName has been opened and if you worked less than required, it displays a warning MessageBox. + +This example also demonstrates how to cleanup when Var:ProductName exits. All you have to do is subscribe to `Application.Closing` event. You can use `CancelEventArgs` to prevent Var:ProductName from closing. + +### Simple Plugin Initializer + +```cs +using System; +using System.Windows.Forms; +using Sdl.Desktop.IntegrationApi; +using Sdl.Desktop.IntegrationApi.Extensions; +using Sdl.TranslationStudioAutomation.IntegrationApi; + +namespace StudioInitializer.Sample +{ + /// + /// Implements an application initializer which will keep track of the application startup and closing time. + /// + [ApplicationInitializer] + class PluginInitializer : IApplicationInitializer + { + private const int MinimumWorkTime = 4; + + /// + /// This method is executed when the application is starting. + /// + public void Execute() + { + StudioTracking.Start(); + + // Setting up a check at the application closure verifying if the user has worked less then the minimum amount of time + // If the time passed since Studio opening and Studio closing is less than the MinimumWorkTime(4h) than + // request a confirmation from the user for the application closure otherwise just exit. + SdlTradosStudio.Application.Closing += (s, e) => + { + TimeSpan elapsedTime = StudioTracking.Elapsed; + if (elapsedTime.Hours < MinimumWorkTime) + { + DialogResult dialogResult = + MessageBox.Show( + string.Format("You have been working for {0:dd\.hh\:mm\:ss} and spending less than {1} hours. Are you sure you want to quit ?", StudioTracking.Elapsed, MinimumWorkTime) + , string.Format("Total work time is {0} minutes", elapsedTime.Minutes) + , MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (dialogResult == DialogResult.No) + { + //Cancel the the application closing + e.Cancel = true; + return; + } + } + StudioTracking.Stop(); + }; + } + } +} +``` diff --git a/apiconcepts/integration/create_a_trados_studio_autosuggest_provider.md b/apiconcepts/integration/create_a_trados_studio_autosuggest_provider.md index f302672f8c..1f0908b62f 100644 --- a/apiconcepts/integration/create_a_trados_studio_autosuggest_provider.md +++ b/apiconcepts/integration/create_a_trados_studio_autosuggest_provider.md @@ -1,13 +1,158 @@ -Create a Var:ProductName AutoSuggest provider -==== -Var:ProductName Integration API provides support for third-party developers to add specific functionalities for a custom AutoSuggest provider. +# Create a Var:ProductName AutoSuggest Provider -Creating a Var:ProductName AutoSuggest provider ----- -In order to create a Var:ProductName AutoSuggest provider, a third-party developer will require the following steps: +The Var:ProductName Integration API enables third-party developers to add custom AutoSuggest provider functionality. -* Create an initialization class which implements the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) abstract class. -* Overrite the the abstract methods of the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) base class to implement your custom provider. -* Decorate the initialization class with the [AutoSuggestProviderAttribute](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.AutoSuggestProviderAttribute.yml) attribute +## Creating an AutoSuggest Provider -[Creating a Var:ProductName AutoSuggest provider Sample](trados_studio_autosuggest_provider.md) +To create a Var:ProductName AutoSuggest provider, follow these steps: + +- Implement the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) abstract class in a provider class. +- Override the abstract methods in the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) base class to implement your custom provider. +- Decorate the provider class with the [AutoSuggestProviderAttribute](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.AutoSuggestProviderAttribute.yml) attribute. + +If you fail to implement [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml), an exception will be thrown. If you omit the [AutoSuggestProviderAttribute](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.AutoSuggestProviderAttribute.yml), your plugin will simply be ignored when Var:ProductName starts. + +## Example + +The following example demonstrates how to implement a custom AutoSuggest provider. + +The plugin implements the required abstract methods of the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) base class: + +- **GetSuggestions** — returns the list of items for the auto suggestion list box +- **OnActiveSegmentChanged** — prepares the list of suggested items for the newly selected segment +- **OnSettingsChanged** — reacts to any change of the document settings +- **OnActiveDocumentChanged** — reacts to changes of the active document + +### Sample AutoSuggest Provider + +```cs +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Sdl.FileTypeSupport.Framework.BilingualApi; +using Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest; +using Sdl.TranslationStudioAutomation.IntegrationApi.Extensions; + +namespace AutoSuggest.Sample +{ + [AutoSuggestProvider(Id = "SourceCopyAutoSuggestProvider", Name = "AutoSuggest provider for copying the source words")] + public class SourceCopyAutoSuggestProvider : AbstractAutoSuggestProvider + { + private List _segmentWordSuggestCandidates; + + public SourceCopyAutoSuggestProvider() + { + // Set the default icon for the suggestions from this provider + Icon = new Icon(SystemIcons.Exclamation, 16, 16); + } + + #region AutoSuggestProvider Implementation + /// + /// This function is not necessary for this sample. It just shows in case you need dictionary or some other language specific action, you can do it here. + /// + protected override void OnActiveDocumentChanged() + { + if (ActiveDocument != null) + { + var sourceLanguage = ActiveDocument.Project.GetProjectInfo().SourceLanguage; + var targetLanguage = ActiveDocument.Files.First().Language; + + System.Diagnostics.Debug.WriteLine("SourceCopyAutoSuggestProvider Language pair: {0}->{1}", sourceLanguage.DisplayName, targetLanguage.DisplayName); + + // in case you need prepare the dictionary for this language pair, do it here + } + else + { + _segmentWordSuggestCandidates = null; + } + + System.Diagnostics.Debug.WriteLine("OnActiveDocumentChanged {0}", ActiveDocument != null); + } + + // when user goes to a segment, we want to prepare the AutoSuggest Candidate first. + // when it takes long, for performance reason, the execution might be done in a separate thread. + protected override void OnActiveSegmentChanged() + { + if (Settings.Enabled) + { + PrepareSegmentSuggestCandiates(); + } + else + { + _segmentWordSuggestCandidates = null; + } + System.Diagnostics.Debug.WriteLine("OnActiveSegmentChanged {0}", ActiveSegmentPair != null); + } + + /// + /// We only provide the AutoSuggest when the candidate is available. The user might have the change from disabled to enabled, we need preapre the candidate. + /// + protected override void OnSettingsChanged() + { + if (Settings.Enabled) + { + PrepareSegmentSuggestCandiates(); + } + else + { + _segmentWordSuggestCandidates = null; + } + } + + protected override IEnumerable GetSuggestions(AbstractEditingContext context) + { + if (Settings.Enabled) + { + string suffix = context.GetAllPrefixes().First(); + if (!string.IsNullOrEmpty(suffix) && _segmentWordSuggestCandidates != null && _segmentWordSuggestCandidates.Count > 0) + { + return _segmentWordSuggestCandidates + .Where(item => item.StartsWith(suffix, Settings.CaseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)) + .Select(item => + { + var result = new AutoSuggestTextResult(context, item); + result.Priority = Settings.Priority; + + // Set different icon for suggestions starting with "a". For the rest set the default provider icon + result.Icon = result.Text.StartsWith("a") ? new Icon(SystemIcons.Question, 16, 16) : Icon; + + return result; + }); + } + + } + return null; + } + + #endregion + + private void PrepareSegmentSuggestCandiates() + { + if (ActiveSegmentPair != null) + { + var stringBuilder = new StringBuilder(); + foreach (var item in ActiveSegmentPair.Source.AllSubItems) + { + var text = item as IText; + if (text != null) + { + stringBuilder.Append(text.Properties.Text); + } + } + + // Split the sentence to words in a naive way, in practice a better way is needed to to tokenize the sentence. + // As a sample we will show the source words in the AutoSuggest, in practice, translation to the target language are needed + _segmentWordSuggestCandidates = Regex.Split(stringBuilder.ToString(), @"\W+").ToList(); + + System.Diagnostics.Debug.WriteLine("PrepareSegmentSuggestCandiates: {0}", stringBuilder.ToString()); + System.Diagnostics.Debug.WriteLine("{0}", _segmentWordSuggestCandidates == null); + } + } + + } +} +``` diff --git a/apiconcepts/integration/create_a_trados_studio_commandLineProcessor.md b/apiconcepts/integration/create_a_trados_studio_commandLineProcessor.md index 10b28ed95a..31623e6765 100644 --- a/apiconcepts/integration/create_a_trados_studio_commandLineProcessor.md +++ b/apiconcepts/integration/create_a_trados_studio_commandLineProcessor.md @@ -1,20 +1,87 @@ -Var:ProductName Command line processor -==== -If you need to run Var:ProductName from a command line and you what to execute a custom processing based on a command with arguments the Integration API enables you to create your own command line processor. +# Var:ProductName Command Line Processor -Creating a Var:ProductName command line argument processor ---- +If you need to run Var:ProductName from a command line and execute custom processing for a specific command with arguments, the Integration API enables you to create your own command line processor. -To create a Var:ProductName command line processor as a third-party developer : +## Creating a Command Line Argument Processor -* implement the [IExternalCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalCommandLineProcessor.yml) or [IExternalWindowAwareCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalWindowAwareCommandLineProcessor.yml) depending if you want to run the command line processor before or after the main screen is displayed. +To create a Var:ProductName command line processor, follow these steps: -* from `Sdl.Desktop.IntegrationApi.Extensions.CommandLine` namespace and decorate your class with [ExternalCommandLineProcessorAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.ExternalCommandLineProcessorAttribute.yml) attribute. +- Implement either [IExternalCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalCommandLineProcessor.yml) or [IExternalWindowAwareCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalWindowAwareCommandLineProcessor.yml), depending on whether you want the processor to run before or after the main screen displays. -If you don't implement [IExternalCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalCommandLineProcessor.yml) or [IExternalWindowAwareCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalWindowAwareCommandLineProcessor.yml), an exception will be thrown, but if you omit the [ExternalCommandLineProcessorAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.ExternalCommandLineProcessorAttribute.yml), your plugin will simply be ignored when Var:ProductName starts. +- Decorate your class with the [ExternalCommandLineProcessorAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.ExternalCommandLineProcessorAttribute.yml) attribute from the `Sdl.Desktop.IntegrationApi.Extensions.CommandLine` namespace. -After successfully creating your command line processor you can check the Help generated for it by and running the following command in cmd.exe : Var:InstallationFolder\SdlTradosStudio.exe ? . Your command will appear, among other commands available, in the following screen : - +## Requirements and Behavior -[Creating a Var:ProductName Command line processor Sample] -(trados_studio_command_processor.md) +If you do not implement [IExternalCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalCommandLineProcessor.yml) or [IExternalWindowAwareCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalWindowAwareCommandLineProcessor.yml), an exception is thrown. If you omit the [ExternalCommandLineProcessorAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.ExternalCommandLineProcessorAttribute.yml), your plug-in is ignored when Var:ProductName starts. + +## Viewing Your Command in Help + +After creating your command line processor, view the generated help by running the following command in cmd.exe: + +``` +Var:InstallationFolder\SdlTradosStudio.exe ? +``` + +Your command appears, along with other available commands, in the resulting help screen: + +![Command Help Window](images/cmdHelpWindow.jpg) + +## Example + +The following example demonstrates how to implement a custom command line processor. + +The plugin implements the required interfaces mentioned above with the following key properties: + +- **TaskName** — returns the name of the command processing unit +- **TaskDescription** — describes what that processing will do +- **SupportedArguments** — lists supported arguments + +### C# + +```cs +using Sdl.Desktop.IntegrationApi.Extensions.CommandLine; +using System.Windows.Forms; +using System.Collections.Generic; + +namespace Sdl.CustomPlugin.Packaging.OpenPackageWizard +{ + [ExternalCommandLineProcessor(Id = "OpenPackageCommandLineProcessor_Id", Name = "OpenPackageCommandLineProcessor_Name", Description = "OpenPackageCommandLineProcessor_Description")] + public class OpenPackageCommandLineProcessor : IExternalWindowAwareCommandLineProcessor + { + private readonly IList _supportedArguments; + private const string OpenPackageArgument = "openPackage"; + + public OpenPackageCommandLineProcessor() + { + _supportedArguments = new List() + { + new ExternalCommandLineArgumentDefinition(OpenPackageArgument, + StringResources.OpenPackageCommandLineTask_Files) + { + MinValues = 1, + MaxValues = 1, + SampleValues = new[] { "package" } + } + }; + } + + public string TaskName => StringResources.OpenPackageCommandLineTask_Name; + + public string TaskDescription => StringResources.OpenPackageCommandLineTask_Description; + + public IEnumerable SupportedArguments => _supportedArguments; + + public void ProcessCommandLine(ExternalCommandLineArguments args) + { + ExternalCommandLineArgument packagesToOpen = args[OpenPackageArgument]; + if (packagesToOpen == null) + { + return; + } + + var uiPackageOpener = new UIPackageOpener(Form.ActiveForm); + uiPackageOpener.OpenPackage(packagesToOpen.Values[0]); + } + } +} +``` diff --git a/apiconcepts/integration/creating_actions.md b/apiconcepts/integration/creating_actions.md index 3d5a5ce8b6..15c3c71016 100644 --- a/apiconcepts/integration/creating_actions.md +++ b/apiconcepts/integration/creating_actions.md @@ -1,53 +1,64 @@ -Creating actions -===== -Var:ProductName Integration API provides support for third-party developers to implement actions inside the Var:ProductName desktop applications. +# Creating Actions -An action is a piece of code which can have a UI representation and is usually executed over a UI controller. Most of the time, it is used to allow users to execute an application-specific functionality. +The Var:ProductName Integration API allows developers to implement custom actions in Var:ProductName desktop applications. -About actions ----- -There are two kind of actions that can be created inside Var:ProductName applications: +An action is a piece of code that can have a UI representation and executes over a UI controller. Actions allow users to trigger application-specific functionality. -* Actions which have a global purpose beeing executed in the application context (see: **StudioContext**). -* Actions which are executed over a view or viewpart controller (see: [Creating views](creating_views.md), [Creating viewparts](creating_viewparts.md)). +## Action Types -For a sample on how to create a global context actions integrated into a custom ribbon group, see: Integrating actions +Var:ProductName supports two types of actions: -Creating an action ------- -In order to create an action, a third-party developer will require the following steps: +* **Global actions** execute in the application context (see [StudioContext](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractApplication.yml)) +* **Controller actions** execute in the context of a view or view part controller (see [Creating views](creating_views.md), [Creating viewparts](creating_viewparts.md)) -* Create a class inherited based on the scope from: -[AbstractAction](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractAction.yml) if the action requires to be available in a Var:ProductName global context and its execution is not specific to a view or viewpart, but to the application. -[AbstractViewControllerAction](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewControllerAction-1.yml) if the action requires to be available in any context, but it is specific to one of the view or viewpart controller. -* Decorate the newly created class using the [ActionAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ActionAttribute.yml) attribute to define the action. -* Decorate single or multiple times the newly created class using the [ActionLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ActionLayoutAttribute.yml) attribute to define the action layout settings. The location specified in the action layout settings can be either a custom ribbon group (see: [Integrating ribbon groups](integrating_ribbon_groups.md)), or one of the following default locations: - * [StudioDefaultRibbonTabs.AddinsRibbonTabLocation](../../api/integration/Sdl.Desktop.IntegrationApi.DefaultLocations.StudioDefaultRibbonTabs.AddinsRibbonTabLocation.yml) - * [StudioDefaultRibbonTabs.HelpRibbonTabLocation](../../api/integration/Sdl.Desktop.IntegrationApi.DefaultLocations.StudioDefaultRibbonTabs.HelpRibbonTabLocation.yml) - * [StudioDefaultRibbonTabs.ViewRibbonTabLocation](../../api/integration/Sdl.Desktop.IntegrationApi.DefaultLocations.StudioDefaultRibbonTabs.ViewRibbonTabLocation.yml) - * [TranslationStudioDefaultRibbonTabs.EditorAdvancedRibbonTabLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.EditorAdvancedRibbonTabLocation.yml) - * [TranslationStudioDefaultRibbonTabs.EditorReviewRibbonTabLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.EditorReviewRibbonTabLocation.yml) - * [TranslationStudioDefaultRibbonTabs.HomeRibbonTabLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.HomeRibbonTabLocation.yml) - * [TranslationStudioDefaultContextMenus.EditorDocumentContextMenuLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultContextMenus.EditorDocumentContextMenuLocation.yml) - * [TranslationStudioDefaultContextMenus.FilesContextMenuLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultContextMenus.FilesContextMenuLocation.yml) - * [TranslationStudioDefaultContextMenus.ProjectsContextMenuLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultContextMenus.ProjectsContextMenuLocation.yml) +See [Integrating actions](integrating_actions.md) for an example of a global action integrated into a custom ribbon group. +## Creating an Action -For a sample on how to create actions, see: [Integrating actions](integrating_actions.md) +To create an action, complete the following steps: + +* Create a class that inherits from one of the following base classes: + * [AbstractAction](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractAction.yml) — for global application context actions + * [AbstractViewControllerAction<TController>](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewControllerAction-1.yml) — for context-specific view or view part actions +* Apply the [ActionAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ActionAttribute.yml) attribute to specify action metadata +* Apply one or more [ActionLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ActionLayoutAttribute.yml) attributes to specify layout settings and location + +### Action Locations + +Specify the action location using one of the following default ribbon tabs or context menus: + +**Studio Ribbon Tabs:** +* [StudioDefaultRibbonTabs.AddinsRibbonTabLocation](../../api/integration/Sdl.Desktop.IntegrationApi.DefaultLocations.StudioDefaultRibbonTabs.AddinsRibbonTabLocation.yml) +* [StudioDefaultRibbonTabs.HelpRibbonTabLocation](../../api/integration/Sdl.Desktop.IntegrationApi.DefaultLocations.StudioDefaultRibbonTabs.HelpRibbonTabLocation.yml) +* [StudioDefaultRibbonTabs.ViewRibbonTabLocation](../../api/integration/Sdl.Desktop.IntegrationApi.DefaultLocations.StudioDefaultRibbonTabs.ViewRibbonTabLocation.yml) + +**Translation Studio Ribbon Tabs:** +* [TranslationStudioDefaultRibbonTabs.EditorAdvancedRibbonTabLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.EditorAdvancedRibbonTabLocation.yml) +* [TranslationStudioDefaultRibbonTabs.EditorReviewRibbonTabLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.EditorReviewRibbonTabLocation.yml) +* [TranslationStudioDefaultRibbonTabs.HomeRibbonTabLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.HomeRibbonTabLocation.yml) + +**Translation Studio Context Menus:** +* [TranslationStudioDefaultContextMenus.EditorDocumentContextMenuLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultContextMenus.EditorDocumentContextMenuLocation.yml) +* [TranslationStudioDefaultContextMenus.FilesContextMenuLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultContextMenus.FilesContextMenuLocation.yml) +* [TranslationStudioDefaultContextMenus.ProjectsContextMenuLocation](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultContextMenus.ProjectsContextMenuLocation.yml) + +You can also target a custom ribbon group (see [Integrating ribbon groups](integrating_ribbon_groups.md)). + +See [Integrating actions](integrating_actions.md) for an example. -> [!NOTE] +> +> [!TIP] > > On how to obtain an already created action, see: [GetAction< TAction>](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractApplication.yml#Sdl_Desktop_IntegrationApi_AbstractApplication_GetAction__1) -Creating a keyboard shortcut for an action ------- -The Var:ProductName Integration API provides support for third-party developers to add keyboard shortcuts to the actions they implement. +## Keyboard Shortcuts -In order to create a shortcut action, a third-party developer will require to decorate the action class with the [ShortcutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ShortcutAttribute.yml) and specify the combination of keyboard keys on which the action should be triggered and executed. +The Var:ProductName Integration API allows developers to add keyboard shortcuts to actions. -You can see in the sample below how ALT+F8 is added as a shortcut key for the action. +To create a keyboard shortcut for an action, apply the [ShortcutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ShortcutAttribute.yml) to your action class and specify the keyboard key combination that triggers the action. > [!NOTE] > -> The shortcut keys that are in conflict with shortcuts will have a lower priority and will be ignored. +> Shortcuts that conflict with existing shortcuts have lower priority and are ignored. + diff --git a/apiconcepts/integration/creating_ribbon_groups.md b/apiconcepts/integration/creating_ribbon_groups.md index fe841bf547..61e9ec7a56 100644 --- a/apiconcepts/integration/creating_ribbon_groups.md +++ b/apiconcepts/integration/creating_ribbon_groups.md @@ -1,21 +1,21 @@ -Creating ribbon groups -==== -Var:ProductName Integration API provides support for third-party developers to integrate UI ribbon groups inside the Var:ProductName desktop applications. +# Creating Ribbon Groups -Creating ribbon groups ---- -In order to create ribbon groups, a third-party developer will require the following steps: +The Var:ProductName Integration API allows developers to integrate custom UI ribbon groups into Var:ProductName desktop applications. -* Create a class inherited from [AbstractRibbonGroup](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractRibbonGroup.yml) -* Decorate the newly created class using the [RibbonGroupAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.RibbonGroupAttribute.yml) attribute to define the ribbon group. -* Decorate single or multiple times the newly created class using the [RibbonGroupLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.RibbonGroupLayoutAttribute.yml) attribute to define the ribbon group layout settings. - -For a sample on how to create a ribbon group, see: [Integrating ribbon groups](integrating_ribbon_groups.md) +## Basic Ribbon Group -> [!NOTE] +To create ribbon groups, complete the following steps: + +* Create a class that inherits from [AbstractRibbonGroup](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractRibbonGroup.yml) +* Apply the [RibbonGroupAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.RibbonGroupAttribute.yml) attribute to specify ribbon group metadata +* Apply one or more [RibbonGroupLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.RibbonGroupLayoutAttribute.yml) attributes to specify layout settings + +See [Integrating ribbon groups](integrating_ribbon_groups.md) for an example. + +> [!IMPORTANT] > -> If there are no UI elements added inside the ribbon group, it will not be visible. +> You must add at least one UI element to the ribbon group. Empty ribbon groups do not appear in the UI. + +## Related Topics -See Also ------ -[Creating action](creating_actions.md) +* [Creating action](creating_actions.md) diff --git a/apiconcepts/integration/creating_the_ui_editor_control_for_your_display_filter.md b/apiconcepts/integration/creating_the_ui_editor_control_for_your_display_filter.md index 08456c9c83..0ad5509fde 100644 --- a/apiconcepts/integration/creating_the_ui_editor_control_for_your_display_filter.md +++ b/apiconcepts/integration/creating_the_ui_editor_control_for_your_display_filter.md @@ -1,27 +1,38 @@ -Creating the UI Editor Control for your Display Filter -==== -To apply your implementation of the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml), get a reference to the active document and from there, apply the filter through the `ApplyFilterOnSegments` method. This will invoke a filter action on the document and while iterating over each of the segments, the API will call back into your implementation where you can assert whether or not the segment should be visible in the Var:ProductName Editor. +# Creating the UI Editor Control for your Display Filter -For a more complete solution, it would be useful to make this type of functionality available from the Var:ProductName Editor, so that the end-user can choose which criteria they would like to include in the filter. +To apply your [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) implementation, get a reference to the active document and apply the filter using the `ApplyFilterOnSegments` method. This invokes a filter action on the document. As the API iterates over each segment, it calls back into your implementation to determine whether each segment should display in the Var:ProductName Editor. -Add two files to the project that permit the user to view the control in the Studio Editor and then select and apply the filter criteria on the document: +For a complete solution, expose this functionality from the Var:ProductName Editor so end-users can choose which filter criteria to include. -* User Control - The user control will contain the code related to the filter criteria that will be applied on the document -* Controller - The controller is a simple class that is decorated with the extensions that are required by the API to add the user control to the studio editor; for this example, there is very little work involved with the controller. +Add two files to your project: -Add a new user control to the project and name it `DisplayFilterControl`, as shown in the example below: +- **User Control** - Contains the code for filter criteria that apply to the document +- **Controller** - A simple class decorated with the required API extensions to add the user control to the Studio Editor -Include UI design elements to the user control that permit the user to choose the appropriate criteria settings for the filter that will be applied on the document. Make reference to the following images an example of how this might look in your control. For the purpose of this example we will be concentrating more on how to apply the display filter as opposed to how the UI design elements are presented in the control. +## Add the DisplayFilterControl + +Create a new user control and name it `DisplayFilterControl`. + +Add UI design elements that let users select appropriate filter criteria settings. The following examples show how this might appear. For this guide, we focus on applying the display filter rather than UI design details. > [!NOTE] -> -> The code related to the design controls is available in the SDK so that you can eventually make reference to it. +> +> The SDK includes design control code that you can reference. + +Open the user control in code view. To apply your [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) implementation to the active document: + +1. Get a reference to the [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml). +2. Subscribe to the [ActiveDocumentChanged](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml#Sdl_TranslationStudioAutomation_IntegrationApi_EditorController_ActiveDocumentChanged) event to track the active document from the editor. Subscribe in the constructor to ensure the control has a reference when instantiated in the Editor. + +Once you have a reference to the active document, call the [ApplyFilterOnSegments](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.IStudioDocument.yml#Sdl_TranslationStudioAutomation_IntegrationApi_IStudioDocument_ApplyFilterOnSegments_Sdl_TranslationStudioAutomation_IntegrationApi_DisplayFilters_IDisplayFilter_) method with your [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) implementation: -Once you have added the UI design elements, open the user control in code view. In order to apply your implementation of the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) on the active document, you will first need to get a reference to the [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml), and then subscribe to the [ActiveDocumentChanged](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml#Sdl_TranslationStudioAutomation_IntegrationApi_EditorController_ActiveDocumentChanged) event to ensure that you are always working with the active document from the editor. Making reference to the example code underneath, you can see that we subscribe to this event in the constructor to ensure that we have a handle on this when the control is instantiated in the Editor. +```csharp +ActiveDocument.ApplyFilterOnSegments(new DisplayFilter(filterSettings)); +``` -Once you have a reference to the active document, you only need to call the method [ApplyFilterOnSegments](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.IStudioDocument.yml#Sdl_TranslationStudioAutomation_IntegrationApi_IStudioDocument_ApplyFilterOnSegments_Sdl_TranslationStudioAutomation_IntegrationApi_DisplayFilters_IDisplayFilter_) with your implementation of the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml), as follows: `ActiveDocument.ApplyFilterOnSegments(new DisplayFilter(filterSettings););` This will then invoke a filter action on the document and while iterating over each of the segments, the API will call back into to the method `EvaluateRow` of your implementation. +The API invokes a filter action on the document and calls the `EvaluateRow` method of your implementation as it iterates over each segment. -Subscribing to the [DocumentFilterChanged](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.IStudioDocument.yml#Sdl_TranslationStudioAutomation_IntegrationApi_IStudioDocument_DocumentFilterChanged) event is quite useful as it permits you to understand when a filter has been applied on the document and then further deduct whether or not that filter is derived from you implementation of the interface. +Subscribe to the [DocumentFilterChanged](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.IStudioDocument.yml#Sdl_TranslationStudioAutomation_IntegrationApi_IStudioDocument_DocumentFilterChanged) event to understand when the document applies a filter and whether that filter comes from your implementation. # [C#](#tab/tabid-1) ```cs using System; @@ -43,20 +54,16 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls { public partial class DisplayFilterControl : UserControl { - #region | Delegates | - public delegate void OnApplyFilterHandler(IDisplayFilterSettings displayFilterSettings, FilteredCountsCallback result); public event OnApplyFilterHandler OnApplyDisplayFilter; public delegate void FilteredCountsCallback(int filteredSegments, int totalSegments); - #endregion - - #region | Properties | private static EditorController GetEditorController() { return SdlTradosStudio.Application.GetController(); } + private EditorController EditorController { get; set; } private Document ActiveDocument { get; set; } @@ -71,7 +78,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls { get { - #region | get settings | var settings = new DisplayFilterSettings() { IsRegularExpression = checkBox_regularExpression.Checked, @@ -84,7 +90,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls ShowAllContent = false }; - foreach (var contextInfo in listView_contextInfo.SelectedItems .Cast().Select(selectedItem => selectedItem.Tag as IContextInfo) .Where(contextInfo => contextInfo != null @@ -113,15 +118,12 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls else if (item.Group == GroupContentTypesSelected) settings.SegmentContentTypes.Add(item.Tag.ToString()); } - #endregion + return settings; } set { if (value == null) return; - #region | set settings | - - #region | content panel | textBox_source.Text = value.SourceText; textBox_target.Text = value.TargetText; @@ -129,10 +131,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls checkBox_regularExpression.Checked = value.IsRegularExpression; checkBox_caseSensitive.Checked = value.IsCaseSensitive; - #endregion - - #region | filters panel | - try { listView_available.BeginUpdate(); @@ -149,11 +147,9 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls StringResources.DisplayFilterControl_ShowAllContent && value.ShowAllContent)) { - MoveListViewItem(listView_available, item, listView_selected); } - if (value.RepetitionTypes.Any()) { foreach (var item in listView_available.Items.Cast() @@ -162,7 +158,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls item.Group == GroupRepetitionTypesAvailable && value.RepetitionTypes.Contains(item.Tag.ToString()))) { - MoveListViewItem(listView_available, item, listView_selected); } } @@ -175,7 +170,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls item.Group == GroupReviewTypesAvailable && value.SegmentReviewTypes.Contains(item.Tag.ToString()))) { - MoveListViewItem(listView_available, item, listView_selected); } } @@ -188,7 +182,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls item.Group == GroupLockingTypesAvailable && value.SegmentLockingTypes.Contains(item.Tag.ToString()))) { - MoveListViewItem(listView_available, item, listView_selected); } } @@ -201,12 +194,10 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls item.Group == GroupContentTypesAvailable && value.SegmentContentTypes.Contains(item.Tag.ToString()))) { - MoveListViewItem(listView_available, item, listView_selected); } } - if (value.ConfirmationLevels.Any()) { foreach (var item in listView_available.Items.Cast() @@ -215,15 +206,12 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls item.Group == GroupStatusAvailable && value.ConfirmationLevels.Contains(item.Tag.ToString()))) { - MoveListViewItem(listView_available, item, listView_selected); } } - if (value.OriginTypes.Any()) { - foreach (var item in listView_available.Items.Cast() .Where( item => @@ -236,7 +224,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls if (value.PreviousOriginTypes.Any()) { - foreach (var item in listView_available.Items.Cast() .Where( item => @@ -253,20 +240,10 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls listView_selected.EndUpdate(); } - #endregion - - #region | comments panel | - textBox_commentText.Text = value.CommentText; textBox_commentAuthor.Text = value.CommentAuthor; comboBox_commentSeverity.SelectedIndex = value.CommentSeverity; - - #endregion - - #region | context info panel | - - foreach (ListViewItem item in listView_contextInfo.Items) { var contextInfoItem = item.Tag as IContextInfo; @@ -275,16 +252,9 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls else item.Selected = false; } - - #endregion - - #endregion } } - - #region | ListView Groups | - internal static ListViewGroup GroupStatusAvailable { get; set; } internal static ListViewGroup GroupOriginAvailable { get; set; } internal static ListViewGroup GroupPreviousOriginAvailable { get; set; } @@ -294,7 +264,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls internal static ListViewGroup GroupLockingTypesAvailable { get; set; } internal static ListViewGroup GroupContentTypesAvailable { get; set; } - private static ListViewGroup GroupStatusSelected { get; set; } private static ListViewGroup GroupOriginSelected { get; set; } private static ListViewGroup GroupPreviousOriginSelected { get; set; } @@ -304,25 +273,16 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls private static ListViewGroup GroupLockingTypesSelected { get; set; } private static ListViewGroup GroupContentTypesSelected { get; set; } - #endregion - - - #endregion - - #region | Constructor | public DisplayFilterControl() { InitializeComponent(); AddGroupsToOriginTypeListview(); - InitializeSettings(); - listView_available.ListViewItemSorter = new ListViewItemComparer(); listView_selected.ListViewItemSorter = new ListViewItemComparer(); - EditorController = GetEditorController(); EditorController.ActiveDocumentChanged += EditorController_ActiveDocumentChanged; @@ -330,95 +290,64 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls OnApplyDisplayFilter += ApplyDisplayFilter; - listView_available.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Collapsed); listView_selected.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Normal); listView_available.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Normal, listView_available.Groups[1]); listView_available.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Normal, listView_available.Groups[2]); - } - - - #endregion - - private void InitializeSettings() { - #region | content panel | - textBox_source.Text = string.Empty; textBox_target.Text = string.Empty; checkBox_regularExpression.Checked = false; checkBox_caseSensitive.Checked = false; - #endregion - - #region | filters panel | - try { listView_available.BeginUpdate(); listView_selected.BeginUpdate(); - listView_available.Items.Clear(); listView_selected.Items.Clear(); - var _item = - listView_available.Items.Add( - StringResources.DisplayFilterControl_Show_All_Content); + var _item = listView_available.Items.Add(StringResources.DisplayFilterControl_Show_All_Content); _item.Group = GroupGeneralAvailable; _item.Tag = StringResources.DisplayFilterControl_ShowAllContent; - foreach (var type in Enum.GetValues(typeof(DisplayFilterSettings.RepetitionType))) { - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.RepetitionType)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.RepetitionType)type)); item.Group = GroupRepetitionTypesAvailable; item.Tag = type; } - foreach (var type in Enum.GetValues(typeof(DisplayFilterSettings.SegmentReviewType))) { - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.SegmentReviewType)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.SegmentReviewType)type)); item.Group = GroupReviewTypesAvailable; item.Tag = type; } - foreach (var type in Enum.GetValues(typeof(DisplayFilterSettings.SegmentLockingType))) { - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.SegmentLockingType)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.SegmentLockingType)type)); item.Group = GroupLockingTypesAvailable; item.Tag = type; } - foreach (var type in Enum.GetValues(typeof(DisplayFilterSettings.SegmentContentType))) { - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.SegmentContentType)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.SegmentContentType)type)); item.Group = GroupContentTypesAvailable; item.Tag = type; } - foreach (var type in Enum.GetValues(typeof(DisplayFilterSettings.ConfirmationLevel))) { - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.ConfirmationLevel)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.ConfirmationLevel)type)); item.Group = GroupStatusAvailable; item.Tag = type; } @@ -428,25 +357,21 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls if (type.ToString() == "None") continue; - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.OriginType)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.OriginType)type)); item.Group = GroupOriginAvailable; - item.Tag = type; } + foreach (var type in Enum.GetValues(typeof(DisplayFilterSettings.OriginType))) { if (type.ToString() == "None") continue; - var item = - listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.OriginType)type)); - + var item = listView_available.Items.Add(Helper.GetTypeName((DisplayFilterSettings.OriginType)type)); item.Group = GroupPreviousOriginAvailable; - item.Tag = type; } + listView_available.Items[0].Selected = true; } finally @@ -455,10 +380,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls listView_selected.EndUpdate(); } - #endregion - - #region | comments panel | - textBox_commentText.Text = string.Empty; textBox_commentAuthor.Text = string.Empty; @@ -468,21 +389,10 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls comboBox_commentSeverity.SelectedIndex = 0; - #endregion - - #region | context info panel | - PopulateContextInfoList(); - #endregion - - #region | filter status counter | - - // initialize the filter status counter UpdateFilteredCountDisplay(0, 0); - #endregion - InitializeTabPageIcons(); } @@ -497,9 +407,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls public void ClearFilter() { - InitializeSettings(); - ApplyFilter(); } @@ -528,18 +436,14 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls Filter = StringResources.DisplayFilterControl_Settings_XML_File_sdladfsettings }; - if (loadSettingsDialog.ShowDialog() != DialogResult.OK) return; try { - // read in the xml content string settingsXml; using (var sr = new StreamReader(loadSettingsDialog.FileName, Encoding.UTF8)) settingsXml = sr.ReadToEnd(); - // deserialize the to the settings xml DisplayFilterSettings = DisplayFilterSerializer.DeserializeSettings(settingsXml); - ApplyFilter(); } catch (Exception ex) @@ -548,16 +452,15 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls } } - private void ActiveDocument_DocumentFilterChanged(object sender, DocumentFilterEventArgs e) { if (e.DisplayFilter == null || e.DisplayFilter.GetType() != typeof(DisplayFilters.DisplayFilter)) InitializeSettings(); - UpdateFilteredCountDisplay(e.FilteredSegmentPairsCount, e.TotalSegmentPairsCount); } + private void EditorController_ActiveDocumentChanged(object sender, DocumentEventArgs e) { InitializeSettings(); @@ -565,7 +468,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls if (ActiveDocument != null) ActiveDocument.DocumentFilterChanged -= ActiveDocument_DocumentFilterChanged; - // get a reference to the active document ActiveDocument = e.Document; if (ActiveDocument != null) @@ -578,24 +480,23 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls if (ActiveDocument.DisplayFilter != null && ActiveDocument.DisplayFilter.GetType() == typeof(DisplayFilters.DisplayFilter)) { - //invalidate UI with display settings recovered from the active document DisplayFilterSettings = ((DisplayFilters.DisplayFilter)ActiveDocument.DisplayFilter).Settings as DisplayFilterSettings; } UpdateFilteredCountDisplay(ActiveDocument.FilteredSegmentPairsCount, ActiveDocument.TotalSegmentPairsCount); } } + private void ApplyDisplayFilter(IDisplayFilterSettings displayFilterSettings, FilteredCountsCallback result) { if (ActiveDocument == null) return; DisplayFilter = new DisplayFilters.DisplayFilter(displayFilterSettings, ActiveDocument); - ActiveDocument.ApplyFilterOnSegments(DisplayFilter); - result.Invoke(ActiveDocument.FilteredSegmentPairsCount, ActiveDocument.TotalSegmentPairsCount); } + private void UpdateFilteredCountDisplay(int filteredSegments, int totalSegments) { FilteredSegmentPairsCount = filteredSegments; @@ -608,6 +509,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls UpdateFilterExpression(); CheckEnabledFilterIcons(); } + private void UpdateFilterExpression() { filterExpressionControl.ClearItems(); @@ -679,7 +581,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls + Helper.GetTypeName((DisplayFilterSettings.SegmentContentType)Enum.Parse( typeof(DisplayFilterSettings.SegmentContentType), item, true))) + ")"); - if (DisplayFilterSettings.CommentText != string.Empty) filterExpressionControl.AddItem(StringResources.DisplayFilterControl_Comment_text + ":\"" + DisplayFilterSettings.CommentText + "\""); if (DisplayFilterSettings.CommentAuthor != string.Empty) @@ -687,7 +588,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls if (DisplayFilterSettings.CommentSeverity > 0) filterExpressionControl.AddItem(StringResources.DisplayFilterControl_Comment_severity + ":\"" + (DisplayFilterSettings.CommentSeverityType)DisplayFilterSettings.CommentSeverity + "\""); - if (DisplayFilterSettings.ContextInfoTypes.Any()) filterExpressionControl.AddItem(StringResources.DisplayFilterControl_Document_structure + ":" + "(" + DisplayFilterSettings.ContextInfoTypes.Aggregate(string.Empty, (current, item) => current @@ -695,13 +595,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls + ContextInfoList.FirstOrDefault(a => a.ContextType == item).DisplayCode) + ")"); } - - - #region | Helpers | - - - #region | Tab icons | - private void InitializeTabPageIcons() { tabPage_content.ImageIndex = -1; @@ -709,6 +602,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls tabPage_comments.ImageIndex = -1; tabPage_contextInfo.ImageIndex = -1; } + private void CheckEnabledFilterIcons() { if (ActiveDocument != null) @@ -742,6 +636,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls panel_filterStatusBarImage.Visible = visible; panel_filterStatusBar.BackColor = visible ? SystemColors.GradientInactiveCaption : Color.Transparent; } + private bool IsFilterApplied(IDisplayFilterSettings settings) { if (!string.IsNullOrEmpty(settings.SourceText) @@ -767,10 +662,12 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls return false; } } + private void InvalidateIconsFilterApplied(TabPage tabPage) { tabPage.ImageIndex = -1; } + private void InvalidateIconsFilterApplied_contentTab(IDisplayFilterSettings settings) { if (!string.IsNullOrEmpty(settings.SourceText) @@ -782,11 +679,10 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls { tabPage_content.ImageIndex = -1; } - } + private void InvalidateIconsFilterApplied_filtersTab(IDisplayFilterSettings settings) { - if (settings.SegmentReviewTypes.Any() || settings.ConfirmationLevels.Any() || settings.OriginTypes.Any() @@ -803,11 +699,10 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls { tabPage_filters.ImageIndex = -1; } - } + private void InvalidateIconsFilterApplied_commentsTab(IDisplayFilterSettings settings) { - if (!string.IsNullOrEmpty(settings.CommentText) || !string.IsNullOrEmpty(settings.CommentAuthor) || settings.CommentSeverity > 0) @@ -818,8 +713,8 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls { tabPage_comments.ImageIndex = -1; } - } + private void InvalidateIconsFilterApplied_contextInfoTab(IDisplayFilterSettings settings) { if (settings.ContextInfoTypes.Any()) @@ -830,11 +725,10 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls { tabPage_contextInfo.ImageIndex = -1; } - } + private void InvalidateIconsFilterEdited(TabPage tabPage) { - if (ActiveDocument != null && ActiveDocument.DisplayFilter != null && ActiveDocument.DisplayFilter.GetType() == typeof(DisplayFilters.DisplayFilter)) { @@ -863,7 +757,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls || settings.SegmentReviewTypes.Any() || settings.ShowAllContent)) { - var list1 = new List { DisplayFilterSettings.ShowAllContent.ToString() }; list1.AddRange(DisplayFilterSettings.OriginTypes); list1.AddRange(DisplayFilterSettings.PreviousOriginTypes); @@ -873,7 +766,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls list1.AddRange(DisplayFilterSettings.SegmentLockingTypes); list1.AddRange(DisplayFilterSettings.SegmentContentTypes); - var list2 = new List { settings.ShowAllContent.ToString() }; list2.AddRange(settings.OriginTypes); list2.AddRange(settings.PreviousOriginTypes); @@ -902,7 +794,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls } else if (tabPage == tabPage_contextInfo && settings.ContextInfoTypes.Any()) { - // check if identical selection var list = new List(); foreach (var contextInfo in listView_contextInfo.SelectedItems .Cast().Select(selectedItem => selectedItem.Tag as IContextInfo) @@ -914,7 +805,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls tabPage.ImageIndex = string.Join(", ", list) == string.Join(", ", settings.ContextInfoTypes) ? 0 : 1; - } else tabPage.ImageIndex = 1; @@ -925,11 +815,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls } } - - #endregion - - #region | Filter Attributes group | - private void CheckEnabledActionButtons() { var add = true; @@ -949,6 +834,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls button_remove.Enabled = remove; button_removeAll.Enabled = removeAll; } + private void MoveSelectedListViewItem(ListView from, ListView to) { if (from.SelectedItems.Count > 0) @@ -962,7 +848,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls AssignOriginTypeListViewItemGroup(itemTo, itemFrom.Group); - itemFrom.Remove(); } @@ -974,6 +859,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls CheckEnabledActionButtons(); } } + private static void SelectDefaultItem(ListView from, int itemIndex) { if (from.Items.Count > 0) @@ -987,6 +873,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls from.Items[itemIndex].Selected = true; } } + private void MoveListViewItem(ListView from, ListViewItem itemFrom, ListView to) { var itemIndex = itemFrom.Index; @@ -1003,8 +890,8 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls listView_selected.Sort(); CheckEnabledActionButtons(); - } + private void MoveAllListViewItems(ListView from, ListView to) { foreach (ListViewItem itemFrom in from.Items) @@ -1020,6 +907,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls CheckEnabledActionButtons(); } + private void AssignOriginTypeListViewItemGroup(ListViewItem itemTo, ListViewGroup fromGroup) { if (itemTo.ListView.Equals(listView_available) @@ -1065,9 +953,9 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls } } } + private void AddGroupsToOriginTypeListview() { - listView_available.ShowGroups = true; listView_selected.ShowGroups = true; @@ -1108,9 +996,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls listView_selected.Groups.Add(GroupContentTypesSelected); } - #endregion - - #region | Context info | private void SetContextInfoList() { ContextInfoList = new List(); @@ -1126,6 +1011,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls } } } + private void PopulateContextInfoList() { try @@ -1152,12 +1038,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls UpdatedContextInfoSelectedStatusCount(); } - #endregion - - #endregion - - #region | ToolbarStrip events | - private void toolStripButton_applyFilter_Click(object sender, EventArgs e) { ApplyFilter(); @@ -1178,10 +1058,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls LoadFilter(); } - #endregion - - #region | Content tab events | - private void textBox_source_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Return) @@ -1194,7 +1070,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls ApplyFilter(); } - private void textBox_source_TextChanged(object sender, EventArgs e) { InvalidateIconsFilterEdited(tabPage_content); @@ -1215,11 +1090,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls InvalidateIconsFilterEdited(tabPage_content); } - #endregion - - #region | Filter Attributes tab events | - - private void button_add_Click(object sender, EventArgs e) { MoveSelectedListViewItem(listView_available, listView_selected); @@ -1248,11 +1118,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls CheckEnabledActionButtons(); } - - #endregion - - #region | Comments tab events | - private void textBox_commentText_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Return) @@ -1265,8 +1130,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls ApplyFilter(); } - - private void textBox_commentText_TextChanged(object sender, EventArgs e) { InvalidateIconsFilterEdited(tabPage_comments); @@ -1282,9 +1145,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls InvalidateIconsFilterEdited(tabPage_comments); } - #endregion - - #region | Contextinfo tab events | private void linkLabel_contextInfoClearSelection_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { listView_contextInfo.BeginUpdate(); @@ -1325,10 +1185,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls label_contextInfoSelected.Text = string.Format("Selected: {0}", listView_contextInfo.SelectedItems.Count); } - #endregion - - - private void listView_contextInfo_Resize(object sender, EventArgs e) { var width = ((ListView)sender).Width - 20 - SystemInformation.VerticalScrollBarWidth; @@ -1341,7 +1197,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls private void listView_available_Resize(object sender, EventArgs e) { var width = ((ListView)sender).Width - 20 - SystemInformation.VerticalScrollBarWidth; - columnHeader_filtersAvailable_name.Width = width; + columnHeader_filtersAvailable_name.Width = width; } private void listView_selected_Resize(object sender, EventArgs e) @@ -1349,16 +1205,9 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Controls var width = ((ListView)sender).Width - 20 - SystemInformation.VerticalScrollBarWidth; columnHeader_filtersSelected_name.Width = width; } - - } - - - - } ``` -**** To load the user control in the Var:ProductName Editor, you will need to add a controller and decorate it with the appropriate extensions that will provide the API with enough information to identify and then load it. @@ -1399,4 +1248,3 @@ namespace Community.AdvancedDisplayFilter.Controls } } ``` -***** diff --git a/apiconcepts/integration/creating_viewparts.md b/apiconcepts/integration/creating_viewparts.md index 86fa90ad2b..234d2709d6 100644 --- a/apiconcepts/integration/creating_viewparts.md +++ b/apiconcepts/integration/creating_viewparts.md @@ -1,37 +1,36 @@ -Creating viewparts -==== - -Var:ProductName Integration API provides support for third-party developers to integrate UI viewparts inside the Var:ProductName desktop applications. - -Creating viewparts for a custom view ----- -In order to create view parts, a third-party developer will require the following steps: - -* Create a view which allows viewparts -* Create one or more viewparts to define the main view content area - * Create a windows form user control to define the content of the viewpart - * Create a controller class that will define the main content area of the view which must implement the [AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) -* Decorate the controller class with the following attributes to provide metadata information regarding the viewparts: - * [ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) - * [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) -* Target the viewpart location by setting the `LocationByType` property with the view controller type. -* Set the `Dock` property to `Fill` -* Create the other viewparts as the content viewpart with the exception that the docking will not be of type `Fill`. - -[ntegrating viewpart sample](integrating_viewparts.md) - -Creating viewparts for Var:ProductName views ------ -In order to create viewparts and integrate them into the Var:ProductName views, the third-party developer will require the following steps: - -* Create a windows form user control to define the content of the viewpart -* Create a viewpart controller class which must implement the `AbstractViewPartController` -* Decorate the controller class with the following attributes to provide metadata information regarding the viewparts: - * [ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) - * [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) -* Target the viewpart location by setting the `LocationByType` property with the one of the view controllers defined: - * [ProjectsController](projects_controller.md) - * [FilesController](files_controller.md) - * [EditorController](editor_controller.md) - -[Integrating viewpart sample](integrating_viewparts.md) +# Creating View Parts + +The Var:ProductName Integration API allows developers to integrate custom UI view parts into Var:ProductName desktop applications. + +## View Parts for Custom Views + +To create custom view parts for a custom view, complete the following steps: + +* Create a view that allows view parts +* Create one or more view parts to define the content area: + * Create a Windows Forms user control for the view part content + * Create a controller class that implements [AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) +* Apply the following attributes to specify view part metadata: + * [ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) + * [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) +* Set the `LocationByType` property to target the view controller +* Set the `Dock` property to `Fill` for the main content area +* Create additional view parts with appropriate docking (not `Fill`) + +See [Integrating viewpart sample](integrating_viewparts.md) for an example. + +## View Parts for Var:ProductName Views + +To create view parts and integrate them into Var:ProductName views, complete the following steps: + +* Create a Windows Forms user control for the view part content +* Create a view part controller class that implements `AbstractViewPartController` +* Apply the following attributes to specify view part metadata: + * [ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) + * [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) +* Set the `LocationByType` property to target one of the following view controllers: + * [ProjectsController](projects_controller.md) + * [FilesController](files_controller.md) + * [EditorController](editor_controller.md) + +See [Integrating viewpart sample](integrating_viewparts.md) for an example. diff --git a/apiconcepts/integration/creating_views.md b/apiconcepts/integration/creating_views.md index 4b535965a4..39f4708777 100644 --- a/apiconcepts/integration/creating_views.md +++ b/apiconcepts/integration/creating_views.md @@ -1,25 +1,23 @@ -Creating views -=== -Var:ProductName Integration API provides support for the third-party developers to integrate UI views inside the Studio desktop applications. +# Creating Views -Creating a new view ---- +The Var:ProductName Integration API allows developers to integrate custom UI views into Studio desktop applications. -In order to create a new view, a third-party developer will require the following steps: +## Basic View -* Create a windows form user control to define the content of the view -* Create a controller class for the view, which must implement the [AbstractViewController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewController.yml) class -* Decorate the controller class with the [ViewAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewAttribute.yml) attribute to provide metadata informations regarding the view +To create a basic view, complete the following steps: -[Integrating view sample](integrating_views.md) +* Create a Windows Forms user control to define the view's content +* Create a controller class that implements the [AbstractViewController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewController.yml) class +* Apply the [ViewAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewAttribute.yml) attribute to the controller class to specify view metadata -Creating a new view which allows view parts ---- -In order to create a new view which allows viewparts, a third-party developer will require the following steps: +See [Integrating view sample](integrating_views.md) for an example. -* Create a controller class for the view, which must implement the [AbstractViewController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewController.yml) class -* Decorate the controller class with the [ViewAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewAttribute.yml) attribute to provide metadata informations regarding the view -* Set the boolean property `AllowViewParts` to `true` +## View with View Parts +To create a view that supports view parts, complete the following steps: -For more detailed information on how to create a view which contains viewparts, see the topic [Integrating viewparts](integrating_viewparts.md). +* Create a controller class that implements the [AbstractViewController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewController.yml) class +* Apply the [ViewAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewAttribute.yml) attribute to the controller class to specify view metadata +* Set the `AllowViewParts` property to `true` + +See [Integrating viewparts](integrating_viewparts.md) for more information. diff --git a/apiconcepts/integration/customize_create_return_package_wizard.md b/apiconcepts/integration/customize_create_return_package_wizard.md index 46595fa6b7..80710e78c3 100644 --- a/apiconcepts/integration/customize_create_return_package_wizard.md +++ b/apiconcepts/integration/customize_create_return_package_wizard.md @@ -1,25 +1,28 @@ -# Customize the *Create Return Package* wizard +# Customize the Create Return Package wizard -Var:ProductName Integration API provides support for third-party developers to trigger the __Create Return Package__ wizard from their own custom logic or actions and extend it's basic functionality by: -- specifying the project Guid for which a return package needs to be created -- specifying the project and the files that should be contained in the resulting return package -- specifying the project and all files associated to the given task that should be contained in the resulting return package -- injecting additional wizard pages at the beginning of the wizard -- injecting additional wizard pages before the final processing of the package -- injecting specific processing logic during the package processing phase +The Var:ProductName Integration API enables you to launch the **Create Return Package** wizard from custom code or actions and extend its functionality by: -All above details are passed into an instance of [CreateReturnPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.CreateReturnPackageEvent.yml) and published via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml). The exact purpose of each parameter is explained in the table bellow for all constructor options available. +- Specifying the project GUID for creating a return package +- Selecting which project files to include in the return package +- Selecting a task and all associated files to include in the return package +- Injecting custom wizard pages at the beginning of the wizard +- Injecting custom wizard pages before the final processing step +- Adding custom processing logic during package creation + +All these options are passed through a [CreateReturnPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.CreateReturnPackageEvent.yml) instance and published via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml). The following table explains each constructor parameter: | Property | Description | | ------------- | -----| -| `projectId` | The project `Guid` which you can obtain from the [ProjectInfo](../../api/projectautomation/Sdl.ProjectAutomation.Core.ProjectInfo.yml) class.| -| `job` | Used to pass an [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml) object to be executed once the package was loaded in Studio. Should be left `null` if no custom job needs to be executed. Details on how to create a custom execution job can be found [here](implementing_custom_job.md). | -| `files` | Used to specify the language files that need to be included in the return package as a collection of `Guid`s. | -| `taskId` |Used to specify the task `Guid` that needs to be included in the return package. | -|`firstpages`| A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to be displayed at the start of the wizard. Details on how to implement a custom wizard page can be found [here](adding_custom_wizard_steps.md)| -|`lastpages`| A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to be displayed at the end of the wizard. Details on how to implement a custom wizard page can be found [here](adding_custom_wizard_steps.md). The pages will be inserted before the processing step in the wizard.| +| `projectId` | The project `Guid` from the [ProjectInfo](../../api/projectautomation/Sdl.ProjectAutomation.Core.ProjectInfo.yml) class. | +| `job` | An [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml) object to execute after the package loads in Studio. Set to `null` if no custom job is needed. See [implementing custom jobs](implementing_custom_job.md) for details. | +| `files` | A collection of `Guid` values specifying which language files to include in the return package. | +| `taskId` | The task `Guid` to include in the return package. | +| `firstPages` | A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to display at the wizard start. See [adding custom wizard steps](adding_custom_wizard_steps.md) for details. | +| `lastPages` | A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to display before the processing step. See [adding custom wizard steps](adding_custom_wizard_steps.md) for details. | + +## Example -Bellow you can see a sample of how a custom call to open the __Create Return Package__ wizard should look like. +The following code sample shows how to launch the **Create Return Package** wizard: ```cs var initialWizardSteps = new List @@ -28,10 +31,10 @@ var initialWizardSteps = new List new SecondPage() }; -//create the Job object +// Create the Job object var publishJob = new SampleJob() { JobName = "Sample Job" }; -//obtain the project Guid +// Get the project Guid var currentProject = SdlTradosStudio.Application.GetController().CurrentProject; if (currentProject != null) { @@ -43,4 +46,4 @@ if (currentProject != null) firstPages: initialWizardSteps, lastPages: null)); } -``` +``` \ No newline at end of file diff --git a/apiconcepts/integration/customize_open_package_wizard.md b/apiconcepts/integration/customize_open_package_wizard.md index f936d14e72..e10beffee0 100644 --- a/apiconcepts/integration/customize_open_package_wizard.md +++ b/apiconcepts/integration/customize_open_package_wizard.md @@ -1,25 +1,28 @@ -# Customize the *Open Package* wizard - -Var:ProductName Integration API provides support for third-party developers to trigger the __Open Project Package__ wizard from their own custom logic or actions and extend it's basic functionality by -- providing the physical location of the package -- providing a custom icon for the final imported project -- specifying the origin of the imported project -- injecting additional wizard pages at the beginning of the wizard -- injecting additional wizard pages before the final processing of the package -- injecting specific processing logic during the package processing phase - -All above details are passed into an instance of [OpenProjectPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.OpenProjectPackageEvent.yml) and published via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml). The exact purpose of each parameter is explained in the table bellow: - -| Property | Description | -| ------------- | -----| -| `packageFilePath` | Used to specify a path to the package to be opened.| -| `job` | Used to pass an [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml) object to be executed once the package was loaded in Studio. Should be left `null` if no custom job needs to be executed. Details on how to create a custom execution job can be found [here](implementing_custom_job.md). | -| `iconPath` | Used to set an icon for your project. This allows you to customize the Projects View and have project icons specific to your plugin. | -| `projectOrigin` | Used to set a project type. This allows you to customize the Projects View and have the project type specific to your plugin. | -|`firstpages`| A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to be displayed at the start of the wizard. Details on how to implement a custom wizard page can be found [here](adding_custom_wizard_steps.md)| -|`lastpages`| A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to be displayed at the end of the wizard. Details on how to implement a custom wizard page can be found [here](adding_custom_wizard_steps.md). The pages will be inserted before the processing step in the wizard.| - -Bellow you can see a sample of how a custom call to open the __Open Package__ wizard should look like. +# Customize the Open Package wizard + +The Var:ProductName Integration API enables you to launch the **Open Package** wizard from custom code or actions and extend its functionality by: + +- Specifying the physical location of the package +- Providing a custom icon for the imported project +- Specifying the project type/origin +- Injecting custom wizard pages at the beginning of the wizard +- Injecting custom wizard pages before the final processing step +- Adding custom processing logic during package processing + +All these options are passed through an [OpenProjectPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.OpenProjectPackageEvent.yml) instance and published via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml). The following table explains each parameter: + +| Property | Description | +| --- | --- | +| `packageFilePath` | Path to the package to open. | +| `job` | An [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml) object to execute after the package loads in Studio. Set to `null` if no custom job is needed. See [implementing custom jobs](implementing_custom_job.md) for details. | +| `iconPath` | Icon path to customize the project appearance in the Projects View. | +| `projectOrigin` | Project type to differentiate projects in the Projects View. | +| `firstPages` | A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to display at the wizard start. See [adding custom wizard steps](adding_custom_wizard_steps.md) for details. | +| `lastPages` | A collection of [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml) objects to display before the processing step. See [adding custom wizard steps](adding_custom_wizard_steps.md) for details. | + +## Example + +The following code sample shows how to launch the **Open Package** wizard: ```cs var initialWizardSteps = new List { @@ -42,7 +45,9 @@ _eventAggregator.Publish( lastPages: finalWizardSteps)); ``` -See also: [Full sample application with source code](https://github.com/RWS/trados-studio-api-samples/tree/master/TranslationStudioAutomation/Sdl.CustomWizardSteps.Sample) (on GitHub). +## See also + +[Full sample application with source code](https://github.com/RWS/trados-studio-api-samples/tree/master/TranslationStudioAutomation/Sdl.CustomWizardSteps.Sample) (on GitHub) diff --git a/apiconcepts/integration/display_filter.md b/apiconcepts/integration/display_filter.md index f053b72af3..30d9976fc9 100644 --- a/apiconcepts/integration/display_filter.md +++ b/apiconcepts/integration/display_filter.md @@ -1,30 +1,26 @@ -Introduction -===== -Find out what the Display Filter API does and how you can leverage it to create a custom filter. +# Introduction -What is a Custom Display Filter? ---- -In Var:ProductName, a display filter limits the display of segments in the Editor based on specific attributes. Third-party developers can integrate their own custom display filters that can process the segments in the Var:ProductName Editor. +Learn about the Display Filter API and how to create a custom filter to enhance segment filtering in Var:ProductName. -The Advanced Display Filter that ships with Var:ProductName is an example of an implementation based on the Display Filter API. The Advanced Display Filter enables Var:ProductName power-users to access more segment filtering options than the standard Display Filter does. +## What is a Custom Display Filter? -To access the Advanced Display Filter the user has to click **View > Advanced Display Filter**. +A display filter in Var:ProductName limits which segments the Editor displays based on specific attributes. Third-party developers can integrate custom display filters that process segments in the Var:ProductName Editor. -In the Advanced Display Filter window, end-users can create and save filters based on: +The Advanced Display Filter that ships with Var:ProductName demonstrates one Display Filter API implementation. It provides Var:ProductName power-users with more filtering options than the standard Display Filter offers. -* segment content - this displays the segments that contain a certain text in source or target. -* filter attributes - users can filter by a certain segment status, a certain origin or by other attributes. -* comments - users can further refine their search by displaying only segments reviewed and commented by a certain person or segments with a certain severity. -* document structure - this filters by document structure elements. +Access the Advanced Display Filter by clicking **View > Advanced Display Filter**. -Working with the Advanced Display Filter ------ -End-users can set the attributes they need to filter segments in the Var:ProductName Editor in the tabs of the Advanced Display Filter. +In the Advanced Display Filter window, end-users create and save filters based on: -They could, for example, filter segments by their source and target text. +- **Segment content** - Display segments containing certain text in source or target +- **Filter attributes** - Filter by segment status, translation origin, or other attributes +- **Comments** - Refine searches to display only segments reviewed by specific people or segments with certain severity levels +- **Document structure** - Filter by document structure elements -Moving on, they could choose from a range of segment attributes that could be applied to the filter, for example segment status, translation origin or review mode. +## Use the Advanced Display Filter -If, for example, an end-user wants to display the segments that were commented by a certain reviewer on a certain topic, they could filter by that. +The Advanced Display Filter tabs let end-users configure filtering attributes for the Editor. -And finally, end-users can filter segments by their document structure. +Users can filter segments by source and target text. They can then apply segment attributes such as status, translation origin, or review mode. + +To display only segments commented by a certain reviewer on a topic, users filter by author and subject. Finally, users can filter by document structure. diff --git a/apiconcepts/integration/editor_controller.md b/apiconcepts/integration/editor_controller.md index c0647b4cbf..3417c5831c 100644 --- a/apiconcepts/integration/editor_controller.md +++ b/apiconcepts/integration/editor_controller.md @@ -1,25 +1,25 @@ -Editor controller -=== -Var:ProductName Integration API provides support for third-party developers to implement editor functionalities for the Var:ProductName application. +# Editor Controller -Editor controller ----- -The [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) enables the third-party developer to integrate custom UI functionalities inside Var:ProductName editor view and perform operations on translatable documents. +The Var:ProductName Integration API enables third-party developers to implement editor functionalities in the Var:ProductName application. -For a sample on how to use it, see the following sample: [Using Var:ProductName EditorController](using_trados_studio_editorcontroller.md) +## EditorController Overview -Enhance Var:ProductName editor view using EditorController ---- -The [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) provide support for integrating custom UI inside the Var:ProductName editor view. +The [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) enables third-party developers to integrate custom UI functionalities into the Var:ProductName editor view and perform operations on translatable documents. -* Integrating viewparts (see [Integrating viewparts](integrating_viewparts.md)) -* Integrating menus -* Integrating context menus +For a complete code sample, see [Using Var:ProductName EditorController](using_trados_studio_editorcontroller.md). -Operations on translatable documents ----- -Based on MVVM pattern, the [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) provides support for translatable document operations. +## Enhancing the Editor View -* Open, save, close, activate document operations using [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) -* Operations on [Document](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Document.yml) (see also [Bilingual API - Overview](bilingual_api.md)) -* Operations on **DocumentView** +The [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) supports integrating custom UI into the Var:ProductName editor view: + +- Integrating viewparts (see [Integrating viewparts](integrating_viewparts.md)) +- Integrating menus +- Integrating context menus + +## Operations on Translatable Documents + +Based on the MVVM pattern, the [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) supports translatable document operations: + +- Open, save, close, and activate document operations using [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) +- Operations on [Document](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Document.yml) (see also [Bilingual API - Overview](bilingual_api.md)) +- Operations on [DocumentView](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DocumentView.yml) diff --git a/apiconcepts/integration/extend_standard_packaging_support.md b/apiconcepts/integration/extend_standard_packaging_support.md index 4198923b07..982910a18d 100644 --- a/apiconcepts/integration/extend_standard_packaging_support.md +++ b/apiconcepts/integration/extend_standard_packaging_support.md @@ -1,26 +1,28 @@ -# Extend default packaging functionality +# Extend Default Packaging Functionality -Var:ProductName Integration API provides support for third-party developers to extend the default project packaging operations by injecting additional pages and jobs in the project packaging wizards. It also allows direct integration with other systems package formats. +The Var:ProductName Integration API enables third-party developers to extend default project packaging operations by injecting additional pages and jobs into the project packaging wizards. You can also integrate directly with other systems' package formats. -## Extending **Open Package** functionality +## Extending Open Package Functionality -In order to extend the standard **Open Package** functionality, a third party developer will require the following steps: -- Create a specific action in the ribbon. (See [Creating Actions](creating_actions.md)) -- Implement specific wizard pages -- Trigger the [OpenProjectPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.OpenProjectPackageEvent.yml) via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml) and passing on the custom wizard pages (see [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml)) and the custom external job (see [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml)) +To extend the standard Open Package functionality, follow these steps: -See [Customizing the Open Package Wizard Sample](customize_open_package_wizard.md) +- Create a specific action in the ribbon (see [Creating Actions](creating_actions.md)) +- Implement specific wizard pages +- Trigger the [OpenProjectPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.OpenProjectPackageEvent.yml) via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml), passing the custom wizard pages (see [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml)) and custom external job (see [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml)) -## Extending **Create Return Package** functionality +For a complete code sample, see [Customizing the Open Package Wizard Sample](customize_open_package_wizard.md). -In order to extend the standard **Create Return Package** functionality, a third party developer will require the following steps: -- Create a specific action in the ribbon. (See [Creating Actions](creating_actions.md)) -- Implement specific wizard pages -- Trigger the [CreateReturnPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.CreateReturnPackageEvent.yml) via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml) and passing on the custom wizard pages (see [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml)) and the custom external job (see [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml)) +## Extending Create Return Package Functionality -See [Customizing the Create Return Package Wizard Sample](customize_create_return_package_wizard.md) +To extend the standard Create Return Package functionality, follow these steps: -## Importing and Exporting custom project packages +- Create a specific action in the ribbon (see [Creating Actions](creating_actions.md)) +- Implement specific wizard pages +- Trigger the [CreateReturnPackageEvent](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Events.CreateReturnPackageEvent.yml) via the [IStudioEventAggregator](../../api/integration/Sdl.Desktop.IntegrationApi.Interfaces.IStudioEventAggregator.yml), passing the custom wizard pages (see [StudioWizardPage](../../api/integration/Sdl.Desktop.IntegrationApi.Wizard.StudioWizardPage.yml)) and custom external job (see [IExternalJobWithProgress](../../api/integration/Sdl.Desktop.IntegrationApi.Jobs.IExternalJobWithProgress.yml)) -In order to be able to process project packages that are not the proprietary Var:ProductName package formats, a third party developer can implement an [external package convertor](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IExternalPackageConverter.yml) +For a complete code sample, see [Customizing the Create Return Package Wizard Sample](customize_create_return_package_wizard.md). + +## Importing and Exporting Custom Project Packages + +To process project packages that are not in the proprietary Var:ProductName package format, third-party developers can implement an [external package converter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IExternalPackageConverter.yml). diff --git a/apiconcepts/integration/files_controller.md b/apiconcepts/integration/files_controller.md index 6a0936b548..36a7c52b70 100644 --- a/apiconcepts/integration/files_controller.md +++ b/apiconcepts/integration/files_controller.md @@ -1,31 +1,31 @@ -Files controller -===== - Var:ProductName Integration API provides support for third-party developers to implement project files functionalities for the Var:ProductName application. +# Files Controller -Files controller ----- -The [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) enables the third-party developer to integrate custom UI functionalities inside Var:ProductName files view and perform project files operations over the current opened project. +The Var:ProductName Integration API enables third-party developers to implement project file functionalities in the Var:ProductName application. -For more information: [About project files](../projectautomation/about_project_files.md) +## FilesController Overview -For a sample on how to use it, see the following sample: [Using Var:ProductName FilesController](using_trados_studio_filescontroller.md) +The [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) enables third-party developers to integrate custom UI functionalities into the Var:ProductName files view and perform project file operations on the current open project. -Enhance Var:ProductName files view using FilesController ----- -The [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) provide support for integrating custom UI inside the Var:ProductName files view. +For more information, see [About project files](../projectautomation/about_project_files.md). -* Integrating viewparts(see [Integrating viewparts](integrating_viewparts.md)) -* Integrating menus -* Integrating context menus +For a complete code sample, see [Using Var:ProductName FilesController](using_trados_studio_filescontroller.md). -Operations on current project files ----- -The [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) provide support to perform operations for the current project. +## Enhancing the Files View -* Operations on the project files and folders -* Operations on the selected files -* Operations on the user selected tasks +The [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) supports integrating custom UI into the Var:ProductName files view: -For more information: [About project files](../projectautomation/about_project_files.md) +- Integrating viewparts (see [Integrating viewparts](integrating_viewparts.md)) +- Integrating menus +- Integrating context menus -To open project files for editing, see the [Editor controller](editor_controller.md). +## Operations on Current Project Files + +The [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) supports performing operations on the current project: + +- Operations on project files and folders +- Operations on selected files +- Operations on user-selected tasks + +For more information, see [About project files](../projectautomation/about_project_files.md). + +To open project files for editing, see [Editor controller](editor_controller.md). diff --git a/apiconcepts/integration/implementing_custom_job.md b/apiconcepts/integration/implementing_custom_job.md index 2c38936a88..69c9123168 100644 --- a/apiconcepts/integration/implementing_custom_job.md +++ b/apiconcepts/integration/implementing_custom_job.md @@ -1,13 +1,17 @@ -# Implementing a custom job +# Implementing a Custom Job -The `IExternalJob` and `IExternalJobWithProgress` interfaces are the bridge that will allow you to inject custom code into the wizards as well as into Var:ProductName's job mechanism. This gives you the advantage to achieve the same look and feel for long processing jobs besides helping you complete your work faster. Once you have an implementation ready all you need to do is publish `ExecuteExternalJobEvent` using `IStudioEventAggregator`. As a result, Var:ProductName will pick the job and execute it on a background thread or inject it into the previously-mentioned events. If the job is cancelled for any reason, you can handle that from the `JobCanceled` method. +The `IExternalJob` and `IExternalJobWithProgress` interfaces enable you to inject custom code into wizards and Var:ProductName's job mechanism. This approach maintains consistent look and feel for long-running processing jobs while improving performance. + +To use a custom job, implement one of these interfaces and publish `ExecuteExternalJobEvent` using `IStudioEventAggregator`. Var:ProductName picks up the job and executes it on a background thread or injects it into the specified events. If the job is cancelled, handle it in the `JobCanceled` method. | Interface | Purpose | | ------------- | -----| -| `IExternalJob`| Implement this interface when you want to run a long processing job. The logic will be automatically executed on a background thread.| -| `IExternalJobWithProgress` | Implement this interface when you want to run a long processing job that can also report progress to the user. Triggering the `ProgressReported` event handler will allow you to report progress on the execution of your job to the user. | +| `IExternalJob`| Use this interface for long-running processing jobs. The logic executes automatically on a background thread.| +| `IExternalJobWithProgress` | Use this interface for long-running processing jobs that report progress. Trigger the `ProgressReported` event handler to report job progress to the user. | + +## Code Sample -Here is a code sample on how such an implementation should look like: +The following example shows a custom job implementation: ```cs public class SampleJob : IExternalJobWithProgress @@ -56,7 +60,8 @@ public class SampleJob : IExternalJobWithProgress ``` > [!NOTE] -> The `JobData` property acts as a bridge between Var:ProductName and your plugin in case of using the job inside the **Open Package** and **Create Return Package** wizards. Var:ProductName will set the file path on the property as follows: -> - the file path to the project that was just imported into Var:ProductName, in the case of the **Open Package** wizard -> - the file path for the created package, in the case of the **Create Return Package** wizard. -> All constants used can be referenced from [PackagingConstants](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.PackagingConstants.yml) +> The `JobData` property acts as a bridge between Var:ProductName and your plug-in when using the job inside the **Open Package** and **Create Return Package** wizards. Var:ProductName sets the file path on the property as follows: +> - The file path to the project imported into Var:ProductName in the **Open Package** wizard +> - The file path for the created package in the **Create Return Package** wizard +> +> Reference the available constants from [PackagingConstants](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.PackagingConstants.yml). diff --git a/apiconcepts/integration/implementing_filtering_capabilities_to_your_display_filter.md b/apiconcepts/integration/implementing_filtering_capabilities_to_your_display_filter.md index 9ec166e673..6fb5e0b5ce 100644 --- a/apiconcepts/integration/implementing_filtering_capabilities_to_your_display_filter.md +++ b/apiconcepts/integration/implementing_filtering_capabilities_to_your_display_filter.md @@ -1,17 +1,24 @@ -Implementing filtering capabilities to your Display Filter -====== -Add the basic filtering functionality to your custom filter. +# Implementing filtering capabilities to your Display Filter -To work with the Display Filter API, you need to create a class that implements the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) interface from the [Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.yml) namespace, which exposes one method called [EvaluateRow](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml#Sdl_TranslationStudioAutomation_IntegrationApi_DisplayFilters_IDisplayFilter_EvaluateRow_Sdl_TranslationStudioAutomation_IntegrationApi_DisplayFilters_IDisplayFilterRowInfo_). This method will then be called by the API for each row after the filter is applied on the document, passing in the [IDisplayFilterRowInfo](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilterRowInfo.yml) model (which includes the [ISegmentPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegmentPair.yml) and other relevant properties) that will permit the developer to assert whether or not the segments are visible in the editor. +Add basic filtering functionality to your custom filter. -Create a new class called `FilterSettings`. This class will manage some basic settings that will persist on the document once the filter has been applied. Make reference to the following example: +## Implement the IDisplayFilter interface +To work with the Display Filter API, create a class that implements the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) interface from the [Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.yml) namespace. This interface exposes the [EvaluateRow](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml#Sdl_TranslationStudioAutomation_IntegrationApi_DisplayFilters_IDisplayFilter_EvaluateRow_Sdl_TranslationStudioAutomation_IntegrationApi_DisplayFilters_IDisplayFilterRowInfo_) method. -To recover the source and target content, we will need to create a class that implements the [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml). This interface is designed in such a way that you decide what properties from the [ISegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegment.yml) are relevant and then process only those. +The API calls this method for each row after applying the filter to the document. It passes the [IDisplayFilterRowInfo](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilterRowInfo.yml) model, which includes the [ISegmentPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegmentPair.yml) and other properties. Use this method to determine whether segments should appear in the editor. -For the purpose of this example, we will recover the content as plain text only, including tags and revisions. This should be sufficient in allowing us to apply a filter to the content. +## Create the FilterSettings class -Create a new class called `ContentProcessor` with reference to the following code: +Create a new class called `FilterSettings`. This class manages basic settings that persist on the document after applying the filter. + +## Create the ContentProcessor class + +To extract source and target content, create a class that implements the [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml) interface. This interface lets you decide which [ISegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegment.yml) properties to process. + +For this example, extract the content as plain text only, including tags and revisions. This approach provides sufficient content for applying the filter. + +Create a new class called `ContentProcessor`: # [C#](#tab/tabid-1) ```cs using System; @@ -26,7 +33,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Content { public class ContentProcessor : IMarkupDataVisitor { - public ContentProcessor() { Initialize(); @@ -37,6 +43,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Content PlainText = new StringBuilder(""); Comments = new List(); } + public List Comments { get; set; } public StringBuilder PlainText { get; set; } @@ -136,15 +143,16 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.Content } } ``` -**** -Next, create a new class called `DisplayFilter`. This will implement the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) interface so that we can evaluate each of the segments and decide whether or not they should be displayed in the Var:ProductName Editor. +## Create the DisplayFilter class -It is good design to include a reference to `IFilterSetting` interface in this class as it will be persisted on the document once the filter has been applied. This is useful to understand the type of filter that is applied (if any), especially in the case when the user is moving between documents in the editor. It permits the developer to differentiate between the internal system filter provider and their own implementation or multiple implementations and then take the appropriate action based on that. +Create a new class called `DisplayFilter`. This class implements the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) interface to evaluate segments and determine whether to display them in the Var:ProductName Editor. -This example demonstrates how to implement a few filters that are evaluated as the API is iterating over each of the segments after the filter has been applied on the document. Further on in the walkthrough we will discuss how to apply this implementation of the [IDisplayFilter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.DisplayFilters.IDisplayFilter.yml) on the document itself. +Include a reference to the `IFilterSetting` interface in this class. This interface persists on the document after applying the filter. It helps you understand which filter applies (if any), especially when users move between documents. This approach lets you differentiate between the internal system filter provider and your custom implementations. -You will notice from the filter examples that we are using the `ContentProcessor` functionality that we created earlier to recover the plain text from both the source and target segments and then apply either a regular expression or normal search as criteria for the filter. +The following example demonstrates several filters that the API evaluates as it iterates over segments after applying the filter. Later in this walkthrough, you will learn how to apply this `DisplayFilter` implementation to the document. + +The filter examples use the `ContentProcessor` functionality to extract plain text from source and target segments. The code then applies either a regular expression or normal search as filter criteria. # [C#](#tab/tabid-2) ```cs @@ -162,23 +170,12 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters { public class DisplayFilter : IDisplayFilter { - #region | Public | - - /// - /// Display filter settings - /// public IDisplayFilterSettings Settings { get; private set; } - - #endregion - #region | Private | - private ContentProcessor ContentProcessor { get; set; } private Document ActiveDocument { get; set; } - #endregion - #region | Constructor | public DisplayFilter(IDisplayFilterSettings settings, Document document) { ContentProcessor = new ContentProcessor(); @@ -186,9 +183,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters Settings = settings; } - #endregion - - public bool EvaluateRow(DisplayFilterRowInfo rowInfo) { var success = !(!Settings.ShowAllContent && !rowInfo.IsSegment); @@ -198,51 +192,39 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters if (success && Settings.SegmentReviewTypes != null && Settings.SegmentReviewTypes.Any()) success = IsSegmentReviewTypes(rowInfo); - if (success && Settings.ConfirmationLevels != null && Settings.ConfirmationLevels.Any()) success = IsConfirmationLevelFound(rowInfo); - if (success && Settings.OriginTypes != null && Settings.OriginTypes.Any()) success = IsOriginTypeFound(rowInfo); - if (success && Settings.PreviousOriginTypes != null && Settings.PreviousOriginTypes.Any()) success = IsPreviousOriginTypeFound(rowInfo); - if (success && Settings.RepetitionTypes != null && Settings.RepetitionTypes.Any()) success = IsRepetitionTypes(rowInfo); - if (success && Settings.SegmentLockingTypes != null && Settings.SegmentLockingTypes.Any()) success = IsSegmentLockingTypes(rowInfo); - if (success && Settings.SegmentContentTypes != null && Settings.SegmentContentTypes.Any()) success = IsSegmentContentTypes(rowInfo); - if (success && Settings.SourceText.Trim() != string.Empty) success = IsTextFoundInSource(rowInfo); - if (success && Settings.TargetText.Trim() != string.Empty) success = IsTextFoundInTarget(rowInfo); - if (success && Settings.CommentText.Trim() != string.Empty) success = IsTextFoundInComment(rowInfo); - if (success && Settings.CommentAuthor.Trim() != string.Empty) success = IsAuthorFoundInComment(rowInfo); - if (success && Settings.CommentSeverity > 0) success = IsSeverityFoundInComment(rowInfo); - if (success && Settings.ContextInfoTypes.Any()) success = IsContextInfoTypes(rowInfo); } @@ -250,9 +232,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } - - #region | Helpers | - private bool IsSegmentReviewTypes(DisplayFilterRowInfo rowInfo) { var success = SegmentWithTQAs(rowInfo) @@ -262,6 +241,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool SegmentWithTQAs(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentReviewTypes.ToList() @@ -273,6 +253,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool SegmentWithTrackedChanges(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentReviewTypes.ToList() @@ -284,22 +265,22 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool SegmentWithComments(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentReviewTypes.ToList() .Any(status => string.Compare(status, DisplayFilterSettings.SegmentReviewType.WithComments.ToString() , StringComparison.OrdinalIgnoreCase) == 0); - // check if comments exist in the target segment if (success && !ContentProcessor.GetSegmentComments(rowInfo.SegmentPair.Target).Any()) { - // check if comments exit in the source segment if (!ContentProcessor.GetSegmentComments(rowInfo.SegmentPair.Source).Any()) success = false; } return success; } + private bool SegmentWithMessages(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentReviewTypes.ToList() @@ -322,6 +303,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsAuthorFoundInComment(DisplayFilterRowInfo rowInfo) { var success = ContentProcessor.GetSegmentComments(rowInfo.SegmentPair.Target) @@ -332,6 +314,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsTextFoundInComment(DisplayFilterRowInfo rowInfo) { var success = ContentProcessor.GetSegmentComments(rowInfo.SegmentPair.Target) @@ -356,37 +339,32 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters { var success = false; - var translationType = - Helper.GetOriginType(rowInfo.SegmentPair.Properties.TranslationOrigin); + var translationType = Helper.GetOriginType(rowInfo.SegmentPair.Properties.TranslationOrigin); success = Settings.OriginTypes.ToList() .Any(status => string.Compare(status, translationType.ToString() , StringComparison.OrdinalIgnoreCase) == 0); - return success; } + private bool IsPreviousOriginTypeFound(DisplayFilterRowInfo rowInfo) { var success = false; if (rowInfo.SegmentPair.Properties.TranslationOrigin.OriginBeforeAdaptation != null) { - var previousTranslationType = - Helper.GetOriginType( - rowInfo.SegmentPair.Properties.TranslationOrigin.OriginBeforeAdaptation); - if ( - Settings.PreviousOriginTypes.ToList() - .Any(status => string.Compare(status, - previousTranslationType.ToString() - , StringComparison.OrdinalIgnoreCase) == 0)) + var previousTranslationType = Helper.GetOriginType( + rowInfo.SegmentPair.Properties.TranslationOrigin.OriginBeforeAdaptation); + if (Settings.PreviousOriginTypes.ToList() + .Any(status => string.Compare(status, previousTranslationType.ToString() + , StringComparison.OrdinalIgnoreCase) == 0)) success = true; } return success; } - private bool IsRepetitionTypes(DisplayFilterRowInfo rowInfo) { var success = IsRepetitionsAll(rowInfo) @@ -395,6 +373,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsRepetitionsAll(DisplayFilterRowInfo rowInfo) { var success = Settings.RepetitionTypes.ToList() @@ -406,6 +385,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsRepetitionsFirstOccurrences(DisplayFilterRowInfo rowInfo) { var success = Settings.RepetitionTypes.ToList() @@ -417,6 +397,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsRepetitionsExcludingFirstOccurrences(DisplayFilterRowInfo rowInfo) { var success = Settings.RepetitionTypes.ToList() @@ -429,7 +410,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } - private bool IsSegmentLockingTypes(DisplayFilterRowInfo rowInfo) { var success = IsSegmentLockingTypeLocked(rowInfo) @@ -437,6 +417,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsSegmentLockingTypeLocked(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentLockingTypes.ToList() @@ -448,20 +429,19 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsSegmentLockingTypeUnLocked(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentLockingTypes.ToList() .Any(status => string.Compare(status, DisplayFilterSettings.SegmentLockingType.Unlocked.ToString() , StringComparison.OrdinalIgnoreCase) == 0); - if (success) success = !rowInfo.SegmentPair.Properties.IsLocked; return success; } - private bool IsSegmentContentTypes(DisplayFilterRowInfo rowInfo) { var success = IsSegmentContentTypeNumbersOnly(rowInfo) @@ -469,6 +449,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsSegmentContentTypeNumbersOnly(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentContentTypes.ToList() @@ -488,6 +469,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsSegmentContentTypeExcludingNumberOnly(DisplayFilterRowInfo rowInfo) { var success = Settings.SegmentContentTypes.ToList() @@ -509,12 +491,8 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } - - - private bool IsTextFoundInSource(DisplayFilterRowInfo rowInfo) { - var text = ContentProcessor.GetPlainText(rowInfo.SegmentPair.Source, true); var success = Settings.IsRegularExpression @@ -523,6 +501,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private bool IsTextFoundInTarget(DisplayFilterRowInfo rowInfo) { var text = ContentProcessor.GetPlainText(rowInfo.SegmentPair.Target, true); @@ -533,6 +512,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return success; } + private static bool RegularExpressionMatch(string searchFor, string searchIn, bool isCaseSensitive) { var regex = new Regex(searchFor, @@ -541,6 +521,7 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return match.Success; } + private static bool StringMatch(string searchFor, string searchIn, bool isCaseSensitive) { if (isCaseSensitive) @@ -549,9 +530,6 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters return searchIn.IndexOf(searchFor, StringComparison.OrdinalIgnoreCase) > -1 ? true : false; } - - - private bool IsContextInfoTypes(DisplayFilterRowInfo rowInfo) { var success = false; @@ -562,14 +540,8 @@ namespace TranslationStudio.Plugins.AdvancedDisplayFilter.DisplayFilters success = true; } - return success; } - - - #endregion - } } ``` -*** diff --git a/apiconcepts/integration/integrating_actions.md b/apiconcepts/integration/integrating_actions.md index ab12010b36..06c23a5782 100644 --- a/apiconcepts/integration/integrating_actions.md +++ b/apiconcepts/integration/integrating_actions.md @@ -1,12 +1,10 @@ -Integrating actions -===== +# Integrating Actions -Desktop Integration API provides support for third-party developers to integrate actions inside the Var:ProductName desktop applications. +The Desktop Integration API allows third-party developers to integrate custom actions into Var:ProductName desktop applications. -Integrating general actions ------ +## Global Actions -The following example demonstrates how to create an action into the Var:ProductName application which has a general purpose and integrate it into a custom ribbon group (see: [Integrating ribbon groups](integrating_ribbon_groups.md)). +The following example demonstrates how to create an action with general purpose and integrate it into a custom ribbon group (see [Integrating ribbon groups](integrating_ribbon_groups.md)). # [C#](#tab/tabid-1) ```cs [Action("MyMainIconAction", Icon = "MyAction_Icon")] @@ -22,9 +20,9 @@ public class MyMainIconAction : AbstractAction ``` *** -Integrating controller actions ------ -The following example demonstrates how to create an action specific to a controller and integrate it into a custom ribbon group (see: [Integrating ribbon groups](integrating_ribbon_groups.md). +## Controller-Specific Actions + +The following example demonstrates how to create an action specific to a controller and integrate it into a custom ribbon group (see [Integrating ribbon groups](integrating_ribbon_groups.md)). # [C#](#tab/tabid-2) ```cs diff --git a/apiconcepts/integration/integrating_ribbon_groups.md b/apiconcepts/integration/integrating_ribbon_groups.md index 4bc00a10ed..8871e03c41 100644 --- a/apiconcepts/integration/integrating_ribbon_groups.md +++ b/apiconcepts/integration/integrating_ribbon_groups.md @@ -1,11 +1,10 @@ -Integrating ribbon groups -===== +# Integrating Ribbon Groups -Desktop Integration API provides support for third-party developers to integrate UI ribbon groups inside the Var:ProductName desktop applications. +The Desktop Integration API allows third-party developers to integrate custom UI ribbon groups into Var:ProductName desktop applications. -Integrating ribbon groups ------ -The following example demonstrates how to create a ribbon group into a Var:ProductName application. +## Example + +The following example demonstrates how to create a ribbon group in a Var:ProductName application. # [C#](#tab/tabid-1) [!code-csharp[CreatingRibbonGroups](code_samples/CreatingRibbonGroups.cs#L1-L14)] @@ -13,24 +12,18 @@ The following example demonstrates how to create a ribbon group into a Var:Produ > [!NOTE] > -> Var:ProductName Integration API provide a special location for the plug-ins (see: [TranslationStudioDefaultRibbonTabs](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.yml)). +> Var:ProductName Integration API provides a special location for plug-ins (see [TranslationStudioDefaultRibbonTabs](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.yml)). -For information on how to add UI items inside a ribbon group, read about the actions. (see: [Creating actions](creating_actions.md) or check the sample [Integrating actions](integrating_actions.md)) +To add UI elements to a ribbon group, see [Creating actions](creating_actions.md) or the [Integrating actions](integrating_actions.md) sample. -> [!NOTE] +> [!IMPORTANT] > -> If there are no UI elements added inside the ribbon group, it will not be visible. - - -See Also --- - -**Reference** - -[AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) +> You must add at least one UI element to the ribbon group. Empty ribbon groups do not appear. -[ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) -[ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) +## Reference -[TranslationStudioDefaultRibbonTabs](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.yml) +* [AbstractRibbonGroup](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractRibbonGroup.yml) +* [RibbonGroupAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.RibbonGroupAttribute.yml) +* [RibbonGroupLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.RibbonGroupLayoutAttribute.yml) +* [TranslationStudioDefaultRibbonTabs](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.yml) diff --git a/apiconcepts/integration/integrating_viewparts.md b/apiconcepts/integration/integrating_viewparts.md index ad97cf2d23..410db39b99 100644 --- a/apiconcepts/integration/integrating_viewparts.md +++ b/apiconcepts/integration/integrating_viewparts.md @@ -1,35 +1,36 @@ -Integrating viewparts -===== +# Integrating View Parts -Desktop Integration API provides support for third-party developers to integrate UI view parts inside the Var:ProductName desktop applications. +The Desktop Integration API allows third-party developers to integrate custom UI view parts into Var:ProductName desktop applications. -Integrating view parts implies changes, in the way that a view is no longer having one content, but is built by one too many viewparts having at least one main centered viewpart, which is filling its content. +View parts allow you to build a view from multiple parts instead of a single content area. A view typically has one main content view part (with `Dock` set to `Fill`) and one or more additional view parts. -The viewparts can be added to be part of an integrated view (see the sample regarding the integration of a view) or to an existing view (see [ProjectsController](projects_controller.md), [FilesController](files_controller.md), [EditorController](editor_controller.md)). +You can add view parts to a custom view or to existing Var:ProductName views such as [ProjectsController](projects_controller.md), [FilesController](files_controller.md), or [EditorController](editor_controller.md). -Integrating view parts inside a custom view ------ -The following example demonstrates how to create a view built by viewparts into a Var:ProductName application. +## Integrating View Parts in a Custom View -First, create and integrate a view which allows viewparts: +The following example demonstrates how to create a view built from view parts in a Var:ProductName application. + +### Step 1: Create a View That Allows View Parts # [C#](#tab/tabid-1) [!code-csharp[MyViewWithParts](code_samples/MyViewWithParts.cs#L1-L25)] *** -Create the main viewpart content of the view. +### Step 2: Create the Main View Part Content -To define a main content viewpart, set the `Dock` property of the [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) attribute to `Fill`. +To define the main content view part, set the `Dock` property of the [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) attribute to `Fill`. # [C#](#tab/tabid-2) [!code-csharp[MyCustomViewPartContent](code_samples/MyCustomViewPartContent.cs#L1-L29)] *** -Define other viewparts and order their relevance by setting the `ZIndex` property. +### Step 3: Create Additional View Parts + +Define other view parts and order them by setting the `ZIndex` property. > [!NOTE] > -> The ZIndex ordering is performed only for the intergrated viewparts and displayed only after Var:ProductName viewparts and acts as importance from left to right or top to bottom. The highest ZIndex value is in the left or top and the lowest value is in the right or bottom. +> The `ZIndex` ordering applies only to integrated view parts and displays after Var:ProductName's default view parts. Higher `ZIndex` values appear on the left or top; lower values appear on the right or bottom. # [C#](#tab/tabid-3) [!code-csharp[MyCustomViewPart1](code_samples/MyCustomViewPart1.cs#L1-L30)] @@ -44,21 +45,16 @@ Define other viewparts and order their relevance by setting the `ZIndex` propert [!code-csharp[MyCustomViewPart3](code_samples/MyCustomViewPart3.cs#L1-L29)] *** -Integrating viewparts inside an existing Var:ProductName view ------- -The following example demonstrates how to create a viewpart and integrate it into the Var:ProductName Projects View. +## Integrating View Parts in Existing Var:ProductName Views + +The following example demonstrates how to create a view part and integrate it into the Var:ProductName Projects View. # [C#](#tab/tabid-5) [!code-csharp[MyProjectViewPart](code_samples/MyProjectViewPart.cs#L1-L44)] *** -See Also --- - -**Reference** - -[AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) - -[ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) +## Reference -[ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) +* [AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) +* [ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) +* [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) diff --git a/apiconcepts/integration/integrating_views.md b/apiconcepts/integration/integrating_views.md index 12e4801488..0e1f7d574f 100644 --- a/apiconcepts/integration/integrating_views.md +++ b/apiconcepts/integration/integrating_views.md @@ -1,24 +1,17 @@ -Integrating views -===== -Desktop Integration API provides support for third-party developers to integrate UI views inside the Var:ProductName desktop applications. +# Integrating Views -Example ----- -The following example demonstrates how a view can be integrated into the Var:ProductName application. +The Desktop Integration API allows third-party developers to integrate custom UI views into Var:ProductName desktop applications. -# [C#](#tab/tabid-1) -[!code-csharp[MyNewStudioView](code_samples/MyNewStudioView.cs)] -*** - -See Also --- +## Example -**Reference** +The following example demonstrates how to integrate a view into the Var:ProductName application. -[AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) - -[ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) +# [C#](#tab/tabid-1) +[!code-csharp[MyNewStudioView](code_samples/MyNewStudioView.cs)] -[ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) +## Reference -[TranslationStudioDefaultRibbonTabs](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.yml) +* [AbstractViewPartController](../../api/integration/Sdl.Desktop.IntegrationApi.AbstractViewPartController.yml) +* [ViewPartAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartAttribute.yml) +* [ViewPartLayoutAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ViewPartLayoutAttribute.yml) +* [TranslationStudioDefaultRibbonTabs](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Presentation.DefaultLocations.TranslationStudioDefaultRibbonTabs.yml) diff --git a/apiconcepts/integration/integration_samples.md b/apiconcepts/integration/integration_samples.md deleted file mode 100644 index 7662abb2f4..0000000000 --- a/apiconcepts/integration/integration_samples.md +++ /dev/null @@ -1,9 +0,0 @@ -Studio application initializers -==== -Integration API makes easy to execute code when Var:ProductName starts so you can initialize your plugin. All you need to do is implement [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml) interface, from `Sdl.Desktop.IntegrationApi` namespace and decorate your class with ApplicationInitializerAttribute. If you fail to implement [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml) an exception will be thrown, but if you omit the [ApplicationInitializerAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ApplicationInitializerAttribute.yml) your plugin will simply be ignored when Var:ProductName Starts. - -Example ----- -The following example demonstrates a simple plugin data initialization. This plugin measures the time since Var:ProductName has been opened and if you worked less than required displays a warning MessageBox. - -This example also demonstrates how to cleanup when Var:ProductName exits. All you have to do is subscribe to `Application.Closing` event. You can use `CancelEventArgs` to prevent Var:ProductName from closing. diff --git a/apiconcepts/integration/overview.md b/apiconcepts/integration/overview.md index cfc7d80776..db85380e8f 100644 --- a/apiconcepts/integration/overview.md +++ b/apiconcepts/integration/overview.md @@ -1,22 +1,25 @@ -Var:ProductName Integration API -==== +# Var:ProductName Integration API -Welcome to the Var:ProductName Integration API. This API provides access to Var:ProductName application functionality. +The Var:ProductName Integration API allows third-party developers to extend or customize Var:ProductName applications. You can create plug-ins to: - Var:ProductName Integration API - ----- -The Var:ProductName Integration API enables third-party developers to add or customize new functionalities in Studio applications and more specific to Var:ProductName application (for more information see: [What you can do with the Integration API](what_you_can_do_with_the_integration_API.md)). +* [Extend or customize the user interface for Studio applications.](user_interface_integration.md) +* [Provide custom functionalities for the Var:ProductName application.](studio_automation.md) -The main topics of the Var:ProductName Integration API are: +![PluginTypes](images/PluginTypes.png) -* [User interface integration](user_interface_integration.md) -* [Studio automation integration](studio_automation.md) +## Modular Architecture -Var:ProductName's architecture is modular, being based on components called plug-ins, set up both at the system level (for the built-in features) and as extensions provided by the community and installed by end users. Here is a small diagram illustrating this approach: +Var:ProductName uses a modular architecture based on plug-ins. The system includes built-in plug-ins for core functionality and accepts custom extensions that users install. The following diagram illustrates this architecture: ![Modularity](images/Modularity.png) -We recommend reading the following topics before you start using Var:ProductName Integration API: +## Before You Begin + +Read the following topics to prepare for using the Var:ProductName Integration API: * [Setting up a Development Machine](../../articles/gettingstarted/setting_up_a_developer_machine.md) -* [Studio plug-ins overview](../../articles/gettingstarted/studio_plugin_overview.md) +* [Studio plug-ins overview](../../articles/gettingstarted/studio_plugin_overview.md) + +## Code Examples + +The Var:ProductName API documentation includes [examples](https://github.com/RWS/trados-studio-api-samples/tree/master/TranslationStudioAutomation) written in C# of common patterns and best practices for plug-in development. diff --git a/apiconcepts/integration/process_custom_project_package_formats.md b/apiconcepts/integration/process_custom_project_package_formats.md index 5c2c37d2f2..53ebcccb80 100644 --- a/apiconcepts/integration/process_custom_project_package_formats.md +++ b/apiconcepts/integration/process_custom_project_package_formats.md @@ -1,30 +1,30 @@ # Processing custom project package formats -Var:ProductName Integration API provides support for third-party developers to transform third-party packages into a format that Var:ProductName can work with. -This page will describe the steps required to create a custom package converter. +The Var:ProductName Integration API enables you to transform third-party packages into a format that Var:ProductName can work with. This page describes the steps required to create a custom package converter. -## Declaring a custom package converter +## Declare a custom package converter -The first step in creating a custom package converter is the declaration: -- Create a class that implements [IExternalPackageConverter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IExternalPackageConverter.yml) interface and provide specific implementations for the following methods: +Creating a custom package converter starts with the declaration: - |Method Name| Description| - | -------- | -----------| - |`ConvertPackage`| This method allows implementing logic that will transform a third party package format into a format recognised by Var:ProductName. | - |`ConvertReturnPackage`|This method allows conversion from the Var:ProductName return package format into the third party package format.| +- Implement the [IExternalPackageConverter](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IExternalPackageConverter.yml) interface with the following methods: + + | Method Name | Description | + | -------- | ----------- | + | `ConvertPackage` | Transforms a third-party package format into a format Var:ProductName recognizes. | + | `ConvertReturnPackage` | Converts a Var:ProductName return package into the third-party package format. | + +- Decorate the class with the [ExternalPackageConvertorExtension](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.ExternalPackageConvertorExtensionAttribute.yml) attribute: -- Decorate the class with the [ExternalPackageConvertorExtension](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.ExternalPackageConvertorExtensionAttribute.yml) attribute. - | Property | Description | | -------- | ----------- | - | `Id`| Unique identifier for the converter. To avoid confusion with other third party plugins we recommend using a combination of the project namespace and class name. | - | `Name` | Name of the converter | - | `Description` | Description for the converter | - | `PackageFileFilter` | The filter to be used by the Windows OS File Opener dialog. This allows the user to see only files that match the given extension and thus pick a valid file. | - |`PackageFileExtension`| The file extension of the package to be imported into Var:ProductName.| - |`ReturnPackageFileExtension`|The file extension of the return package.| + | `Id` | Unique identifier for the converter. We recommend using a combination of the project namespace and class name to avoid conflicts. | + | `Name` | Display name for the converter | + | `Description` | Description of the converter | + | `PackageFileFilter` | File filter for the Windows file dialog (e.g., "Sample Packages (*.zip)\|*.zip"). This lets users see only compatible files. | + | `PackageFileExtension` | File extension of the package to import (e.g., ".zip") | + | `ReturnPackageFileExtension` | File extension of the return package (e.g., ".zip") | -The bellow sample provides a visual to the elements described above: +The following code sample shows the basic structure: ```cs [ExternalPackageConvertorExtension( @@ -58,23 +58,26 @@ public class SamplePackageConverter : IExternalPackageConverter ``` > [!NOTE] -> The __Open Package__ and __Create Return Package__ wizard's `Data` object is available in the custom package converter as well, via the [ExternalPackageConversionInfo.CustomData](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.ExternalPackageConversionInfo.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_ExternalPackageConversionInfo_CustomData) property, allowing third party developers to use inside the converter data that has been captured in their custom wizard pages . +> The **Open Package** and **Create Return Package** wizards' `Data` object is available in the custom package converter through the [ExternalPackageConversionInfo.CustomData](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.ExternalPackageConversionInfo.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_ExternalPackageConversionInfo_CustomData) property. This allows third-party developers to use data captured in their custom wizard pages inside the converter. + +## Import a custom package -## Importing a custom package -Importing a custom package is done by implementing the `ConvertPackage(IConversionContext context, ExternalPackageConversionInfo externalPackageConversionInfo)` method. The usual steps within the implementation are as follows: -- Unzipping the package -- Creating an [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object by calling the [IConversionContext.CreatePackage](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IConversionContext.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_IConversionContext_CreatePackage_System_String_Sdl_Core_Globalization_Language_System_DateTime_System_String_System_Guid_) method. The parameters required here are as follows +Importing a custom package involves implementing the `ConvertPackage(IConversionContext context, ExternalPackageConversionInfo externalPackageConversionInfo)` method. Typical implementation steps include: + +- Unzip the package +- Create an [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object by calling [IConversionContext.CreatePackage](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IConversionContext.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_IConversionContext_CreatePackage_System_String_Sdl_Core_Globalization_Language_System_DateTime_System_String_System_Guid_) with these parameters: | Parameter Name | Description | | -------------- | ----------- | - |`projectName`| The name of the final project to be imported. | - |`sourceLanguage`| The source language of the project to be imported. | - |`createdAt`| The `DateTime` creation details. | - |`createdBy`| The user who created the package. | - |`originalProjectGuid`| Pass this as `Guid.Empty` if this is the first time the project is imported into Var:ProductName, otherwise pass the original project id. The presence of the project in Var:ProductName can be determined by calling [IConversionContext.CheckForExistingProject()](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IConversionContext.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_IConversionContext_CheckForExistingProject_System_Guid_) -- Adding the resources to the package [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object such as: files, translation memories, termbases, specific settings -- Physically packaging the package into Var:ProductName valid format by calling [IPackage.Pack()](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml#Sdl_ProjectAutomation_Core_IPackage_Pack_System_String_) and specifying the location where the package will be saved. -- Performing cleanup on temporary resources used, such as files. + | `projectName` | The name of the final project to import. | + | `sourceLanguage` | The source language of the project to import. | + | `createdAt` | The `DateTime` creation details. | + | `createdBy` | The user who created the package. | + | `originalProjectGuid` | Pass `Guid.Empty` if this is the first import into Var:ProductName. Otherwise, pass the original project ID. Use [IConversionContext.CheckForExistingProject()](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IConversionContext.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_IConversionContext_CheckForExistingProject_System_Guid_) to verify if the project exists in Var:ProductName. | + +- Add resources to the [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object: files, translation memories, termbases, and settings +- Package the converted data into Var:ProductName format by calling [IPackage.Pack()](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml#Sdl_ProjectAutomation_Core_IPackage_Pack_System_String_) with the target location +- Clean up temporary resources and files ```cs public void ConvertPackage(IConversionContext context, ExternalPackageConversionInfo externalPackageConversionInfo) @@ -100,11 +103,13 @@ public void ConvertPackage(IConversionContext context, ExternalPackageConversion } ``` -## Exporting a return package into a custom format -Exporting a return package into a custom package is done by implementing the `ConvertReturnPackage(IConversionContext context, ExternalPackageConversionInfo externalPackageConversionInfo)` method. The usual steps within the implementation are as follows: -- Creating an [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object from the return package file by calling the [IConversionContext.OpenPackage](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IConversionContext.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_IConversionContext_OpenPackage_System_String_) method. -- Extracting the necessary resources from the [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object and creating the custom return package. -- Performing cleanup on temporary resources used, such as files. +## Export a return package to a custom format + +Exporting a return package to a custom format involves implementing the `ConvertReturnPackage(IConversionContext context, ExternalPackageConversionInfo externalPackageConversionInfo)` method. Typical implementation steps include: + +- Open an [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object from the return package file by calling [IConversionContext.OpenPackage](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Packaging.IConversionContext.yml#Sdl_TranslationStudioAutomation_IntegrationApi_Packaging_IConversionContext_OpenPackage_System_String_) +- Extract the required resources from the [IPackage](../../api/projectautomation/Sdl.ProjectAutomation.Core.IPackage.yml) object and create the custom return package +- Clean up temporary resources and files ```cs public void ConvertReturnPackage(IConversionContext context, ExternalPackageConversionInfo externalPackageConversionInfo) diff --git a/apiconcepts/integration/project_creator.md b/apiconcepts/integration/project_creator.md index 9751d2714a..d0b775e52e 100644 --- a/apiconcepts/integration/project_creator.md +++ b/apiconcepts/integration/project_creator.md @@ -1,9 +1,8 @@ -Project Creator -== +# Project Creator -This class transforms a list of ProjectRequests into the corresponding file based projects using a project template. +This class transforms a list of ProjectRequests into file-based projects using a project template. -This task is carried out by the Execute method. It calls the CreateProject method for each request and using the CreateProject method in the Project Automation API creates a new instance of FileBasedProject and adds files from the ProjectRequest object. It then uses FileBasedProjectReference to run a Scan task on the files followed by a DefaultTaskSequence after which it saves the new project. The sample also illustrates how the ProgressChanged and MessageReported events are handled. +The Execute method drives this transformation. It calls CreateProject for each request, which uses the Project Automation API to create a new FileBasedProject instance. Files from the ProjectRequest object are added to the project. The sample then runs a Scan task and a DefaultTaskSequence, saves the project, and handles ProgressChanged and MessageReported events. # [C#](#tab/tabid-1) ```cs @@ -153,22 +152,12 @@ namespace StudioIntegrationApiSample ``` *** +## See Also -See Also --- - - - -[Content Connector](content_connector.md) - -[Reference Sample](reference_sample.md) - -[Wikipedia Search](wikipedia_search.md) - -[Integrating actions](integrating_actions.md) - -[Integrating ribbon groups](integrating_ribbon_groups.md) - -[Integrating viewparts](integrating_viewparts.md) - -[Integrating views](integrating_views.md) +- [Content Connector](content_connector.md) +- [Reference Sample](reference_sample.md) +- [Wikipedia Search](wikipedia_search.md) +- [Integrating actions](integrating_actions.md) +- [Integrating ribbon groups](integrating_ribbon_groups.md) +- [Integrating viewparts](integrating_viewparts.md) +- [Integrating views](integrating_views.md) diff --git a/apiconcepts/integration/projects_controller.md b/apiconcepts/integration/projects_controller.md index 36cd1e1445..e377a14e50 100644 --- a/apiconcepts/integration/projects_controller.md +++ b/apiconcepts/integration/projects_controller.md @@ -1,37 +1,35 @@ -Projects controller -==== -Var:ProductName Integration API provides support for third-party developers to implement project functionalities for the Var:ProductName application. +# Projects Controller -Projects controller ----- -The [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) enables the third-party developer to integrate custom UI functionalities inside Var:ProductName projects view and perform project operations. +The Var:ProductName Integration API enables third-party developers to implement project functionalities in the Var:ProductName application. -For more information: [About projects](../projectautomation/about_projects.md) +## ProjectsController Overview -For a sample on how to use it, see the following sample: [Using Var:ProductName ProjectsController](using_trados_studio_projectscontroller.md) +The [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) enables third-party developers to integrate custom UI functionalities into the Var:ProductName projects view and perform project operations. -Enhance Var:ProductName projects view using ProjectsController ----- -The [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) provide support for integrating custom UI inside the Var:ProductName projects view. +For more information, see [About projects](../projectautomation/about_projects.md). -Integrating viewparts (see [Integrating viewparts](integrating_viewparts.md)) +For a complete code sample, see [Using Var:ProductName ProjectsController](using_trados_studio_projectscontroller.md). -* Integrating menus -* Integrating context menus +## Enhancing the Projects View -Operations on the projects ---- -The [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) provide support for performing project operations. +The [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) supports integrating custom UI into the Var:ProductName projects view: -* Adding projects to the projects list -* Opening a project -* Closing projects -* Operations on the current project +- Integrating viewparts (see [Integrating viewparts](integrating_viewparts.md)) +- Integrating menus +- Integrating context menus -For more informations: [About projects](../projectautomation/about_projects.md) +## Project Operations -To perform project files operations on the current open project, see the [Files controller](files_controller.md) +The [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) supports performing project operations: + +- Adding projects to the projects list +- Opening a project +- Closing projects +- Performing operations on the current project + +For more information, see [About projects](../projectautomation/about_projects.md). + +To perform project file operations on the current open project, see [Files controller](files_controller.md). > [!NOTE] -> -> If you make changes to the projects by using the Project Automation API, you may need to call [Save](../../api/projectautomation/Sdl.ProjectAutomation.FileBased.FileBasedProject.yml#Sdl_ProjectAutomation_FileBased_FileBasedProject_Save) for saving the changes and [RefreshProjects](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml#Sdl_TranslationStudioAutomation_IntegrationApi_ProjectsController_RefreshProjects) to reflect the changes in the UI. +> If you modify projects using the Project Automation API, call [Save](../../api/projectautomation/Sdl.ProjectAutomation.FileBased.FileBasedProject.yml#Sdl_ProjectAutomation_FileBased_FileBasedProject_Save) to save changes and [RefreshProjects](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml#Sdl_TranslationStudioAutomation_IntegrationApi_ProjectsController_RefreshProjects) to update the UI. diff --git a/apiconcepts/integration/reference_sample.md b/apiconcepts/integration/reference_sample.md index c805c83f97..50666ae389 100644 --- a/apiconcepts/integration/reference_sample.md +++ b/apiconcepts/integration/reference_sample.md @@ -1,12 +1,14 @@ -Reference Sample -====== -The Integration API provides support for third-party developers to integrate actions, ribbon groups, views and view parts within Var:ProductName. The reference sample takes advantage of these features to provide a working example. +# Reference Sample -Description ------ -The reference sample demonstrates how the different extension points offered by the Var:ProductName Integration API can be used to create a fully functional plug-in. Custom actions, ribbon groups, views and view parts are blended together to provide an example in which a working folder (local drive or network location) is used as a drop location for files to be translated. The Var:ProductName user can then see the files grouped by folders and create projects based on the name of each folder. Furthermore, this sample extends the translation editor functionality to allow the Var:ProductName user to search Wikipedia for words and phrases found in the document. +The Integration API enables third-party developers to integrate actions, ribbon groups, views, and view parts into Var:ProductName. The reference sample demonstrates how to use these features in a working example. -The custom list features: +## Description + +The reference sample demonstrates how to combine the different extension points in the Var:ProductName Integration API to create a fully functional plug-in. It shows custom actions, ribbon groups, views, and view parts working together. + +The sample uses a working folder (local drive or network location) as a drop location for files to be translated. Users can view files grouped by folder and create projects based on folder names. The sample also extends the translation editor to enable users to search Wikipedia for words and phrases in the document. + +The custom list includes these features: [Content Connector](content_connector.md) diff --git a/apiconcepts/integration/setting_up_the_visual_studio_project.md b/apiconcepts/integration/setting_up_the_visual_studio_project.md index cc42332b0e..6444be8b3a 100644 --- a/apiconcepts/integration/setting_up_the_visual_studio_project.md +++ b/apiconcepts/integration/setting_up_the_visual_studio_project.md @@ -1,37 +1,42 @@ -Setting up the Visual Studio Project -===== -To start setting up your custom display filter project, you need to generate a plug-in that can compile and that implements an empty display filter which can be seen and selected in Var:ProductName. For the moment, it will not contain any application logic, that is it will not actually perform a real task +# Setting up the Visual Studio Project + +This guide walks you through creating a custom display filter plug-in project. You will generate a plug-in that compiles and implements an empty display filter visible in Var:ProductName. Initially, it contains no application logic and does not perform any real filtering task. + +## Create the Visual Studio Project + +After installing the Var:ProductName SDK, open Var:VisualStudioEdition. The following templates appear when you create a new project: -How to create the Visual Studio Project ------ -Assuming that you already installed the Var:ProductName SDK, open Var:VisualStudioEdition. You will see the following options when you create a new project: -With the above templates you can set up the skeleton of an Var:ProductName plug-in project. +These templates help you set up the skeleton of a Var:ProductName plug-in project. -Create a new project from Var:VisualStudioEdition using the Var:ProductName (2021) project template. Give the plugin a name, for example, AdvancedDisplayFilter.Example. +Create a new project using the Var:ProductName (2021) project template and name it, for example, `AdvancedDisplayFilter.Example`. -Creating the Visual Studio project using the Var:ProductName (2021) template automates the initial setup phase for your development project. It will automatically include all of the standard references to the studio assemblies that you might require for building your project, along with the plugin manifest and resource files. It will also setup the output path of your build environment to the correct location in your systems roaming directory. +The Var:ProductName (2021) template automates the initial setup phase for your development project. It: -Your project should look like this after creating the project using the Var:ProductName (2021) template: +- Includes all standard references to the studio assemblies your project might require +- Adds the plugin manifest and resource files +- Sets the build output path to the correct location in your system's roaming directory + +Your project should look like this after creation: > [!IMPORTANT] > -> The *The Sdl.Core.Globalization* assembly is not automatically added to the project with the Var:ProductName (2021) template. This assembly will be required for this project, as we will be making reference to some of the [ISegmentPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegmentPair.yml) enumerators. +> The Var:ProductName (2021) template does not automatically add the *Sdl.Core.Globalization* assembly to the project. This project requires this assembly because it references some of the [ISegmentPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegmentPair.yml) enumerators. > -> To add this assembly, from the Solution Explorer, right-click on the **References** node and click **Add Reference** from the context menu. Then, navigate to the **Var:InstallationFolder** and select the **Sdl.Core.Globalization.dll file**. +> To add this assembly, right-click the **References** node in Solution Explorer and select **Add Reference** from the context menu. Then navigate to **Var:InstallationFolder** and select **Sdl.Core.Globalization.dll**. + +## Sign the solution - How to sign the solution - ---- -To sign your development solution from the project properties area. +Follow these steps to sign your development solution from the project properties area: -1. In Var:VisualStudioEdition, go to **Project > AdvancedDisplayFilter.Example Properties.** -2. Go to the **Signing tab** -3. To sign the assembly of the project, select the **Sign the assembly checkbox** and then the **New…** option from the **Choose a strong name key file** combo box. -4. In the **Create Strong Name Key** dialog, provide a name, click **OK** and save the project. +1. In Var:VisualStudioEdition, go to **Project > AdvancedDisplayFilter.Example Properties**. +2. Select the **Signing** tab. +3. Select the **Sign the assembly** checkbox and choose **New…** from the **Choose a strong name key file** combo box. +4. In the **Create Strong Name Key** dialog, provide a name, click **OK**, and save the project. -Once you have saved the project properties, you will notice that a new file has been added to your project with the .snk extension. This file holds the Strong Name Key details that you provided. +After saving the project properties, a new file with the `.snk` extension appears in your project. This file holds the Strong Name Key details you provided. > [!NOTE] > -> There are a few reasons why we sign the project, one of the most obvious is that it provides a level of authenticity with the assembly, ensuring that the origins of the assembly are in fact from that author; in turn, it prevents tampering with the assembly. It is also required if you want to include your assembly in the Global Assembly Cache (GAC). +> Signing the project provides authenticity for the assembly, ensuring the assembly originates from the specified author and preventing tampering. You also need to sign assemblies to include them in the Global Assembly Cache (GAC). diff --git a/apiconcepts/integration/studio_automation.md b/apiconcepts/integration/studio_automation.md index 2da5ce8f6f..e35d8852c9 100644 --- a/apiconcepts/integration/studio_automation.md +++ b/apiconcepts/integration/studio_automation.md @@ -1,31 +1,32 @@ -Introduction -==== -The Var:ProductName Integration API enables third-party developers to extend, customize and integrate their own functionalities inside the Var:ProductName application. +# Studio Automation + +The Var:ProductName Integration API enables third-party developers to extend, customize, and integrate custom functionalities into the Var:ProductName application. ![Automation plug-ins](images/Automation.png) -Make sure the following references are added to your project, you will find them in the installation folder Var:ProductName. +## Required Project References + +Add the following references to your project. You can find them in the Var:ProductName installation folder: -* Sdl.Desktop.IntegrationApi.dll -* Sdl.Desktop.IntegrationApi.Extensions.dll -* Sdl.TranslationStudioAutomation.IntegrationApi.dll -* Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.dll -* Sdl.FileTypeSupport.Framework.Core -* Sdl.FileTypeSupport.Framework.Implementation -* Sdl.ProjectAutomation.Core -* Sdl.ProjectAutomation.FileBased -* Sdl.ProjectAutomation.Settings +- Sdl.Desktop.IntegrationApi.dll +- Sdl.Desktop.IntegrationApi.Extensions.dll +- Sdl.TranslationStudioAutomation.IntegrationApi.dll +- Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.dll +- Sdl.FileTypeSupport.Framework.Core +- Sdl.FileTypeSupport.Framework.Implementation +- Sdl.ProjectAutomation.Core +- Sdl.ProjectAutomation.FileBased +- Sdl.ProjectAutomation.Settings -> [!NOTE] +## Important Configuration + +> [!IMPORTANT] +> Choose *Var:PluginPackedPath* as the build output path for your implementations. +> +> Ensure your library references point to the Var:ProductName folder (for example, *Var:InstallationFolder*). > -> As build output path for your implementations please choose the *Var:PluginPackedPath*. +> For detailed information, see [Building a plug-in](building_plugin.md) and [Plug-in deployment](plugin_deployment.md). > -> Also check that your library references are pointing to the Var:ProductName folder. e.g. *Var:InstallationFolder*. -> -> For more information on how to build and deploy a Studio plug-in, see (Building a plug-in and Plug-in deployment) -> -> Sign and use Strong-Named Assemblies to enable the loading of your plug-ins inside the Var:ProductName. +> Sign your assemblies with a strong name to enable loading in Var:ProductName. See [How to: Sign an Assembly with a Strong Name](https://docs.microsoft.com/en-us/dotnet/standard/assembly/sign-strong-name). > -> [How to: Sign an Assembly with a Strong Name](https://docs.microsoft.com/en-us/dotnet/standard/assembly/sign-strong-name?redirectedfrom=MSDN) -> -> Choosing a different build output path or not signing your assembly will prevent your plugin from loading. +> Using a different build output path or failing to sign your assembly prevents your plug-in from loading. diff --git a/apiconcepts/integration/trados_studio_application_initializers.md b/apiconcepts/integration/trados_studio_application_initializers.md deleted file mode 100644 index 47b135c904..0000000000 --- a/apiconcepts/integration/trados_studio_application_initializers.md +++ /dev/null @@ -1,62 +0,0 @@ -Var:ProductName application initializers -===== -Integration API makes it easy to execute code when Var:ProductName starts, so you can initialize your plugin. All you need to do is implement [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml) interface, from `Sdl.Desktop.IntegrationApi` namespace and decorate your class with [ApplicationInitializerAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ApplicationInitializerAttribute.yml). If you fail to implement [IApplicationInitializer](../../api/integration/Sdl.Desktop.IntegrationApi.IApplicationInitializer.yml), an exception will be thrown, but if you omit the [ApplicationInitializerAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.ApplicationInitializerAttribute.yml), your plugin will simply be ignored when Var:ProductName Starts. - -Example ----- -The following example demonstrates a simple plugin data initialization. This plugin measures the time since Var:ProductName has been opened and if you worked less than required, it displays a warning MessageBox. - -This example also demonstrates how to cleanup when Var:ProductName exits. All you have to do is subscribe to `Application.Closing` event. You can use `CancelEventArgs` to prevent Var:ProductName from closing. - -# [Simple Plugin Initializer](#tab/tabid-1) -```cs -using System; -using System.Windows.Forms; -using Sdl.Desktop.IntegrationApi; -using Sdl.Desktop.IntegrationApi.Extensions; -using Sdl.TranslationStudioAutomation.IntegrationApi; - -namespace StudioInitializer.Sample -{ - /// - /// Implements an application initializer which will keep track of the application startup and closing time. - /// - [ApplicationInitializer] - class PluginInitializer : IApplicationInitializer - { - private const int MinimumWorkTime = 4; - - /// - /// This method is executed when the application is starting. - /// - public void Execute() - { - StudioTracking.Start(); - - // Setting up a check at the application closure verifying if the user has worked less then the minimum amount of time - // If the time passed since Studio opening and Studio closing is less than the MinimumWorkTime(4h) than - // request a confirmation from the user for the application closure otherwise just exit. - SdlTradosStudio.Application.Closing += (s, e) => - { - TimeSpan elapsedTime = StudioTracking.Elapsed; - if (elapsedTime.Hours < MinimumWorkTime) - { - DialogResult dialogResult = - MessageBox.Show( - string.Format("You have been working for {0:dd\\.hh\\:mm\\:ss} and spending less than {1} hours. Are you sure you want to quit ?", StudioTracking.Elapsed, MinimumWorkTime) - , string.Format("Total work time is {0} minutes", elapsedTime.Minutes) - , MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (dialogResult == DialogResult.No) - { - //Cancel the the application closing - e.Cancel = true; - return; - } - } - StudioTracking.Stop(); - }; - } - } -} -``` -**** diff --git a/apiconcepts/integration/trados_studio_autosuggest_provider.md b/apiconcepts/integration/trados_studio_autosuggest_provider.md deleted file mode 100644 index df8f182ecf..0000000000 --- a/apiconcepts/integration/trados_studio_autosuggest_provider.md +++ /dev/null @@ -1,148 +0,0 @@ -Var:ProductName AutoSuggest provider -==== -Integration API makes it easy to to create your own AutoSuggest provider. All you need to do is implement the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) abstract class, from `Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest` namespace and decorate your class with `AutoSuggestProvider` attribute. If you fail to implement [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml), an exception will be thrown, but if you omit the `[AutoSuggestProviderAttribute](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.AutoSuggestProviderAttribute.yml), your plugin will simply be ignored when Var:ProductName starts. - -Example ------ -The following example demonstrates how to implement a custom AutoSuggest provider. - -The plugin implements the required abstract methods of the [AbstractAutoSuggestProvider](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest.AbstractAutoSuggestProvider.yml) base class. - -* **GetSuggestions** to return the list of the items for auto suggestion list box -* **OnActiveSegmentChanged** to be able to prepare the list of suggested items for the new selected segment -* **OnSettingsChanged** to react to any change of the document settings -* **OnActiveDocumentChanged** to react to changing of the active document - -# [Sample AutoSuggest Provider](#tab/tabid-1) -```cs -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Sdl.FileTypeSupport.Framework.BilingualApi; -using Sdl.TranslationStudioAutomation.IntegrationApi.AutoSuggest; -using Sdl.TranslationStudioAutomation.IntegrationApi.Extensions; - -namespace AutoSuggest.Sample -{ - [AutoSuggestProvider(Id = "SourceCopyAutoSuggestProvider", Name = "AutoSuggest provider for copying the source words")] - public class SourceCopyAutoSuggestProvider : AbstractAutoSuggestProvider - { - private List _segmentWordSuggestCandidates; - - public SourceCopyAutoSuggestProvider() - { - // Set the default icon for the suggestions from this provider - Icon = new Icon(SystemIcons.Exclamation, 16, 16); - } - - #region AutoSuggestProvider Implementation - /// - /// This function is not necessary for this sample. It just shows in case you need dictionary or some other language specific action, you can do it here. - /// - protected override void OnActiveDocumentChanged() - { - if (ActiveDocument != null) - { - var sourceLanguage = ActiveDocument.Project.GetProjectInfo().SourceLanguage; - var targetLanguage = ActiveDocument.Files.First().Language; - - System.Diagnostics.Debug.WriteLine("SourceCopyAutoSuggestProvider Language pair: {0}->{1}", sourceLanguage.DisplayName, targetLanguage.DisplayName); - - // in case you need prepare the dictionary for this language pair, do it here - } - else - { - _segmentWordSuggestCandidates = null; - } - - System.Diagnostics.Debug.WriteLine("OnActiveDocumentChanged {0}", ActiveDocument != null); - } - - // when user goes to a segment, we want to prepare the AutoSuggest Candidate first. - // when it takes long, for performance reason, the execution might be done in a separate thread. - protected override void OnActiveSegmentChanged() - { - if (Settings.Enabled) - { - PrepareSegmentSuggestCandiates(); - } - else - { - _segmentWordSuggestCandidates = null; - } - System.Diagnostics.Debug.WriteLine("OnActiveSegmentChanged {0}", ActiveSegmentPair != null); - } - - /// - /// We only provide the AutoSuggest when the candidate is available. The user might have the change from disabled to enabled, we need preapre the candidate. - /// - protected override void OnSettingsChanged() - { - if (Settings.Enabled) - { - PrepareSegmentSuggestCandiates(); - } - else - { - _segmentWordSuggestCandidates = null; - } - } - - protected override IEnumerable GetSuggestions(AbstractEditingContext context) - { - if (Settings.Enabled) - { - string suffix = context.GetAllPrefixes().First(); - if (!string.IsNullOrEmpty(suffix) && _segmentWordSuggestCandidates != null && _segmentWordSuggestCandidates.Count > 0) - { - return _segmentWordSuggestCandidates - .Where(item => item.StartsWith(suffix, Settings.CaseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)) - .Select(item => - { - var result = new AutoSuggestTextResult(context, item); - result.Priority = Settings.Priority; - - // Set different icon for suggestions starting with "a". For the rest set the default provider icon - result.Icon = result.Text.StartsWith("a") ? new Icon(SystemIcons.Question, 16, 16) : Icon; - - return result; - }); - } - - } - return null; - } - - #endregion - - private void PrepareSegmentSuggestCandiates() - { - if (ActiveSegmentPair != null) - { - var stringBuilder = new StringBuilder(); - foreach (var item in ActiveSegmentPair.Source.AllSubItems) - { - var text = item as IText; - if (text != null) - { - stringBuilder.Append(text.Properties.Text); - } - } - - // Split the sentence to words in a naive way, in practice a better way is needed to to tokenize the sentence. - // As a sample we will show the source words in the AutoSuggest, in practice, translation to the target language are needed - _segmentWordSuggestCandidates = Regex.Split(stringBuilder.ToString(), @"\W+").ToList(); - - System.Diagnostics.Debug.WriteLine("PrepareSegmentSuggestCandiates: {0}", stringBuilder.ToString()); - System.Diagnostics.Debug.WriteLine("{0}", _segmentWordSuggestCandidates == null); - } - } - - } -} -``` -**** diff --git a/apiconcepts/integration/trados_studio_command_processor.md b/apiconcepts/integration/trados_studio_command_processor.md deleted file mode 100644 index 911d7dd443..0000000000 --- a/apiconcepts/integration/trados_studio_command_processor.md +++ /dev/null @@ -1,73 +0,0 @@ -Var:ProductName Command line processor -==== -Creating a Var:ProductName command line argument processor ---- - -To create a Var:ProductName command line processor as a third-party developer : - -* implement the [IExternalCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalCommandLineProcessor.yml) or [IExternalWindowAwareCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalWindowAwareCommandLineProcessor.yml) depending if you want to run the command line processor before or after the main screen is shown. - -* from `Sdl.Desktop.IntegrationApi.Extensions.CommandLine` namespace and decorate your class with [ExternalCommandLineProcessorAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.ExternalCommandLineProcessorAttribute.yml) attribute. - -If you fail to implement [IExternalCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalCommandLineProcessor.yml) or [IExternalWindowAwareCommandLineProcessor](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.IExternalWindowAwareCommandLineProcessor.yml), an exception will be thrown, but if you omit the [ExternalCommandLineProcessorAttribute](../../api/integration/Sdl.Desktop.IntegrationApi.Extensions.CommandLine.ExternalCommandLineProcessorAttribute.yml), your plugin will simply be ignored when Var:ProductName starts. - -Example ------ -The following example demonstrates how to implement a custom command line processor - -The plugin implements the required interfaces mentioned above. - -* **TaskName** returns the name of the command processing unit -* **TaskDescription** describes what that processing will do -* **SupportedArguments** lists supported arguments - -# [C#](#tab/tabid-1) -**** -``` -using Sdl.Desktop.IntegrationApi.Extensions.CommandLine; -using System.Windows.Forms; -using System.Collections.Generic; - -namespace Sdl.CustomPlugin.Packaging.OpenPackageWizard -{ - [ExternalCommandLineProcessor(Id = "OpenPackageCommandLineProcessor_Id", Name = "OpenPackageCommandLineProcessor_Name", Description = "OpenPackageCommandLineProcessor_Description")] - public class OpenPackageCommandLineProcessor : IExternalWindowAwareCommandLineProcessor - { - private readonly IList _supportedArguments; - private const string OpenPackageArgument = "openPackage"; - - public OpenPackageCommandLineProcessor() - { - _supportedArguments = new List() - { - new ExternalCommandLineArgumentDefinition(OpenPackageArgument, - StringResources.OpenPackageCommandLineTask_Files) - { - MinValues = 1, - MaxValues = 1, - SampleValues = new[] { "package" } - } - }; - } - - public string TaskName => StringResources.OpenPackageCommandLineTask_Name; - - public string TaskDescription => StringResources.OpenPackageCommandLineTask_Description; - - public IEnumerable SupportedArguments => _supportedArguments; - - public void ProcessCommandLine(ExternalCommandLineArguments args) - { - ExternalCommandLineArgument packagesToOpen = args[OpenPackageArgument]; - if (packagesToOpen == null) - { - return; - } - - var uiPackageOpener = new UIPackageOpener(Form.ActiveFrom); - uiPackageOpener.OpenPackage(packagesToOpen.Values[0]); - } - } -} -``` -**** diff --git a/apiconcepts/integration/trados_studio_controllers.md b/apiconcepts/integration/trados_studio_controllers.md index a09e9fb953..24338e9c2e 100644 --- a/apiconcepts/integration/trados_studio_controllers.md +++ b/apiconcepts/integration/trados_studio_controllers.md @@ -1,18 +1,21 @@ -Introduction -==== -The Var:ProductName Integration API enables third-party developers to extend, customize and integrate their own functionalities inside Var:ProductName UI application and also gain control and perform operations. +# Var:ProductName Controllers + +The Var:ProductName Integration API enables third-party developers to extend, customize, and integrate custom functionalities into the Var:ProductName UI application. You can also gain control and perform various operations. This topic covers specific Var:ProductName UI integrations and operations. -Based on MVC and MVVM patterns, the Var:ProductName Integration API provides view and viewpart controllers to enable third-party developers to integrate their custom UI. +## MVC and MVVM Patterns + +Based on MVC and MVVM patterns, the Var:ProductName Integration API provides view and viewpart controllers to enable third-party developers to integrate custom UI. -For information on how to create and integrate views and viewparts, see the topics: +For information on how to create and integrate views and viewparts, see: -[Creating views](creating_views.md) +- [Creating views](creating_views.md) +- [Creating viewparts](creating_viewparts.md) -[Creating viewparts](creating_viewparts.md) +## Obtaining Controller Instances -Below is a sample on how you can obtain the view or viewpart controllers of the Var:ProductName application. +The following example shows how to obtain the view or viewpart controllers of the Var:ProductName application: # [C#](#tab/tabid-1) ```cs @@ -23,4 +26,4 @@ private EditorController GetEditorController() ``` *** -The next topics are discussing in-depth about each of the Var:ProductName controllers. +The following topics discuss each Var:ProductName controller in detail. diff --git a/apiconcepts/integration/traversing_document_entities.md b/apiconcepts/integration/traversing_document_entities.md index 7ff3551ad0..66844f7ee9 100644 --- a/apiconcepts/integration/traversing_document_entities.md +++ b/apiconcepts/integration/traversing_document_entities.md @@ -1,48 +1,46 @@ -Traversing document entities -===== +# Traversing document entities -The visitor pattern allows a class implementer to traverse all the child objects in an objects hierarchy without having to know how the hierarchy is implemented or having to be aware of any changes in how the hierarchy is implemented. +The visitor pattern enables a class implementer to traverse all child objects in an object hierarchy without needing to know how the hierarchy is implemented or changes to the implementation. -Implementing `IMarkupDataVisitor` ----- +## Implementing `IMarkupDataVisitor` -All that is required is that your class needs to derive from the [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitTagPair_Sdl_FileTypeSupport_Framework_BilingualApi_ITagPair_) interface and to explicitly implement all the interface’s methods. To use the visitor pattern, it is normally helpful to write the similar private method that calls accept visitor for all the markup data child items of the given parent. +Your class must derive from the [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitTagPair_Sdl_FileTypeSupport_Framework_BilingualApi_ITagPair_) interface and explicitly implement all its methods. To use the visitor pattern effectively, write a private method that calls accept visitor for all markup data child items of the given parent. -This method can then be used to kick off the traversal of all the items in a paragraph-unit so that they can be written to the translated target document. This can be done in the implementation of [ProcessParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_ProcessParagraphUnit_Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_) where the passed [IParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml) object can have its Source and Target paragraphs passed to `AppendItems()` and the implementations of the [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml) interface methods can process the various types of text and mark-up objects that form part of the paragraph data hierarchies. +Use this method to initiate traversal of all items in a paragraph-unit and write them to the translated target document. Implement this in the [ProcessParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IBilingualContentHandler.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IBilingualContentHandler_ProcessParagraphUnit_Sdl_FileTypeSupport_Framework_BilingualApi_IParagraphUnit_) method. Pass the Source and Target paragraphs from the [IParagraphUnit](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IParagraphUnit.yml) object to `AppendItems()`. The [IMarkupDataVisitor](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml) interface methods process the various types of text and markup objects in the paragraph data hierarchies. -**VisitTagPair()** +### VisitTagPair() -[VisitTagPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitTagPair_Sdl_FileTypeSupport_Framework_BilingualApi_ITagPair_) method is called when a tag pair object of type [ITagPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ITagPair.yml) is being visited. This tag pair object is normally processed by writing to the target document the tag pair start tag then processing all the tag pair’s child nodes then writing the tag pair end tag. However, some Bilingual Writers may need to cache this information first. In order to process all the child nodes of a tag pair the `AppendItems()` private helper method can be called with the tag object as the parameter. +The [VisitTagPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitTagPair_Sdl_FileTypeSupport_Framework_BilingualApi_ITagPair_) method executes when visiting a tag pair object of type [ITagPair](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ITagPair.yml). Typically, process this object by writing the tag pair start tag to the target document, processing all child nodes, and writing the tag pair end tag. Some bilingual writers may prefer to cache this information first. Call the `AppendItems()` helper method with the tag object as a parameter to process all child nodes of a tag pair. -**VisitPlaceholderTag())** +### VisitPlaceholderTag() -[VisitPlaceholderTag](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitPlaceholderTag_Sdl_FileTypeSupport_Framework_BilingualApi_IPlaceholderTag_) method is called when a placeholder tag object of type [IPlaceholderTag](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IPlaceholderTag.yml) is being visited. This placeholder object is normally processed by writing to the target document this placeholder tag. However, some Bilingual writers may need to cache this information first. +The [VisitPlaceholderTag](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitPlaceholderTag_Sdl_FileTypeSupport_Framework_BilingualApi_IPlaceholderTag_) method executes when visiting a placeholder tag object of type [IPlaceholderTag](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IPlaceholderTag.yml). Typically, write the placeholder tag to the target document. Some bilingual writers may prefer to cache this information first. -**VisitText()** +### VisitText() -[VisitText](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitText_Sdl_FileTypeSupport_Framework_BilingualApi_IText_) method is called when a text object of type [IText](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IText.yml) is being visited. This text object is normally processed by writing the content of the text object to the target document. However, when processing text items it may be necessary to consider the value of `ContentRestriction` as the content restriction type may indicate that the source text is to be written instead of the target text. If this is the case then when a translatable paragraph-unit is being processed then `AppendItems()` should be called for the source paragraph rather than then target paragraph ensuring that subsequent calls to [VisitText](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitText_Sdl_FileTypeSupport_Framework_BilingualApi_IText_) will be for the source text. +The [VisitText](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitText_Sdl_FileTypeSupport_Framework_BilingualApi_IText_) method executes when visiting a text object of type [IText](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IText.yml). Write the content to the target document. When processing text items, consider the `ContentRestriction` value. The content restriction type indicates whether to write the source or target text. For translatable paragraph-units, call `AppendItems()` for the source paragraph when the restriction requires source text. Subsequent [VisitText](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitText_Sdl_FileTypeSupport_Framework_BilingualApi_IText_) calls will then process the source text. -**VisitSegment()** +### VisitSegment() -[VisitSegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitSegment_Sdl_FileTypeSupport_Framework_BilingualApi_ISegment_) method is called when a segment object of type [ISegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegment.yml) is being visited. This segment object is normally processed by writing any required information from the [ISegmentPairProperties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.NativeApi.ISegmentPairProperties.yml), such as `MatchPercent` or `TranslationOrigin`. +The [VisitSegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitSegment_Sdl_FileTypeSupport_Framework_BilingualApi_ISegment_) method executes when visiting a segment object of type [ISegment](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ISegment.yml). Write any required information from the [ISegmentPairProperties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.NativeApi.ISegmentPairProperties.yml), such as `MatchPercent` or `TranslationOrigin`. -**VisitLocationMarker()** +### VisitLocationMarker() -[VisitLocationMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitLocationMarker_Sdl_FileTypeSupport_Framework_BilingualApi_ILocationMarker_) method is called when a location marker object of type ILocationMarker is being visited. Location markers are typically used for locating a position within a translated document, such as the scroll position when previewing a document within a framework based editor. +The [VisitLocationMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitLocationMarker_Sdl_FileTypeSupport_Framework_BilingualApi_ILocationMarker_) method executes when visiting a location marker object of type ILocationMarker. Location markers identify positions within a translated document, such as the scroll position when previewing a document in a framework-based editor. -**VisitOtherMarker()** +### VisitOtherMarker() -[VisitOtherMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitOtherMarker_Sdl_FileTypeSupport_Framework_BilingualApi_IOtherMarker_) method is called when an alternate location marker object of type [IOtherMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IOtherMarker.yml) is being visited. +The [VisitOtherMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitOtherMarker_Sdl_FileTypeSupport_Framework_BilingualApi_IOtherMarker_) method executes when visiting an alternate location marker object of type [IOtherMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IOtherMarker.yml). -**VisitRevisionMarker()** +### VisitRevisionMarker() -[VisitRevisionMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitRevisionMarker_Sdl_FileTypeSupport_Framework_BilingualApi_IRevisionMarker_) method is called when an track change location marker object of type [IRevisionMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IRevisionMarker.yml) is being visited. +The [VisitRevisionMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitRevisionMarker_Sdl_FileTypeSupport_Framework_BilingualApi_IRevisionMarker_) method executes when visiting a track change location marker object of type [IRevisionMarker](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IRevisionMarker.yml). -**VisitLockedContent()** +### VisitLockedContent() -[VisitLockedContent](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitLockedContent_Sdl_FileTypeSupport_Framework_BilingualApi_ILockedContent_) method is called when a locked content container object of type [ILockedContent](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml) is being visited. This locked content object is normally processed by checking the value of `LockType` in its [Properties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml#Sdl_FileTypeSupport_Framework_BilingualApi_ILockedContent_Properties) property. The value of this lock type may indicate how to treat the contents of this container when writing them to the translated target document. Also when processing this [ILockedContent](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml) container it would normally be the case that 'AppendItems()' would be called for its [Content](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml#Sdl_FileTypeSupport_Framework_BilingualApi_ILockedContent_Content) collection of child objects. +The [VisitLockedContent](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.IMarkupDataVisitor.yml#Sdl_FileTypeSupport_Framework_BilingualApi_IMarkupDataVisitor_VisitLockedContent_Sdl_FileTypeSupport_Framework_BilingualApi_ILockedContent_) method executes when visiting a locked content container object of type [ILockedContent](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml). Check the `LockType` value in its [Properties](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml#Sdl_FileTypeSupport_Framework_BilingualApi_ILockedContent_Properties) property. The lock type indicates how to treat the container contents when writing them to the translated target document. Call `AppendItems()` for the [Content](../../api/filetypesupport/Sdl.FileTypeSupport.Framework.BilingualApi.ILockedContent.yml#Sdl_FileTypeSupport_Framework_BilingualApi_ILockedContent_Content) collection of child objects. -See Also ---------- -[Visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern) -[Design pattern](https://en.wikipedia.org/wiki/Design_Patterns) +## See Also + +- [Visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern) +- [Design pattern](https://en.wikipedia.org/wiki/Design_Patterns) \ No newline at end of file diff --git a/apiconcepts/integration/user_interface_integration.md b/apiconcepts/integration/user_interface_integration.md index 4c75a21320..ee796be818 100644 --- a/apiconcepts/integration/user_interface_integration.md +++ b/apiconcepts/integration/user_interface_integration.md @@ -1,8 +1,10 @@ -Introduction -==== -The Var:ProductNameIntegration API enables third-party developers to extend and integrate their own UI functionalities inside the Var:ProductName application. +# User Interface Integration -Make sure the following references are added to your project, you will find them in the installation folder of Var:ProductName. +The Var:ProductName Integration API allows third-party developers to extend and integrate custom UI functionalities into the Var:ProductName application. + +## Required Assembly References + +Add the following assemblies to your project. You can find them in the Var:ProductName installation folder: ![User interface plug-ins](images/UI.png) * Sdl.Desktop.IntegrationApi.dll @@ -10,24 +12,23 @@ Make sure the following references are added to your project, you will find them * Sdl.TranslationStudioAutomation.IntegrationApi.dll * Sdl.TranslationStudioAutomation.IntegrationApi.Extensions.dll -> [!NOTE] -> -> As build output path for your implementations please choose the *Var:PluginPackedPath*. -> -> Also check that your library references are pointing to the Var:ProductName folder. e.g. *Var:InstallationFolder*. -> -> For more information on building an deploying a Var:ProductName plug-in, see (Building a plug-in and Plug-in deployment). -> -> Sign and use Strong-Named Assemblies to enable the loading of your plug-ins inside the Var:ProductName. +> [!IMPORTANT] +> +> Follow these guidelines when building and deploying plug-ins: +> +> * Set your build output path to *Var:PluginPackedPath* +> * Verify that your library references point to the Var:ProductName folder (for example, *Var:InstallationFolder*) +> * Sign your assembly with a strong name—unsigned assemblies will not load in Var:ProductName +> * See [How to: Sign an Assembly with a Strong Name](https://docs.microsoft.com/en-us/dotnet/standard/assembly/sign-strong-name?redirectedfrom=MSDN) for details +> +> For more information, see [Building a plug-in](building_a_plugin.md) and [Plug-in deployment](plugin_deployment.md). + +## API Namespaces -> [How to: Sign an Assembly with a Strong Name](https://docs.microsoft.com/en-us/dotnet/standard/assembly/sign-strong-name?redirectedfrom=MSDN) +### Sdl.Desktop.IntegrationApi -> Choosing a different build output path or not signing your assembly will prevent your plugin from loading. +[Sdl.Desktop.IntegrationApi](../../api/integration/Sdl.Desktop.IntegrationApi.yml) is the main namespace for integrating new UI functionalities into Studio. -Sdl.Desktop.IntegrationApi ------ -[Sdl.Desktop.IntegrationApi](../../api/integration/Sdl.Desktop.IntegrationApi.yml) is the main namespace which enables the integration of new Studio UI functionalities. +### Sdl.TranslationStudioAutomation.IntegrationApi -Sdl.TranslationStudioAutomation.IntegrationApi ------- -[Sdl.TranslationStudioAutomation.IntegrationApi](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.yml) is the main namespace which enables the integration inside the Var:ProductName application. +[Sdl.TranslationStudioAutomation.IntegrationApi](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.yml) is the main namespace for integrating custom functionality into the Var:ProductName application. diff --git a/apiconcepts/integration/using_trados_studio_editorcontroller.md b/apiconcepts/integration/using_trados_studio_editorcontroller.md index 5d796b469a..7095817521 100644 --- a/apiconcepts/integration/using_trados_studio_editorcontroller.md +++ b/apiconcepts/integration/using_trados_studio_editorcontroller.md @@ -1,23 +1,25 @@ -Using Var:ProductName EditorController -===== -TranslationStudioAutomation provides support for third-party developers to access the Var:ProductName editor view and perform editor operations. +# Using Var:ProductName EditorController -Creating a custom document list inside a viewpart that belongs to the editor view ----- -The following sample demonstrates how to create a custom documents list built by using the [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) and add it to the editor view as a custom viewpart. +The TranslationStudioAutomation API enables you to access the Var:ProductName editor view and perform editor operations. -The custom list features: +## Create a custom document list in a viewpart -* Display the following columns: - * The document file name - * Number of segments to be translated +This sample demonstrates how to create a custom document list using the [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) and add it to the editor view as a custom viewpart. + +The custom list includes: + +* Four columns: + * Document file name + * Number of segments to translate * Source language * Target language -* Activating the document list items will active the document in the editor too. -* The active document will always be displayed as selected in the list. +* Selection synchronization: activating items in the custom list activates the document in the editor +* Active document display: the currently active document appears selected in the list -Start by implementing the windows form user control that will fill the content of the viewpart and is implementing the list view. +### Step 1: Implement the user control + +Create a Windows Forms user control to display the document list: # [C#](#tab/tabid-1) ```cs private void InitializeDocumentListTab() @@ -69,9 +71,10 @@ private Document ActiveDocument } } ``` -**** -Finally, integrate the new viewpart to the editor view. +### Step 2: Integrate the viewpart into the editor view + +Register the viewpart with the editor view: # [C#](#tab/tabid-2) ```cs using System; @@ -104,11 +107,10 @@ namespace EditorOperations.Sample } } ``` -**** -Tracking all editor document events and display them inside a list view. ---------- -The following sample demonstrates how to bind to all [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) related events and add them into a tab as an events list view. +## Track editor document events + +This sample demonstrates how to subscribe to all [EditorController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.EditorController.yml) events and add them to a list view for tracking. # [C#](#tab/tabid-3) ```cs private void InitializeTrackingEventsTab() @@ -170,11 +172,10 @@ private void AddListViewEvent(string eventName, string eventMetadata = "") EventsListView.Items.Insert(0, item); } ``` -**** -Performing operations over document selections ----- -The following sample demonstrates how to retrieve and replace the current document selection. +## Perform operations on document selections + +This sample demonstrates how to retrieve and update the current document selection. # [C#](#tab/tabid-4) ```cs private void InitializeSelectionsTab() @@ -199,5 +200,4 @@ private void ReplaceSelectionButton_Click(object sender, EventArgs e) doc.Selection.Target.Replace(ReplaceSelectionTextBox.Text, "Manual selection replacement"); doc.Selection.Target.Collapse(); } -``` -*** +``` \ No newline at end of file diff --git a/apiconcepts/integration/using_trados_studio_filescontroller.md b/apiconcepts/integration/using_trados_studio_filescontroller.md index 9f95b15f45..c08e9348d3 100644 --- a/apiconcepts/integration/using_trados_studio_filescontroller.md +++ b/apiconcepts/integration/using_trados_studio_filescontroller.md @@ -1,18 +1,19 @@ -Using Var:ProductName FilesController -===== -TranslationStudioAutomation provides support for third-party developers to access the Var:ProductName files view and perform project files operations. +# Using Var:ProductName FilesController -Creating a custom project files list inside a viewpart that belongs to the files view ------ -The following sample demonstrates how to create a custom project files list built by using the [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) and add it to the files view as a custom viewpart. +The TranslationStudioAutomation API enables you to access the Var:ProductName files view and perform file operations. -The custom list features: +## Create a custom file list in a viewpart -* Display two columns: the project file name and the number of total words from the file. -* The projects files selected in the project files list will be in sync with the one from the custom list. +This sample demonstrates how to create a custom file list using the [FilesController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.FilesController.yml) and add it to the files view as a custom viewpart. +The custom list includes: -Start by implementing the windows form user control that will fill the content of the viewpart and is implementing the list view. +* Two columns: the file name and the total word count from the file +* Selection synchronization between the custom list and the files view + +### Step 1: Implement the user control + +Create a Windows Forms user control to display the file list: # [C#](#tab/tabid-1) ```cs @@ -106,9 +107,10 @@ namespace FilesOperations.Sample } } ``` -*** -Finally integrate the new viewpart to the files view. +### Step 2: Integrate the viewpart into the files view + +Register the viewpart with the files view: # [C#](#tab/tabid-2) ```cs @@ -147,4 +149,3 @@ namespace FilesOperations.Sample } } ``` -*** diff --git a/apiconcepts/integration/using_trados_studio_projectscontroller.md b/apiconcepts/integration/using_trados_studio_projectscontroller.md index d6c4f7dca1..459630859d 100644 --- a/apiconcepts/integration/using_trados_studio_projectscontroller.md +++ b/apiconcepts/integration/using_trados_studio_projectscontroller.md @@ -1,19 +1,20 @@ -Using Var:ProductName ProjectsController -===== -TranslationStudioAutomation provides support for third-party developers to access the Var:ProductName projects view and perform project operations. +# Using Var:ProductName ProjectsController -Creating a custom project list inside a viewpart that belongs to the projects view ----- -The following sample demonstrates how to create a custom project list built by using the [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) and add it to the projects view as a custom viewpart. +The TranslationStudioAutomation API enables you to access the Var:ProductName projects view and perform project operations. -The custom list features: +## Create a custom project list in a viewpart -* Display two columns: the project name and the number of target language files contained in the project. -* The projects selected in the list will be selected in the projects view list too. -* Activating a selected project will open it. +This sample demonstrates how to create a custom project list using the [ProjectsController](../../api/integration/Sdl.TranslationStudioAutomation.IntegrationApi.ProjectsController.yml) and add it to the projects view as a custom viewpart. +The custom list includes: -Start by implementing the windows form user control that will fill the content of the viewpart and is implementing the list view. +* Two columns: the project name and the number of target language files in the project +* Selection synchronization between the custom list and the projects view +* The ability to open a project by activating a selected project + +### Step 1: Implement the user control + +Create a Windows Forms user control to display the project list: # [C#](#tab/tabid-1) ```cs @@ -186,9 +187,10 @@ namespace ProjectsOperations.Sample } } ``` -*** -Finally integrate the new viewpart to the projects view. +### Step 2: Integrate the viewpart into the projects view + +Register the viewpart with the projects view: # [C#](#tab/tabid-1) ```cs @@ -222,8 +224,7 @@ namespace ProjectsOperations.Sample } } ``` -*** -See Also ----------- -[Integrating viewparts](integrating_viewparts.md) +## See also + +- [Integrating viewparts](integrating_viewparts.md) diff --git a/apiconcepts/integration/what_the_filter_should_do.md b/apiconcepts/integration/what_the_filter_should_do.md deleted file mode 100644 index ef780a020d..0000000000 --- a/apiconcepts/integration/what_the_filter_should_do.md +++ /dev/null @@ -1,9 +0,0 @@ -What the filter should do -====== -Learn how to develop a custom display filter by following the creation of a simplified sample project which uses the Display Filter API. - -The example custom display filter will be a simple control where the filter is applied on the active document from the editor. Our sample project will contain simplified code examples that show you how to implement: - -* An integration of the display filter in the Var:ProductName UI. -* The addition of some filters to be applied on source and target segments. -* An assertion of whether or not the segments should be visible in the Var:ProductName Editor. diff --git a/apiconcepts/integration/what_you_can_do_with_the_integration_API.md b/apiconcepts/integration/what_you_can_do_with_the_integration_API.md deleted file mode 100644 index 9dcf33e364..0000000000 --- a/apiconcepts/integration/what_you_can_do_with_the_integration_API.md +++ /dev/null @@ -1,13 +0,0 @@ -What you can do with the Integration API -===== - -This page provides a quick overview of what you can do with the Var:ProductName Integration API. - -The following diagram exemplifies how the Var:ProductName Integration API enables you to create custom plug-ins in order to: - -* [Extend or customize the user interface for Studio applications.](user_interface_integration.md) -* [Provide custom functionalities for the Var:ProductName application.](studio_automation.md) - -![PluginTypes](images/PluginTypes.png) - -Var:ProductName API documentation features examples on common and best practices when developing plug-ins using Var:ProductName API. All provided examples are written in C#. diff --git a/apiconcepts/integration/wikipedia_search.md b/apiconcepts/integration/wikipedia_search.md index 257106ebd4..43540dc88c 100644 --- a/apiconcepts/integration/wikipedia_search.md +++ b/apiconcepts/integration/wikipedia_search.md @@ -1,12 +1,12 @@ -Wikipedia Search -== +# Wikipedia Search -Wikipedia Search is a useful addition to this plug-in. It illustrates how a view part can be integrated into an existing view in Studio, in this case a view part which integrates into the editor view and allows a Wikipedia search to be carried out on selected text in the editor itself. To activate this feature, open a document in the editor, navigate to View Tab->Information group and select Wikipedia. This will display the Wikipedia view part. Selecting text in the editor and clicking Search Wikipedia in the Add-Ins tab will populate the Wikipedia view part with the results of the search. +Wikipedia Search extends this plug-in by demonstrating how a view part integrates into an existing Var:ProductName view. The sample integrates a view part into the editor view and allows users to search Wikipedia for selected text in the editor. -Wikipedia Search Action --- +To use this feature, open a document in the editor and navigate to View Tab > Information group, then select Wikipedia. This displays the Wikipedia view part. Select text in the editor and click Search Wikipedia in the Add-Ins tab to populate the Wikipedia view part with search results. -This sample illustrates how a Ribbon Group can be created on the Add-Ins tab and also how actions can be added to it. In the WikipediaSearchAction class the Initialize method shows how a reference to the EditorController can be obtained. The Execute method shows how this reference can be used. +## Wikipedia Search Action + +This sample demonstrates how to create a Ribbon Group on the Add-Ins tab and add actions to it. The WikipediaSearchAction class shows how to obtain a reference to the EditorController in the Initialize method and use it in the Execute method. # [C#](#tab/tabid-1) ```cs @@ -67,10 +67,9 @@ namespace StudioIntegrationApiSample ``` *** -Wikipedia ResultsViewPart Controller --- +## Wikipedia ResultsViewPart Controller -The Var:ProductName Integration API is built in accordance with the MVC pattern. The ViewPart controller is used to add a new view part using the ViewPart attribute. This controller is also responsible for preparing the lookup URI that will be passed to the UI control for display purposes. +The Var:ProductName Integration API follows the MVC pattern. The ViewPart controller adds a new view part using the ViewPart attribute. This controller prepares the lookup URI that the UI control displays. # [C#](#tab/tabid-2) ```cs @@ -99,7 +98,6 @@ namespace StudioIntegrationApiSample return _control.Value; } - private readonly Lazy _control = new Lazy(() => new WikipediaResultsViewPartControl()); public void Lookup(string query) @@ -109,7 +107,6 @@ namespace StudioIntegrationApiSample _control.Value.Navigate(url); } - protected override void Initialize() { } @@ -118,10 +115,9 @@ namespace StudioIntegrationApiSample ``` *** -Wikipedia Results ViewPart Control --- +## Wikipedia Results ViewPart Control -This class is responsible for rendering the UI. The view relies on the controller described above to obtain a search URI and passes it to the web browser in order to search Wikipedia and display the results. +This class renders the UI. The view receives a search URI from the controller and passes it to the web browser to search Wikipedia and display the results. # [C#](#tab/tabid-3) ```cs @@ -145,8 +141,6 @@ namespace StudioIntegrationApiSample InitializeComponent(); } - - public void Navigate(string url) { _webBrowser.Navigate(url); @@ -156,21 +150,12 @@ namespace StudioIntegrationApiSample ``` *** -See Also --- - - - -[Reference Sample](reference_sample.md) - -[Project Creator](project_creator.md) - -[Content Connector](content_connector.md) - -[Integrating actions](integrating_actions.md) - -[Integrating ribbon groups](integrating_ribbon_groups.md) - -[Integrating viewparts](integrating_viewparts.md) +## See Also -[Integrating views](integrating_views.md) +- [Reference Sample](reference_sample.md) +- [Project Creator](project_creator.md) +- [Content Connector](content_connector.md) +- [Integrating actions](integrating_actions.md) +- [Integrating ribbon groups](integrating_ribbon_groups.md) +- [Integrating viewparts](integrating_viewparts.md) +- [Integrating views](integrating_views.md) diff --git a/apiconcepts/toc.yml b/apiconcepts/toc.yml index 2182505beb..75efd4bcd7 100644 --- a/apiconcepts/toc.yml +++ b/apiconcepts/toc.yml @@ -626,8 +626,6 @@ items: - name: Overview href: integration/overview.md - - name: What you can do with the Integration API - href: integration/what_you_can_do_with_the_integration_API.md - name: User Interface integration href: integration/user_interface_integration.md items: @@ -689,14 +687,8 @@ - name: Extend default packaging functionality href: integration/extend_standard_packaging_support.md - name: Integration Samples - href: integration/integration_samples.md + href: integration/using_trados_studio_projectscontroller.md items: - - name: Trados Studio application initializers - href: integration/trados_studio_application_initializers.md - - name: Trados Studio AutoSuggest provider - href: integration/trados_studio_autosuggest_provider.md - - name: Trados Studio command line processor - href: integration/trados_studio_command_processor.md - name: Using Trados Studio ProjectsController href: integration/using_trados_studio_projectscontroller.md - name: Using Trados Studio FilesController @@ -720,18 +712,13 @@ href: integration/display_filter.md items: - name: Introduction - href: integration/display_filter.md - - name: Developing a Sample Custom Display Filter - href: integration/what_the_filter_should_do.md - items: - - name: What the filter should do - href: integration/what_the_filter_should_do.md - - name: Setting up the Visual Studio Project - href: integration/setting_up_the_visual_studio_project.md - - name: Implementing filtering capabilities to your Display Filter - href: integration/implementing_filtering_capabilities_to_your_display_filter.md - - name: Creating the UI Editor Control for your Display Filter - href: integration/creating_the_ui_editor_control_for_your_display_filter.md + href: integration/display_filter.md + - name: Setting up the Visual Studio Project + href: integration/setting_up_the_visual_studio_project.md + - name: Implementing filtering capabilities to your Display Filter + href: integration/implementing_filtering_capabilities_to_your_display_filter.md + - name: Creating the UI Editor Control for your Display Filter + href: integration/creating_the_ui_editor_control_for_your_display_filter.md - name: API Reference href: ../api/integration/toc.yml - name: Verification diff --git a/developer_license.md b/developer_license.md index aa9e15f053..7f86da0e1d 100644 --- a/developer_license.md +++ b/developer_license.md @@ -1,9 +1,3 @@ ---- -uid: developer_license -title: "Request a Developer License" -description: "How to request a developer license for Trados solutions." ---- - # Request a Developer License ## Selecting the Right License