Skip to content
146 changes: 146 additions & 0 deletions INTERNATIONALIZATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Internationalization (i18n) Support

Majorsilence Reporting includes internationalization support for multiple languages through .NET resource files (.resx).

## Supported Languages

The following languages are currently supported:

- **English (en-US)** - Default/Base language
- **Russian (ru-RU)** - Full translation
- **French (fr)** - Partial translation
- **Spanish (es)** - NEW! Full translation with 453+ translated strings

## Language Configuration

### Setting the Language in the Report Designer

1. Open the Report Designer
2. Navigate to **Tools** → **Options**
3. In the **Desktop** tab, select your preferred language from the Language dropdown
4. Restart the application for changes to take effect

### Setting the Language Programmatically

The language is determined by the current thread's `CurrentCulture` and `CurrentUICulture`. You can set it in your application:

```csharp
using System.Globalization;
using System.Threading;

// Set Spanish as the UI language
var culture = new CultureInfo("es");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
```

For ASP.NET applications:

```csharp
using System.Globalization;

// In your Startup.cs or Program.cs
var supportedCultures = new[] { "en-US", "ru-RU", "fr", "es" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture("en-US")
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);
```

## Translation Coverage

### Spanish (es)

The es translation includes:

- ✅ **Core Engine** (RdlEngine) - Error messages, data processing strings
- ✅ **Report Viewer** (RdlViewer) - UI elements, viewer controls
- ✅ **Report Designer** (RdlDesign) - All designer dialogs and controls
- ✅ **Map Editor** (RdlMapFile) - Map file editor interface
- ✅ **Report Reader** (RdlReader) - Reader application UI

**Total: 453+ translated strings across 79 resource files**

Common translations include:
- UI buttons and menus (Open, Save, Close, Print, etc.)
- Error messages and warnings
- Report elements (Table, Chart, Matrix, Subreport, etc.)
- Data operations (Grouping, Sorting, Filtering, etc.)
- Formatting options (Font, Style, Border, Background, etc.)

## Adding a New Language

To add support for a new language:

1. **Identify the language code** (e.g., `de-DE` for German, `pt-BR` for Portuguese-Brazil)

2. **Copy existing resource files**: For each base `.resx` file, create a new file with your language code:
```
Strings.resx → Strings.[language-code].resx
```

3. **Translate strings**: Open the `.resx` files and translate the `<value>` elements while keeping the `<data name>` attributes unchanged.

4. **Test your translation**:
- Build the solution
- Set the culture in your application
- Verify translations appear correctly in the UI

5. **Submit a Pull Request**: Share your translation with the community!

## Resource File Locations

Resource files are located in the following directories:

- `RdlEngine/Resources/` - Core engine strings
- `RdlViewer/Resources/` - Viewer component strings
- `RdlDesign/Resources/` - Designer main strings
- `RdlDesign/*.resx` - Individual control/dialog translations
- `RdlMapFile/Resources/` - Map editor strings
- `RdlReader/Resources/` - Reader application strings
- `RdlDesktop/Resources/` - Desktop application strings

## Translation Guidelines

When contributing translations:

1. **Be consistent** with terminology across all resource files
2. **Use appropriate locale** conventions (date formats, number formats, etc.)
3. **Keep technical terms** in English when appropriate (e.g., SQL, HTML, XML)
4. **Preserve placeholders** like `{0}`, `{1}` in format strings
5. **Test thoroughly** especially with longer translations that might affect UI layout
6. **Consider cultural context** - use translations appropriate for the target region

## Known Issues

- Some UI elements may require application restart to display translated text
- Very long translations may cause layout issues in some dialogs
- Not all third-party controls support full internationalization

## Contributing

