Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/po/Makefile.am2
-rw-r--r--main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationNodeBuilder.cs2
-rw-r--r--main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationProjectNodeBuilder.cs2
-rw-r--r--main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/GettextTool.cs10
-rw-r--r--main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs950
5 files changed, 487 insertions, 479 deletions
diff --git a/main/po/Makefile.am b/main/po/Makefile.am
index 0b44e025eb..14d6750416 100644
--- a/main/po/Makefile.am
+++ b/main/po/Makefile.am
@@ -11,7 +11,7 @@ MO_FILES = $(foreach po,$(FILES), $(INSTALL_DIR)/$(basename $(po))/LC_MESSAGES/$
all: $(GMO_FILES) post-strip-mnemonics
update-po:
- $(MDTOOL_RUN) gettext-update -f:$(top_srcdir)/Main.sln
+ $(MDTOOL_RUN) gettext-update --sort -f:$(top_srcdir)/Main.sln
$(GMO_FILES): $(LC_BUILD)/%/LC_MESSAGES/$(PACKAGE).mo: %.po strip-mnemonics
$(MKDIR_P) $(dir $@)
diff --git a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationNodeBuilder.cs b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationNodeBuilder.cs
index 04f0d6d85f..74a5a2c965 100644
--- a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationNodeBuilder.cs
@@ -131,7 +131,7 @@ namespace MonoDevelop.Gettext.NodeBuilders
void UpdateTranslationsAsync (ProgressMonitor monitor, TranslationProject project, Translation translation)
{
try {
- project.UpdateTranslations (monitor, translation);
+ project.UpdateTranslations (monitor, false, translation);
Gtk.Application.Invoke ((o, args) => {
POEditorWidget.ReloadWidgets ();
});
diff --git a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationProjectNodeBuilder.cs b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationProjectNodeBuilder.cs
index e6cc4c2e18..01e255d42a 100644
--- a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationProjectNodeBuilder.cs
+++ b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext.NodeBuilders/TranslationProjectNodeBuilder.cs
@@ -162,7 +162,7 @@ namespace MonoDevelop.Gettext.NodeBuilders
void UpdateTranslationsAsync (ProgressMonitor monitor, TranslationProject project)
{
try {
- project.UpdateTranslations (monitor);
+ project.UpdateTranslations (monitor, false);
Gtk.Application.Invoke ((o, args) => {
POEditorWidget.ReloadWidgets ();
});
diff --git a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/GettextTool.cs b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/GettextTool.cs
index 5be0513971..6baf226108 100644
--- a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/GettextTool.cs
+++ b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/GettextTool.cs
@@ -41,6 +41,7 @@ namespace MonoDevelop.Gettext
bool help;
string file;
string project;
+ bool sort;
public async Task<int> Run (string[] arguments)
{
@@ -54,6 +55,7 @@ namespace MonoDevelop.Gettext
Console.WriteLine ("gettext-update [options] [project-file]");
Console.WriteLine ("--f --file:FILE Project or solution file to build.");
Console.WriteLine ("--p --project:PROJECT Name of the project to build.");
+ Console.WriteLine ("--sort Sorts the output po file");
Console.WriteLine ();
return 0;
}
@@ -99,11 +101,11 @@ namespace MonoDevelop.Gettext
Console.WriteLine ("The project '" + item.FileName + "' is not a translation project");
return 1;
}
- tp.UpdateTranslations (monitor);
+ tp.UpdateTranslations (monitor, sort);
}
else {
foreach (TranslationProject p in solution.GetAllItems <TranslationProject>())
- p.UpdateTranslations (monitor);
+ p.UpdateTranslations (monitor, sort);
}
return 0;
@@ -151,6 +153,10 @@ namespace MonoDevelop.Gettext
project = value;
break;
+ case "sort":
+ sort = true;
+ break;
+
default:
throw new Exception("Unknown option '" + option + "'");
}
diff --git a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs
index 14e4396528..4cfaf6d88c 100644
--- a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs
+++ b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs
@@ -1,475 +1,477 @@
-//
-// TranslationProject.cs
-//
-// Author:
-// Mike Krüger <mkrueger@novell.com>
-//
-// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Xml;
-
-using MonoDevelop.Core;
-using MonoDevelop.Projects;
-using MonoDevelop.Core.Serialization;
-using MonoDevelop.Deployment;
-using MonoDevelop.Ide;
-using MonoDevelop.Core.Execution;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace MonoDevelop.Gettext
-{
- class TranslationProject : Project, IDeployable
- {
- [ItemProperty("packageName")]
- string packageName = null;
-
- [ItemProperty("outputType")]
- TranslationOutputType outputType;
-
- [ItemProperty(Name = "relPath", DefaultValue = "")]
- string relPath = String.Empty;
-
- bool isDirty;
-
- public string PackageName {
- get { return packageName; }
- set { packageName = value; }
- }
-
- public string RelPath {
- get { return relPath; }
- set { relPath = value; }
- }
-
- public TranslationOutputType OutputType {
- get { return outputType; }
- set { outputType = value; }
- }
-
- TranslationCollection translations;
-
- [ItemProperty]
- List<TranslationProjectInformation> projectInformations = new List<TranslationProjectInformation> ();
-
- [ItemProperty ("translations")]
- public TranslationCollection Translations {
- get { return translations; }
- }
-
- public ReadOnlyCollection<TranslationProjectInformation> TranslationProjectInformations {
- get { return projectInformations.AsReadOnly (); }
- }
-
- public TranslationProject ()
- {
- Initialize (this);
- translations = new TranslationCollection (this);
- }
-
- protected override IEnumerable<FilePath> OnGetItemFiles (bool includeReferencedFiles)
+//
+// TranslationProject.cs
+//
+// Author:
+// Mike Krüger <mkrueger@novell.com>
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Xml;
+
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Core.Serialization;
+using MonoDevelop.Deployment;
+using MonoDevelop.Ide;
+using MonoDevelop.Core.Execution;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace MonoDevelop.Gettext
+{
+ class TranslationProject : Project, IDeployable
+ {
+ [ItemProperty("packageName")]
+ string packageName = null;
+
+ [ItemProperty("outputType")]
+ TranslationOutputType outputType;
+
+ [ItemProperty(Name = "relPath", DefaultValue = "")]
+ string relPath = String.Empty;
+
+ bool isDirty;
+
+ public string PackageName {
+ get { return packageName; }
+ set { packageName = value; }
+ }
+
+ public string RelPath {
+ get { return relPath; }
+ set { relPath = value; }
+ }
+
+ public TranslationOutputType OutputType {
+ get { return outputType; }
+ set { outputType = value; }
+ }
+
+ TranslationCollection translations;
+
+ [ItemProperty]
+ List<TranslationProjectInformation> projectInformations = new List<TranslationProjectInformation> ();
+
+ [ItemProperty ("translations")]
+ public TranslationCollection Translations {
+ get { return translations; }
+ }
+
+ public ReadOnlyCollection<TranslationProjectInformation> TranslationProjectInformations {
+ get { return projectInformations.AsReadOnly (); }
+ }
+
+ public TranslationProject ()
{
- List<FilePath> col = base.OnGetItemFiles (includeReferencedFiles).ToList();
- if (includeReferencedFiles) {
- foreach (Translation tr in translations)
- col.Add (tr.PoFile);
- }
- return col;
- }
-
- public TranslationProjectInformation GetProjectInformation (SolutionFolderItem entry, bool force)
- {
- foreach (TranslationProjectInformation info in this.projectInformations) {
- if (info.ProjectName == entry.Name)
- return info;
- }
- if (force) {
- TranslationProjectInformation newInfo = new TranslationProjectInformation (entry.Name);
- this.projectInformations.Add (newInfo);
- return newInfo;
- }
- return null;
- }
-
- public bool IsIncluded (SolutionFolderItem entry)
- {
- TranslationProjectInformation info = GetProjectInformation (entry, false);
- if (info != null)
- return info.IsIncluded;
- return true;
- }
-
- protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
- {
- //NOTE: we don't really need multiple configurations for this project type, since nothing actually uses them
- //but it makes the solution configuration mapping look more consistent
- //Perhaps in future there will be some per-config settings
- foreach (string config in new [] { "Debug", "Release"})
- Configurations.Add (new TranslationProjectConfiguration (config));
-
- OutputType = (TranslationOutputType)Enum.Parse (typeof(TranslationOutputType), template.GetAttribute ("outputType"));
- PackageName = template.GetAttribute ("packageName");
- RelPath = template.GetAttribute ("relPath");
- }
-
- string GetFileName (string isoCode)
- {
- return Path.Combine (base.BaseDirectory, isoCode + ".po");
- }
-
- public class MatchLocation
- {
- string originalString;
- string originalPluralString;
- int line;
-
- public string OriginalString {
- get { return originalString; }
- }
-
- public string OriginalPluralString {
- get { return originalPluralString; }
- }
-
- public int Line {
- get { return line; }
- }
-
- public MatchLocation (string originalString, string originalPluralString, int line)
- {
- this.originalString = originalString;
- this.originalPluralString = originalPluralString;
- this.line = line;
- }
-
- public MatchLocation (string originalString, int line) : this (originalString, null, line)
- {
- }
- }
-
-
- public Translation AddNewTranslation (string isoCode, ProgressMonitor monitor)
- {
- try {
- Translation tr = new Translation (this, isoCode);
- translations.Add (tr);
- string templateFile = Path.Combine (this.BaseDirectory, "messages.po");
- string translationFile = GetFileName (isoCode);
- if (!File.Exists (templateFile))
- CreateDefaultCatalog (monitor);
- File.Copy (templateFile, translationFile);
-
- monitor.ReportSuccess (String.Format (GettextCatalog.GetString ("Language '{0}' successfully added."), isoCode));
- monitor.Step (1);
- SaveAsync (monitor);
- return tr;
- } catch (Exception e) {
- monitor.ReportError (String.Format ( GettextCatalog.GetString ("Language '{0}' could not be added: "), isoCode), e);
- return null;
- } finally {
- monitor.EndTask ();
- }
- }
-
- public Translation GetTranslation (string isoCode)
- {
- foreach (Translation translation in this.translations) {
- if (translation.IsoCode == isoCode)
- return translation;
- }
- return null;
- }
-
- public void RemoveTranslation (string isoCode)
- {
- Translation translation = GetTranslation (isoCode);
- if (translation != null)
- this.translations.Remove (translation);
- }
-
- internal void NotifyTranslationAdded (Translation tr)
- {
- if (!Loading)
- isDirty = true;
- OnTranslationAdded (EventArgs.Empty);
- }
-
- internal void NotifyTranslationRemoved (Translation tr)
- {
- isDirty = true;
- OnTranslationRemoved (EventArgs.Empty);
- }
-
- protected override SolutionItemConfiguration OnCreateConfiguration (string name, ConfigurationKind kind)
- {
- return new TranslationProjectConfiguration (name);
- }
-
- internal string GetOutputDirectory (ConfigurationSelector configuration)
- {
- if (this.ParentSolution.StartupItem == null)
- return BaseDirectory;
- if (this.ParentSolution.StartupItem is DotNetProject) {
- return Path.Combine (Path.GetDirectoryName (((DotNetProject)ParentSolution.StartupItem).GetOutputFileName (configuration)), RelPath);
- }
- return Path.Combine (this.ParentSolution.StartupItem.BaseDirectory, RelPath);
- }
-
- void CreateDefaultCatalog (ProgressMonitor monitor)
- {
- IFileScanner[] scanners = TranslationService.GetFileScanners ();
-
- Catalog catalog = new Catalog (this);
- List<Project> projects = new List<Project> ();
- foreach (Project p in ParentSolution.GetAllProjects ()) {
- if (IsIncluded (p))
- projects.Add (p);
- }
- foreach (Project p in projects) {
- monitor.Log.WriteLine (GettextCatalog.GetString ("Scanning project {0}...", p.Name));
- foreach (ProjectFile file in p.Files) {
- if (!File.Exists (file.FilePath))
- continue;
- if (file.Subtype == Subtype.Code) {
- string mimeType = DesktopService.GetMimeTypeForUri (file.FilePath);
- foreach (IFileScanner fs in scanners) {
- if (fs.CanScan (this, catalog, file.FilePath, mimeType))
- fs.UpdateCatalog (this, catalog, monitor, file.FilePath);
- }
- }
- }
- if (monitor.CancellationToken.IsCancellationRequested)
- return;
- monitor.Step (1);
- }
- catalog.Save (Path.Combine (this.BaseDirectory, "messages.po"));
- }
-
- public void UpdateTranslations (ProgressMonitor monitor)
- {
- UpdateTranslations (monitor, translations.ToArray ());
- }
-
- public void UpdateTranslations (ProgressMonitor monitor, params Translation[] translations)
- {
- monitor.BeginTask (null, Translations.Count + 1);
-
- try {
- List<Project> projects = new List<Project> ();
- foreach (Project p in ParentSolution.GetAllProjects ()) {
- if (IsIncluded (p))
- projects.Add (p);
- }
- monitor.BeginTask (GettextCatalog.GetString ("Updating message catalog"), projects.Count);
- CreateDefaultCatalog (monitor);
- monitor.Log.WriteLine (GettextCatalog.GetString ("Done"));
- } finally {
- monitor.EndTask ();
- monitor.Step (1);
- }
- if (monitor.CancellationToken.IsCancellationRequested) {
- monitor.Log.WriteLine (GettextCatalog.GetString ("Operation cancelled."));
- return;
- }
-
- Dictionary<string, bool> isIncluded = new Dictionary<string, bool> ();
- foreach (Translation translation in translations) {
- isIncluded[translation.IsoCode] = true;
- }
- foreach (Translation translation in this.Translations) {
- if (!isIncluded.ContainsKey (translation.IsoCode))
- continue;
- string poFileName = translation.PoFile;
- monitor.BeginTask (GettextCatalog.GetString ("Updating {0}", translation.PoFile), 1);
- try {
- var pb = new ProcessArgumentBuilder ();
- pb.Add ("-U");
- pb.AddQuoted (poFileName);
- pb.Add ("-v");
- pb.AddQuoted (this.BaseDirectory.Combine ("messages.po"));
-
- var process = Runtime.ProcessService.StartProcess (Translation.GetTool ("msgmerge"),
- pb.ToString (), this.BaseDirectory, monitor.Log, monitor.Log, null);
- process.WaitForOutput ();
- }
- catch (System.ComponentModel.Win32Exception) {
- var msg = GettextCatalog.GetString ("Did not find msgmerge. Please ensure that gettext tools are installed.");
- monitor.ReportError (msg, null);
- }
- catch (Exception ex) {
- monitor.ReportError (GettextCatalog.GetString ("Could not update file {0}", translation.PoFile), ex);
- }
- finally {
- monitor.EndTask ();
- monitor.Step (1);
- }
- if (monitor.CancellationToken.IsCancellationRequested) {
- monitor.Log.WriteLine (GettextCatalog.GetString ("Operation cancelled."));
- return;
- }
- }
- }
- public void RemoveEntry (string msgstr)
- {
- foreach (Translation translation in this.Translations) {
- string poFileName = translation.PoFile;
- Catalog catalog = new Catalog (this);
- catalog.Load (new MonoDevelop.Core.ProgressMonitor (), poFileName);
- CatalogEntry entry = catalog.FindItem (msgstr);
- if (entry != null) {
- catalog.RemoveItem (entry);
- catalog.Save (poFileName);
- }
- }
- }
-
- protected async override Task<BuildResult> OnBuild (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
- {
- var toBuild = Translations.Where (t => t.NeedsBuilding(configuration)).ToArray ();
- BuildResult results = new BuildResult ("", 1, 0);
- string outputDirectory = GetOutputDirectory (configuration);
- if (!string.IsNullOrEmpty (outputDirectory)) {
- await Task.Run (delegate {
- foreach (Translation translation in toBuild) {
- if (translation.NeedsBuilding (configuration)) {
- BuildResult res = translation.Build (monitor, configuration);
- results.Append (res);
- }
- }
- isDirty = false;
- });
- }
- return results;
- }
-
- protected async override Task<BuildResult> OnClean (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
- {
- isDirty = true;
- monitor.Log.WriteLine (GettextCatalog.GetString ("Removing all .mo files."));
- string outputDirectory = GetOutputDirectory (configuration);
- if (string.IsNullOrEmpty (outputDirectory))
- return BuildResult.CreateSuccess ();
-
- var toClean = Translations.Select (t => t.GetOutFile (configuration)).ToArray ();
- await Task.Run (delegate {
- foreach (string moFileName in toClean) {
- if (File.Exists (moFileName))
- File.Delete (moFileName);
- }
- });
- return BuildResult.CreateSuccess ();
- }
-
-#region Deployment
- public DeployFileCollection GetDeployFiles (ConfigurationSelector configuration)
- {
- DeployFileCollection result = new DeployFileCollection ();
- foreach (Translation translation in this.Translations) {
- if (OutputType == TranslationOutputType.SystemPath) {
- string moDirectory = Path.Combine ("locale", translation.IsoCode);
- moDirectory = Path.Combine (moDirectory, "LC_MESSAGES");
- string moFileName = Path.Combine (moDirectory, PackageName + ".mo");
- result.Add (new DeployFile (this, translation.GetOutFile (configuration), moFileName, TargetDirectory.CommonApplicationDataRoot));
- } else {
- string moDirectory = Path.Combine (RelPath, translation.IsoCode);
- moDirectory = Path.Combine (moDirectory, "LC_MESSAGES");
- string moFileName = Path.Combine (moDirectory, PackageName + ".mo");
- result.Add (new DeployFile (this, translation.GetOutFile (configuration), moFileName, TargetDirectory.ProgramFiles));
- }
- }
- return result;
- }
-#endregion
-
- protected override bool OnGetNeedsBuilding (ConfigurationSelector configuration)
- {
- if (isDirty)
- return true;
- foreach (Translation translation in this.Translations) {
- if (translation.NeedsBuilding (configuration))
- return true;
- }
- return false;
- }
-
- protected virtual void OnTranslationAdded (EventArgs e)
- {
- if (TranslationAdded != null)
- TranslationAdded (this, e);
- }
-
- public event EventHandler TranslationAdded;
-
- protected virtual void OnTranslationRemoved (EventArgs e)
- {
- if (TranslationRemoved != null)
- TranslationRemoved (this, e);
- }
-
- public event EventHandler TranslationRemoved;
- }
-
- enum TranslationOutputType {
- RelativeToOutput,
- SystemPath
- }
-
- class TranslationProjectConfiguration : ProjectConfiguration
- {
- public TranslationProjectConfiguration (string id): base (id)
- {
- }
- }
-
- class TranslationProjectInformation
- {
- [ItemProperty]
- string projectName;
-
- [ItemProperty]
- bool isIncluded;
-
- public string ProjectName {
- get { return projectName; }
- set { projectName = value; }
- }
-
- public bool IsIncluded {
- get { return isIncluded; }
- set { isIncluded = value; }
- }
-
- public TranslationProjectInformation ()
- {
- }
-
- public TranslationProjectInformation (string projectName)
- {
- this.projectName = projectName;
- }
- }
-}
+ Initialize (this);
+ translations = new TranslationCollection (this);
+ }
+
+ protected override IEnumerable<FilePath> OnGetItemFiles (bool includeReferencedFiles)
+ {
+ List<FilePath> col = base.OnGetItemFiles (includeReferencedFiles).ToList();
+ if (includeReferencedFiles) {
+ foreach (Translation tr in translations)
+ col.Add (tr.PoFile);
+ }
+ return col;
+ }
+
+ public TranslationProjectInformation GetProjectInformation (SolutionFolderItem entry, bool force)
+ {
+ foreach (TranslationProjectInformation info in this.projectInformations) {
+ if (info.ProjectName == entry.Name)
+ return info;
+ }
+ if (force) {
+ TranslationProjectInformation newInfo = new TranslationProjectInformation (entry.Name);
+ this.projectInformations.Add (newInfo);
+ return newInfo;
+ }
+ return null;
+ }
+
+ public bool IsIncluded (SolutionFolderItem entry)
+ {
+ TranslationProjectInformation info = GetProjectInformation (entry, false);
+ if (info != null)
+ return info.IsIncluded;
+ return true;
+ }
+
+ protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
+ {
+ //NOTE: we don't really need multiple configurations for this project type, since nothing actually uses them
+ //but it makes the solution configuration mapping look more consistent
+ //Perhaps in future there will be some per-config settings
+ foreach (string config in new [] { "Debug", "Release"})
+ Configurations.Add (new TranslationProjectConfiguration (config));
+
+ OutputType = (TranslationOutputType)Enum.Parse (typeof(TranslationOutputType), template.GetAttribute ("outputType"));
+ PackageName = template.GetAttribute ("packageName");
+ RelPath = template.GetAttribute ("relPath");
+ }
+
+ string GetFileName (string isoCode)
+ {
+ return Path.Combine (base.BaseDirectory, isoCode + ".po");
+ }
+
+ public class MatchLocation
+ {
+ string originalString;
+ string originalPluralString;
+ int line;
+
+ public string OriginalString {
+ get { return originalString; }
+ }
+
+ public string OriginalPluralString {
+ get { return originalPluralString; }
+ }
+
+ public int Line {
+ get { return line; }
+ }
+
+ public MatchLocation (string originalString, string originalPluralString, int line)
+ {
+ this.originalString = originalString;
+ this.originalPluralString = originalPluralString;
+ this.line = line;
+ }
+
+ public MatchLocation (string originalString, int line) : this (originalString, null, line)
+ {
+ }
+ }
+
+
+ public Translation AddNewTranslation (string isoCode, ProgressMonitor monitor)
+ {
+ try {
+ Translation tr = new Translation (this, isoCode);
+ translations.Add (tr);
+ string templateFile = Path.Combine (this.BaseDirectory, "messages.po");
+ string translationFile = GetFileName (isoCode);
+ if (!File.Exists (templateFile))
+ CreateDefaultCatalog (monitor);
+ File.Copy (templateFile, translationFile);
+
+ monitor.ReportSuccess (String.Format (GettextCatalog.GetString ("Language '{0}' successfully added."), isoCode));
+ monitor.Step (1);
+ SaveAsync (monitor);
+ return tr;
+ } catch (Exception e) {
+ monitor.ReportError (String.Format ( GettextCatalog.GetString ("Language '{0}' could not be added: "), isoCode), e);
+ return null;
+ } finally {
+ monitor.EndTask ();
+ }
+ }
+
+ public Translation GetTranslation (string isoCode)
+ {
+ foreach (Translation translation in this.translations) {
+ if (translation.IsoCode == isoCode)
+ return translation;
+ }
+ return null;
+ }
+
+ public void RemoveTranslation (string isoCode)
+ {
+ Translation translation = GetTranslation (isoCode);
+ if (translation != null)
+ this.translations.Remove (translation);
+ }
+
+ internal void NotifyTranslationAdded (Translation tr)
+ {
+ if (!Loading)
+ isDirty = true;
+ OnTranslationAdded (EventArgs.Empty);
+ }
+
+ internal void NotifyTranslationRemoved (Translation tr)
+ {
+ isDirty = true;
+ OnTranslationRemoved (EventArgs.Empty);
+ }
+
+ protected override SolutionItemConfiguration OnCreateConfiguration (string name, ConfigurationKind kind)
+ {
+ return new TranslationProjectConfiguration (name);
+ }
+
+ internal string GetOutputDirectory (ConfigurationSelector configuration)
+ {
+ if (this.ParentSolution.StartupItem == null)
+ return BaseDirectory;
+ if (this.ParentSolution.StartupItem is DotNetProject) {
+ return Path.Combine (Path.GetDirectoryName (((DotNetProject)ParentSolution.StartupItem).GetOutputFileName (configuration)), RelPath);
+ }
+ return Path.Combine (this.ParentSolution.StartupItem.BaseDirectory, RelPath);
+ }
+
+ void CreateDefaultCatalog (ProgressMonitor monitor)
+ {
+ IFileScanner[] scanners = TranslationService.GetFileScanners ();
+
+ Catalog catalog = new Catalog (this);
+ List<Project> projects = new List<Project> ();
+ foreach (Project p in ParentSolution.GetAllProjects ()) {
+ if (IsIncluded (p))
+ projects.Add (p);
+ }
+ foreach (Project p in projects) {
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Scanning project {0}...", p.Name));
+ foreach (ProjectFile file in p.Files) {
+ if (!File.Exists (file.FilePath))
+ continue;
+ if (file.Subtype == Subtype.Code) {
+ string mimeType = DesktopService.GetMimeTypeForUri (file.FilePath);
+ foreach (IFileScanner fs in scanners) {
+ if (fs.CanScan (this, catalog, file.FilePath, mimeType))
+ fs.UpdateCatalog (this, catalog, monitor, file.FilePath);
+ }
+ }
+ }
+ if (monitor.CancellationToken.IsCancellationRequested)
+ return;
+ monitor.Step (1);
+ }
+ catalog.Save (Path.Combine (this.BaseDirectory, "messages.po"));
+ }
+
+ public void UpdateTranslations (ProgressMonitor monitor, bool sort)
+ {
+ UpdateTranslations (monitor, sort, translations.ToArray ());
+ }
+
+ public void UpdateTranslations (ProgressMonitor monitor, bool sort, params Translation[] translations)
+ {
+ monitor.BeginTask (null, Translations.Count + 1);
+
+ try {
+ List<Project> projects = new List<Project> ();
+ foreach (Project p in ParentSolution.GetAllProjects ()) {
+ if (IsIncluded (p))
+ projects.Add (p);
+ }
+ monitor.BeginTask (GettextCatalog.GetString ("Updating message catalog"), projects.Count);
+ CreateDefaultCatalog (monitor);
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Done"));
+ } finally {
+ monitor.EndTask ();
+ monitor.Step (1);
+ }
+ if (monitor.CancellationToken.IsCancellationRequested) {
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Operation cancelled."));
+ return;
+ }
+
+ Dictionary<string, bool> isIncluded = new Dictionary<string, bool> ();
+ foreach (Translation translation in translations) {
+ isIncluded[translation.IsoCode] = true;
+ }
+ foreach (Translation translation in this.Translations) {
+ if (!isIncluded.ContainsKey (translation.IsoCode))
+ continue;
+ string poFileName = translation.PoFile;
+ monitor.BeginTask (GettextCatalog.GetString ("Updating {0}", translation.PoFile), 1);
+ try {
+ var pb = new ProcessArgumentBuilder ();
+ pb.Add ("--update");
+ pb.AddQuoted (poFileName);
+ pb.Add ("--verbose");
+ if (sort)
+ pb.Add ("--sort-output");
+ pb.AddQuoted (this.BaseDirectory.Combine ("messages.po"));
+
+ var process = Runtime.ProcessService.StartProcess (Translation.GetTool ("msgmerge"),
+ pb.ToString (), this.BaseDirectory, monitor.Log, monitor.Log, null);
+ process.WaitForOutput ();
+ }
+ catch (System.ComponentModel.Win32Exception) {
+ var msg = GettextCatalog.GetString ("Did not find msgmerge. Please ensure that gettext tools are installed.");
+ monitor.ReportError (msg, null);
+ }
+ catch (Exception ex) {
+ monitor.ReportError (GettextCatalog.GetString ("Could not update file {0}", translation.PoFile), ex);
+ }
+ finally {
+ monitor.EndTask ();
+ monitor.Step (1);
+ }
+ if (monitor.CancellationToken.IsCancellationRequested) {
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Operation cancelled."));
+ return;
+ }
+ }
+ }
+ public void RemoveEntry (string msgstr)
+ {
+ foreach (Translation translation in this.Translations) {
+ string poFileName = translation.PoFile;
+ Catalog catalog = new Catalog (this);
+ catalog.Load (new MonoDevelop.Core.ProgressMonitor (), poFileName);
+ CatalogEntry entry = catalog.FindItem (msgstr);
+ if (entry != null) {
+ catalog.RemoveItem (entry);
+ catalog.Save (poFileName);
+ }
+ }
+ }
+
+ protected async override Task<BuildResult> OnBuild (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
+ {
+ var toBuild = Translations.Where (t => t.NeedsBuilding(configuration)).ToArray ();
+ BuildResult results = new BuildResult ("", 1, 0);
+ string outputDirectory = GetOutputDirectory (configuration);
+ if (!string.IsNullOrEmpty (outputDirectory)) {
+ await Task.Run (delegate {
+ foreach (Translation translation in toBuild) {
+ if (translation.NeedsBuilding (configuration)) {
+ BuildResult res = translation.Build (monitor, configuration);
+ results.Append (res);
+ }
+ }
+ isDirty = false;
+ });
+ }
+ return results;
+ }
+
+ protected async override Task<BuildResult> OnClean (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
+ {
+ isDirty = true;
+ monitor.Log.WriteLine (GettextCatalog.GetString ("Removing all .mo files."));
+ string outputDirectory = GetOutputDirectory (configuration);
+ if (string.IsNullOrEmpty (outputDirectory))
+ return BuildResult.CreateSuccess ();
+
+ var toClean = Translations.Select (t => t.GetOutFile (configuration)).ToArray ();
+ await Task.Run (delegate {
+ foreach (string moFileName in toClean) {
+ if (File.Exists (moFileName))
+ File.Delete (moFileName);
+ }
+ });
+ return BuildResult.CreateSuccess ();
+ }
+
+#region Deployment
+ public DeployFileCollection GetDeployFiles (ConfigurationSelector configuration)
+ {
+ DeployFileCollection result = new DeployFileCollection ();
+ foreach (Translation translation in this.Translations) {
+ if (OutputType == TranslationOutputType.SystemPath) {
+ string moDirectory = Path.Combine ("locale", translation.IsoCode);
+ moDirectory = Path.Combine (moDirectory, "LC_MESSAGES");
+ string moFileName = Path.Combine (moDirectory, PackageName + ".mo");
+ result.Add (new DeployFile (this, translation.GetOutFile (configuration), moFileName, TargetDirectory.CommonApplicationDataRoot));
+ } else {
+ string moDirectory = Path.Combine (RelPath, translation.IsoCode);
+ moDirectory = Path.Combine (moDirectory, "LC_MESSAGES");
+ string moFileName = Path.Combine (moDirectory, PackageName + ".mo");
+ result.Add (new DeployFile (this, translation.GetOutFile (configuration), moFileName, TargetDirectory.ProgramFiles));
+ }
+ }
+ return result;
+ }
+#endregion
+
+ protected override bool OnGetNeedsBuilding (ConfigurationSelector configuration)
+ {
+ if (isDirty)
+ return true;
+ foreach (Translation translation in this.Translations) {
+ if (translation.NeedsBuilding (configuration))
+ return true;
+ }
+ return false;
+ }
+
+ protected virtual void OnTranslationAdded (EventArgs e)
+ {
+ if (TranslationAdded != null)
+ TranslationAdded (this, e);
+ }
+
+ public event EventHandler TranslationAdded;
+
+ protected virtual void OnTranslationRemoved (EventArgs e)
+ {
+ if (TranslationRemoved != null)
+ TranslationRemoved (this, e);
+ }
+
+ public event EventHandler TranslationRemoved;
+ }
+
+ enum TranslationOutputType {
+ RelativeToOutput,
+ SystemPath
+ }
+
+ class TranslationProjectConfiguration : ProjectConfiguration
+ {
+ public TranslationProjectConfiguration (string id): base (id)
+ {
+ }
+ }
+
+ class TranslationProjectInformation
+ {
+ [ItemProperty]
+ string projectName;
+
+ [ItemProperty]
+ bool isIncluded;
+
+ public string ProjectName {
+ get { return projectName; }
+ set { projectName = value; }
+ }
+
+ public bool IsIncluded {
+ get { return isIncluded; }
+ set { isIncluded = value; }
+ }
+
+ public TranslationProjectInformation ()
+ {
+ }
+
+ public TranslationProjectInformation (string projectName)
+ {
+ this.projectName = projectName;
+ }
+ }
+}