/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt VS Tools. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.VCProjectEngine; using QtVsTools.Core; using QtVsTools.VisualStudio; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace QtVsTools { using static Core.HelperFunctions; using QtMsBuild; /// /// Run Qt translation tools by invoking the corresponding Qt/MSBuild targets /// public static class Translation { public static void RunlRelease(VCFile vcFile) { var vcProj = vcFile.project as VCProject; var project = vcProj?.Object as EnvDTE.Project; RunTranslationTarget(BuildAction.Release, project, new[] { vcFile.RelativePath }); } public static void RunlRelease(VCFile[] vcFiles) { var vcProj = vcFiles.FirstOrDefault()?.project as VCProject; var project = vcProj?.Object as EnvDTE.Project; RunTranslationTarget(BuildAction.Release, project, vcFiles.Select(vcFile => vcFile?.RelativePath)); } public static void RunlRelease(EnvDTE.Project project) { RunTranslationTarget(BuildAction.Release, project); } public static void RunlRelease(EnvDTE.Solution solution) { if (solution == null) return; foreach (var project in HelperFunctions.ProjectsInSolution(solution.DTE)) RunlRelease(project); } public static void RunlUpdate(VCFile vcFile) { var vcProj = vcFile.project as VCProject; var project = vcProj?.Object as EnvDTE.Project; RunTranslationTarget(BuildAction.Update, project, new[] { vcFile.RelativePath }); } public static void RunlUpdate(VCFile[] vcFiles) { var vcProj = vcFiles.FirstOrDefault()?.project as VCProject; var project = vcProj?.Object as EnvDTE.Project; RunTranslationTarget(BuildAction.Update, project, vcFiles.Select(vcFile => vcFile?.RelativePath)); } public static void RunlUpdate(EnvDTE.Project project) { RunTranslationTarget(BuildAction.Update, project); } enum BuildAction { Update, Release } static void RunTranslationTarget( BuildAction buildAction, EnvDTE.Project project, IEnumerable selectedFiles = null) { using (WaitDialog.Start( "Qt Visual Studio Tools", "Running translation tool...")) { var qtPro = QtProject.Create(project); if (project == null || qtPro == null) { Messages.Print( "translation: Error accessing project interface"); return; } if (qtPro.FormatVersion < Resources.qtMinFormatVersion_Settings) { Messages.Print("translation: Legacy project format"); try { Legacy_RunTranslation(buildAction, qtPro, selectedFiles); } catch (Exception e) { Messages.Print( e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace); } return; } var activeConfig = project.ConfigurationManager?.ActiveConfiguration; if (activeConfig == null) { Messages.Print( "translation: Error accessing build interface"); return; } var activeConfigId = string.Format("{0}|{1}", activeConfig.ConfigurationName, activeConfig.PlatformName); var target = "QtTranslation"; var properties = new Dictionary(); switch (buildAction) { case BuildAction.Update: properties["QtTranslationForceUpdate"] = "true"; break; case BuildAction.Release: properties["QtTranslationForceRelease"] = "true"; break; } if (selectedFiles != null) properties["SelectedFiles"] = string.Join(";", selectedFiles); QtProjectBuild.StartBuild(project, activeConfigId, properties, new[] { target }); } } public static void RunlUpdate(EnvDTE.Solution solution) { if (solution == null) return; foreach (var project in HelperFunctions.ProjectsInSolution(solution.DTE)) RunlUpdate(project); } static void Legacy_RunTranslation( BuildAction buildAction, QtProject qtProject, IEnumerable tsFiles) { if (tsFiles == null) { tsFiles = (qtProject.VCProject .GetFilesEndingWith(".ts") as IVCCollection) .Cast() .Select(vcFile => vcFile.RelativePath); if (tsFiles == null) { Messages.Print("translation: no translation files found"); return; } } string tempFile = null; foreach (var file in tsFiles.Where(file => file != null)) Legacy_RunTranslation(buildAction, qtProject, file, ref tempFile); } static void Legacy_RunTranslation( BuildAction buildAction, QtProject qtProject, string tsFile, ref string tempFile) { var qtVersion = qtProject.GetQtVersion(); var qtInstallPath = QtVersionManager.The().GetInstallPath(qtVersion); if (string.IsNullOrEmpty(qtInstallPath)) { Messages.Print("translation: Error accessing Qt installation"); return; } var procInfo = new ProcessStartInfo { WorkingDirectory = qtProject.ProjectDir, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, Arguments = "" }; switch (buildAction) { case BuildAction.Update: Messages.Print("\r\n--- (lupdate) file: " + tsFile); procInfo.FileName = Path.Combine(qtInstallPath, "bin", "lupdate.exe"); var options = QtVSIPSettings.GetLUpdateOptions(); if (!string.IsNullOrEmpty(options)) procInfo.Arguments += options + " "; if (tempFile == null) { var inputFiles = GetProjectFiles(qtProject.Project, FilesToList.FL_HFiles) .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_CppFiles)) .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_UiFiles)) .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_QmlFiles)); tempFile = Path.GetTempFileName(); File.WriteAllLines(tempFile, inputFiles); } procInfo.Arguments += string.Format("\"@{0}\" -ts \"{1}\"", tempFile, tsFile); break; case BuildAction.Release: Messages.Print("\r\n--- (lrelease) file: " + tsFile); procInfo.FileName = Path.Combine(qtInstallPath, "bin", "lrelease.exe"); options = QtVSIPSettings.GetLReleaseOptions(); if (!string.IsNullOrEmpty(options)) procInfo.Arguments += options + " "; procInfo.Arguments += string.Format("\"{0}\"", tsFile); break; } using (var proc = Process.Start(procInfo)) { proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) => { if (!string.IsNullOrEmpty(e.Data)) Messages.Print(e.Data); }; proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => { if (!string.IsNullOrEmpty(e.Data)) Messages.Print(e.Data); }; proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.WaitForExit(); switch (proc.ExitCode) { case 0: Messages.Print("translation: ok"); break; default: Messages.Print(string.Format("translation: ERROR {0}", proc.ExitCode)); break; } } } public static void CreateNewTranslationFile(EnvDTE.Project project) { if (project == null) return; using (var transDlg = new AddTranslationDialog(project)) { if (transDlg.ShowDialog() == DialogResult.OK) { try { var qtPro = QtProject.Create(project); var file = qtPro.AddFileInFilter(Filters.TranslationFiles(), transDlg.TranslationFile, true); RunlUpdate(file); } catch (QtVSException e) { Messages.DisplayErrorMessage(e.Message); } catch (System.Exception ex) { Messages.DisplayErrorMessage(ex.Message); } } } } } }