We welcome translations for new languages! Please see our [Contributing Guide](https://github.com/majorsilence/My-FyiReporting/wiki/Contribute) for more information.

To contribute a translation:

1. Fork the repository
2. Create a new branch for your translation
3. Add your translated resource files
4. Test the translation
5. Submit a pull request with a description of your changes

## Resources

- [.NET Globalization and Localization](https://docs.microsoft.com/en-us/dotnet/core/extensions/globalization-and-localization)
- [ResX Resource File Format](https://docs.microsoft.com/en-us/dotnet/framework/resources/creating-resource-files-for-desktop-apps#resources-in-resx-files)
- [CultureInfo Class](https://docs.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo)

## Support

If you have questions about internationalization or need help with translations:

- [Discussion Forum](https://groups.google.com/d/forum/myfyireporting)
- [GitHub Issues](https://github.com/majorsilence/My-FyiReporting/issues)
- [Wiki](https://github.com/majorsilence/My-FyiReporting/wiki)
141 changes: 141 additions & 0 deletions RdlDesign/BackgroundCtl.es.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?xml version='1.0' encoding='utf-8'?>
<root xmlns:ns1="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:schema id="root">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" />
<xs:element name="root" ns1:IsDataSet="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="metadata">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xsd:string" minOccurs="0" />
</xs:sequence>
<xs:attribute name="name" use="required" type="xsd:string" />
<xs:attribute name="type" type="xsd:string" />
<xs:attribute name="mimetype" type="xsd:string" />
<xs:attribute ref="xml:space" />
</xs:complexType>
</xs:element>
<xs:element name="assembly">
<xs:complexType>
<xs:attribute name="alias" type="xsd:string" />
<xs:attribute name="name" type="xsd:string" />
</xs:complexType>
</xs:element>
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xsd:string" minOccurs="0" ns1:Ordinal="1" />
<xs:element name="comment" type="xsd:string" minOccurs="0" ns1:Ordinal="2" />
</xs:sequence>
<xs:attribute name="name" type="xsd:string" use="required" ns1:Ordinal="1" />
<xs:attribute name="type" type="xsd:string" ns1:Ordinal="3" />
<xs:attribute name="mimetype" type="xsd:string" ns1:Ordinal="4" />
<xs:attribute ref="xml:space" />
</xs:complexType>
</xs:element>
<xs:element name="resheader">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xsd:string" minOccurs="0" ns1:Ordinal="1" />
</xs:sequence>
<xs:attribute name="name" type="xsd:string" use="required" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="label15.Size" type="System.Drawing.Size, System.Drawing">
<value>88, 16</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>End Color</value>
</data>
<data name="label10.Size" type="System.Drawing.Size, System.Drawing">
<value>74, 16</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>Degradado</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>Color</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Fondo</value>
</data>
<data name="groupBox2.Text" xml:space="preserve">
<value>Background Image Source</value>
</data>
<data name="bRepeatExpr.Location" type="System.Drawing.Point, System.Drawing">
<value>228, 184</value>
</data>
<data name="rbNone.Size" type="System.Drawing.Size, System.Drawing">
<value>90, 24</value>
</data>
<data name="rbNone.Text" xml:space="preserve">
<value>Ausente</value>
</data>
<data name="cbRepeat.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 184</value>
</data>
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
<value>74, 23</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Repetición</value>
</data>
<data name="bMimeExpr.Location" type="System.Drawing.Point, System.Drawing">
<value>198, 121</value>
</data>
<data name="tbValueExternal.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 55</value>
</data>
<data name="tbValueExternal.Size" type="System.Drawing.Size, System.Drawing">
<value>268, 20</value>
</data>
<data name="cbValueDatabase.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 151</value>
</data>
<data name="cbValueDatabase.Size" type="System.Drawing.Size, System.Drawing">
<value>268, 21</value>
</data>
<data name="cbMIMEType.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 119</value>
</data>
<data name="cbValueEmbedded.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 87</value>
</data>
<data name="cbValueEmbedded.Size" type="System.Drawing.Size, System.Drawing">
<value>268, 21</value>
</data>
<data name="rbDatabase.Size" type="System.Drawing.Size, System.Drawing">
<value>90, 24</value>
</data>
<data name="rbDatabase.Text" xml:space="preserve">
<value>Base de datos</value>
</data>
<data name="rbEmbedded.Size" type="System.Drawing.Size, System.Drawing">
<value>90, 24</value>
</data>
<data name="rbEmbedded.Text" xml:space="preserve">
<value>Incrustado</value>
</data>
<data name="rbExternal.Text" xml:space="preserve">
<value>Externo</value>
</data>
</root>
106 changes: 106 additions & 0 deletions RdlDesign/BodyCtl.es.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?xml version='1.0' encoding='utf-8'?>
<root xmlns:ns1="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:schema id="root">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" />
<xs:element name="root" ns1:IsDataSet="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="metadata">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xsd:string" minOccurs="0" />
</xs:sequence>
<xs:attribute name="name" use="required" type="xsd:string" />
<xs:attribute name="type" type="xsd:string" />
<xs:attribute name="mimetype" type="xsd:string" />
<xs:attribute ref="xml:space" />
</xs:complexType>
</xs:element>
<xs:element name="assembly">
<xs:complexType>
<xs:attribute name="alias" type="xsd:string" />
<xs:attribute name="name" type="xsd:string" />
</xs:complexType>
</xs:element>
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xsd:string" minOccurs="0" ns1:Ordinal="1" />
<xs:element name="comment" type="xsd:string" minOccurs="0" ns1:Ordinal="2" />
</xs:sequence>
<xs:attribute name="name" type="xsd:string" use="required" ns1:Ordinal="1" />
<xs:attribute name="type" type="xsd:string" ns1:Ordinal="3" />
<xs:attribute name="mimetype" type="xsd:string" ns1:Ordinal="4" />
<xs:attribute ref="xml:space" />
</xs:complexType>
</xs:element>
<xs:element name="resheader">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xsd:string" minOccurs="0" ns1:Ordinal="1" />
</xs:sequence>
<xs:attribute name="name" type="xsd:string" use="required" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
<value>119, 25</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Altura</value>
</data>
<data name="label1.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>TopRight</value>
</data>
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
<value>119, 61</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>Columns</value>
</data>
<data name="label2.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>TopRight</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="label3.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 96</value>
</data>
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
<value>172, 23</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>Column Spacing</value>
</data>
<data name="label3.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>TopRight</value>
</data>
<data name="tbHeight.Location" type="System.Drawing.Point, System.Drawing">
<value>181, 22</value>
</data>
<data name="tbColumns.Location" type="System.Drawing.Point, System.Drawing">
<value>181, 58</value>
</data>
<data name="tbColumnSpacing.Location" type="System.Drawing.Point, System.Drawing">
<value>181, 93</value>
</data>
</root>
Loading
Loading