diff --git a/dotnet/src/dotnetcore/DynService/Cosmos/DynService.CosmosDB.csproj b/dotnet/src/dotnetcore/DynService/Cosmos/DynService.CosmosDB.csproj index 0c61c7593..f2708f522 100644 --- a/dotnet/src/dotnetcore/DynService/Cosmos/DynService.CosmosDB.csproj +++ b/dotnet/src/dotnetcore/DynService/Cosmos/DynService.CosmosDB.csproj @@ -13,7 +13,7 @@ - + diff --git a/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj b/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj index d57e3d3ee..70c2f2130 100644 --- a/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj +++ b/dotnet/src/dotnetcore/DynService/OData/DynServiceOData.csproj @@ -13,7 +13,7 @@ - + diff --git a/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj b/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj index e95fc82c8..5d0f001d5 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj +++ b/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj @@ -29,8 +29,6 @@ - - diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index b2165e979..45c0084ac 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -63,6 +63,7 @@ + @@ -150,22 +151,35 @@ - - + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + - + @@ -174,7 +188,7 @@ - + diff --git a/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj b/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj index 916d3c26d..fbfaea64b 100644 --- a/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj +++ b/dotnet/src/dotnetcore/GxExcel/GxExcel.csproj @@ -18,7 +18,7 @@ - + diff --git a/dotnet/src/dotnetcore/GxMail/GxMail.csproj b/dotnet/src/dotnetcore/GxMail/GxMail.csproj index f8899a0f6..b5a0a100f 100644 --- a/dotnet/src/dotnetcore/GxMail/GxMail.csproj +++ b/dotnet/src/dotnetcore/GxMail/GxMail.csproj @@ -70,7 +70,7 @@ - + diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj b/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj index 522adb9f8..739dadc7b 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/GxNetCoreStartup.csproj @@ -11,17 +11,16 @@ - + - + - - - - - + + + + diff --git a/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj b/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj index 094c0b13e..37b853eee 100644 --- a/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj +++ b/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj @@ -37,6 +37,9 @@ + + + diff --git a/dotnet/src/dotnetcore/GxPdfReportsCS.Itext4/GxPdfReportsCS.Itext4.csproj b/dotnet/src/dotnetcore/GxPdfReportsCS.Itext4/GxPdfReportsCS.Itext4.csproj index a8587b269..5115da19f 100644 --- a/dotnet/src/dotnetcore/GxPdfReportsCS.Itext4/GxPdfReportsCS.Itext4.csproj +++ b/dotnet/src/dotnetcore/GxPdfReportsCS.Itext4/GxPdfReportsCS.Itext4.csproj @@ -15,14 +15,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/dotnet/src/dotnetcore/GxPdfReportsCS/GxPdfReportsCS.csproj b/dotnet/src/dotnetcore/GxPdfReportsCS/GxPdfReportsCS.csproj index 95fa355b4..d36958702 100644 --- a/dotnet/src/dotnetcore/GxPdfReportsCS/GxPdfReportsCS.csproj +++ b/dotnet/src/dotnetcore/GxPdfReportsCS/GxPdfReportsCS.csproj @@ -16,7 +16,7 @@ - + @@ -31,8 +31,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportPDFPig.cs b/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportPDFPig.cs index 0f1a30120..9a6f45587 100644 --- a/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportPDFPig.cs +++ b/dotnet/src/dotnetcore/GxPdfReportsCS/PDFReportPDFPig.cs @@ -1,9 +1,20 @@ using System; using System.Collections.Generic; +#if NETCORE +using GeneXus.Drawing; +using GeneXus.Drawing.Imaging; +using GeneXus.Drawing.Text; +using GeneXus.Drawing.Drawing2D; +using Color = GeneXus.Drawing.Color; +using Font = GeneXus.Drawing.Font; +#else using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Drawing.Text; +using Color = System.Drawing.Color; +using Font = System.Drawing.Font; +#endif using System.IO; using System.Net.Http; using System.Text; @@ -14,8 +25,6 @@ using static GeneXus.Utils.StringUtil; using static UglyToad.PdfPig.Writer.PdfDocumentBuilder; using static UglyToad.PdfPig.Writer.PdfPageBuilder; -using Color = System.Drawing.Color; -using Font = System.Drawing.Font; using PageSize = UglyToad.PdfPig.Content.PageSize; using PdfRectangle = UglyToad.PdfPig.Core.PdfRectangle; diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj index 5aebdae39..42e749e51 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureEventGrid/GXAzureEventGrid.csproj @@ -8,7 +8,7 @@ - + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj index 7ae7307f7..81c0958b9 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureQueue/GXAzureQueue.csproj @@ -8,7 +8,7 @@ - + diff --git a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj index 049e25bef..3e70edf34 100644 --- a/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj +++ b/dotnet/src/dotnetcore/Providers/Messaging/GXAzureServiceBus/GXAzureServiceBus.csproj @@ -8,7 +8,7 @@ - + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/GXOtel.Diagnostics.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/GXOtel.Diagnostics.csproj index ef080b861..dd8e4c2cb 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/GXOtel.Diagnostics.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/GXOtel.Diagnostics.csproj @@ -12,8 +12,7 @@ - - + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/OtelSpan.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/OtelSpan.cs index d05c93aa8..0bd11c1c9 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/OtelSpan.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/Diagnostics/GXOtel.Diagnostics/OtelSpan.cs @@ -44,7 +44,7 @@ public void Stop() } public void RecordException(string message) { - _activity?.RecordException(new Exception(message)); + _activity?.AddException(new Exception(message)); } public void SetStringAttribute(string property, string value) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj index 64f9fc9ee..12161778e 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj @@ -9,13 +9,13 @@ - - - - - - - + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs index 124a86da6..03c48f9c5 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs @@ -23,8 +23,11 @@ public static TracerProviderBuilder AddGxAspNetInstrumentation(this TracerProvid .AddSqlClientInstrumentation(opt => { opt.RecordException = true; - opt.EnableConnectionLevelAttributes = true; - opt.SetDbStatementForText = true; + // OpenTelemetry.Instrumentation.SqlClient 1.15+ removed EnableConnectionLevelAttributes + // and SetDbStatementForText. Connection-level attributes and db.statement text are + // now emitted by default following the stable OpenTelemetry semantic conventions + // (gated by OTEL_SEMCONV_STABILITY_OPT_IN at the consumer's runtime if needed). + // For finer control re-enable via EnrichWithSqlCommand and manual Activity tagging. }); string envvar = Environment.GetEnvironmentVariable("OTEL_TRACES_EXPORTER"); if (envvar != null && envvar.Contains("console")) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAzureMonitor/GeneXus.OpenTelemetry.Azure.AppInsights.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAzureMonitor/GeneXus.OpenTelemetry.Azure.AppInsights.csproj index b627b6bd5..97b0aafb9 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAzureMonitor/GeneXus.OpenTelemetry.Azure.AppInsights.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAzureMonitor/GeneXus.OpenTelemetry.Azure.AppInsights.csproj @@ -11,13 +11,13 @@ - - - + + + - - - + + + diff --git a/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.cs b/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.cs index 38db8239f..fa7882a2d 100644 --- a/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.cs +++ b/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.cs @@ -99,7 +99,7 @@ private void InitializeConnection() if (builder.TryGetValue("Data Source", out object url)) { serviceUri = url.ToString(); - clientSettings = new ODataClientSettings(serviceUri, credentials); + clientSettings = new ODataClientSettings(new Uri(serviceUri), credentials); clientSettings.IgnoreUnmappedProperties = true; } else throw new ArgumentException("Data source url cannot be empty"); @@ -2077,9 +2077,27 @@ public GXODataClient Select(Object[] columns) public GXODataClient Expand(params ODataExpression[] associations) { - return Apply(BoundClient.ExpandMap(ApplyEntityMappings(associations))); + // Build each ODataExpandAssociation upfront so Filter(expression) can wire + // per-entity FilterExpressions onto the same objects later. The fork's 6.0.2 + // IFluentClient exposes Expand(IEnumerable), which lets + // us pass our pre-built chain in directly — no reflection needed. + var mappings = ApplyEntityMappings(associations); + var odataAssociations = new List(mappings.Length); + foreach (var mapping in mappings) + { + var association = ODataExpandAssociation.From(mapping.Value); + odataAssociations.Add(association); + string aliasRoot = mapping.Key.Split(separator)[0]; + _expansionsByAlias[aliasRoot] = association; + } + BoundClient = BoundClient.Expand(odataAssociations); + return this; } + // Tracks the first-segment alias used by the caller (e.g. "Friends" for Expand("Friends/People")) + // against the corresponding root ODataExpandAssociation attached to BoundClient. + private readonly Dictionary _expansionsByAlias = new Dictionary(); + private static char[] separator = new char[] { '/' }; private static string strSeparator = "/"; private string[] ApplySelectMappings(ODataExpression[] references, int minus) @@ -2154,7 +2172,7 @@ public GXODataClient ThenByDescending(params ODataExpression[] columns) public GXODataClient Filter(ODataExpression expression) { try - { // In the conditions of type Att = parmStr it does a parmStr.rtrim in order to support + { // In the conditions of type Att = parmStr it does a parmStr.rtrim in order to support // FK from an SQL table to an OData entity. In the SQL table the FK is left with spaces at the end. // de tener una FK desde una tabla SQL hacia una entidad OData. En la tabla SQL la FK queda con espacios al final if (GetFieldValue(expression, "_operator").Equals(ExpressionType.Equal) && @@ -2173,7 +2191,63 @@ public GXODataClient Filter(ODataExpression expression) } catch { } - return Apply(BoundClient.Filter(expression)); + if (object.ReferenceEquals(expression, null)) + return this; + + // GeneXus.Odata.Client >= 6.0 no longer auto-decomposes a cross-entity filter expression + // into per-expanded-entity sub-filters at the FluentCommand level. Do it here using the + // ProcessFilter extension still exposed by the fork: walks the expression and groups the + // sub-expressions by the entity they reference. The base-entity bucket goes through the + // standard BoundClient.Filter; the others are written into the FilterExpression of the + // matching ODataExpandAssociation captured by Expand(). + IDictionary> entityFilters; + try + { + var baseCollection = Session.Metadata.GetEntityCollection(BaseEntity); + entityFilters = expression.ProcessFilter(Session, baseCollection); + } + catch + { + // If decomposition fails (e.g. metadata unavailable, non-cross-entity expression), + // fall back to the simple base-entity filter — preserves the pre-6.0 behaviour for + // the common single-entity case. + return Apply(BoundClient.Filter(expression)); + } + + foreach (KeyValuePair> entityFilter in entityFilters) + { + if (entityFilter.Value == null || entityFilter.Value.Count == 0) + continue; + + ODataExpression combined = null; + foreach (ODataExpression sub in entityFilter.Value) + combined = object.ReferenceEquals(combined, null) ? sub : combined && sub; + if (object.ReferenceEquals(combined, null)) + continue; + + if (string.IsNullOrEmpty(entityFilter.Key) || entityFilter.Key == BaseEntity) + { + BoundClient = BoundClient.Filter(combined); + } + else if (_expansionsByAlias.TryGetValue(entityFilter.Key, out ODataExpandAssociation association)) + { + // Walk to the deepest nested association for chained expands like "Friends/People". + var leaf = association; + while (leaf.ExpandAssociations != null && leaf.ExpandAssociations.Count > 0) + leaf = leaf.ExpandAssociations[0]; + leaf.FilterExpression = object.ReferenceEquals(leaf.FilterExpression, null) + ? combined + : leaf.FilterExpression && combined; + } + else + { + // No matching expand found for this entity — apply to the base filter so the + // query still includes the constraint instead of silently dropping it. + BoundClient = BoundClient.Filter(combined); + } + } + + return this; } public T GetFieldValue(object obj, string name) diff --git a/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj b/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj index 2cf30c8fd..e28d1af1a 100644 --- a/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj +++ b/dotnet/src/dotnetframework/DynServiceOData/DynServiceOData.csproj @@ -10,7 +10,7 @@ - + diff --git a/dotnet/src/dotnetframework/DynServiceOData/app.config b/dotnet/src/dotnetframework/DynServiceOData/app.config index d5e9233c6..c06c19ab6 100644 --- a/dotnet/src/dotnetframework/DynServiceOData/app.config +++ b/dotnet/src/dotnetframework/DynServiceOData/app.config @@ -8,31 +8,31 @@ - + - + - + - + - + - + - + diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs index 3106475bf..549630751 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs @@ -34,18 +34,25 @@ using GeneXus.Cryptography; using GeneXus.Data.NTier; using System.Collections.Generic; -using System.Drawing; using Microsoft.Win32; using System.Security.Cryptography; using System.Collections.Concurrent; -using System.Drawing.Drawing2D; using GeneXus.Storage; using GeneXus.Services; using GeneXus.Http; using System.Security; -using System.Drawing.Imaging; using System.Net.Http.Headers; +#if NETCORE +using Image = GeneXus.Drawing.Image; +using GeneXus.Drawing; +using GeneXus.Drawing.Drawing2D; +using GeneXus.Drawing.Imaging; +#else using Image = System.Drawing.Image; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +#endif using System.Net.Http; namespace GeneXus.Utils @@ -6098,7 +6105,7 @@ public static string Resize(string imageFile, int width, int height, bool keepAs newheight = (int)(image.Height / resize);// set the new heigth of the current image }//return the image resized to the given heigth and width Image output = image.GetThumbnailImage(width, newheight, null, IntPtr.Zero); - modifiedImage = Save(output, imageFile, ImageFormat.Bmp); + modifiedImage = Save(output, imageFile, GetImageFormat(image)); } } catch (Exception ex) @@ -6137,14 +6144,16 @@ public static string Crop(string imageFile, int X, int Y, int Width, int Height) { using (Bitmap bmp = new Bitmap(Width, Height)) { +#if !NETCORE bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution); +#endif using (Graphics Graphic = Graphics.FromImage(bmp)) { Graphic.SmoothingMode = SmoothingMode.AntiAlias; Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality; Graphic.DrawImage(OriginalImage, new Rectangle(0, 0, Width, Height), X, Y, Width, Height, GraphicsUnit.Pixel); - modifiedImage = Save(bmp, imageFile, OriginalImage.RawFormat); + modifiedImage = Save(bmp, imageFile, GetImageFormat(OriginalImage)); } } } @@ -6201,16 +6210,16 @@ public static string RoundBorders(string imageFile, int topLeftRadius, int topRi g.FillPath(br, path); } } + // Rounded images are basically images with transparent rounded borders and jpg and jpeg formats do not + // support transparency, so we have to create a new identical image but in png format + if (imageFile.IndexOf(".jpg") > 0) + modifiedImage = Save(roundedImage, imageFile.Replace(".jpg", ".png"), ImageFormat.Png); + else if (imageFile.IndexOf(".jpeg") > 0) + modifiedImage = Save(roundedImage, imageFile.Replace(".jpeg", ".png"), ImageFormat.Png); + else + modifiedImage = Save(roundedImage, imageFile, GetImageFormat(OriginalImage)); } } - // Rounded images are basically images with transparent rounded borders and jpg and jpeg formats do not - // support transparency, so we have to create a new identical image but in png format - if (imageFile.IndexOf(".jpg") > 0) - modifiedImage = Save(roundedImage, imageFile.Replace(".jpg", ".png"), ImageFormat.Png); - else if (imageFile.IndexOf(".jpeg") > 0) - modifiedImage = Save(roundedImage, imageFile.Replace(".jpeg", ".png"), ImageFormat.Png); - else - modifiedImage = Save(roundedImage, imageFile, OriginalImage.RawFormat); } } } @@ -6226,25 +6235,21 @@ public static string Rotate(string imageFile, int angle) string modifiedImage = string.Empty; try { - using (MemoryStream ms = new MemoryStream()) - { - using (Image OriginalImage = ImageCreateFromStream(imageFile)) + using (Image OriginalImage = ImageCreateFromStream(imageFile)) + { + using (Bitmap rotatedImage = new Bitmap(OriginalImage.Width, OriginalImage.Height)) { - using (Bitmap rotatedImage = new Bitmap(OriginalImage.Width, OriginalImage.Height)) - { - rotatedImage.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution); + rotatedImage.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution); - using (Graphics g = Graphics.FromImage(rotatedImage)) - { - g.TranslateTransform(OriginalImage.Width / 2, OriginalImage.Height / 2); - g.RotateTransform(angle); - g.TranslateTransform(-OriginalImage.Width / 2, -OriginalImage.Height / 2); - g.DrawImage(OriginalImage, new Point(0, 0)); - } - rotatedImage.Save(ms, OriginalImage.RawFormat); - modifiedImage = Save(rotatedImage, imageFile, OriginalImage.RawFormat); + using (Graphics g = Graphics.FromImage(rotatedImage)) + { + g.TranslateTransform(OriginalImage.Width / 2, OriginalImage.Height / 2); + g.RotateTransform(angle); + g.TranslateTransform(-OriginalImage.Width / 2, -OriginalImage.Height / 2); + g.DrawImage(OriginalImage, new Point(0, 0)); + modifiedImage = Save(rotatedImage, imageFile, GetImageFormat(OriginalImage)); } - } + } } } catch (Exception ex) @@ -6253,6 +6258,24 @@ public static string Rotate(string imageFile, int angle) } return modifiedImage; } +#if NETCORE + static ImageFormat GetImageFormat(Image bitmap) + { + ImageFormat format = bitmap.RawFormat; + + if (format.Equals(ImageFormat.Jpeg)) return ImageFormat.Jpeg; + if (format.Equals(ImageFormat.Png)) return ImageFormat.Png; + if (format.Equals(ImageFormat.Bmp)) return ImageFormat.Png; //Unsupported Bmp + if (format.Equals(ImageFormat.Gif)) return ImageFormat.Gif; + + return ImageFormat.Png; + } +#else + static ImageFormat GetImageFormat(Image bitmap) + { + return bitmap.RawFormat; + } +#endif public static string FlipHorizontally(string imageFile) { string modifiedImage = string.Empty; @@ -6261,7 +6284,7 @@ public static string FlipHorizontally(string imageFile) using (Bitmap bmp = BitmapCreateFromStream(imageFile)) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipX); - modifiedImage = Save(bmp, imageFile, bmp.RawFormat); + modifiedImage = Save(bmp, imageFile, GetImageFormat(bmp)); return modifiedImage; } } @@ -6279,7 +6302,7 @@ public static string FlipVertically(string imageFile) using (Bitmap bmp = BitmapCreateFromStream(imageFile)) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); - modifiedImage = Save(bmp, imageFile, bmp.RawFormat); + modifiedImage = Save(bmp, imageFile, GetImageFormat(bmp)); return modifiedImage; } } @@ -6303,7 +6326,7 @@ public static string Save(Image bitmap, string imageFile, ImageFormat format) { //In some cases, copied memory image fails to save when ImageFormat MemoryBmp //https://stackoverflow.com/questions/9073619/image-save-crashing-value-cannot-be-null-r-nparameter-name-encoder - bitmap.Save(ms, ImageFormat.Bmp); + bitmap.Save(ms, ImageFormat.Png); } ms.Position = 0; try @@ -6377,6 +6400,7 @@ public static long GetFileSize(string imageFile) return 0; } } + public class StorageUtils { public const string DELIMITER = "/"; diff --git a/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs b/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs index 65a8aa494..60d99777f 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs @@ -450,7 +450,7 @@ public static CultureInfo GetCultureForLang(string lang) #if NETCORE public static IConfiguration ConfigRoot { get ; set; } const string Log4NetShortName = "log4net"; - static Version Log4NetVersion = new Version(2, 0, 15); + static Version Log4NetVersion = new Version(3, 3, 1, 0); const string ConfigurationManagerBak = "System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"; const string ConfigurationManagerFileName = "System.Configuration.ConfigurationManager.dll"; @@ -497,7 +497,7 @@ private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEven #else static Dictionary AssemblyRedirect = new Dictionary { - {"log4net", new Version(2, 0, 11) }, + {"log4net", new Version(3, 3, 1, 0) }, { "System.Threading.Tasks.Extensions", new Version(4, 2, 0, 1) }, { "System.Runtime.CompilerServices.Unsafe", new Version(4, 0, 4, 1) }, { "System.Buffers", new Version(4, 0, 3, 0)}, diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs index a7fa9c31d..43dfaeec4 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs @@ -1596,6 +1596,8 @@ public class GxSqlServer : GxDataRecord private const int MILLISECONDS_BETWEEN_RETRY_ATTEMPTS = 500; private const string MULTIPLE_DATAREADERS = "MultipleActiveResultSets"; #if NETCORE + private const string TRUST_SERVER_CERTIFICATE = "TrustServerCertificate"; + private const bool TRUST_CERT_DEFAULT = true; private const string INTEGRATED_SECURITY = "Integrated Security"; private const string INTEGRATED_SECURITY_NO = "no"; #endif @@ -2062,6 +2064,14 @@ protected override string BuildConnectionString(string datasourceName, string us connectionString.AppendFormat(";Password={0}", userPassword); } extra = ResolveConnectionStringAuthentication(extra, additionalConnectionString); + + string tSrvCertificate = GetParameterValue(extra, TRUST_SERVER_CERTIFICATE); + if (string.IsNullOrEmpty(tSrvCertificate)) + { + //TODO:Remove Temporary compatibility setting to bypass certificate validation + connectionString.AppendFormat(";{0}={1}", TRUST_SERVER_CERTIFICATE, TRUST_CERT_DEFAULT); + } + #else if (userId!=null) { diff --git a/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj b/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj index 7be48a51b..ad5963095 100644 --- a/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj @@ -15,13 +15,13 @@ - + - + diff --git a/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinter.cs b/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinter.cs index 8c3044799..76ee52e86 100644 --- a/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinter.cs +++ b/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinter.cs @@ -4,8 +4,13 @@ namespace GeneXus.Printer using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; +#if NETCORE + using GeneXus.Drawing; + using GeneXus.Drawing.Imaging; +#else using System.Drawing; using System.Drawing.Imaging; +#endif using System.Drawing.Printing; using System.Globalization; using System.IO; @@ -18,6 +23,7 @@ namespace GeneXus.Printer using GeneXus.Configuration; using GeneXus.Utils; using GeneXus.XML; + using System.Runtime.Versioning; public interface IPrintHandler { @@ -772,347 +778,21 @@ IPrintHandler GetPrintHandler( StreamReader s) case "TXT": ph = new GxTxtPrinter( s ); break; - default : + default: +#if NETCORE + if (OperatingSystem.IsWindows()) + ph = new GxPrinterDevice(s); + else + ph = new GxTxtPrinter(s); +#else ph = new GxPrinterDevice( s ); +#endif break; } return ph; } } - public class GxPrinterDevice : IPrintHandler - { - Font currentFont; - Color currentForeColor; - Color currentBackColor; - String lastLine; - - bool pageStarted; - StreamReader streamToRead; - Graphics _gr; - - int originalScaleX = 96; // Dots x inch - int originalScaleY = 96; // Dots x inch - - public GxPrinterDevice(StreamReader sr) - { - streamToRead = sr; - lastLine = null; - } - public string Name - { - get { return "GxPrinterDevice";} - } - public bool CanSlot - { - get {return true;} - } - public void Open(StreamWriter output) - { - } - public StreamReader InputStream - { - get { return streamToRead;} - set {streamToRead = value; lastLine = null; } - } - public void Open() - { - } - public void Print(string configString) - { - PrintingPermission pp = new PrintingPermission(PrintingPermissionLevel.AllPrinting); - pp.Demand(); - PrintDocument pd = new PrintDocument(); - pd.PrintController = new StandardPrintController(); - pd.PrintPage += new PrintPageEventHandler(evt_PrintPage); - if (configString.Length > 0) - initPrnReport(configString, pd.PrinterSettings, pd.DefaultPageSettings); - if (pd.PrinterSettings.IsValid) - pd.Print(); - else - { - streamToRead.Close(); - throw new Exception("Printer settins not valid"); - } - pd.Dispose(); - } - public void Close() - { - try - { - streamToRead.Close(); - }catch(Exception) - { - //NOOP - } - } - void initPrnReport( string configString, PrinterSettings printerSettings, PageSettings pageSettings) - { - NameValueCollection configSettings; - - configSettings = GxPrinterConfig.ConfigPrinterSettings( configString); - - if (configSettings == null) - return; - - originalScaleX = Convert.ToInt32(configSettings["XPAGE"]); - originalScaleY = Convert.ToInt32(configSettings["YPAGE"]); - - if ( printerSettings != null) - { - - if (configSettings["PRINTER"].Length > 0) - foreach( string prnName in PrinterSettings.InstalledPrinters) - if ( prnName == configSettings["PRINTER"]) - { - printerSettings.PrinterName = configSettings["PRINTER"]; - break; - } - // Number of copies - printerSettings.Copies = Convert.ToInt16( configSettings["COPIES"]); - // Duplex - if ( printerSettings.CanDuplex) - printerSettings.Duplex = Convert.ToInt32( configSettings["DUPLEX"]) == 1 ? Duplex.Simplex : Duplex.Vertical ; - } - if ( pageSettings != null) - { - // Landscape - pageSettings.Landscape = Convert.ToInt32( configSettings["ORIENTATION"]) != 1; - // Color - if ( printerSettings.SupportsColor) - pageSettings.Color = Convert.ToInt32(configSettings["COLOR"]) == 1; - // paper try - - foreach( PaperSource pSrc in printerSettings.PaperSources) - if ( (int)(pSrc.Kind) == Convert.ToInt32(configSettings["DEFAULTSOURCE"])) - { - pageSettings.PaperSource = pSrc; - break; - } - // paper size - if ( configSettings["PAPERSIZE"] == "0") - pageSettings.PaperSize = new PaperSize( "Custom", - Convert.ToInt32( configSettings["PAPERLENGTH"])/1440 *100, - Convert.ToInt32( configSettings["PAPERWIDTH"])/1440 *100); - else - foreach( PaperSize pSz in printerSettings.PaperSizes) - if ( (int)(pSz.Kind) == Convert.ToInt32(configSettings["PAPERSIZE"])) - { - pageSettings.PaperSize = pSz; - break; - } - } - - } - - private void evt_PrintPage(object sender, PrintPageEventArgs ev) - { - bool morePages = false; - bool printPage = true; - _gr = ev.Graphics; - if (lastLine == null) - lastLine = streamToRead.ReadLine(); - - while (lastLine != null && printPage) { - printPage = processPrinterCommand( ev, lastLine, ref morePages ); - lastLine = streamToRead.ReadLine(); - } - if (lastLine == null || lastLine == GxReportBuilderNative.END_DOCUMENT || ! morePages) - ev.HasMorePages = false; - else - ev.HasMorePages = true; - } - private bool processPrinterCommand(PrintPageEventArgs ev, string line, ref bool morePages ) - { - GroupCollection grCol; - string cmd = line.Substring(0,3); - switch (cmd.ToUpper().Trim()) - { - case "DR": - if( (grCol = GxPrintCommandParser.ParseRect( line)) != null) - DrawRect( new Point( Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), - new Point( Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value)), - Convert.ToInt32(grCol["pen"].Value), - Color.FromArgb( Convert.ToInt32(grCol["fr"].Value), - Convert.ToInt32(grCol["fg"].Value), - Convert.ToInt32(grCol["fb"].Value)), - Convert.ToInt32(grCol["bm"].Value) == 1 ? - Color.FromArgb( Convert.ToInt32(grCol["br"].Value), - Convert.ToInt32(grCol["bg"].Value), - Convert.ToInt32(grCol["bb"].Value)) : - Color.Empty); - break; - case "DL": - if( (grCol = GxPrintCommandParser.ParseLine( line)) != null) - DrawLine( - new Point( Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), - new Point( Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value)), - Convert.ToInt32(grCol["width"].Value), - Color.FromArgb( Convert.ToInt32(grCol["fr"].Value), - Convert.ToInt32(grCol["fg"].Value), - Convert.ToInt32(grCol["fb"].Value))); - break; - case "DB": - if( (grCol = GxPrintCommandParser.ParseBitmap( line)) != null) - DrawBitmap( - grCol["bitmap"].Value, - new Point( Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), - new Point( Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value))); - break; - case "DT": - if ((grCol = GxPrintCommandParser.ParseText(line)) != null) - { - string text = grCol["text"].Value; - text = GxCommandFileSender.NormalizeFromRegExp(text); - DrawText(text, - new Point(Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), - new Point(Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value)), - this.currentFont, - Convert.ToInt32(grCol["align"].Value), - this.currentForeColor, - this.currentBackColor); - } - break; - case "ATT": - if( (grCol = GxPrintCommandParser.ParseTextAttributes( line)) != null) - setTextAttributes( grCol["name"].Value, - Convert.ToInt32(grCol["size"].Value), - Convert.ToInt32(grCol["bold"].Value)== 1, - Convert.ToInt32(grCol["italic"].Value)== 1, - Convert.ToInt32(grCol["underline"].Value)== 1, - Convert.ToInt32(grCol["strike"].Value)== 1, - Convert.ToInt32(grCol["pen"].Value), - Convert.ToInt32(grCol["fr"].Value), - Convert.ToInt32(grCol["fg"].Value), - Convert.ToInt32(grCol["fb"].Value), - Convert.ToInt32(grCol["bm"].Value), - Convert.ToInt32(grCol["br"].Value), - Convert.ToInt32(grCol["bg"].Value), - Convert.ToInt32(grCol["bb"].Value)); - break; - case "SPG": - pageStarted = true; - break; - case GxReportBuilderNative.END_PAGE: - if (pageStarted) - { - morePages = true; - pageStarted = false; - return false; - } - break; - case GxReportBuilderNative.END_DOCUMENT: - morePages = false; - return false; - } - return true; - } - void setTextAttributes(String fontName, int fontSize, bool fontBold, bool fontItalic, bool fontUnderline, bool fontStrikethru, int Pen, int foreRed, int foreGreen, int foreBlue, int backMode, int backRed, int backGreen, int backBlue) - { - FontStyle fntSt = 0; - if ( fontBold ) fntSt |= FontStyle.Bold ; - if ( fontItalic ) fntSt |= FontStyle.Italic ; - if ( fontUnderline ) fntSt |= FontStyle.Underline ; - if ( fontStrikethru ) fntSt |= FontStyle.Strikeout ; - this.currentFont = new Font( fontName, fontSize, fntSt); - this.currentForeColor = Color.FromArgb( foreRed, foreGreen, foreBlue); - if (backMode != 1) - this.currentBackColor = Color.Empty; - else - this.currentBackColor = Color.FromArgb( backRed, backGreen, backBlue); - } - void DrawRect(Point p1, Point p2, int penSize, Color foreColor, Color backColor) - { - float l = convertX(p1.X); - float t = convertY(p1.Y); - float r = convertX(p2.X); - float b = convertY(p2.Y); - if (penSize > 0) - { - using (Pen pen = new Pen(foreColor, penSize)) - { - _gr.DrawRectangle(pen, l, t, r - l, b - t); - } - } - if (backColor != Color.Empty) - { - using (Brush br = new SolidBrush(backColor)) - { - _gr.FillRectangle(br, l, t, r - l, b - t); - } - } - } - void DrawLine(Point p1, Point p2, int penSize, Color foreColor) - { - float l = convertX(p1.X); - float t = convertY(p1.Y); - float r = convertX(p2.X); - float b = convertY(p2.Y); - using (Pen pen = new Pen(foreColor, penSize)) - { - _gr.DrawLine(pen, l, t, r, b); - } - } - void DrawBitmap(string bitmap, Point p1, Point p2) - { - float l = convertX(p1.X); - float t = convertY(p1.Y); - float r = convertX(p2.X); - float b = convertY(p2.Y); - Image img = Image.FromFile(bitmap); - _gr.DrawImage( img, l, t, r-l, b-t); - } - void DrawText(string text, Point p1, Point p2, Font fnt, int align, Color foreColor, Color backColor) - { - float l = convertX(p1.X); - float t = convertY(p1.Y); - float r = convertX(p2.X); - float b = convertY(p2.Y); - DrawRect( p1, p2, 0, foreColor, backColor); - RectangleF rect = new RectangleF(correctTextCoor(l, align), t, r-l, b-t); - using (Brush br = new SolidBrush(foreColor)) - { - _gr.DrawString(text, fnt, br, rect, stringFormatFromAlign(align)); - } - } - StringFormat stringFormatFromAlign( int align) - { - - StringFormat sfmt = new StringFormat(); - sfmt.Trimming = StringTrimming.None; - if ( (align & 256) > 0) - sfmt.FormatFlags |= StringFormatFlags.NoClip; - if ( (align & 16) == 0) - sfmt.FormatFlags |= StringFormatFlags.NoWrap; - if ( (align & 2) > 0) - sfmt.Alignment |= StringAlignment.Far; - else if ( (align & 1) > 0) - sfmt.Alignment |= StringAlignment.Center; - else - sfmt.Alignment |= StringAlignment.Near; - return sfmt; - } - float correctTextCoor(float l, int align) - { - int mn = 4; - float ret; - if ( (align & 2) > 0) - ret = l + mn; - else if ( (align & 1) > 0) - ret = l; - else - ret = l - mn; - return ret; - } - float convertX( float x) - { - return x/this.originalScaleX * 100; - } - float convertY( float y) - { - return y/this.originalScaleY * 100; - } - } public class GxTxtPrinter : IPrintHandler { private static readonly IGXLogger log = GXLoggerFactory.GetLogger(); @@ -1555,7 +1235,11 @@ void DrawBitmap(string bitmap, Point p1, Point p2) streamToWrite.Write( sBuffer); using (Bitmap bm = new Bitmap(bitmap)) { +#if NETCORE + bm.Save(streamToWrite.BaseStream, ImageFormat.Png); +#else bm.Save(streamToWrite.BaseStream, ImageFormat.Emf); +#endif } streamToWrite.Write( "}}\n"); } diff --git a/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinterDevice.cs b/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinterDevice.cs new file mode 100644 index 000000000..72c7711fa --- /dev/null +++ b/dotnet/src/dotnetframework/GxClasses/Printer/GxPrinterDevice.cs @@ -0,0 +1,354 @@ +using System.Collections.Specialized; +using System.IO; +using System.Text.RegularExpressions; +using System; +using System.Drawing; +using System.Drawing.Printing; +#if NETCORE +using System.Runtime.Versioning; +#endif + +namespace GeneXus.Printer +{ +#if NETCORE + [SupportedOSPlatform("windows")] +#endif + + public class GxPrinterDevice : IPrintHandler + { + Font currentFont; + Color currentForeColor; + Color currentBackColor; + String lastLine; + + bool pageStarted; + StreamReader streamToRead; + Graphics _gr; + + int originalScaleX = 96; // Dots x inch + int originalScaleY = 96; // Dots x inch + + public GxPrinterDevice(StreamReader sr) + { + streamToRead = sr; + lastLine = null; + } + public string Name + { + get { return "GxPrinterDevice"; } + } + public bool CanSlot + { + get { return true; } + } + public void Open(StreamWriter output) + { + } + public StreamReader InputStream + { + get { return streamToRead; } + set { streamToRead = value; lastLine = null; } + } + public void Open() + { + } + public void Print(string configString) + { +#if !NETCORE + PrintingPermission pp = new PrintingPermission(PrintingPermissionLevel.AllPrinting); + pp.Demand(); +#endif + PrintDocument pd = new PrintDocument(); + pd.PrintController = new StandardPrintController(); + pd.PrintPage += new PrintPageEventHandler(evt_PrintPage); + if (configString.Length > 0) + initPrnReport(configString, pd.PrinterSettings, pd.DefaultPageSettings); + if (pd.PrinterSettings.IsValid) + pd.Print(); + else + { + streamToRead.Close(); + throw new Exception("Printer settins not valid"); + } + pd.Dispose(); + } + public void Close() + { + try + { + streamToRead.Close(); + } + catch (Exception) + { + //NOOP + } + } + void initPrnReport(string configString, PrinterSettings printerSettings, PageSettings pageSettings) + { + NameValueCollection configSettings; + + configSettings = GxPrinterConfig.ConfigPrinterSettings(configString); + + if (configSettings == null) + return; + + originalScaleX = Convert.ToInt32(configSettings["XPAGE"]); + originalScaleY = Convert.ToInt32(configSettings["YPAGE"]); + + if (printerSettings != null) + { + + if (configSettings["PRINTER"].Length > 0) + foreach (string prnName in PrinterSettings.InstalledPrinters) + if (prnName == configSettings["PRINTER"]) + { + printerSettings.PrinterName = configSettings["PRINTER"]; + break; + } + // Number of copies + printerSettings.Copies = Convert.ToInt16(configSettings["COPIES"]); + // Duplex + if (printerSettings.CanDuplex) + printerSettings.Duplex = Convert.ToInt32(configSettings["DUPLEX"]) == 1 ? Duplex.Simplex : Duplex.Vertical; + } + if (pageSettings != null) + { + // Landscape + pageSettings.Landscape = Convert.ToInt32(configSettings["ORIENTATION"]) != 1; + // Color + if (printerSettings.SupportsColor) + pageSettings.Color = Convert.ToInt32(configSettings["COLOR"]) == 1; + // paper try + + foreach (PaperSource pSrc in printerSettings.PaperSources) + if ((int)(pSrc.Kind) == Convert.ToInt32(configSettings["DEFAULTSOURCE"])) + { + pageSettings.PaperSource = pSrc; + break; + } + // paper size + if (configSettings["PAPERSIZE"] == "0") + pageSettings.PaperSize = new PaperSize("Custom", + Convert.ToInt32(configSettings["PAPERLENGTH"]) / 1440 * 100, + Convert.ToInt32(configSettings["PAPERWIDTH"]) / 1440 * 100); + else + foreach (PaperSize pSz in printerSettings.PaperSizes) + if ((int)(pSz.Kind) == Convert.ToInt32(configSettings["PAPERSIZE"])) + { + pageSettings.PaperSize = pSz; + break; + } + } + + } + private void evt_PrintPage(object sender, PrintPageEventArgs ev) + { + bool morePages = false; + bool printPage = true; + _gr = ev.Graphics; + if (lastLine == null) + lastLine = streamToRead.ReadLine(); + + while (lastLine != null && printPage) + { + printPage = processPrinterCommand(ev, lastLine, ref morePages); + lastLine = streamToRead.ReadLine(); + } + if (lastLine == null || lastLine == GxReportBuilderNative.END_DOCUMENT || !morePages) + ev.HasMorePages = false; + else + ev.HasMorePages = true; + } + private bool processPrinterCommand(PrintPageEventArgs ev, string line, ref bool morePages) + { + GroupCollection grCol; + string cmd = line.Substring(0, 3); + switch (cmd.ToUpper().Trim()) + { + case "DR": + if ((grCol = GxPrintCommandParser.ParseRect(line)) != null) + DrawRect(new Point(Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), + new Point(Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value)), + Convert.ToInt32(grCol["pen"].Value), + Color.FromArgb(Convert.ToInt32(grCol["fr"].Value), + Convert.ToInt32(grCol["fg"].Value), + Convert.ToInt32(grCol["fb"].Value)), + Convert.ToInt32(grCol["bm"].Value) == 1 ? + Color.FromArgb(Convert.ToInt32(grCol["br"].Value), + Convert.ToInt32(grCol["bg"].Value), + Convert.ToInt32(grCol["bb"].Value)) : + Color.Empty); + break; + case "DL": + if ((grCol = GxPrintCommandParser.ParseLine(line)) != null) + DrawLine( + new Point(Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), + new Point(Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value)), + Convert.ToInt32(grCol["width"].Value), + Color.FromArgb(Convert.ToInt32(grCol["fr"].Value), + Convert.ToInt32(grCol["fg"].Value), + Convert.ToInt32(grCol["fb"].Value))); + break; + case "DB": + if ((grCol = GxPrintCommandParser.ParseBitmap(line)) != null) + DrawBitmap( + grCol["bitmap"].Value, + new Point(Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), + new Point(Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value))); + break; + case "DT": + if ((grCol = GxPrintCommandParser.ParseText(line)) != null) + { + string text = grCol["text"].Value; + text = GxCommandFileSender.NormalizeFromRegExp(text); + + DrawText(text, + new Point(Convert.ToInt32(grCol["left"].Value), Convert.ToInt32(grCol["top"].Value)), + new Point(Convert.ToInt32(grCol["right"].Value), Convert.ToInt32(grCol["bottom"].Value)), + this.currentFont, + Convert.ToInt32(grCol["align"].Value), + this.currentForeColor, + this.currentBackColor); + } + break; + case "ATT": + if ((grCol = GxPrintCommandParser.ParseTextAttributes(line)) != null) + setTextAttributes(grCol["name"].Value, + Convert.ToInt32(grCol["size"].Value), + Convert.ToInt32(grCol["bold"].Value) == 1, + Convert.ToInt32(grCol["italic"].Value) == 1, + Convert.ToInt32(grCol["underline"].Value) == 1, + Convert.ToInt32(grCol["strike"].Value) == 1, + Convert.ToInt32(grCol["pen"].Value), + Convert.ToInt32(grCol["fr"].Value), + Convert.ToInt32(grCol["fg"].Value), + Convert.ToInt32(grCol["fb"].Value), + Convert.ToInt32(grCol["bm"].Value), + Convert.ToInt32(grCol["br"].Value), + Convert.ToInt32(grCol["bg"].Value), + Convert.ToInt32(grCol["bb"].Value)); + break; + case "SPG": + pageStarted = true; + break; + case GxReportBuilderNative.END_PAGE: + if (pageStarted) + { + morePages = true; + pageStarted = false; + return false; + } + break; + case GxReportBuilderNative.END_DOCUMENT: + morePages = false; + return false; + } + return true; + } + void setTextAttributes(String fontName, int fontSize, bool fontBold, bool fontItalic, bool fontUnderline, bool fontStrikethru, int Pen, int foreRed, int foreGreen, int foreBlue, int backMode, int backRed, int backGreen, int backBlue) + { + FontStyle fntSt = 0; + if (fontBold) fntSt |= FontStyle.Bold; + if (fontItalic) fntSt |= FontStyle.Italic; + if (fontUnderline) fntSt |= FontStyle.Underline; + if (fontStrikethru) fntSt |= FontStyle.Strikeout; + this.currentFont = new Font(fontName, fontSize, fntSt); + this.currentForeColor = Color.FromArgb(foreRed, foreGreen, foreBlue); + if (backMode != 1) + this.currentBackColor = Color.Empty; + else + this.currentBackColor = Color.FromArgb(backRed, backGreen, backBlue); + } + void DrawRect(Point p1, Point p2, int penSize, Color foreColor, Color backColor) + { + float l = convertX(p1.X); + float t = convertY(p1.Y); + float r = convertX(p2.X); + float b = convertY(p2.Y); + if (penSize > 0) + { + using (Pen pen = new Pen(foreColor, penSize)) + { + _gr.DrawRectangle(pen, l, t, r - l, b - t); + } + } + if (backColor != Color.Empty) + { + using (Brush br = new SolidBrush(backColor)) + { + _gr.FillRectangle(br, l, t, r - l, b - t); + } + } + } + void DrawLine(Point p1, Point p2, int penSize, Color foreColor) + { + float l = convertX(p1.X); + float t = convertY(p1.Y); + float r = convertX(p2.X); + float b = convertY(p2.Y); + using (Pen pen = new Pen(foreColor, penSize)) + { + _gr.DrawLine(pen, l, t, r, b); + } + } + void DrawBitmap(string bitmap, Point p1, Point p2) + { + float l = convertX(p1.X); + float t = convertY(p1.Y); + float r = convertX(p2.X); + float b = convertY(p2.Y); + Image img = Image.FromFile(bitmap); + _gr.DrawImage(img, l, t, r - l, b - t); + } + void DrawText(string text, Point p1, Point p2, Font fnt, int align, Color foreColor, Color backColor) + { + float l = convertX(p1.X); + float t = convertY(p1.Y); + float r = convertX(p2.X); + float b = convertY(p2.Y); + DrawRect(p1, p2, 0, foreColor, backColor); + RectangleF rect = new RectangleF(correctTextCoor(l, align), t, r - l, b - t); + using (Brush br = new SolidBrush(foreColor)) + { + _gr.DrawString(text, fnt, br, rect, stringFormatFromAlign(align)); + } + } + StringFormat stringFormatFromAlign(int align) + { + + StringFormat sfmt = new StringFormat(); + sfmt.Trimming = StringTrimming.None; + if ((align & 256) > 0) + sfmt.FormatFlags |= StringFormatFlags.NoClip; + if ((align & 16) == 0) + sfmt.FormatFlags |= StringFormatFlags.NoWrap; + if ((align & 2) > 0) + sfmt.Alignment |= StringAlignment.Far; + else if ((align & 1) > 0) + sfmt.Alignment |= StringAlignment.Center; + else + sfmt.Alignment |= StringAlignment.Near; + return sfmt; + } + float correctTextCoor(float l, int align) + { + int mn = 4; + float ret; + if ((align & 2) > 0) + ret = l + mn; + else if ((align & 1) > 0) + ret = l; + else + ret = l - mn; + return ret; + } + float convertX(float x) + { + return x / this.originalScaleX * 100; + } + float convertY(float y) + { + return y / this.originalScaleY * 100; + } + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxMail/GxMail.csproj b/dotnet/src/dotnetframework/GxMail/GxMail.csproj index fa8a83e9a..4ac284477 100644 --- a/dotnet/src/dotnetframework/GxMail/GxMail.csproj +++ b/dotnet/src/dotnetframework/GxMail/GxMail.csproj @@ -11,7 +11,8 @@ - + + diff --git a/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj b/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj index 2ae847298..64b0363da 100644 --- a/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj +++ b/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj @@ -10,6 +10,8 @@ + + diff --git a/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj b/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj index 30b4f1d29..c768ee21a 100644 --- a/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj +++ b/dotnet/src/dotnetframework/Projects/StoreManager/StoreManager.csproj @@ -10,7 +10,7 @@ - + diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXAzureStorage/GXAzureStorage.csproj b/dotnet/src/dotnetframework/Providers/Storage/GXAzureStorage/GXAzureStorage.csproj index 1a886e79f..3ea2ff229 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXAzureStorage/GXAzureStorage.csproj +++ b/dotnet/src/dotnetframework/Providers/Storage/GXAzureStorage/GXAzureStorage.csproj @@ -8,6 +8,8 @@ + + diff --git a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj index e8dd2dcb3..8f7391945 100644 --- a/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj +++ b/dotnet/src/dotnetframework/Providers/Storage/GXGoogleCloud/GXGoogleCloud.csproj @@ -9,7 +9,7 @@ - + diff --git a/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj b/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj index 436ee7ca2..c02aacbc4 100644 --- a/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj +++ b/dotnet/src/extensions/Azure/Handlers/GeneXus.Deploy.AzureFunctions.Handlers.csproj @@ -69,7 +69,7 @@ - + diff --git a/dotnet/src/extensions/Azure/test/AzureFunctionsTest/AzureFunctionsTest.csproj b/dotnet/src/extensions/Azure/test/AzureFunctionsTest/AzureFunctionsTest.csproj index 6b54739ec..56f943873 100644 --- a/dotnet/src/extensions/Azure/test/AzureFunctionsTest/AzureFunctionsTest.csproj +++ b/dotnet/src/extensions/Azure/test/AzureFunctionsTest/AzureFunctionsTest.csproj @@ -7,7 +7,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj index 666954743..94d3f4981 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/GeneXusXmlSignatureNetCore/GeneXusXmlSignatureNetCore.csproj @@ -27,7 +27,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj index 98801732c..5b65aa96e 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetcore/SecurityAPICommonsNetCore/SecurityAPICommonsNetCore.csproj @@ -36,7 +36,7 @@ - + diff --git a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj index 2cac667b1..0c1aa980e 100644 --- a/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj +++ b/dotnet/src/extensions/SecurityAPI/dotnet/dotnetframework/GeneXusJWT/GeneXusJWT.csproj @@ -20,7 +20,7 @@ - + diff --git a/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj b/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj index 2c702c0a9..9c96c6ccd 100644 --- a/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj +++ b/dotnet/src/extensions/mocking/test/TestMockDBAccess/TestMockDBAccess.csproj @@ -10,7 +10,7 @@ - + diff --git a/dotnet/test/DotNetCoreChunkedTest/DotNetCoreChunkedTest.csproj b/dotnet/test/DotNetCoreChunkedTest/DotNetCoreChunkedTest.csproj index 5cfc441ba..7551bc3b0 100644 --- a/dotnet/test/DotNetCoreChunkedTest/DotNetCoreChunkedTest.csproj +++ b/dotnet/test/DotNetCoreChunkedTest/DotNetCoreChunkedTest.csproj @@ -18,7 +18,7 @@ - + diff --git a/dotnet/test/DotNetCoreOpenTelemetryTest/DotNetCoreOpenTelemetryTest.csproj b/dotnet/test/DotNetCoreOpenTelemetryTest/DotNetCoreOpenTelemetryTest.csproj index f9111e8f4..a3943be46 100644 --- a/dotnet/test/DotNetCoreOpenTelemetryTest/DotNetCoreOpenTelemetryTest.csproj +++ b/dotnet/test/DotNetCoreOpenTelemetryTest/DotNetCoreOpenTelemetryTest.csproj @@ -16,7 +16,7 @@ - + diff --git a/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj b/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj index ea60a3be1..f098d3363 100644 --- a/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj +++ b/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj @@ -4,6 +4,15 @@ CS8032;1701;1702;NU1701 Major + + + + + + + TRACE;NETCORE @@ -61,7 +70,7 @@ - + @@ -153,6 +162,9 @@ Always + + Always + Always diff --git a/dotnet/test/DotNetCoreUnitTest/resources/Minions-PNG-Photo.png b/dotnet/test/DotNetCoreUnitTest/resources/Minions-PNG-Photo.png new file mode 100644 index 000000000..99a9723ec Binary files /dev/null and b/dotnet/test/DotNetCoreUnitTest/resources/Minions-PNG-Photo.png differ diff --git a/dotnet/test/DotNetCoreWebUnitTest/DotNetCoreWebUnitTest.csproj b/dotnet/test/DotNetCoreWebUnitTest/DotNetCoreWebUnitTest.csproj index 5533a4645..cfb2aeaec 100644 --- a/dotnet/test/DotNetCoreWebUnitTest/DotNetCoreWebUnitTest.csproj +++ b/dotnet/test/DotNetCoreWebUnitTest/DotNetCoreWebUnitTest.csproj @@ -18,7 +18,7 @@ - + diff --git a/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj b/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj index 164d730a1..b3d61150e 100644 --- a/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj +++ b/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj @@ -122,6 +122,9 @@ Always + + Always + Always diff --git a/dotnet/test/DotNetUnitTest/ImageUtils/ImageUtilTest.cs b/dotnet/test/DotNetUnitTest/ImageUtils/ImageUtilTest.cs index e62630a16..4310bbce7 100644 --- a/dotnet/test/DotNetUnitTest/ImageUtils/ImageUtilTest.cs +++ b/dotnet/test/DotNetUnitTest/ImageUtils/ImageUtilTest.cs @@ -13,8 +13,8 @@ namespace DotNetCoreUnitTest.ImageUtils { public class ImageUtilTest : FileSystemTest { - private readonly string IMAGE_FILE_PATH = System.IO.Path.Combine(BaseDir, "resources", "bird-thumbnail.jpg"); - private readonly string IMAGE_FILE_PATH_OUTPUT = System.IO.Path.Combine(BaseDir, "resources", "bird-thumbnail-{0}-{1}.jpg"); + private readonly string IMAGE_FILE_PATH = System.IO.Path.Combine(BaseDir, "resources", "bird-thumbnail.jpg");//Minions-PNG-Photo.png + private readonly string IMAGE_FILE_PATH_OUTPUT = System.IO.Path.Combine(BaseDir, "resources", "bird-thumbnail-{0}-{1}.jpg");//Minions-PNG-Photo private readonly int IMAGE_HEIGHT = 900; private readonly int IMAGE_WIDTH = 720; @@ -82,6 +82,18 @@ public void TestImageResize() int imageWidth = GxImageUtil.GetImageWidth(imagePath); Assert.Equal(300, imageWidth); } + [Fact] + public void TestImageRotate() + { + string fileName = Initialize("rotated"); + string imagePath = GxImageUtil.Rotate(fileName, 45); + + int imageHeight = GxImageUtil.GetImageHeight(imagePath); + Assert.Equal(900, imageHeight); + + int imageWidth = GxImageUtil.GetImageWidth(imagePath); + Assert.Equal(720, imageWidth); + } [Fact] diff --git a/dotnet/test/DotNetUnitTest/resources/Minions-PNG-Photo.png b/dotnet/test/DotNetUnitTest/resources/Minions-PNG-Photo.png new file mode 100644 index 000000000..99a9723ec Binary files /dev/null and b/dotnet/test/DotNetUnitTest/resources/Minions-PNG-Photo.png differ