Search Results for

    Show / Hide Table of Contents

    Better Studio interactivity in day to day flow

    Together with the release of Trados Studio 2019 SR2 we decided to make some improvements to our public APIs and give our 3rd Party developers more access to Studio's functional flows as well as user interface styling. Throughout this article we will present the functionality we exposed in our APIs and the means by which you can make the most out of it.

    Improved Notification System

    The notification system in Trados Studio, which can be accessed via the Notification View pane (on the right-hand side), was intended as a mechanism allowing us to promote notifications in a non-intrusive manner, while translators interact with Studio. We continued to take advantage of it, but while developing new features, we realized it had some short-comings that needed to be addressed. After we fixed the issues, we decided to make them available in the public APIs.

    In order to allow translators to remove a specific notification, we introduced two new properties on the IStudioNotification interface. As developers, you will have full control over which notifications can be removed by translators and which not, as well as over what should happen within the remove logic.

    Property Type Purpose
    AllowsUserToDismiss bool Set this to true for the user to see a dismiss button when hovering over a notification.
    ClearNotificationAction IStudioNotificationCommand Assign an instance of the implemented interface to this property. The dismiss button will trigger the behavior specified in your implementation.

    We also enhanced the control over the notification system by exposing additional events. With the help of these events we now give full access to creating and removing notification groups, but also to what happens inside a group: remove a notification from a group, add a specific notification to a group or create that group if it does not exist.

    Event Purpose
    AddStudioNotificationOrCreateGroupEvent Trigger this event to add an IStudioNotification instance to an existing group or create a new group if the group with the given key already exists. The event expects the unique identifier of the group, the notification to be added and a group title in case it needs to create a new group.
    RemoveStudioNotificationFromGroupEvent Trigger this event via the EventAggregator to remove a specific notification identified by its unique id from the group with the given key.

    The following code snippet demonstrates how to publish dismissible notifications via the IStudioEventAggregator

        //create a unique identifier for the notification
        var notificationId = Guid.NewGuid();
        //create an instance of IStudioNotification
        var sampleNotification = new StudioTestNotification(notificationId)
        {
            Title = "Sample Notification Title",
            AlwaysVisibleDetails = new List<string> 
            { 
                "Will be added to an existing group or will create a new one." 
            },
            AllowsUserToDismiss = true,
            ClearNotificationAction = new ClearNotificationAction(GroupId, notificationId),
            IsExpanderVisible = false,
            IsLinkVisible = true,
            LinkAction = new OpenLinkCommand("https://appstore.sdl.com/language/developers/sdk.html")
            {
                CommandText = "Learn more on the Studio 2019 SDK",
                CommandToolTip = "Learn more on the Studio 2019 SDK"
            },
            IsActionVisible = false
        };
    
        //create an instance of the event
        var addTestGroup = new AddStudioNotificationOrCreateGroupEvent(
                                    GroupId, 
                                    sampleNotification, 
                                    NotificationGroupTitle);
        //publish the event via the Event Aggregator
        var ea = SdlTradosStudio.Application.GetService<IStudioEventAggregator>();
        ea.Publish(addTestGroup);
    

    The ClearNotificationAction class implements the logic required to remove the notification from the group. It implements the IStudioNotificationCommand interface which is just an extension over the standard WPF ICommand.

    public class ClearNotificationAction : IStudioNotificationCommand
    {
        private readonly string _groupId;
        private readonly Guid _notificationId;
    
        public ClearNotificationAction(string groupNotificationKey, Guid notificationId)
        {
            .......//some constructor logic
        }
    
        ....... //Interface implementation (properties and methods)       
            
        public void Execute(object parameter)
        {
            var ea = SdlTradosStudio.Application.GetService<IStudioEventAggregator>();
            ea.Publish(new RemoveStudioNotificationFromGroupEvent(_groupId, _notificationId));
        }
    }
    

    If you are unclear about which properties need to be set in order to control various UI elements and inject custom behavior, we created a diagram mapping the elements of a Notification Group and a Notification to the properties of the IStudioNotificationGroup and IStudioNotification interfaces.

    Improved interactivity with projects

    In this section we will present some of the new API events and interfaces that we exposed to help your plugins integrate better with Trados Studio's project and package flows.

    Accessing the New Project wizard

    With Studio 2019 SR2 you can now request for New Project wizard to be opened from your code by publishing the OpenNewProjectWizardEvent via the IStudioEventAggregator. This event will also allow you to pre-specify data for the new project in a ProjectWizardData object.

    Property Description
    ProjectName Use this property to pre-set a value for your project name.
    Content Use this enumeration to send a list of files or folders given by their full path.
    ProjectTemplate Set this property to the full path of a project template file (*.sdltpl) that will be used by the wizard for creating the project.
    ProjectReference Set this property to the full path of a project file (*.sdlproj) that will be used by the wizard for creating the project.

    Please note that you can either pass a project template or a project reference template. In the event you pass values for both, Trados Studio will use the project template file.

    Here is a small code sample on how to implement the event publishing:

    var wizardData = new ProjectWizardData()
    {
        ProjectName = "My Project",
        Content = new List<string>() { "C:\MySample.doc" }
    };
    _eventAggregator.Publish(new OpenNewProjectWizardEvent(wizardData));
    

    And this is how it should behave in Studio:

    Executing custom logic within package flows

    Up until Studio 2019 SR2 the only option you had to invoke the Open Package wizard from a plugin was similar to this:

     var app = new StudioApplication();
     app.ExecuteAction<OpenPackageAction>();
    

    Going forward, you will now be able to trigger the same Open Package wizard and pass along additional details such as the package file path, the project icon and even a custom job to be executed after the package is imported in Studio. Same as above, all you need to do is publish an OpenProjectPackageEvent object with your desired data.

    Property Description
    packageFilePath Use this parameter to specify a path to the package to be opened.
    job Use this parameter to pass an IExternalJobWithProgress object to be executed once the package was loaded in Studio. Leave this null if you do not wish to execute a custom job.
    iconPath Use this parameter to set an icon for your project. This allows you to customize the Projects View and have project icons specific to your plugin.
    projectOrigin Use this parameter to set a project type. This allows you to customize the Projects View and have the project type specific to your plugin.

    Here is a code sample from the above capture. The details on how to implement a custom job will be presented later on in this article.

      var sampleJob = new SampleJob() { JobName = "Sample" };
      eventAggregator.Publish(new OpenProjectPackageEvent(packagePath, sampleJob, iconPath, projectType));
    

    The same improvements were added for creating return packages, where you can specify a custom job to be executed when triggering the Create Return Package wizard. You might find these usefull if your plugin needs to upload the package to a server, as everything will be processed together within the wizard. To achieve this, publish the CreateReturnPackageEvent using the IStudioEventAggregator.

    Property Description
    id This is the project Guid which you can obtain from the ProjectInfo class.
    job Use this parameter to pass an IExternalJobWithProgress object to be executed once the return package was created. Leave this null if you do not wish to execute a custom job.

    And this is the code sample:

    var sampleJob = new SampleJob() { JobName = "Sample" };
    var project = SdlTradosStudio.Application.GetController<ProjectsController>().CurrentProject;
    if (project != null)
    {
        var selectedProjectId = project.GetProjectInfo().Id.ToString();
        eventAggregator.Publish(new CreateReturnPackageEvent(selectedProjectid, sampleJob));
    }
    

    The IExternalJob and IExternalJobWithProgress interfaces are the bridge that will allow you to inject custom code into the wizards as well as into Trados Studio'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, Trados Studio 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.

    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.

    Here is a code sample on how such an implementation should look like:

    public class SampleJob : IExternalJobWithProgress
    {
        //Use this property to hold any type of data required for your job
        public object JobData { get; set; }
    
        public string JobName { get; set; }
    
        public event EventHandler<JobProgressArgs> ProgressReported;
    
        public void JobCanceled(object sender, EventArgs e)
        {
            //Job canceled...do something
        }
    
        public void Execute()
        {
            ProgressReported?.Invoke(this, new JobProgressArgs()
            {
                 PercentComplete = 0,
                 StatusMessage = "Sample Job started"
            });
            
            //some long running operation
            ProgressReported?.Invoke(this, new JobProgressArgs()
            {
                PercentComplete = 100,
                StatusMessage = "Sample Job done"
            });
        }
    }
    

    Please note that the JobData property acts as a bridge between Trados Studio and your plugin in case of using the job inside the Open Package and Create Return Package wizards. Trados Studio will set the file path on the property as follows:

    • the file path to the project that was just imported into Trados Studio, in the case of the Open Package wizard
    • the file path for the created package, in the case of the Create Return Package wizard.

    Other improvements

    In this section we will present some additional changes which we consider useful for plugin development.

    Knowing when the Trados Studio main window was created

    There are situations when you want to know when your application has completed loading in order to perform a specific user operation. For example, you want to display a log-in prompt for the translators from your plugin. For such a scenario (but not only), we exposed the StudioWindowCreatedNotificationEvent which will be published from Trados Studio once it completes loading. Now you only need to subscribe to this event and you are set to go.

        protected override void Initialize(IViewContext context)
        {
            var ea = SdlTradosStudio.Application.GetService<IStudioEventAggregator>();
            ea.GetEvent<StudioWindowCreatedNotificationEvent>().Subscribe(OnStudioWindowCreated);
        }
    
        private void OnStudioWindowCreated(StudioWindowCreatedNotificationEvent e)
        {
            MessageBox.Show("Studio was loaded");
        }
    

    Refreshing the Projects view

    For situations where you would like to have the list of Trados Studio projects refreshed in the Projects view you can now publish a RefreshProjectsEvent object via the event aggregator.

       eventAggregator.Publish(new RefreshProjectsEvent());
    

    With this we bring to an end our improvements for Studio 2019 SR2 public APIs. You can find more code examples on GitHub, and make sure to checkout our other article on the exposed [WPF Styles] (../Studio_Styles/StudioStyles.md).

    • Improve this Doc
    In this article
    • Improved Notification System
    • Improved interactivity with projects
      • Accessing the New Project wizard
      • Executing custom logic within package flows
    • Other improvements
      • Knowing when the Trados Studio main window was created
      • Refreshing the Projects view
    Back to top Generated by DocFX