├── .gitignore
├── tests
└── EsapiEssentials.UnitTests
│ ├── packages.config
│ ├── EsapiEssentials.UnitTests.csproj.DotSettings
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── PatientSearch
│ └── PatientSummarySearchTests.cs
│ └── EsapiEssentials.UnitTests.csproj
├── src
├── EsapiEssentials.PluginRunner
│ ├── Application
│ │ ├── PlanType.cs
│ │ ├── PatientMatch.cs
│ │ └── PlanOrPlanSum.cs
│ ├── Persistence
│ │ ├── IDataRepository.cs
│ │ ├── Data.cs
│ │ ├── DataRepository.cs
│ │ └── RecentEntry.cs
│ ├── packages.config
│ ├── app.config
│ ├── EsapiEssentials.PluginRunner.nuspec
│ ├── View
│ │ ├── MainWindow.xaml.cs
│ │ └── UnderscoreConverter.cs
│ ├── PlansAndPlanSumsConverter.cs
│ ├── EsapiEssentials.PluginRunner.csproj.DotSettings
│ ├── ViewModel
│ │ ├── PlanOrSumViewModel.cs
│ │ └── MainViewModel.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── ScriptRunner.cs
└── EsapiEssentials
│ ├── packages.config
│ ├── Standalone
│ ├── PatientSearch
│ │ ├── SearchPatient.cs
│ │ ├── PatientSearch.cs
│ │ └── PatientSummarySearch.cs
│ ├── Async
│ │ ├── LogInRequiredException.cs
│ │ ├── PatientNotOpenedException.cs
│ │ └── AsyncRunner.cs
│ └── StandaloneRunner
│ │ ├── StandaloneRunnerException.cs
│ │ ├── StandaloneRunner.cs
│ │ └── ScriptContextArgs.cs
│ ├── Core
│ └── DoseUnit.cs
│ ├── EsapiEssentials.nuspec
│ ├── Plugin
│ ├── Async
│ │ ├── AsyncRunner.cs
│ │ ├── EsapiServiceBase.cs
│ │ └── UiRunner.cs
│ ├── PluginRunner
│ │ ├── ScriptBase.cs
│ │ ├── ScriptBaseWithWindow.cs
│ │ └── PluginScriptContext.cs
│ └── Settings
│ │ └── AssemblySettings.cs
│ ├── Extensions
│ ├── PatientExtensions.cs
│ ├── DoseValueExtensions.cs
│ ├── StructureExtensions.cs
│ └── PlanningItemExtensions.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── EsapiEssentials.csproj.DotSettings
│ └── EsapiEssentials.csproj
├── samples
├── EsapiEssentials.Samples.Async
│ ├── DialogService
│ │ ├── IDialogProgress.cs
│ │ ├── IDialogService.cs
│ │ ├── SimpleProgress.cs
│ │ └── DialogService.cs
│ ├── Esapi
│ │ ├── Plan.cs
│ │ ├── PatientMatch.cs
│ │ ├── DoseMetricCalculator.cs
│ │ ├── IEsapiService.cs
│ │ └── EsapiService.cs
│ ├── ViewModels
│ │ ├── MetricResult.cs
│ │ └── MainViewModel.cs
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── packages.config
│ ├── App.xaml
│ ├── Views
│ │ ├── MainWindow.xaml.cs
│ │ ├── ProgressDialog.xaml
│ │ ├── UnderscoreConverter.cs
│ │ └── ProgressDialog.xaml.cs
│ ├── App.config
│ ├── EsapiEssentials.Samples.Async.csproj.DotSettings
│ └── App.xaml.cs
├── EsapiEssentials.Samples.AsyncPlugin
│ ├── DialogService
│ │ ├── IDialogProgress.cs
│ │ ├── IDialogService.cs
│ │ ├── SimpleProgress.cs
│ │ └── DialogService.cs
│ ├── Esapi
│ │ ├── Plan.cs
│ │ ├── IEsapiService.cs
│ │ ├── DoseMetricCalculator.cs
│ │ └── EsapiService.cs
│ ├── ViewModels
│ │ ├── MetricResult.cs
│ │ └── MainViewModel.cs
│ ├── packages.config
│ ├── Views
│ │ ├── MainWindow.xaml.cs
│ │ ├── ProgressDialog.xaml
│ │ ├── UnderscoreConverter.cs
│ │ ├── ProgressDialog.xaml.cs
│ │ └── MainWindow.xaml
│ ├── app.config
│ ├── Script.cs
│ ├── EsapiEssentials.Samples.AsyncPlugin.csproj.DotSettings
│ └── Properties
│ │ └── AssemblyInfo.cs
├── EsapiEssentials.Samples.PluginScript
│ ├── App.config
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Script.cs
│ └── EsapiEssentials.Samples.PluginScript.csproj
├── EsapiEssentials.Samples.StandaloneApp
│ ├── App.xaml.cs
│ ├── App.config
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── App.xaml
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ └── EsapiEssentials.Samples.StandaloneApp.csproj
├── EsapiEssentials.Samples.AsyncPlugin.Runner
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── App.xaml
│ ├── App.config
│ ├── App.xaml.cs
│ └── EsapiEssentials.Samples.AsyncPlugin.Runner.csproj
├── EsapiEssentials.Samples.PluginScript.Runner
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── App.xaml
│ ├── App.config
│ ├── App.xaml.cs
│ └── EsapiEssentials.Samples.PluginScript.Runner.csproj
└── EsapiEssentials.Samples.StandaloneApp.Runner
│ ├── Script.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ └── EsapiEssentials.Samples.StandaloneApp.Runner.csproj
├── README.md
├── Common.props
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | # User-specific files
2 | *.suo
3 | *.user
4 | *.vs
5 |
6 | # Build results
7 | bin/
8 | obj/
9 |
10 | # NuGet packages
11 | packages/
12 |
--------------------------------------------------------------------------------
/tests/EsapiEssentials.UnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Application/PlanType.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.PluginRunner
2 | {
3 | internal enum PlanType
4 | {
5 | Plan,
6 | PlanSum
7 | }
8 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/DialogService/IDialogProgress.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.Async
2 | {
3 | public interface ISimpleProgress
4 | {
5 | void Increment();
6 | }
7 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/DialogService/IDialogProgress.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.AsyncPlugin
2 | {
3 | public interface ISimpleProgress
4 | {
5 | void Increment();
6 | }
7 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace EsapiEssentials.Samples.StandaloneRunner.App
4 | {
5 | public partial class App : Application
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Persistence/IDataRepository.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.PluginRunner
2 | {
3 | internal interface IDataRepository
4 | {
5 | Data Load();
6 | void Save(Data data);
7 | }
8 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Esapi/Plan.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.Async
2 | {
3 | public class Plan
4 | {
5 | public string CourseId { get; set; }
6 | public string PlanId { get; set; }
7 | }
8 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Esapi/Plan.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.AsyncPlugin
2 | {
3 | public class Plan
4 | {
5 | public string CourseId { get; set; }
6 | public string PlanId { get; set; }
7 | }
8 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/ViewModels/MetricResult.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.Async
2 | {
3 | public class MetricResult
4 | {
5 | public string StructureId { get; set; }
6 | public double Result { get; set; }
7 | }
8 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/ViewModels/MetricResult.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.AsyncPlugin
2 | {
3 | public class MetricResult
4 | {
5 | public string StructureId { get; set; }
6 | public double Result { get; set; }
7 | }
8 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Esapi/PatientMatch.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Samples.Async
2 | {
3 | public class PatientMatch
4 | {
5 | public string Id { get; set; }
6 | public string FirstName { get; set; }
7 | public string LastName { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Application/PatientMatch.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.PluginRunner
2 | {
3 | internal class PatientMatch
4 | {
5 | public string Id { get; set; }
6 | public string LastName { get; set; }
7 | public string FirstName { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/App.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EsapiEssentials
2 | C# class library with extra functionality for ESAPI
3 |
4 | See the following related posts for more information:
5 |
6 | - [Introducing ESAPI Essentials](http://www.carlosjanderson.com/introducing-esapi-essentials)
7 | - [ESAPI Essentials 1.1 and 2.0](http://www.carlosjanderson.com/esapi-essentials-1-1-and-2-0)
8 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp.Runner/Script.cs:
--------------------------------------------------------------------------------
1 | using EsapiEssentials.Standalone;
2 | using VMS.TPS.Common.Model.API;
3 |
4 | namespace VMS.TPS
5 | {
6 | public class Script
7 | {
8 | public void Execute(ScriptContext context)
9 | {
10 | StandaloneRunner.RunWith(context);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Persistence/Data.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace EsapiEssentials.PluginRunner
4 | {
5 | internal class Data
6 | {
7 | public Data()
8 | {
9 | Recents = new List();
10 | }
11 |
12 | public List Recents { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/PatientSearch/SearchPatient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.Standalone
4 | {
5 | internal class SearchPatient
6 | {
7 | public string Id { get; set; }
8 | public string FirstName { get; set; }
9 | public string LastName { get; set; }
10 | public DateTime? CreationDateTime { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/Async/LogInRequiredException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.Standalone
4 | {
5 | public class LogInRequiredException : Exception
6 | {
7 | public LogInRequiredException() { }
8 |
9 | public LogInRequiredException(Exception innerException)
10 | : base("The user has not logged in to Eclipse.", innerException) { }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Core/DoseUnit.cs:
--------------------------------------------------------------------------------
1 | namespace EsapiEssentials.Core
2 | {
3 | ///
4 | /// Represents the dose unit (Gy or cGy).
5 | ///
6 | public enum DoseUnit
7 | {
8 | ///
9 | /// Gray (Gy)
10 | ///
11 | Gy,
12 |
13 | ///
14 | /// Centigray (cGy)
15 | ///
16 | CGy
17 | }
18 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/Async/PatientNotOpenedException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.Standalone
4 | {
5 | public class PatientNotOpenedException : Exception
6 | {
7 | public PatientNotOpenedException() { }
8 |
9 | public PatientNotOpenedException(Exception innerException)
10 | : base("The patient has not been opened.", innerException) { }
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/DialogService/IDialogService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace EsapiEssentials.Samples.Async
5 | {
6 | public interface IDialogService
7 | {
8 | void ShowProgressDialog(string message, Func workAsync);
9 | void ShowProgressDialog(string message, int maximum, Func workAsync);
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/DialogService/IDialogService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace EsapiEssentials.Samples.AsyncPlugin
5 | {
6 | public interface IDialogService
7 | {
8 | void ShowProgressDialog(string message, Func workAsync);
9 | void ShowProgressDialog(string message, int maximum, Func workAsync);
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Esapi/IEsapiService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace EsapiEssentials.Samples.AsyncPlugin
4 | {
5 | public interface IEsapiService
6 | {
7 | Task GetPlansAsync();
8 | Task GetStructureIdsAsync(string courseId, string planId);
9 |
10 | Task CalculateMeanDoseAsync(string courseId, string planId, string structureId);
11 | }
12 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/StandaloneRunner/StandaloneRunnerException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.Standalone
4 | {
5 | public class StandaloneRunnerException : Exception
6 | {
7 | public StandaloneRunnerException(string message)
8 | : base(message) { }
9 |
10 | public StandaloneRunnerException(string message, Exception innerException)
11 | : base(message, innerException) { }
12 | }
13 | }
--------------------------------------------------------------------------------
/tests/EsapiEssentials.UnitTests/EsapiEssentials.UnitTests.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Views/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Interactivity;
3 |
4 | namespace EsapiEssentials.Samples.AsyncPlugin
5 | {
6 | public partial class MainWindow : Window
7 | {
8 | public MainWindow()
9 | {
10 | // Force Interactivity assembly to be included in build files
11 | Interaction.GetBehaviors(this);
12 |
13 | InitializeComponent();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/DialogService/SimpleProgress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.Samples.Async
4 | {
5 | public class SimpleProgress : ISimpleProgress
6 | {
7 | private readonly Action _onIncrement;
8 |
9 | public SimpleProgress(Action onIncrement)
10 | {
11 | _onIncrement = onIncrement;
12 | }
13 |
14 | public void Increment()
15 | {
16 | _onIncrement();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/DialogService/SimpleProgress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.Samples.AsyncPlugin
4 | {
5 | public class SimpleProgress : ISimpleProgress
6 | {
7 | private readonly Action _onIncrement;
8 |
9 | public SimpleProgress(Action onIncrement)
10 | {
11 | _onIncrement = onIncrement;
12 | }
13 |
14 | public void Increment()
15 | {
16 | _onIncrement();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Views/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace EsapiEssentials.Samples.Async
4 | {
5 | public partial class MainWindow : Window
6 | {
7 | public MainWindow(MainViewModel viewModel)
8 | {
9 | InitializeComponent();
10 | DataContext = viewModel;
11 | }
12 |
13 | private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
14 | {
15 | SearchTextBox.Focus();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/EsapiEssentials.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $author$
8 | $author$
9 | MIT
10 | https://github.com/redcurry/EsapiEssentials
11 | false
12 | $description$
13 | Copyright 2019
14 | esapi varian
15 |
16 |
17 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/Async/AsyncRunner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using System.Windows.Threading;
4 |
5 | namespace EsapiEssentials.Plugin
6 | {
7 | internal class AsyncRunner
8 | {
9 | private readonly Dispatcher _dispatcher;
10 |
11 | public AsyncRunner()
12 | {
13 | _dispatcher = Dispatcher.CurrentDispatcher;
14 | }
15 |
16 | public Task RunAsync(Action a) =>
17 | _dispatcher.InvokeAsync(a).Task;
18 |
19 | public Task RunAsync(Func f) =>
20 | _dispatcher.InvokeAsync(f).Task;
21 | }
22 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/EsapiEssentials.PluginRunner.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $author$
8 | $author$
9 | MIT
10 | https://github.com/redcurry/EsapiEssentials
11 | false
12 | $description$
13 | Copyright 2019
14 | esapi varian
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Common.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ESAPI_13;$(DefineConstants)
5 | C:\esapi\13.6
6 |
7 |
8 | ESAPI_15;$(DefineConstants)
9 | C:\esapi\15.6
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/View/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 |
4 | namespace EsapiEssentials.PluginRunner
5 | {
6 | internal partial class MainWindow : Window
7 | {
8 | public MainWindow(MainViewModel vm)
9 | {
10 | InitializeComponent();
11 | DataContext = vm;
12 | }
13 |
14 | private void PlansAndPlanSums_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
15 | {
16 | // Prevent selection for this ListBox
17 | var listBox = (ListBox)sender;
18 | listBox.UnselectAll();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using EsapiEssentials.PluginRunner;
2 | using System.Windows;
3 | using VMS.TPS;
4 | using VMS.TPS.Common.Model.API;
5 |
6 | namespace EsapiEssentials.Samples.AsyncPlugin.Runner
7 | {
8 | public partial class App : System.Windows.Application
9 | {
10 | private void App_OnStartup(object sender, StartupEventArgs e)
11 | {
12 | // Note: EsapiEssentials and EsapiEssentials.PluginRunner must be referenced,
13 | // as well as the project that contains the Script class
14 | ScriptRunner.Run(new Script());
15 | }
16 |
17 | public void Dummy(PlanSetup plan) { }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using EsapiEssentials.PluginRunner;
3 | using VMS.TPS;
4 | using VMS.TPS.Common.Model.API;
5 |
6 | namespace EsapiEssentials.Samples.PluginScript.Runner
7 | {
8 | public partial class App : System.Windows.Application
9 | {
10 | private void App_OnStartup(object sender, StartupEventArgs e)
11 | {
12 | // Note: EsapiEssentials and EsapiEssentials.PluginRunner must be referenced,
13 | // as well as the project that contains the Script class
14 | ScriptRunner.Run(new Script());
15 | }
16 |
17 | // Fix UnauthorizedScriptingAPIAccessException
18 | public void DoNothing(PlanSetup plan) { }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Views/ProgressDialog.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Views/ProgressDialog.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/View/UnderscoreConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 |
5 | namespace EsapiEssentials.PluginRunner
6 | {
7 | // This converter duplicates all underscores
8 | // because WPF doesn't display single underscores
9 | public class UnderscoreConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | if (value is string s)
14 | return s.Replace("_", "__");
15 | return null;
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | return null;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Views/UnderscoreConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 |
5 | namespace EsapiEssentials.Samples.Async
6 | {
7 | // This converter duplicates all underscores
8 | // because WPF doesn't display single underscores
9 | public class UnderscoreConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | if (value is string s)
14 | return s.Replace("_", "__");
15 | return null;
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | return null;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Views/UnderscoreConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 |
5 | namespace EsapiEssentials.Samples.AsyncPlugin
6 | {
7 | // This converter duplicates all underscores
8 | // because WPF doesn't display single underscores
9 | public class UnderscoreConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | if (value is string s)
14 | return s.Replace("_", "__");
15 | return null;
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | return null;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/PlansAndPlanSumsConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Windows.Data;
6 |
7 | namespace EsapiEssentials.PluginRunner
8 | {
9 | public class PlansAndPlanSumsConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | if (value is IEnumerable planAndPlanSums)
14 | return string.Join(", ", planAndPlanSums.Select(p => p.Id));
15 | return null;
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | return null;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Script.cs:
--------------------------------------------------------------------------------
1 | using EsapiEssentials.Plugin;
2 | using EsapiEssentials.Samples.AsyncPlugin;
3 |
4 | namespace VMS.TPS
5 | {
6 | public class Script : ScriptBase
7 | {
8 | public override void Run(PluginScriptContext context)
9 | {
10 | var esapiService = new EsapiService(context);
11 |
12 | using (var ui = new UiRunner())
13 | {
14 | ui.Run(() =>
15 | {
16 | var window = new MainWindow();
17 | var dialogService = new DialogService(window);
18 | var viewModel = new MainViewModel(esapiService, dialogService);
19 | window.DataContext = viewModel;
20 | window.ShowDialog();
21 | });
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/EsapiEssentials.Samples.Async.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/EsapiEssentials.Samples.AsyncPlugin.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace EsapiEssentials.Samples.Async
4 | {
5 | public partial class App : Application
6 | {
7 | private EsapiService _esapiService;
8 |
9 | private void App_OnStartup(object sender, StartupEventArgs e)
10 | {
11 | _esapiService = new EsapiService();
12 | var dialogService = new DialogService(this);
13 | var viewModel = new MainViewModel(_esapiService, dialogService);
14 | var window = new MainWindow(viewModel);
15 | window.Show();
16 | }
17 |
18 | // The EsapiService must be disposed before exiting;
19 | // otherwise, an exception from ESAPI is thrown
20 | private void App_OnExit(object sender, ExitEventArgs e)
21 | {
22 | _esapiService.Dispose();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/Async/AsyncRunner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using System.Threading.Tasks.Schedulers;
5 |
6 | namespace EsapiEssentials.Standalone
7 | {
8 | internal class AsyncRunner : IDisposable
9 | {
10 | private readonly StaTaskScheduler _taskScheduler;
11 |
12 | public AsyncRunner()
13 | {
14 | _taskScheduler = new StaTaskScheduler(1);
15 | }
16 |
17 | public Task RunAsync(Action a) => Task.Factory.StartNew(
18 | a, CancellationToken.None, TaskCreationOptions.None, _taskScheduler);
19 |
20 | public Task RunAsync(Func f) => Task.Factory.StartNew(
21 | f, CancellationToken.None, TaskCreationOptions.None, _taskScheduler);
22 |
23 | public void Dispose()
24 | {
25 | _taskScheduler.Dispose();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Views/ProgressDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace EsapiEssentials.Samples.Async
4 | {
5 | public partial class ProgressDialog : Window
6 | {
7 | public ProgressDialog()
8 | {
9 | InitializeComponent();
10 | ProgressBar.IsIndeterminate = true;
11 | }
12 |
13 | public string Message
14 | {
15 | get => MessageTextBlock.Text;
16 | set => MessageTextBlock.Text = value;
17 | }
18 |
19 | public int MaxProgress
20 | {
21 | get => (int)ProgressBar.Maximum;
22 | set
23 | {
24 | ProgressBar.Maximum = value;
25 | ProgressBar.IsIndeterminate = false;
26 | }
27 | }
28 |
29 | public void IncrementProgress()
30 | {
31 | ProgressBar.Value += 1;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Views/ProgressDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace EsapiEssentials.Samples.AsyncPlugin
4 | {
5 | public partial class ProgressDialog : Window
6 | {
7 | public ProgressDialog()
8 | {
9 | InitializeComponent();
10 | ProgressBar.IsIndeterminate = true;
11 | }
12 |
13 | public string Message
14 | {
15 | get => MessageTextBlock.Text;
16 | set => MessageTextBlock.Text = value;
17 | }
18 |
19 | public int MaxProgress
20 | {
21 | get => (int)ProgressBar.Maximum;
22 | set
23 | {
24 | ProgressBar.Maximum = value;
25 | ProgressBar.IsIndeterminate = false;
26 | }
27 | }
28 |
29 | public void IncrementProgress()
30 | {
31 | ProgressBar.Value += 1;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/EsapiEssentials.PluginRunner.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
6 | True
--------------------------------------------------------------------------------
/src/EsapiEssentials/Extensions/PatientExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using VMS.TPS.Common.Model.API;
4 |
5 | namespace EsapiEssentials
6 | {
7 | ///
8 | /// Extension methods for the Patient class.
9 | ///
10 | public static class PatientExtensions
11 | {
12 | ///
13 | /// Gets every PlanningItem (PlanSetup and PlanSum) of the given Patient.
14 | ///
15 | /// The Patient.
16 | /// Every PlanningItem of the given Patient.
17 | public static IEnumerable GetPlanningItems(this Patient patient)
18 | {
19 | var plans = patient.Courses?.SelectMany(c => c.PlanSetups) ?? new List();
20 | var planSums = patient.Courses?.SelectMany(c => c.PlanSums) ?? new List();
21 | return plans.Concat(planSums);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Extensions/DoseValueExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using EsapiEssentials.Core;
3 | using VMS.TPS.Common.Model.Types;
4 |
5 | namespace EsapiEssentials
6 | {
7 | ///
8 | /// Extension methods for the DoseValue struct.
9 | ///
10 | public static class DoseValueExtensions
11 | {
12 | ///
13 | /// Converts the given DoseValue instance to a Dose object.
14 | ///
15 | ///
16 | /// The Dose object that represents the given DoseValue.
17 | public static Dose ToDose(this DoseValue doseValue)
18 | {
19 | switch (doseValue.Unit)
20 | {
21 | case DoseValue.DoseUnit.Gy: return new Dose(doseValue.Dose, DoseUnit.Gy);
22 | case DoseValue.DoseUnit.cGy: return new Dose(doseValue.Dose, DoseUnit.CGy);
23 | default:
24 | throw new ArgumentException($"Dose unit {doseValue.Unit} is not supported.");
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Carlos Anderson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Persistence/DataRepository.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using YamlDotNet.Serialization;
3 |
4 | namespace EsapiEssentials.PluginRunner
5 | {
6 | internal class DataRepository : IDataRepository
7 | {
8 | private readonly string _path;
9 |
10 | private readonly ISerializer _serializer;
11 | private readonly IDeserializer _deserializer;
12 |
13 | public DataRepository(string path)
14 | {
15 | _path = path;
16 |
17 | _serializer = new SerializerBuilder().Build();
18 | _deserializer = new DeserializerBuilder().Build();
19 | }
20 |
21 | public Data Load()
22 | {
23 | if (!File.Exists(_path))
24 | return new Data();
25 |
26 | var dataString = File.ReadAllText(_path);
27 | return _deserializer.Deserialize(dataString);
28 | }
29 |
30 | public void Save(Data data)
31 | {
32 | var dataString = _serializer.Serialize(data);
33 | File.WriteAllText(_path, dataString);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/PluginRunner/ScriptBase.cs:
--------------------------------------------------------------------------------
1 | using VMS.TPS.Common.Model.API;
2 |
3 | namespace EsapiEssentials.Plugin
4 | {
5 | ///
6 | /// Provides the Execute method that the PluginRunner needs to call.
7 | /// Any script that will use the PluginRunner should derive from this class.
8 | /// Derive from this class if you're going to create your own Window.
9 | ///
10 | public abstract class ScriptBase
11 | {
12 | ///
13 | /// The method that Eclipse calls when the plugin script is started from there.
14 | /// This method is called automatically, you should never need to deal with it.
15 | ///
16 | public void Execute(ScriptContext context)
17 | {
18 | Run(new PluginScriptContext(context));
19 | }
20 |
21 | ///
22 | /// The method you need to implement for your script to do anything.
23 | ///
24 | /// A copy of the script context of the Eclipse session.
25 | public abstract void Run(PluginScriptContext context);
26 | }
27 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Esapi/DoseMetricCalculator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using VMS.TPS.Common.Model.API;
3 | using VMS.TPS.Common.Model.Types;
4 |
5 | namespace EsapiEssentials.Samples.Async
6 | {
7 | // This class works directly with ESAPI objects, but it will be wrapped by EsapiService,
8 | // which doesn't expose ESAPI objects in order to isolate the app from ESAPI
9 | public class DoseMetricCalculator
10 | {
11 | public double CalculateMean(PlanningItem planningItem, Structure structure)
12 | {
13 | try
14 | {
15 | var dvhResult = planningItem.GetDVHCumulativeData(
16 | structure, DoseValuePresentation.Absolute, VolumePresentation.AbsoluteCm3, 0.001);
17 | return dvhResult.MeanDose.Dose;
18 | }
19 | catch (Exception e)
20 | {
21 | // There are many reasons the DVH calculation could fail,
22 | // so wrap any exception in a general exception
23 | throw new InvalidOperationException("Unable to calculate the mean dose.", e);
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Esapi/DoseMetricCalculator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using VMS.TPS.Common.Model.API;
3 | using VMS.TPS.Common.Model.Types;
4 |
5 | namespace EsapiEssentials.Samples.AsyncPlugin
6 | {
7 | // This class works directly with ESAPI objects, but it will be wrapped by EsapiService,
8 | // which doesn't expose ESAPI objects in order to isolate the script from ESAPI
9 | public class DoseMetricCalculator
10 | {
11 | public double CalculateMean(PlanningItem planningItem, Structure structure)
12 | {
13 | try
14 | {
15 | var dvhResult = planningItem.GetDVHCumulativeData(
16 | structure, DoseValuePresentation.Absolute, VolumePresentation.AbsoluteCm3, 0.001);
17 | return dvhResult?.MeanDose.Dose ?? double.NaN;
18 | }
19 | catch (Exception e)
20 | {
21 | // There are many reasons the DVH calculation could fail,
22 | // so wrap any exception in a general exception
23 | throw new InvalidOperationException("Unable to calculate the mean dose.", e);
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Esapi/IEsapiService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace EsapiEssentials.Samples.Async
4 | {
5 | // Interface to ESAPI functionality while not exposing ESAPI objects.
6 | // This allows the interface to be passed to other projects
7 | // without requiring those objects to depend on ESAPI.
8 | // Also, this interface allows for mocking in unit testing.
9 | // Finally, all the methods are asynchronous because the implementation
10 | // uses a separate thread to run ESAPI methods.
11 | // This prevents slow ESAPI methods from blocking the GUI thread.
12 | public interface IEsapiService
13 | {
14 | Task LogInAsync();
15 | #if ESAPI_13
16 | Task LogInAsync(string userId, string password);
17 | #endif
18 |
19 | Task OpenPatientAsync(string patientId);
20 | Task ClosePatientAsync();
21 |
22 | Task SearchAsync(string searchText);
23 |
24 | Task GetPlansAsync();
25 | Task GetStructureIdsAsync(string courseId, string planId);
26 |
27 | Task CalculateMeanDoseAsync(string courseId, string planId, string structureId);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.Async.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.StandaloneApp.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Extensions/StructureExtensions.cs:
--------------------------------------------------------------------------------
1 | using VMS.TPS.Common.Model.API;
2 |
3 | namespace EsapiEssentials
4 | {
5 | ///
6 | /// Extension methods for the Structure class.
7 | ///
8 | public static class StructureExtensions
9 | {
10 | ///
11 | /// Determines whether the given Structure is a target (DICOM type: GTV, CTV, or PTV).
12 | ///
13 | /// The Structure to determine whether it is a target.
14 | /// true, if the given Structure is a target; false, otherwise.
15 | public static bool IsTarget(this Structure structure) =>
16 | structure.DicomType == "GTV" || structure.DicomType == "CTV" || structure.DicomType == "PTV";
17 |
18 | ///
19 | /// Determines whether the given Structure is an organ (DICOM type: ORGAN).
20 | ///
21 | /// The Structure to determine whether it is an organ.
22 | /// true, if the given Structure is an organ; false, otherwise.
23 | public static bool IsOrgan(this Structure structure) =>
24 | structure.DicomType == "ORGAN";
25 | }
26 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.AsyncPlugin.Runner.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.PluginScript.Runner.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/PluginRunner/ScriptBaseWithWindow.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using VMS.TPS.Common.Model.API;
3 |
4 | namespace EsapiEssentials.Plugin
5 | {
6 | ///
7 | /// Provides the Execute method that the PluginRunner needs to call.
8 | /// Any script that will use the PluginRunner should derive from this class.
9 | /// Derive from this class if you want to use the Window that Eclipse provides.
10 | ///
11 | public abstract class ScriptBaseWithWindow
12 | {
13 | ///
14 | /// The method that Eclipse calls when the plugin script is started from there.
15 | /// This method is called automatically, you should never need to deal with it.
16 | ///
17 | public void Execute(ScriptContext context, Window window)
18 | {
19 | Execute(new PluginScriptContext(context), window);
20 | }
21 |
22 | ///
23 | /// The method you need to implement for your script to do anything.
24 | ///
25 | /// A copy of the script context of the Eclipse session.
26 | /// The Window for your script that Eclipse will display.
27 | public abstract void Execute(PluginScriptContext context, Window window);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/Async/EsapiServiceBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace EsapiEssentials.Plugin
5 | {
6 | public abstract class EsapiServiceBase
7 | {
8 | private readonly TContext _context;
9 | private readonly AsyncRunner _runner;
10 |
11 | protected EsapiServiceBase(TContext context)
12 | {
13 | _context = context;
14 | _runner = new AsyncRunner();
15 | }
16 |
17 | ///
18 | /// Runs the given Action on the ESAPI thread.
19 | ///
20 | /// The Action to run.
21 | /// A Task to perform this action.
22 | protected Task RunAsync(Action a) =>
23 | RunAsync(() => a(_context));
24 |
25 | ///
26 | /// Runs the given Func on the ESAPI thread.
27 | ///
28 | /// The type of the returned object.
29 | /// The Func to run.
30 | /// A Task to perform this action.
31 | protected Task RunAsync(Func f) =>
32 | RunAsync(() => f(_context));
33 |
34 | protected Task RunAsync(Action a) =>
35 | _runner.RunAsync(a);
36 |
37 | protected Task RunAsync(Func f) =>
38 | _runner.RunAsync(f);
39 | }
40 | }
--------------------------------------------------------------------------------
/tests/EsapiEssentials.UnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EsapiEssentials.UnitTests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EsapiEssentials.UnitTests")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("46821c78-494d-4bd4-8ba1-cc3b430c24f0")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EsapiEssentials.Samples.AsyncPlugin")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EsapiEssentials.Samples.AsyncPlugin")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("96e0ce2e-799b-473d-bf00-15ddc693a421")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/ViewModel/PlanOrSumViewModel.cs:
--------------------------------------------------------------------------------
1 | using GalaSoft.MvvmLight;
2 |
3 | namespace EsapiEssentials.PluginRunner
4 | {
5 | internal class PlanOrPlanSumViewModel : ViewModelBase
6 | {
7 | private PlanType _type;
8 | public PlanType Type
9 | {
10 | get => _type;
11 | set
12 | {
13 | if (Set(ref _type, value))
14 | RaisePropertyChanged(nameof(CanBeActive));
15 | }
16 | }
17 |
18 | private string _id;
19 | public string Id
20 | {
21 | get => _id;
22 | set => Set(ref _id, value);
23 | }
24 |
25 | private string _courseId;
26 | public string CourseId
27 | {
28 | get => _courseId;
29 | set => Set(ref _courseId, value);
30 | }
31 |
32 | private bool _isInScope;
33 | public bool IsInScope
34 | {
35 | get => _isInScope;
36 | set
37 | {
38 | if (Set(ref _isInScope, value))
39 | {
40 | if (!IsInScope)
41 | IsActive = false;
42 | RaisePropertyChanged(nameof(CanBeActive));
43 | }
44 | }
45 | }
46 |
47 | private bool _isActive;
48 | public bool IsActive
49 | {
50 | get => _isActive;
51 | set => Set(ref _isActive, value);
52 | }
53 |
54 | public bool CanBeActive =>
55 | Type == PlanType.Plan && IsInScope;
56 | }
57 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EsapiEssentials.Samples.PluginScript")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EsapiEssentials.Samples.PluginScript")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("feb1e304-ccc9-4b61-acd2-fe76de6e1125")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Application/PlanOrPlanSum.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace EsapiEssentials.PluginRunner
4 | {
5 | internal class PlanOrPlanSum : IEquatable
6 | {
7 | public PlanType Type { get; set; }
8 | public string Id { get; set; }
9 | public string CourseId { get; set; }
10 |
11 | public bool Equals(PlanOrPlanSum other)
12 | {
13 | if (ReferenceEquals(null, other)) return false;
14 | if (ReferenceEquals(this, other)) return true;
15 | return Type == other.Type && string.Equals(Id, other.Id) && string.Equals(CourseId, other.CourseId);
16 | }
17 |
18 | public override bool Equals(object obj)
19 | {
20 | if (ReferenceEquals(null, obj)) return false;
21 | if (ReferenceEquals(this, obj)) return true;
22 | if (obj.GetType() != this.GetType()) return false;
23 | return Equals((PlanOrPlanSum)obj);
24 | }
25 |
26 | public override int GetHashCode()
27 | {
28 | unchecked
29 | {
30 | var hashCode = (int)Type;
31 | hashCode = (hashCode * 397) ^ (Id != null ? Id.GetHashCode() : 0);
32 | hashCode = (hashCode * 397) ^ (CourseId != null ? CourseId.GetHashCode() : 0);
33 | return hashCode;
34 | }
35 | }
36 |
37 | public static bool operator ==(PlanOrPlanSum p1, PlanOrPlanSum p2) =>
38 | Equals(p1, p2);
39 |
40 | public static bool operator !=(PlanOrPlanSum p1, PlanOrPlanSum p2) =>
41 | !(p1 == p2);
42 | }
43 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp.Runner/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EsapiEssentials.Samples.StandaloneApp.Runner")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EsapiEssentials.Samples.StandaloneApp.Runner")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("b6bd150a-2a22-4d28-9152-d6e02e97b218")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EsapiEssentials.PluginRunner")]
9 | [assembly: AssemblyDescription("Plugin runner for EsapiEssentials (ESAPI 15.6)")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Carlos Anderson")]
12 | [assembly: AssemblyProduct("EsapiEssentials.PluginRunner")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("e575892d-81d0-4a2f-9fb1-495d3f404502")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("2.0.0.0")]
36 | [assembly: AssemblyFileVersion("2.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EsapiEssentials")]
9 | [assembly: AssemblyDescription("Essential tools for working with ESAPI 15.6")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Carlos Anderson")]
12 | [assembly: AssemblyProduct("EsapiEssentials")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("fdc15e5d-0179-42cf-b352-48b74b234454")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("2.0.0.0")]
36 | [assembly: AssemblyFileVersion("2.0.0.0")]
37 |
38 | [assembly: InternalsVisibleTo("EsapiEssentials.UnitTests")]
39 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/DialogService/DialogService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace EsapiEssentials.Samples.Async
5 | {
6 | public class DialogService : IDialogService
7 | {
8 | private readonly App _app;
9 |
10 | public DialogService(App app)
11 | {
12 | _app = app;
13 | }
14 |
15 | public void ShowProgressDialog(string message, Func workAsync)
16 | {
17 | CreateProgressDialog(message, workAsync).ShowDialog();
18 | }
19 |
20 | public void ShowProgressDialog(string message, int maximum, Func workAsync)
21 | {
22 | CreateProgressDialog(message, maximum, workAsync).ShowDialog();
23 | }
24 |
25 | private ProgressDialog CreateProgressDialog(string message, Func workAsync)
26 | {
27 | var progressDialog = new ProgressDialog();
28 | progressDialog.Owner = _app.MainWindow;
29 | progressDialog.Message = message;
30 | progressDialog.Loaded += async (sender, args) =>
31 | {
32 | var progress = new SimpleProgress(() => progressDialog.IncrementProgress());
33 | await workAsync(progress);
34 | progressDialog.Close();
35 | };
36 | return progressDialog;
37 | }
38 |
39 | private ProgressDialog CreateProgressDialog(string message, int maximum, Func workAsync)
40 | {
41 | var progressDialog = CreateProgressDialog(message, workAsync);
42 | progressDialog.MaxProgress = maximum;
43 | return progressDialog;
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/Async/UiRunner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using System.Threading.Tasks.Schedulers;
5 | using System.Windows.Threading;
6 |
7 | namespace EsapiEssentials.Plugin
8 | {
9 | public class UiRunner : IDisposable
10 | {
11 | private readonly DispatcherFrame _frame = new DispatcherFrame();
12 | private readonly StaTaskScheduler _scheduler = new StaTaskScheduler(1);
13 |
14 | ///
15 | /// Runs the given Action on a new UI thread.
16 | ///
17 | /// The Action to run, passing a DispatcherWorker,
18 | /// which allows the Action to run code on the calling thread.
19 | public void Run(Action a)
20 | {
21 | Task.Factory.StartNew(() =>
22 | {
23 | a();
24 | _frame.Continue = false;
25 | }, CancellationToken.None, TaskCreationOptions.None, _scheduler);
26 |
27 | Dispatcher.PushFrame(_frame);
28 | }
29 |
30 | ///
31 | /// Runs the given Func on a new UI thread.
32 | ///
33 | /// The Func to run, passing a DispatcherWorker,
34 | /// which allows the Func to run code on the calling thread.
35 | public void Run(Func f)
36 | {
37 | Task.Factory.StartNew(async () =>
38 | {
39 | await f();
40 | _frame.Continue = false;
41 | }, CancellationToken.None, TaskCreationOptions.None, _scheduler);
42 |
43 | Dispatcher.PushFrame(_frame);
44 | }
45 |
46 | public void Dispose()
47 | {
48 | _scheduler?.Dispose();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/DialogService/DialogService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace EsapiEssentials.Samples.AsyncPlugin
5 | {
6 | public class DialogService : IDialogService
7 | {
8 | private readonly MainWindow _mainWindow;
9 |
10 | public DialogService(MainWindow mainWindow)
11 | {
12 | _mainWindow = mainWindow;
13 | }
14 |
15 | public void ShowProgressDialog(string message, Func workAsync)
16 | {
17 | CreateProgressDialog(message, workAsync).ShowDialog();
18 | }
19 |
20 | public void ShowProgressDialog(string message, int maximum, Func workAsync)
21 | {
22 | CreateProgressDialog(message, maximum, workAsync).ShowDialog();
23 | }
24 |
25 | private ProgressDialog CreateProgressDialog(string message, Func workAsync)
26 | {
27 | var progressDialog = new ProgressDialog();
28 | progressDialog.Owner = _mainWindow;
29 | progressDialog.Message = message;
30 | progressDialog.Loaded += async (sender, args) =>
31 | {
32 | var progress = new SimpleProgress(() => progressDialog.IncrementProgress());
33 | await workAsync(progress);
34 | progressDialog.Close();
35 | };
36 | return progressDialog;
37 | }
38 |
39 | private ProgressDialog CreateProgressDialog(string message, int maximum, Func workAsync)
40 | {
41 | var progressDialog = CreateProgressDialog(message, workAsync);
42 | progressDialog.MaxProgress = maximum;
43 | return progressDialog;
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/Settings/AssemblySettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Reflection;
4 |
5 | namespace EsapiEssentials.Plugin
6 | {
7 | ///
8 | /// Provides read-only access to an assembly's settings.
9 | /// The settings must be in the assembly's App.config file,
10 | /// in a section called appSettings (see the Microsoft documentation).
11 | ///
12 | public class AssemblySettings
13 | {
14 | private readonly Assembly _assembly;
15 |
16 | ///
17 | /// Instantiates a new instance of the AssemblySettings class.
18 | ///
19 | /// The assembly that has the settings.
20 | public AssemblySettings(Assembly assembly)
21 | {
22 | _assembly = assembly;
23 | }
24 |
25 | ///
26 | /// Gets the value of the setting with the given key (i.e., name).
27 | ///
28 | /// The name of the setting.
29 | /// The value of the setting.
30 | ///
31 | /// An exception occured while trying to obtain the setting.
32 | ///
33 | public string GetSetting(string key)
34 | {
35 | try
36 | {
37 | var asmPath = _assembly.Location;
38 | var config = ConfigurationManager.OpenExeConfiguration(asmPath);
39 | var setting = config.AppSettings.Settings[key];
40 | return setting.Value;
41 | }
42 | catch (Exception e)
43 | {
44 | throw new InvalidOperationException("Unable to read the configuration setting.", e);
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Extensions/PlanningItemExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using VMS.TPS.Common.Model.API;
3 |
4 | namespace EsapiEssentials
5 | {
6 | ///
7 | /// Extension methods for the PlanningItem class.
8 | ///
9 | public static class PlanningItemExtensions
10 | {
11 | ///
12 | /// Gets the parent Course of the given PlanningItem.
13 | ///
14 | /// The PlanningItem whose Course will be obtained.
15 | /// The parent Course of the given PlanningItem.
16 | public static Course GetCourse(this PlanningItem planningItem)
17 | {
18 | if (planningItem is PlanSetup plan)
19 | return plan.Course;
20 |
21 | if (planningItem is PlanSum planSum)
22 | return planSum.Course;
23 |
24 | throw new ArgumentException(GetUnknownSubclassMessage(planningItem));
25 | }
26 |
27 | ///
28 | /// Gets the StructureSet of the given PlanningItem.
29 | ///
30 | /// The PlanningItem whose StructureSet will be obtained.
31 | /// The StructureSet of the given PlanningItem.
32 | public static StructureSet GetStructureSet(this PlanningItem planningItem)
33 | {
34 | if (planningItem is PlanSetup plan)
35 | return plan.StructureSet;
36 |
37 | if (planningItem is PlanSum planSum)
38 | return planSum.StructureSet;
39 |
40 | throw new ArgumentException(GetUnknownSubclassMessage(planningItem));
41 | }
42 |
43 | private static string GetUnknownSubclassMessage(PlanningItem planningItem) =>
44 | $"{planningItem.GetType()} is not a known subclass of {nameof(PlanningItem)}.";
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/Persistence/RecentEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace EsapiEssentials.PluginRunner
6 | {
7 | internal class RecentEntry : IEquatable
8 | {
9 | public string PatientId { get; set; }
10 | public List PlansAndPlanSumsInScope { get; set; }
11 | public PlanOrPlanSum ActivePlan { get; set; }
12 |
13 | public bool Equals(RecentEntry other)
14 | {
15 | if (ReferenceEquals(null, other)) return false;
16 | if (ReferenceEquals(this, other)) return true;
17 | return string.Equals(PatientId, other.PatientId) &&
18 | Enumerable.SequenceEqual(PlansAndPlanSumsInScope, other.PlansAndPlanSumsInScope) &&
19 | Equals(ActivePlan, other.ActivePlan);
20 | }
21 |
22 | public override bool Equals(object obj)
23 | {
24 | if (ReferenceEquals(null, obj)) return false;
25 | if (ReferenceEquals(this, obj)) return true;
26 | if (obj.GetType() != this.GetType()) return false;
27 | return Equals((RecentEntry)obj);
28 | }
29 |
30 | public override int GetHashCode()
31 | {
32 | unchecked
33 | {
34 | var hashCode = (PatientId != null ? PatientId.GetHashCode() : 0);
35 | hashCode = (hashCode * 397) ^ (PlansAndPlanSumsInScope != null ? PlansAndPlanSumsInScope.GetHashCode() : 0);
36 | hashCode = (hashCode * 397) ^ (ActivePlan != null ? ActivePlan.GetHashCode() : 0);
37 | return hashCode;
38 | }
39 | }
40 |
41 | public static bool operator ==(RecentEntry r1, RecentEntry r2) =>
42 | Equals(r1, r2);
43 |
44 | public static bool operator !=(RecentEntry r1, RecentEntry r2) =>
45 | !(r1 == r2);
46 | }
47 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript/Script.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Windows;
5 | using EsapiEssentials.Plugin;
6 | using VMS.TPS.Common.Model.Types;
7 |
8 | namespace VMS.TPS
9 | {
10 | // This script demonstrates deriving from ScriptBase in order to use the PluginRunner,
11 | // which needs to be referenced from a separate WPF project.
12 |
13 | // This script also demonstrates using AssemblySettings in order to obtain
14 | // the desired structure ID from the App.config file.
15 | // This file is not automatically created in a class library project,
16 | // so it must be added manually to the project (via Add New Item).
17 | public class Script : ScriptBase
18 | {
19 | public override void Run(PluginScriptContext context)
20 | {
21 | // Define the desired structure ID
22 | var structureId = GetStructureIdFromSettings();
23 |
24 | // Find the structure in the current structure set
25 | var structure = context?.StructureSet?.Structures?.FirstOrDefault(x => x.Id == structureId);
26 |
27 | if (structure == null)
28 | throw new InvalidOperationException("Unable to find the structure.");
29 |
30 | // Calculate D2cc[Gy]
31 | var d2cc = context?.PlanSetup?.GetDoseAtVolume(structure, 2, VolumePresentation.AbsoluteCm3, DoseValuePresentation.Absolute);
32 |
33 | if (d2cc == null)
34 | throw new InvalidOperationException("Unable to calculate the dose metric.");
35 |
36 | // Show the result
37 | MessageBox.Show($"{structureId} D2cc[Gy] = {d2cc}");
38 | }
39 |
40 | private string GetStructureIdFromSettings()
41 | {
42 | var settings = new AssemblySettings(Assembly.GetExecutingAssembly());
43 | return settings.GetSetting("StructureId");
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/ScriptRunner.cs:
--------------------------------------------------------------------------------
1 | using EsapiEssentials.Plugin;
2 |
3 | namespace EsapiEssentials.PluginRunner
4 | {
5 | ///
6 | /// Provides the functionality to start the PluginRunner and run your script.
7 | ///
8 | public static class ScriptRunner
9 | {
10 | #if ESAPI_13
11 | ///
12 | /// Runs the plugin runner for the given script (accepts a Window).
13 | ///
14 | /// The script to run. This script accepts the Window provided by Eclipse.
15 | /// The optional user ID to log in to Eclipse.
16 | /// The optional user password to log in to Eclipse.
17 | public static void Run(ScriptBaseWithWindow script, string userId = null, string password = null) =>
18 | RunWith(new PluginRunner(script, userId, password));
19 | #elif ESAPI_15
20 | public static void Run(ScriptBaseWithWindow script) =>
21 | RunWith(new PluginRunner(script));
22 | #endif
23 |
24 | #if ESAPI_13
25 | ///
26 | /// Runs the plugin runner for the given script (does not accept a Window).
27 | ///
28 | /// The script to run. This script does not use an Eclipse-provided Window.
29 | /// The optional user ID to log in to Eclipse.
30 | /// The optional user password to log in to Eclipse.
31 | public static void Run(ScriptBase script, string userId = null, string password = null) =>
32 | RunWith(new PluginRunner(script, userId, password));
33 | #elif ESAPI_15
34 | public static void Run(ScriptBase script) =>
35 | RunWith(new PluginRunner(script));
36 | #endif
37 |
38 | private static void RunWith(PluginRunner runner)
39 | {
40 | var vm = new MainViewModel(runner);
41 | var window = new MainWindow(vm);
42 | window.Closed += (o, e) => runner.Dispose();
43 | window.Show();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Plugin/PluginRunner/PluginScriptContext.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using VMS.TPS.Common.Model.API;
3 |
4 | namespace EsapiEssentials.Plugin
5 | {
6 | ///
7 | /// Duplicates all the properties from the ESAPI ScriptContext class,
8 | /// so that they can be accessed from a plugin script using the PluginScriptRunner.
9 | ///
10 | public class PluginScriptContext
11 | {
12 | public PluginScriptContext() { }
13 |
14 | public PluginScriptContext(ScriptContext context)
15 | {
16 | CurrentUser = context.CurrentUser;
17 | Course = context.Course;
18 | Image = context.Image;
19 | StructureSet = context.StructureSet;
20 | Patient = context.Patient;
21 | PlanSetup = context.PlanSetup;
22 | ExternalPlanSetup = context.ExternalPlanSetup;
23 | BrachyPlanSetup = context.BrachyPlanSetup;
24 | PlansInScope = context.PlansInScope;
25 | ExternalPlansInScope = context.ExternalPlansInScope;
26 | BrachyPlansInScope = context.BrachyPlansInScope;
27 | PlanSumsInScope = context.PlanSumsInScope;
28 | ApplicationName = context.ApplicationName;
29 | VersionInfo = context.VersionInfo;
30 | }
31 |
32 | public User CurrentUser { get; set; }
33 | public Course Course { get; set; }
34 | public Image Image { get; set; }
35 | public StructureSet StructureSet { get; set; }
36 | public Patient Patient { get; set; }
37 | public PlanSetup PlanSetup { get; set; }
38 | public ExternalPlanSetup ExternalPlanSetup { get; set; }
39 | public BrachyPlanSetup BrachyPlanSetup { get; set; }
40 | public IEnumerable PlansInScope { get; set; }
41 | public IEnumerable ExternalPlansInScope { get; set; }
42 | public IEnumerable BrachyPlansInScope { get; set; }
43 | public IEnumerable PlanSumsInScope { get; set; }
44 | public string ApplicationName { get; set; }
45 | public string VersionInfo { get; set; }
46 | }
47 | }
--------------------------------------------------------------------------------
/tests/EsapiEssentials.UnitTests/PatientSearch/PatientSummarySearchTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using EsapiEssentials.Standalone;
3 | using NUnit.Framework;
4 |
5 | namespace EsapiEssentials.UnitTests
6 | {
7 | [TestFixture]
8 | public class PatientSummarySearchTests
9 | {
10 | private SearchPatient[] _patients;
11 |
12 | [SetUp]
13 | public void SetUp()
14 | {
15 | _patients = new[]
16 | {
17 | new SearchPatient {Id = "001", FirstName = "Yvonne", LastName = "McCarthy"},
18 | new SearchPatient {Id = "002", FirstName = "Marlene", LastName = "Lyons"},
19 | new SearchPatient {Id = "003", FirstName = "Carl", LastName = "Butler"},
20 | new SearchPatient {Id = "004", FirstName = "Lamar", LastName = "Nguyen"},
21 | new SearchPatient {Id = "005", FirstName = "Terence", LastName = "Hampton"},
22 | new SearchPatient {Id = "006", FirstName = "Mike", LastName = "Massey"},
23 | new SearchPatient {Id = "007", FirstName = "Hernietta", LastName = "Reid"},
24 | new SearchPatient {Id = "008", FirstName = "Carol", LastName = "Dawson"},
25 | new SearchPatient {Id = "009", FirstName = "Katie", LastName = "Wagner"},
26 | new SearchPatient {Id = "010", FirstName = "Kelley", LastName = "Houston"},
27 | };
28 | }
29 |
30 | [TestCase("", new string[0])]
31 | [TestCase(" ", new string[0])]
32 | [TestCase("car", new[] {"003", "008"})]
33 | [TestCase("mike", new[] {"006"})]
34 | [TestCase("robert", new string[0])]
35 | [TestCase("ngu lam", new[] {"004"})]
36 | [TestCase("ngu lam", new[] {"004"})]
37 | [TestCase("dawson,c", new[] {"008"})]
38 | public void SearchTest(string searchText, string[] resultIds)
39 | {
40 | var search = new PatientSearch(_patients, 10);
41 |
42 | var results = search.FindMatches(searchText).ToArray();
43 |
44 | Assert.That(results.Select(x => x.Id).ToArray(), Is.EqualTo(resultIds));
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/StandaloneRunner/StandaloneRunner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using VMS.TPS.Common.Model.API;
7 |
8 | namespace EsapiEssentials.Standalone
9 | {
10 | ///
11 | /// Allows a binary plugin script to run a standalone application,
12 | /// while preserving the script context (sent via command-line arguments).
13 | /// The plugin script assembly must be in the same directory as the
14 | /// standalone application. One way to do that is to reference
15 | /// the script project from the standalone application project.
16 | ///
17 | public class StandaloneRunner
18 | {
19 | ///
20 | /// Run the standalone application with the given script context.
21 | ///
22 | /// The script context from the plugin script.
23 | ///
24 | /// An exception occurred while trying to run the standalone application.
25 | /// Perhaps the application was not found or an error occurred while
26 | /// building the command-line arguments from the script context.
27 | ///
28 | public static void RunWith(ScriptContext context)
29 | {
30 | try
31 | {
32 | var contextArgs = ScriptContextArgs.From(context);
33 | Process.Start(GetStandalonePath(), contextArgs.ToArgs());
34 | }
35 | catch (Exception)
36 | {
37 | throw new StandaloneRunnerException("Unable to launch the application.");
38 | }
39 | }
40 |
41 | private static string GetStandalonePath() =>
42 | FirstExeIn(DirectoryOf(Assembly()));
43 |
44 | private static string FirstExeIn(string dir) =>
45 | Directory.GetFiles(dir, "*.exe").First();
46 |
47 | private static string DirectoryOf(Assembly asm) =>
48 | Path.GetDirectoryName(asm.Location);
49 |
50 | private static Assembly Assembly() =>
51 | System.Reflection.Assembly.GetExecutingAssembly();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Esapi/EsapiService.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Threading.Tasks;
3 | using EsapiEssentials.Plugin;
4 | using VMS.TPS.Common.Model.API;
5 |
6 | namespace EsapiEssentials.Samples.AsyncPlugin
7 | {
8 | public class EsapiService : EsapiServiceBase, IEsapiService
9 | {
10 | private readonly DoseMetricCalculator _metricCalc;
11 |
12 | public EsapiService(PluginScriptContext context) : base(context)
13 | {
14 | _metricCalc = new DoseMetricCalculator();
15 | }
16 |
17 | public Task GetPlansAsync() =>
18 | RunAsync(context => context.Patient.Courses?
19 | .SelectMany(x => x.PlanSetups)
20 | .Select(x => new Plan
21 | {
22 | PlanId = x.Id,
23 | CourseId = x.Course?.Id
24 | })
25 | .ToArray());
26 |
27 | public Task GetStructureIdsAsync(string courseId, string planId) =>
28 | RunAsync(context =>
29 | {
30 | var plan = GetPlan(context.Patient, courseId, planId);
31 | return plan?.StructureSet?.Structures?.Select(x => x.Id).ToArray() ?? new string[0];
32 | });
33 |
34 | public Task CalculateMeanDoseAsync(string courseId, string planId, string structureId) =>
35 | RunAsync(context => CalculateMeanDose(context.Patient, courseId, planId, structureId));
36 |
37 | private double CalculateMeanDose(Patient patient, string courseId, string planId, string structureId)
38 | {
39 | var plan = GetPlan(patient, courseId, planId);
40 | var structure = GetStructure(plan, structureId);
41 | return _metricCalc.CalculateMean(plan, structure);
42 | }
43 |
44 | private PlanSetup GetPlan(Patient patient, string courseId, string planId) =>
45 | GetCourse(patient, courseId)?.PlanSetups?.FirstOrDefault(x => x.Id == planId);
46 |
47 | private Course GetCourse(Patient patient, string courseId) =>
48 | patient?.Courses?.FirstOrDefault(x => x.Id == courseId);
49 |
50 | private Structure GetStructure(PlanSetup plan, string structureId) =>
51 | plan?.StructureSet?.Structures?.FirstOrDefault(x => x.Id == structureId);
52 | }
53 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Linq;
4 | using System.Windows;
5 | using EsapiEssentials.Standalone;
6 | using Application = VMS.TPS.Common.Model.API.Application;
7 |
8 | namespace EsapiEssentials.Samples.StandaloneRunner.App
9 | {
10 | public partial class MainWindow : Window
11 | {
12 | private Application _app;
13 | private StandaloneScriptContext _scriptContext;
14 |
15 | public MainWindow()
16 | {
17 | InitializeComponent();
18 | InitializeEsapi();
19 | InitializeControls();
20 | }
21 |
22 | private void InitializeEsapi()
23 | {
24 | // The ESAPI Application object must be created before the PluginScriptContext
25 | #if ESAPI_13
26 | _app = Application.CreateApplication(null, null);
27 | #elif ESAPI_15
28 | _app = Application.CreateApplication();
29 | #endif
30 |
31 | // The PluginScriptContext requires the command-line arguments and the Application object
32 | // (if there are no command-line arguments, the return is null)
33 | _scriptContext = StandaloneScriptContext.From(Environment.GetCommandLineArgs(), _app);
34 | }
35 |
36 | private void InitializeControls()
37 | {
38 | // Display some information from the created PluginScriptContext object (if not null)
39 | // (for simplicity, we're not using data-binding but directly accessing the controls)
40 | PatientTextBlock.Text = $"Patient: {_scriptContext?.Patient?.LastName}, {_scriptContext?.Patient?.FirstName}";
41 | CourseTextBlock.Text = $"Course: {_scriptContext?.Course?.Id}";
42 | PlanTextBlock.Text = $"Plan: {_scriptContext?.PlanSetup?.Id}";
43 | PlanSumsInScopeTextBlock.Text = $"Plan sums in scope: {GetFormattedPlanSumIds()}";
44 | }
45 |
46 | private string GetFormattedPlanSumIds() =>
47 | string.Join(", ", _scriptContext?.PlanSumsInScope?.Select(x => x.Id) ?? new string[0]);
48 |
49 | private void MainWindow_OnClosing(object sender, CancelEventArgs e)
50 | {
51 | // Always dispose of the ESAPI Application object before exiting the program
52 | _app.Dispose();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/EsapiEssentials.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
6 | False
7 | True
8 | True
9 | True
10 | True
11 | True
12 | False
13 | True
14 | True
15 | True
16 | True
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/PatientSearch/PatientSearch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace EsapiEssentials.Standalone
6 | {
7 | internal class PatientSearch
8 | {
9 | private readonly IEnumerable _patients;
10 | private readonly int _maxResults;
11 |
12 | public PatientSearch(IEnumerable patients, int maxResults)
13 | {
14 | _patients = patients;
15 | _maxResults = maxResults;
16 | }
17 |
18 | public IEnumerable FindMatches(string searchText)
19 | {
20 | if (string.IsNullOrWhiteSpace(searchText))
21 | return Enumerable.Empty();
22 |
23 | var searchTerms = GetSearchTerms(searchText);
24 | return _patients
25 | .Where(p => IsMatch(p, searchTerms))
26 | .OrderByDescending(p => p.CreationDateTime)
27 | .Take(_maxResults);
28 | }
29 |
30 | private bool IsMatch(SearchPatient patient, string[] searchTerms)
31 | {
32 | switch (searchTerms.Length)
33 | {
34 | case 0:
35 | return false;
36 | case 1:
37 | return IsMatchWithOneSearchTerm(patient, searchTerms[0]);
38 | default:
39 | return IsMatchWithTwoSearchTerms(patient, searchTerms[0], searchTerms[1]);
40 | }
41 | }
42 |
43 | private string[] GetSearchTerms(string searchText) =>
44 | searchText.Split(' ', ',').ToArray();
45 |
46 | private bool IsMatchWithOneSearchTerm(SearchPatient patient, string term) =>
47 | IsSubstring(term, patient.Id) ||
48 | IsSubstring(term, patient.LastName) ||
49 | IsSubstring(term, patient.FirstName);
50 |
51 | private bool IsMatchWithTwoSearchTerms(SearchPatient patient, string term1, string term2) =>
52 | IsMatchWithLastThenFirstName(patient, term1, term2) ||
53 | IsMatchWithLastThenFirstName(patient, term2, term1);
54 |
55 | private bool IsMatchWithLastThenFirstName(SearchPatient patient, string lastName, string firstName) =>
56 | IsSubstring(lastName, patient.LastName) && IsSubstring(firstName, patient.FirstName);
57 |
58 | private bool IsSubstring(string small, string large) =>
59 | large.StartsWith(small, StringComparison.OrdinalIgnoreCase);
60 | }
61 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("EsapiEssentials.Samples.Async")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("EsapiEssentials.Samples.Async")]
15 | [assembly: AssemblyCopyright("Copyright © 2019")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("EsapiEssentials.Samples.StandaloneApp")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("EsapiEssentials.Samples.StandaloneApp")]
15 | [assembly: AssemblyCopyright("Copyright © 2019")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("EsapiEssentials.Samples.AsyncPlugin.Runner")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("EsapiEssentials.Samples.AsyncPlugin.Runner")]
15 | [assembly: AssemblyCopyright("Copyright © 2019")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("EsapiEssentials.Samples.PluginScript.Runner")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("EsapiEssentials.Samples.PluginScript.Runner")]
15 | [assembly: AssemblyCopyright("Copyright © 2019")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/ViewModels/MainViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.Windows.Input;
3 | using GalaSoft.MvvmLight;
4 | using GalaSoft.MvvmLight.CommandWpf;
5 |
6 | namespace EsapiEssentials.Samples.AsyncPlugin
7 | {
8 | public class MainViewModel : ViewModelBase
9 | {
10 | private readonly IEsapiService _esapiService;
11 | private readonly IDialogService _dialogService;
12 |
13 | public MainViewModel(IEsapiService esapiService, IDialogService dialogService)
14 | {
15 | _esapiService = esapiService;
16 | _dialogService = dialogService;
17 | }
18 |
19 | private Plan[] _plans;
20 | public Plan[] Plans
21 | {
22 | get => _plans;
23 | set => Set(ref _plans, value);
24 | }
25 |
26 | private Plan _selectedPlan;
27 | public Plan SelectedPlan
28 | {
29 | get => _selectedPlan;
30 | set => Set(ref _selectedPlan, value);
31 | }
32 |
33 | private ObservableCollection _metricResults;
34 | public ObservableCollection MetricResults
35 | {
36 | get => _metricResults;
37 | set => Set(ref _metricResults, value);
38 | }
39 |
40 | public ICommand StartCommand => new RelayCommand(Start);
41 |
42 | private async void Start()
43 | {
44 | Plans = await _esapiService.GetPlansAsync();
45 | }
46 |
47 | public ICommand AnalyzePlanCommand => new RelayCommand(AnalyzePlan);
48 |
49 | private async void AnalyzePlan()
50 | {
51 | var courseId = SelectedPlan?.CourseId;
52 | var planId = SelectedPlan?.PlanId;
53 |
54 | if (courseId == null || planId == null)
55 | return;
56 |
57 | var structureIds = await _esapiService.GetStructureIdsAsync(courseId, planId);
58 |
59 | _dialogService.ShowProgressDialog("Calculating dose metrics", structureIds.Length,
60 | async progress =>
61 | {
62 | MetricResults = new ObservableCollection();
63 | foreach (var structureId in structureIds)
64 | {
65 | double result;
66 |
67 | try
68 | {
69 | result = await _esapiService.CalculateMeanDoseAsync(courseId, planId, structureId);
70 | }
71 | catch
72 | {
73 | result = double.NaN;
74 | }
75 |
76 | MetricResults.Add(new MetricResult
77 | {
78 | StructureId = structureId,
79 | Result = result
80 | });
81 |
82 | progress.Increment();
83 | }
84 | });
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.Async.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EsapiEssentials.Samples.Async.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.StandaloneApp.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EsapiEssentials.Samples.StandaloneApp.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.AsyncPlugin.Runner.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EsapiEssentials.Samples.AsyncPlugin.Runner.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EsapiEssentials.Samples.PluginScript.Runner.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EsapiEssentials.Samples.PluginScript.Runner.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/PatientSearch/PatientSummarySearch.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using VMS.TPS.Common.Model.API;
4 |
5 | namespace EsapiEssentials.Standalone
6 | {
7 | public class PatientSummarySearch
8 | {
9 | private readonly IEnumerable _patients;
10 | private readonly PatientSearch _search;
11 |
12 | ///
13 | /// Initializes a new instance of the PatientSummarySearch class.
14 | ///
15 | /// The list of patients to search.
16 | /// The maximum number of results to return.
17 | public PatientSummarySearch(IEnumerable patients, int maxResults)
18 | {
19 | // Need to convert patients to an array,
20 | // or the IEnumerable will be iterated multiple times
21 | _patients = patients.ToArray();
22 |
23 | // Adapt each PatientSummary to a SearchPatient object
24 | // to make PatientSearch testable without referencing ESAPI
25 | var searchPatients = CreateSearchPatients();
26 | _search = new PatientSearch(searchPatients, maxResults);
27 | }
28 |
29 | ///
30 | /// Finds the patients that match the given search string.
31 | ///
32 | /// The search string.
33 | /// The patients that match the given search string.
34 | ///
35 | /// If the search string is a single word, a patient matches it
36 | /// if the patient's ID, first name, or last name start with it.
37 | /// If the search string contains two or more words, a patient matches it
38 | /// if the patient's first name or last name start with any of the first
39 | /// two words in the search string (the remaining words are ignored).
40 | /// The words in a search string may be separated by a space, a comma, or
41 | /// a semicolon.
42 | ///
43 | public IEnumerable FindMatches(string searchText)
44 | {
45 | // Need to convert matches to an array,
46 | // or the IEnumerable will be iterated multiple times
47 | var matches = _search.FindMatches(searchText);
48 | return GetPatientSummaries(matches.ToArray());
49 | }
50 |
51 | private IEnumerable CreateSearchPatients() =>
52 | _patients.Select(CreateSearchPatient);
53 |
54 | private SearchPatient CreateSearchPatient(PatientSummary patientSummary) =>
55 | new SearchPatient
56 | {
57 | Id = patientSummary.Id,
58 | FirstName = patientSummary.FirstName,
59 | LastName = patientSummary.LastName,
60 | CreationDateTime = patientSummary.CreationDateTime
61 | };
62 |
63 | private IEnumerable GetPatientSummaries(IEnumerable patients) =>
64 | _patients.Where(ps => ContainsById(ps, patients));
65 |
66 | private bool ContainsById(PatientSummary patientSummary, IEnumerable patients) =>
67 | patients.FirstOrDefault(p => p.Id == patientSummary.Id) != null;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Esapi/EsapiService.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Threading.Tasks;
3 | using EsapiEssentials.Standalone;
4 | using VMS.TPS.Common.Model.API;
5 |
6 | namespace EsapiEssentials.Samples.Async
7 | {
8 | // Sample implementation of IEsapiService using EsapiServiceBase
9 | public class EsapiService : EsapiServiceBase, IEsapiService
10 | {
11 | private readonly DoseMetricCalculator _metricCalc;
12 |
13 | private PatientSummarySearch _search;
14 |
15 | public EsapiService()
16 | {
17 | _metricCalc = new DoseMetricCalculator();
18 | }
19 |
20 | // Override the default LogInAsync functionality
21 | // so that the patients are obtained after logging in
22 | public override async Task LogInAsync()
23 | {
24 | await base.LogInAsync();
25 | await InitializeSearchAsync();
26 | }
27 |
28 | #if ESAPI_13
29 | public override async Task LogInAsync(string userId, string password)
30 | {
31 | await base.LogInAsync(userId, password);
32 | await InitializeSearchAsync();
33 | }
34 | #endif
35 |
36 | // Use the RunAsync set of methods to run ESAPI-related actions on a separate thread
37 | public Task SearchAsync(string searchText) =>
38 | RunAsync(() => _search.FindMatches(searchText)
39 | .Select(ps => new PatientMatch
40 | {
41 | Id = ps.Id,
42 | FirstName = ps.FirstName,
43 | LastName = ps.LastName
44 | })
45 | .ToArray());
46 |
47 | public Task GetPlansAsync() =>
48 | RunAsync(patient => patient.Courses?
49 | .SelectMany(x => x.PlanSetups)
50 | .Select(x => new Plan
51 | {
52 | PlanId = x.Id,
53 | CourseId = x.Course?.Id
54 | })
55 | .ToArray());
56 |
57 | public Task GetStructureIdsAsync(string courseId, string planId) =>
58 | RunAsync(patient =>
59 | {
60 | var plan = GetPlan(patient, courseId, planId);
61 | return plan?.StructureSet?.Structures?.Select(x => x.Id).ToArray() ?? new string[0];
62 | });
63 |
64 | public Task CalculateMeanDoseAsync(string courseId, string planId, string structureId) =>
65 | RunAsync(patient => CalculateMeanDose(patient, courseId, planId, structureId));
66 |
67 | private Task InitializeSearchAsync() =>
68 | RunAsync(app => _search = new PatientSummarySearch(app.PatientSummaries, 10));
69 |
70 | private double CalculateMeanDose(Patient patient, string courseId, string planId, string structureId)
71 | {
72 | var plan = GetPlan(patient, courseId, planId);
73 | var structure = GetStructure(plan, structureId);
74 | return _metricCalc.CalculateMean(plan, structure);
75 | }
76 |
77 | private PlanSetup GetPlan(Patient patient, string courseId, string planId) =>
78 | GetCourse(patient, courseId)?.PlanSetups?.FirstOrDefault(x => x.Id == planId);
79 |
80 | private Course GetCourse(Patient patient, string courseId) =>
81 | patient?.Courses?.FirstOrDefault(x => x.Id == courseId);
82 |
83 | private Structure GetStructure(PlanSetup plan, string structureId) =>
84 | plan?.StructureSet?.Structures?.FirstOrDefault(x => x.Id == structureId);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/Standalone/StandaloneRunner/ScriptContextArgs.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using CommandLine;
4 | using VMS.TPS.Common.Model.API;
5 |
6 | namespace EsapiEssentials.Standalone
7 | {
8 | internal class ScriptContextArgs
9 | {
10 | [Option("user-id", Required = true)]
11 | public string CurrentUserId { get; set; }
12 |
13 | [Option("course-id")]
14 | public string CourseId { get; set; }
15 |
16 | // Used to find the exact image
17 | [Option("series-uid")]
18 | public string SeriesUid { get; set; }
19 |
20 | [Option("image-id")]
21 | public string ImageId { get; set; }
22 |
23 | [Option("structure-set-id")]
24 | public string StructureSetId { get; set; }
25 |
26 | [Option("patient-id")]
27 | public string PatientId { get; set; }
28 |
29 | [Option("plan-id")]
30 | public string PlanSetupId { get; set; }
31 |
32 | [Option("external-plan-id")]
33 | public string ExternalPlanSetupId { get; set; }
34 |
35 | [Option("brachy-plan-id")]
36 | public string BrachyPlanSetupId { get; set; }
37 |
38 | [Option("plans-in-scope-uids")]
39 | public IEnumerable PlansInScopeUids { get; set; }
40 |
41 | [Option("external-plans-in-scope-uids")]
42 | public IEnumerable ExternalPlansInScopeUids { get; set; }
43 |
44 | [Option("brachy-plans-in-scope-uids")]
45 | public IEnumerable BrachyPlansInScopeUids { get; set; }
46 |
47 | // Used to find the exact plan sums
48 | [Option("plan-sums-in-scope-course-ids")]
49 | public IEnumerable PlanSumsInScopeCourseIds { get; set; }
50 |
51 | [Option("plan-sums-in-scope-ids")]
52 | public IEnumerable PlanSumsInScopeIds { get; set; }
53 |
54 | [Option("app-name")]
55 | public string ApplicationName { get; set; }
56 |
57 | [Option("version")]
58 | public string VersionInfo { get; set; }
59 |
60 | public static ScriptContextArgs From(ScriptContext context)
61 | {
62 | return new ScriptContextArgs
63 | {
64 | CurrentUserId = context.CurrentUser?.Id,
65 | CourseId = context.Course?.Id,
66 | SeriesUid = context.Image?.Series?.UID,
67 | ImageId = context.Image?.Id,
68 | StructureSetId = context.StructureSet?.Id,
69 | PatientId = context.Patient?.Id,
70 | PlanSetupId = context.PlanSetup?.Id,
71 | ExternalPlanSetupId = context.ExternalPlanSetup?.Id,
72 | BrachyPlanSetupId = context.BrachyPlanSetup?.Id,
73 | PlansInScopeUids = context.PlansInScope?.Select(x => x.UID),
74 | ExternalPlansInScopeUids = context.ExternalPlansInScope?.Select(x => x.UID),
75 | BrachyPlansInScopeUids = context.BrachyPlansInScope?.Select(x => x.UID),
76 | PlanSumsInScopeCourseIds = context.PlanSumsInScope?.Select(x => x.Course?.Id),
77 | PlanSumsInScopeIds = context.PlanSumsInScope?.Select(x => x.Id),
78 | ApplicationName = context.ApplicationName,
79 | VersionInfo = context.VersionInfo
80 | };
81 | }
82 |
83 | public static ScriptContextArgs From(string[] args)
84 | {
85 | ScriptContextArgs scriptContextArgs = null;
86 | Parser.Default.ParseArguments(args)
87 | .WithParsed(parsedArgs => scriptContextArgs = parsedArgs);
88 | return scriptContextArgs;
89 | }
90 |
91 | public string ToArgs()
92 | {
93 | return Parser.Default.FormatCommandLine(this);
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/tests/EsapiEssentials.UnitTests/EsapiEssentials.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Debug
7 | AnyCPU
8 | {46821C78-494D-4BD4-8BA1-CC3B430C24F0}
9 | Library
10 | Properties
11 | EsapiEssentials.UnitTests
12 | EsapiEssentials.UnitTests
13 | v4.5
14 | 512
15 |
16 |
17 |
18 |
19 | true
20 | bin\x64\Debug\
21 | DEBUG;TRACE
22 | full
23 | x64
24 | prompt
25 | MinimumRecommendedRules.ruleset
26 |
27 |
28 | bin\x64\Release\
29 | TRACE
30 | true
31 | pdbonly
32 | x64
33 | prompt
34 | MinimumRecommendedRules.ruleset
35 |
36 |
37 |
38 | ..\..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | {fdc15e5d-0179-42cf-b352-48b74b234454}
57 | EsapiEssentials
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp.Runner/EsapiEssentials.Samples.StandaloneApp.Runner.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B6BD150A-2A22-4D28-9152-D6E02E97B218}
8 | Library
9 | Properties
10 | EsapiEssentials.Samples.StandaloneApp.Runner
11 | EsapiEssentials.Samples.StandaloneApp.Runner.esapi
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 | true
18 | bin\x64\Debug-13.6\
19 | DEBUG;TRACE
20 | full
21 | x64
22 | prompt
23 | MinimumRecommendedRules.ruleset
24 |
25 |
26 | bin\x64\Release-13.6\
27 | TRACE
28 | true
29 | pdbonly
30 | x64
31 | prompt
32 | MinimumRecommendedRules.ruleset
33 |
34 |
35 | true
36 | bin\x64\Debug-15.6\
37 | DEBUG;TRACE
38 | full
39 | x64
40 | prompt
41 | MinimumRecommendedRules.ruleset
42 |
43 |
44 | bin\x64\Release-15.6\
45 | TRACE
46 | true
47 | pdbonly
48 | x64
49 | prompt
50 | MinimumRecommendedRules.ruleset
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | $(EsapiPath)\VMS.TPS.Common.Model.API.dll
64 |
65 |
66 | $(EsapiPath)\VMS.TPS.Common.Model.Types.dll
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | {fdc15e5d-0179-42cf-b352-48b74b234454}
76 | EsapiEssentials
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript/EsapiEssentials.Samples.PluginScript.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FEB1E304-CCC9-4B61-ACD2-FE76DE6E1125}
8 | Library
9 | Properties
10 | EsapiEssentials.Samples.PluginScript
11 | EsapiEssentials.Samples.PluginScript.esapi
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 | true
18 | bin\x64\Debug-13.6\
19 | DEBUG;TRACE
20 | full
21 | x64
22 | prompt
23 | MinimumRecommendedRules.ruleset
24 |
25 |
26 | bin\x64\Release-13.6\
27 | TRACE
28 | true
29 | pdbonly
30 | x64
31 | prompt
32 | MinimumRecommendedRules.ruleset
33 |
34 |
35 | true
36 | bin\x64\Debug-15.6\
37 | DEBUG;TRACE
38 | full
39 | x64
40 | prompt
41 | MinimumRecommendedRules.ruleset
42 |
43 |
44 | bin\x64\Release-15.6\
45 | TRACE
46 | true
47 | pdbonly
48 | x64
49 | prompt
50 | MinimumRecommendedRules.ruleset
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | $(EsapiPath)\VMS.TPS.Common.Model.API.dll
65 |
66 |
67 | $(EsapiPath)\VMS.TPS.Common.Model.Types.dll
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | {FDC15E5D-0179-42CF-B352-48B74B234454}
77 | EsapiEssentials
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/ViewModels/MainViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.Windows.Input;
3 | using GalaSoft.MvvmLight;
4 | using GalaSoft.MvvmLight.CommandWpf;
5 |
6 | namespace EsapiEssentials.Samples.Async
7 | {
8 | public class MainViewModel : ViewModelBase
9 | {
10 | private readonly IEsapiService _esapiService;
11 | private readonly IDialogService _dialogService;
12 |
13 | public MainViewModel(IEsapiService esapiService, IDialogService dialogService)
14 | {
15 | _esapiService = esapiService;
16 | _dialogService = dialogService;
17 | }
18 |
19 | private string _searchText;
20 | public string SearchText
21 | {
22 | get => _searchText;
23 | set => Set(ref _searchText, value);
24 | }
25 |
26 | private PatientMatch[] _patientMatches;
27 | public PatientMatch[] PatientMatches
28 | {
29 | get => _patientMatches;
30 | set => Set(ref _patientMatches, value);
31 | }
32 |
33 | private PatientMatch _selectedPatientMatch;
34 | public PatientMatch SelectedPatientMatch
35 | {
36 | get => _selectedPatientMatch;
37 | set => Set(ref _selectedPatientMatch, value);
38 | }
39 |
40 | private Plan[] _plans;
41 | public Plan[] Plans
42 | {
43 | get => _plans;
44 | set => Set(ref _plans, value);
45 | }
46 |
47 | private Plan _selectedPlan;
48 | public Plan SelectedPlan
49 | {
50 | get => _selectedPlan;
51 | set => Set(ref _selectedPlan, value);
52 | }
53 |
54 | private ObservableCollection _metricResults;
55 | public ObservableCollection MetricResults
56 | {
57 | get => _metricResults;
58 | set => Set(ref _metricResults, value);
59 | }
60 |
61 | public ICommand StartCommand => new RelayCommand(Start);
62 | public ICommand SearchPatientCommand => new RelayCommand(SearchPatient);
63 | public ICommand OpenPatientCommand => new RelayCommand(OpenPatient);
64 | public ICommand AnalyzePlanCommand => new RelayCommand(AnalyzePlan);
65 |
66 | private void Start()
67 | {
68 | _dialogService.ShowProgressDialog("Logging in to Eclipse. Please wait.",
69 | async progress => await _esapiService.LogInAsync());
70 | }
71 |
72 | private async void SearchPatient()
73 | {
74 | PatientMatches = await _esapiService.SearchAsync(SearchText);
75 | }
76 |
77 | private async void OpenPatient()
78 | {
79 | if (SelectedPatientMatch?.Id == null)
80 | return;
81 |
82 | await _esapiService.ClosePatientAsync();
83 | await _esapiService.OpenPatientAsync(SelectedPatientMatch.Id);
84 | Plans = await _esapiService.GetPlansAsync();
85 | }
86 |
87 | private async void AnalyzePlan()
88 | {
89 | var courseId = SelectedPlan?.CourseId;
90 | var planId = SelectedPlan?.PlanId;
91 |
92 | if (courseId == null || planId == null)
93 | return;
94 |
95 | var structureIds = await _esapiService.GetStructureIdsAsync(courseId, planId);
96 |
97 | _dialogService.ShowProgressDialog("Calculating dose metrics", structureIds.Length,
98 | async progress =>
99 | {
100 | MetricResults = new ObservableCollection();
101 | foreach (var structureId in structureIds)
102 | {
103 | double result;
104 |
105 | try
106 | {
107 | result = await _esapiService.CalculateMeanDoseAsync(courseId, planId, structureId);
108 | }
109 | catch
110 | {
111 | result = double.NaN;
112 | }
113 |
114 | MetricResults.Add(new MetricResult
115 | {
116 | StructureId = structureId,
117 | Result = result
118 | });
119 |
120 | progress.Increment();
121 | }
122 | });
123 | }
124 | }
125 | }
--------------------------------------------------------------------------------
/src/EsapiEssentials.PluginRunner/ViewModel/MainViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Windows.Input;
4 | using GalaSoft.MvvmLight;
5 | using GalaSoft.MvvmLight.CommandWpf;
6 |
7 | namespace EsapiEssentials.PluginRunner
8 | {
9 | internal class MainViewModel : ViewModelBase
10 | {
11 | private readonly PluginRunner _runner;
12 |
13 | public MainViewModel(PluginRunner runner)
14 | {
15 | _runner = runner;
16 | Recents = _runner.GetRecentEntries().Reverse().ToList();
17 | }
18 |
19 | private string _searchText;
20 | public string SearchText
21 | {
22 | get => _searchText;
23 | set => Set(ref _searchText, value);
24 | }
25 |
26 | private IEnumerable _patientMatches;
27 | public IEnumerable PatientMatches
28 | {
29 | get => _patientMatches;
30 | set => Set(ref _patientMatches, value);
31 | }
32 |
33 | private PatientMatch _selectedPatientMatch;
34 | public PatientMatch SelectedPatientMatch
35 | {
36 | get => _selectedPatientMatch;
37 | set => Set(ref _selectedPatientMatch, value);
38 | }
39 |
40 | // Must not be IEnumerable or it re-creates the view models
41 | // when accessed in OpenPatient(), losing which items are active
42 | private IList _plansAndPlanSums;
43 | public IList PlansAndPlanSums
44 | {
45 | get => _plansAndPlanSums;
46 | set => Set(ref _plansAndPlanSums, value);
47 | }
48 |
49 | private IList _recents;
50 | public IList Recents
51 | {
52 | get => _recents;
53 | set => Set(ref _recents, value);
54 | }
55 |
56 | private RecentEntry _selectedRecent;
57 | public RecentEntry SelectedRecent
58 | {
59 | get => _selectedRecent;
60 | set => Set(ref _selectedRecent, value);
61 | }
62 |
63 | public ICommand SearchPatientCommand => new RelayCommand(SearchPatient);
64 | public ICommand OpenPatientCommand => new RelayCommand(OpenPatient);
65 | public ICommand OpenRecentEntryCommand => new RelayCommand(OpenRecentEntry);
66 | public ICommand RunCommand => new RelayCommand(Run);
67 |
68 | private void SearchPatient()
69 | {
70 | PatientMatches = _runner.FindPatientMatches(SearchText);
71 |
72 | SelectedPatientMatch = null;
73 | PlansAndPlanSums = null;
74 | }
75 |
76 | private void OpenPatient()
77 | {
78 | var plansAndPlanSums = _runner.GetPlansAndPlanSumsFor(SelectedPatientMatch?.Id);
79 | PlansAndPlanSums = plansAndPlanSums?.Select(CreatePlanOrPlanSumViewModel).ToList();
80 | }
81 |
82 | private PlanOrPlanSumViewModel CreatePlanOrPlanSumViewModel(PlanOrPlanSum planOrPlanSum) =>
83 | new PlanOrPlanSumViewModel
84 | {
85 | Type = planOrPlanSum.Type,
86 | Id = planOrPlanSum.Id,
87 | CourseId = planOrPlanSum.CourseId
88 | };
89 |
90 | private void OpenRecentEntry()
91 | {
92 | SearchText = SelectedRecent?.PatientId;
93 | SearchPatient();
94 | SelectedPatientMatch = PatientMatches?.FirstOrDefault();
95 | OpenPatient();
96 | CheckInScopeOrActiveFromRecent();
97 | }
98 |
99 | private void CheckInScopeOrActiveFromRecent()
100 | {
101 | if (PlansAndPlanSums == null) return;
102 |
103 | foreach (var planOrPlanSumVm in PlansAndPlanSums)
104 | {
105 | if (IsRecentInScope(planOrPlanSumVm))
106 | planOrPlanSumVm.IsInScope = true;
107 | if (IsRecentActive(planOrPlanSumVm))
108 | planOrPlanSumVm.IsActive = true;
109 | }
110 | }
111 |
112 | private bool IsRecentInScope(PlanOrPlanSumViewModel planOrPlanSumVm) =>
113 | SelectedRecent?.PlansAndPlanSumsInScope?.Any(p => p.CourseId == planOrPlanSumVm?.CourseId && p.Id == planOrPlanSumVm?.Id) ?? false;
114 |
115 | private bool IsRecentActive(PlanOrPlanSumViewModel planOrPlanSumVm) =>
116 | SelectedRecent?.ActivePlan?.CourseId == planOrPlanSumVm?.CourseId && SelectedRecent?.ActivePlan?.Id == planOrPlanSumVm?.Id;
117 |
118 | private void Run()
119 | {
120 | _runner.RunScript(SelectedPatientMatch?.Id, GetPlansAndPlanSumsInScope(), GetActivePlan());
121 |
122 | var recents = Recents;
123 | var selectedRecent = SelectedRecent;
124 |
125 | Recents = _runner.GetRecentEntries().Reverse().ToList();
126 |
127 | // If recents changed, it means a new recent was added, so select it as the recent;
128 | // otherwise, select the previously selected recent
129 | SelectedRecent = recents.Count != Recents.Count
130 | ? Recents.FirstOrDefault()
131 | : selectedRecent;
132 | OpenRecentEntry();
133 | }
134 |
135 | private PlanOrPlanSum[] GetPlansAndPlanSumsInScope() =>
136 | PlansAndPlanSums?.Where(p => p.IsInScope).Select(CreatePlanOrPlanSum).ToArray();
137 |
138 | private PlanOrPlanSum GetActivePlan() =>
139 | PlansAndPlanSums?.Where(p => p.IsActive).Select(CreatePlanOrPlanSum).FirstOrDefault();
140 |
141 | private PlanOrPlanSum CreatePlanOrPlanSum(PlanOrPlanSumViewModel vm) =>
142 | new PlanOrPlanSum
143 | {
144 | Type = vm.Type,
145 | Id = vm.Id,
146 | CourseId = vm.CourseId
147 | };
148 | }
149 | }
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.Async/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin/Views/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
70 |
71 |
72 |
73 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
98 |
102 |
106 |
111 |
112 |
116 |
120 |
121 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/src/EsapiEssentials/EsapiEssentials.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FDC15E5D-0179-42CF-B352-48B74B234454}
8 | Library
9 | Properties
10 | EsapiEssentials
11 | EsapiEssentials
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 | true
18 | bin\x64\Debug-13.6\
19 | DEBUG;TRACE
20 | full
21 | x64
22 | prompt
23 | MinimumRecommendedRules.ruleset
24 |
25 |
26 | true
27 | bin\x64\Debug-15.6\
28 | DEBUG;TRACE
29 | full
30 | x64
31 | prompt
32 | MinimumRecommendedRules.ruleset
33 |
34 |
35 | bin\x64\Release-13.6\
36 | TRACE
37 | true
38 | pdbonly
39 | x64
40 | prompt
41 | MinimumRecommendedRules.ruleset
42 |
43 |
44 | bin\x64\Release-15.6\
45 | TRACE
46 | true
47 | pdbonly
48 | x64
49 | prompt
50 | MinimumRecommendedRules.ruleset
51 |
52 |
53 |
54 |
55 | ..\..\packages\CommandLineParser.2.5.0\lib\net45\CommandLine.dll
56 |
57 |
58 | ..\..\packages\MSFT.ParallelExtensionsExtras.1.2.0\lib\ParallelExtensionsExtras.dll
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | $(EsapiPath)\VMS.TPS.Common.Model.API.dll
72 |
73 |
74 | $(EsapiPath)\VMS.TPS.Common.Model.Types.dll
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.AsyncPlugin.Runner/EsapiEssentials.Samples.AsyncPlugin.Runner.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {79D069B9-3FFA-4584-A132-C444937EDF9E}
8 | WinExe
9 | EsapiEssentials.Samples.AsyncPlugin.Runner
10 | EsapiEssentials.Samples.AsyncPlugin.Runner
11 | v4.5
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 |
17 |
18 | true
19 | bin\x64\Debug-13.6\
20 | DEBUG;TRACE
21 | full
22 | x64
23 | prompt
24 | MinimumRecommendedRules.ruleset
25 | true
26 |
27 |
28 | true
29 | bin\x64\Debug-15.6\
30 | DEBUG;TRACE
31 | full
32 | x64
33 | prompt
34 | MinimumRecommendedRules.ruleset
35 | true
36 |
37 |
38 | bin\x64\Release-13.6\
39 | TRACE
40 | true
41 | pdbonly
42 | x64
43 | prompt
44 | MinimumRecommendedRules.ruleset
45 | true
46 |
47 |
48 | bin\x64\Release-15.6\
49 | TRACE
50 | true
51 | pdbonly
52 | x64
53 | prompt
54 | MinimumRecommendedRules.ruleset
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 4.0
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | MSBuild:Compile
77 | Designer
78 |
79 |
80 | App.xaml
81 | Code
82 |
83 |
84 |
85 |
86 | Code
87 |
88 |
89 | True
90 | True
91 | Resources.resx
92 |
93 |
94 | True
95 | Settings.settings
96 | True
97 |
98 |
99 | ResXFileCodeGenerator
100 | Resources.Designer.cs
101 |
102 |
103 | SettingsSingleFileGenerator
104 | Settings.Designer.cs
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | {E575892D-81D0-4A2F-9FB1-495D3F404502}
113 | EsapiEssentials.PluginRunner
114 |
115 |
116 | {FDC15E5D-0179-42CF-B352-48B74B234454}
117 | EsapiEssentials
118 |
119 |
120 | {96E0CE2E-799B-473D-BF00-15DDC693A421}
121 | EsapiEssentials.Samples.AsyncPlugin
122 |
123 |
124 | $(EsapiPath)\VMS.TPS.Common.Model.API.dll
125 |
126 |
127 | $(EsapiPath)\VMS.TPS.Common.Model.Types.dll
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.PluginScript.Runner/EsapiEssentials.Samples.PluginScript.Runner.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CC28EBAC-C301-4CC1-91D0-EF99533C5F08}
8 | WinExe
9 | EsapiEssentials.Samples.PluginScript.Runner
10 | EsapiEssentials.Samples.PluginScript.Runner
11 | v4.5
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 |
17 |
18 | true
19 | bin\x64\Debug-13.6\
20 | DEBUG;TRACE
21 | full
22 | x64
23 | prompt
24 | MinimumRecommendedRules.ruleset
25 | true
26 |
27 |
28 | true
29 | bin\x64\Debug-15.6\
30 | DEBUG;TRACE
31 | full
32 | x64
33 | prompt
34 | MinimumRecommendedRules.ruleset
35 | true
36 |
37 |
38 | bin\x64\Release-13.6\
39 | TRACE
40 | true
41 | pdbonly
42 | x64
43 | prompt
44 | MinimumRecommendedRules.ruleset
45 | true
46 |
47 |
48 | bin\x64\Release-15.6\
49 | TRACE
50 | true
51 | pdbonly
52 | x64
53 | prompt
54 | MinimumRecommendedRules.ruleset
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 4.0
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | MSBuild:Compile
77 | Designer
78 |
79 |
80 | App.xaml
81 | Code
82 |
83 |
84 |
85 |
86 | Code
87 |
88 |
89 | True
90 | True
91 | Resources.resx
92 |
93 |
94 | True
95 | Settings.settings
96 | True
97 |
98 |
99 | ResXFileCodeGenerator
100 | Resources.Designer.cs
101 |
102 |
103 | SettingsSingleFileGenerator
104 | Settings.Designer.cs
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | {E575892D-81D0-4A2F-9FB1-495D3F404502}
113 | EsapiEssentials.PluginRunner
114 |
115 |
116 | {fdc15e5d-0179-42cf-b352-48b74b234454}
117 | EsapiEssentials
118 |
119 |
120 | {feb1e304-ccc9-4b61-acd2-fe76de6e1125}
121 | EsapiEssentials.Samples.PluginScript
122 |
123 |
124 | $(EsapiPath)\VMS.TPS.Common.Model.API.dll
125 |
126 |
127 | $(EsapiPath)\VMS.TPS.Common.Model.Types.dll
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/samples/EsapiEssentials.Samples.StandaloneApp/EsapiEssentials.Samples.StandaloneApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {407BAEEF-029F-4F27-89F0-12B8EAAC790C}
8 | WinExe
9 | EsapiEssentials.Samples.StandaloneApp
10 | EsapiEssentials.Samples.StandaloneApp
11 | v4.5
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 |
17 |
18 | true
19 | bin\x64\Debug-13.6\
20 | DEBUG;TRACE
21 | full
22 | x64
23 | prompt
24 | MinimumRecommendedRules.ruleset
25 | true
26 |
27 |
28 | bin\x64\Release-13.6\
29 | TRACE
30 | true
31 | pdbonly
32 | x64
33 | prompt
34 | MinimumRecommendedRules.ruleset
35 | true
36 |
37 |
38 | true
39 | bin\x64\Debug-15.6\
40 | DEBUG;TRACE
41 | full
42 | x64
43 | prompt
44 | MinimumRecommendedRules.ruleset
45 | true
46 |
47 |
48 | bin\x64\Release-15.6\
49 | TRACE
50 | true
51 | pdbonly
52 | x64
53 | prompt
54 | MinimumRecommendedRules.ruleset
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 4.0
69 |
70 |
71 | $(EsapiPath)\VMS.TPS.Common.Model.API.dll
72 |
73 |
74 | $(EsapiPath)\VMS.TPS.Common.Model.Types.dll
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | MSBuild:Compile
83 | Designer
84 |
85 |
86 | MSBuild:Compile
87 | Designer
88 |
89 |
90 | App.xaml
91 | Code
92 |
93 |
94 | MainWindow.xaml
95 | Code
96 |
97 |
98 |
99 |
100 | Code
101 |
102 |
103 | True
104 | True
105 | Resources.resx
106 |
107 |
108 | True
109 | Settings.settings
110 | True
111 |
112 |
113 | ResXFileCodeGenerator
114 | Resources.Designer.cs
115 |
116 |
117 | SettingsSingleFileGenerator
118 | Settings.Designer.cs
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | {fdc15e5d-0179-42cf-b352-48b74b234454}
127 | EsapiEssentials
128 |
129 |
130 | {b6bd150a-2a22-4d28-9152-d6e02e97b218}
131 | EsapiEssentials.Samples.StandaloneApp.Runner
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------