417 lines
No EOL
18 KiB
C#
417 lines
No EOL
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using JD.Localization.Core.Model;
|
|
using JD.Localization.Core.Model.Attributes;
|
|
using JD.LocalizationExport.Service.API;
|
|
using JD.LocalizationExport.Service.Model;
|
|
using JD.LocalizationExport.Service.Model.Options;
|
|
using JD.Oasis.Module.ViewModel.TreeViewModel;
|
|
using JD.Oasis.Service.API;
|
|
using JD.Reflection;
|
|
using Plume.Core.Logging;
|
|
using Plume.Interfaces.WPF.Notifications;
|
|
using Plume.Interfaces.WPF.StatusBar;
|
|
using Plume.Perforce.Service.Api;
|
|
using Plume.WPF.Commands;
|
|
using Plume.WPF.Mvvm;
|
|
using ExportLanguage = JD.LocalizationExport.Service.Model.Language;
|
|
using ExportLine = JD.LocalizationExport.Service.Model.Line;
|
|
|
|
namespace JD.Oasis.Module.ViewModel
|
|
{
|
|
public class OasisViewModel : BindableBase
|
|
{
|
|
private readonly IOasisService _oasisService;
|
|
private readonly ILocalizationExportService _exportService;
|
|
private readonly IStatusBarManager _statusBarManager;
|
|
private readonly INotificationManager _notificationManager;
|
|
private readonly ILogger _logger;
|
|
private readonly ExportServiceEventsHandler _exportEventsHandler;
|
|
|
|
#region Initialization
|
|
|
|
private OasisViewModel(IOasisService oasisService, ILocalizationExportService exportService, IPerforceService perforceService, string dataServer, string codeServer, IStatusBarManager statusBarManager, INotificationManager notificationManager, ILogger logger)
|
|
{
|
|
_oasisService = oasisService;
|
|
_exportService = exportService;
|
|
_statusBarManager = statusBarManager;
|
|
_notificationManager = notificationManager;
|
|
_logger = logger;
|
|
_progressCallback = new Progress<string>(msg =>
|
|
{
|
|
_statusBarManager.SetMessage(msg);
|
|
_logger.Info(msg);
|
|
});
|
|
|
|
_progressWithValueCallback = new Progress<Tuple<string, int>>(t =>
|
|
{
|
|
_logger.Info(t.Item1);
|
|
ShowProgress(t.Item1, t.Item2);
|
|
});
|
|
|
|
RefreshLocalisationDataCommand = new DelegateCommand(RefreshLocalisationData).ObservesCanExecute(() => IsUIEnabled);
|
|
|
|
_exportEventsHandler =
|
|
new ExportServiceEventsHandler(_exportService, perforceService, dataServer, codeServer, _logger);
|
|
}
|
|
|
|
public static Task<OasisViewModel> CreateAsync(IOasisService oasisService,
|
|
ILocalizationExportService exportService,
|
|
IPerforceService perforceService,
|
|
string dataServer, string codeServer,
|
|
IStatusBarManager statusBarManager,
|
|
INotificationManager notificationManager,
|
|
ILogger logger)
|
|
{
|
|
return new OasisViewModel(oasisService, exportService, perforceService, dataServer, codeServer, statusBarManager, notificationManager, logger).InitializeAsync();
|
|
}
|
|
|
|
private async Task<OasisViewModel> InitializeAsync()
|
|
{
|
|
await RefreshLocalizationDataAsync().ConfigureAwait(false);
|
|
return this;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Commands
|
|
|
|
public DelegateCommand RefreshLocalisationDataCommand { get; }
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
private FolderTreeNodeViewModel _rootNode;
|
|
public FolderTreeNodeViewModel RootNode
|
|
{
|
|
get => _rootNode;
|
|
set => SetProperty(ref _rootNode, value);
|
|
}
|
|
|
|
public List<FileTreeNodeViewModel> NodeList { get; private set; }
|
|
|
|
private bool _isUIEnabled = true;
|
|
public bool IsUIEnabled
|
|
{
|
|
get => _isUIEnabled;
|
|
set => SetProperty(ref _isUIEnabled, value);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Event handlers
|
|
|
|
public async Task OnLocalizationExportLaunched(IDictionary<ExportType, ExportOptionsModel> exportTypesAndOptionsToExecute, IEnumerable<UafLanguage> languagesToExport)
|
|
{
|
|
IsUIEnabled = false;
|
|
|
|
bool hasExportSucceeded = true;
|
|
|
|
IEnumerable<ExportLine> allLines = NodeList.Select(n => new ExportLine(n.LineId, n.MasterText, n.Translations, n.IsLineForPhone));
|
|
IEnumerable<ExportLine> selectedLines = NodeList.Where(n => n.IsChecked == true).Select(n => new ExportLine(n.LineId, n.MasterText, n.Translations, n.IsLineForPhone)).ToArray();
|
|
|
|
if (!selectedLines.Any())
|
|
{
|
|
string noLinesSelectedMessage = "Please select some lines in the tree before launching an export";
|
|
|
|
ShowFailure(noLinesSelectedMessage);
|
|
_logger.Error(noLinesSelectedMessage);
|
|
MessageBox.Show(noLinesSelectedMessage, "No lines selected", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
IsUIEnabled = true;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
ExportType[] exportTypesToExecute = exportTypesAndOptionsToExecute.Keys.ToArray();
|
|
|
|
if (exportTypesToExecute.Length == 0)
|
|
{
|
|
string noExportsSelectedMessage = "Please select some types of exports and try again";
|
|
|
|
ShowFailure(noExportsSelectedMessage);
|
|
_logger.Error(noExportsSelectedMessage);
|
|
MessageBox.Show(noExportsSelectedMessage, "No exports selected", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
IsUIEnabled = true;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
UafLanguage[] languagesToExportArray = languagesToExport.ToArray();
|
|
Dictionary<UafLanguage, string> oasisNamesForLanguagesToExport = await OasisHelpers.GetOasisNamesForLanguagesAsync(_oasisService, languagesToExportArray);
|
|
|
|
if (languagesToExportArray.Length == 0)
|
|
{
|
|
string noLanguagesSelectedMessage = "Please select some languages and try again";
|
|
|
|
ShowFailure(noLanguagesSelectedMessage);
|
|
_logger.Error(noLanguagesSelectedMessage);
|
|
MessageBox.Show(noLanguagesSelectedMessage, "No languages selected", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
IsUIEnabled = true;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
UafLanguage[] allUafLanguagesArray = UafLanguageMethods.GetAllLanguages().ToArray();
|
|
Dictionary<UafLanguage, string> oasisNamesForLanguages = await OasisHelpers.GetOasisNamesForLanguagesAsync(_oasisService, allUafLanguagesArray);
|
|
ExportLanguage[] allLanguages = allUafLanguagesArray.Select(l => new ExportLanguage(oasisNamesForLanguages[l],
|
|
l.ToString(),
|
|
ReflectionHelper.GetEnumDescription(l),
|
|
ReflectionHelper.GetEnumAttribute<CultureNameAttribute>(l).Values,
|
|
(int)ReflectionHelper.GetEnumAttribute<RegionsAttribute>(l).Value,
|
|
l == UafLanguage.ITF_LANGUAGE_DEV_REFERENCE))
|
|
.ToArray();
|
|
|
|
ExportLanguage[] selectedLanguages = allLanguages.Where(l => oasisNamesForLanguagesToExport.ContainsValue(l.OasisName)).ToArray();
|
|
|
|
string exportMessage = "Exporting localization...";
|
|
ShowInitialization(exportMessage);
|
|
_logger.Info(exportMessage);
|
|
|
|
_logger.Info($"Selected exports : {Environment.NewLine + string.Join(Environment.NewLine, exportTypesToExecute)}");
|
|
_logger.Info($"Selected languages : {Environment.NewLine + string.Join(Environment.NewLine, selectedLanguages.Select(l => l.Description))}");
|
|
|
|
|
|
try
|
|
{
|
|
DataToExport dataToExport = new DataToExport(allLines, selectedLines, allLanguages, selectedLanguages);
|
|
|
|
foreach (ExportType exportType in exportTypesToExecute)
|
|
{
|
|
exportMessage = $"Exporting {exportType} localization...";
|
|
|
|
_statusBarManager.SetMessage(exportMessage);
|
|
_logger.Info(exportMessage);
|
|
|
|
ExportRepositoryType repositoryType = _exportService.ExportConfigs[exportType].RepositoryType;
|
|
|
|
switch (exportType)
|
|
{
|
|
case ExportType.Console:
|
|
ConsoleExportOptions consoleExportOptions = exportTypesAndOptionsToExecute[exportType] as ConsoleExportOptions;
|
|
string consoleRepositoryRoot = _exportEventsHandler.RegisterExportTypeAndGetRootPath(exportType, consoleExportOptions, repositoryType);
|
|
|
|
hasExportSucceeded &= await _exportService.ExportConsoleLocalizationAsync(dataToExport, consoleExportOptions, consoleRepositoryRoot, _progressWithValueCallback);
|
|
break;
|
|
|
|
case ExportType.MCA:
|
|
MCAExportOptions mcaExportOptions = exportTypesAndOptionsToExecute[exportType] as MCAExportOptions;
|
|
string mcaRepositoryRoot = _exportEventsHandler.RegisterExportTypeAndGetRootPath(exportType, mcaExportOptions, repositoryType);
|
|
|
|
hasExportSucceeded &= await _exportService.ExportMCALocalizationAsync(dataToExport, mcaExportOptions, mcaRepositoryRoot, _progressWithValueCallback);
|
|
break;
|
|
|
|
case ExportType.Online:
|
|
OnlineExportOptions onlineExportOptions = exportTypesAndOptionsToExecute[exportType] as OnlineExportOptions;
|
|
string onlineRepositoryRoot = _exportEventsHandler.RegisterExportTypeAndGetRootPath(exportType, onlineExportOptions, repositoryType);
|
|
|
|
hasExportSucceeded &= await _exportService.ExportOnlineLocalizationAsync(dataToExport, onlineExportOptions, onlineRepositoryRoot, _progressWithValueCallback);
|
|
break;
|
|
|
|
default:
|
|
_logger.Error($"Unknown export type '{exportType}': check {_exportService.ConfigPath}");
|
|
hasExportSucceeded = false;
|
|
break;
|
|
}
|
|
|
|
if (!hasExportSucceeded)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Error("Error during the export");
|
|
_logger.Error(e.Message);
|
|
_logger.Error(e.StackTrace);
|
|
hasExportSucceeded = false;
|
|
}
|
|
|
|
if (hasExportSucceeded)
|
|
{
|
|
string successfulExportMessage = "Export successful";
|
|
ShowSuccess(successfulExportMessage);
|
|
_logger.Info(successfulExportMessage);
|
|
}
|
|
else
|
|
{
|
|
ShowFailure("Export failed: read the Output logs for more details");
|
|
}
|
|
|
|
IsUIEnabled = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Command implementation
|
|
|
|
private async void RefreshLocalisationData()
|
|
{
|
|
await RefreshLocalizationDataAsync().ConfigureAwait(false);
|
|
}
|
|
|
|
private async Task RefreshLocalizationDataAsync()
|
|
{
|
|
string loadingMessage = _rootNode != null ? "Refreshing localization data..." : "Loading localization data...";
|
|
ShowInitialization(loadingMessage);
|
|
_logger.Info(loadingMessage);
|
|
|
|
IsUIEnabled = false;
|
|
RootNode = null; // Resets the tree UI
|
|
|
|
IEnumerable<LocalizedLine> localizedLines = null;
|
|
bool hasRefreshedOasisDataSuccessfully = true;
|
|
|
|
try
|
|
{
|
|
localizedLines = await _oasisService.GetLocalizedLinesAsync(_progressCallback).ConfigureAwait(false);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Error("Error while loading Oasis data:");
|
|
_logger.Error(e.Message);
|
|
_logger.Error(e.StackTrace);
|
|
hasRefreshedOasisDataSuccessfully = false;
|
|
}
|
|
|
|
if (hasRefreshedOasisDataSuccessfully)
|
|
{
|
|
try
|
|
{
|
|
_progressCallback.Report("Updating tree display...");
|
|
await Task.Run(() => GenerateTreeFromLines(localizedLines)).ConfigureAwait(false);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Error("Error while generating tree display from Oasis data:");
|
|
_logger.Error(e.Message);
|
|
_logger.Error(e.StackTrace);
|
|
hasRefreshedOasisDataSuccessfully = false;
|
|
}
|
|
}
|
|
|
|
if (hasRefreshedOasisDataSuccessfully)
|
|
{
|
|
RootNode.IsExpanded = true;
|
|
|
|
string successfulLoadingMessage = "Localization data loaded successfully";
|
|
ShowSuccess(successfulLoadingMessage);
|
|
_logger.Info(successfulLoadingMessage);
|
|
}
|
|
else
|
|
{
|
|
ShowFailure("Localization data load failed: read the Output logs for more details");
|
|
}
|
|
|
|
IsUIEnabled = true;
|
|
}
|
|
|
|
private void GenerateTreeFromLines(IEnumerable<LocalizedLine> lines, bool areLinesChecked = true)
|
|
{
|
|
string rootNodePath = string.Empty;
|
|
FolderTreeNodeViewModel tempRootNode = new FolderTreeNodeViewModel("Check/Uncheck All", rootNodePath, areLinesChecked);
|
|
Dictionary<string, OasisTreeNodeViewModel> nodeByPaths = new Dictionary<string, OasisTreeNodeViewModel>();
|
|
nodeByPaths[tempRootNode.Path] = tempRootNode;
|
|
|
|
LocalizedLine[] lineArray = lines.OrderBy(l => l.Path).ToArray();
|
|
NodeList = new List<FileTreeNodeViewModel>(lineArray.Length);
|
|
|
|
char separator = '/';
|
|
char[] separators = { separator };
|
|
foreach (LocalizedLine line in lines.OrderBy(l => l.Path))
|
|
{
|
|
string[] pathTokens = line.Path.Split(separators);
|
|
string partialPath = rootNodePath;
|
|
for (int i = 0; i < pathTokens.Length - 1; ++i)
|
|
{
|
|
string previousPartialPath = partialPath;
|
|
string folderName = pathTokens[i];
|
|
partialPath += separator + folderName;
|
|
|
|
if (!nodeByPaths.ContainsKey(partialPath))
|
|
{
|
|
FolderTreeNodeViewModel newFolderNode = new FolderTreeNodeViewModel(pathTokens[i], partialPath, areLinesChecked);
|
|
nodeByPaths[partialPath] = newFolderNode;
|
|
nodeByPaths[previousPartialPath].Children.Add(newFolderNode);
|
|
}
|
|
}
|
|
|
|
FileTreeNodeViewModel newLineNode = new FileTreeNodeViewModel(line, pathTokens[pathTokens.Length - 1], areLinesChecked);
|
|
nodeByPaths[line.Path] = newLineNode;
|
|
nodeByPaths[partialPath].Children.Add(newLineNode);
|
|
NodeList.Add(newLineNode);
|
|
}
|
|
|
|
RootNode = tempRootNode;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
// TODO: Update TaskManager with these methods to use it instead of letting them here
|
|
#region Status Bar
|
|
|
|
private static readonly TimeSpan TemporaryMessageDuration = TimeSpan.FromSeconds(4);
|
|
private const string IdleMessage = "Ready";
|
|
|
|
private void ShowInitialization(string message)
|
|
{
|
|
_statusBarManager.ResetDefaultBackgroundColor();
|
|
_statusBarManager.SetMessage(message);
|
|
_statusBarManager.SetProgressVisible(true);
|
|
_statusBarManager.SetProgressIndeterminate(true);
|
|
}
|
|
|
|
private void ShowSuccess(string successMessage)
|
|
{
|
|
_statusBarManager.SetProgressVisible(false);
|
|
_statusBarManager.ResetDefaultBackgroundColor();
|
|
_statusBarManager.SetMessage(IdleMessage);
|
|
_statusBarManager.SetMessage(successMessage, TemporaryMessageDuration, Colors.Green);
|
|
|
|
_notificationManager.ShowSuccess(successMessage);
|
|
}
|
|
|
|
private void ShowFailure(string errorMessage)
|
|
{
|
|
_statusBarManager.SetProgressVisible(false);
|
|
_statusBarManager.ResetDefaultBackgroundColor();
|
|
_statusBarManager.SetMessage(IdleMessage);
|
|
_statusBarManager.SetMessage(errorMessage, TemporaryMessageDuration, Colors.Red);
|
|
|
|
_notificationManager.ShowError(errorMessage);
|
|
}
|
|
|
|
private void ShowProgress(string progressMessage, int progressValue)
|
|
{
|
|
_statusBarManager.SetProgressVisible(true);
|
|
|
|
if (progressValue < 0)
|
|
{
|
|
_statusBarManager.SetProgressIndeterminate(true);
|
|
}
|
|
else
|
|
{
|
|
_statusBarManager.SetProgressIndeterminate(false);
|
|
_statusBarManager.SetProgress(progressValue);
|
|
}
|
|
_statusBarManager.SetMessage(progressMessage);
|
|
}
|
|
|
|
private readonly IProgress<string> _progressCallback;
|
|
private readonly IProgress<Tuple<string, int>> _progressWithValueCallback;
|
|
|
|
#endregion
|
|
}
|
|
} |