diff --git a/Demos/OpenSource/WPFOpenSourceViewer/OpenSourceCustomViewer/OpenSourceCustomViewer.csproj b/Demos/OpenSource/WPFOpenSourceViewer/OpenSourceCustomViewer/OpenSourceCustomViewer.csproj index cde16845..6f20366f 100644 --- a/Demos/OpenSource/WPFOpenSourceViewer/OpenSourceCustomViewer/OpenSourceCustomViewer.csproj +++ b/Demos/OpenSource/WPFOpenSourceViewer/OpenSourceCustomViewer/OpenSourceCustomViewer.csproj @@ -118,4 +118,4 @@ - + \ No newline at end of file diff --git a/Demos/OpenSource/WinFormsOpenSourceViewer/WinFormsOpenSource/WinFormsOpenSource.csproj b/Demos/OpenSource/WinFormsOpenSourceViewer/WinFormsOpenSource/WinFormsOpenSource.csproj index 9e6bbef0..c3e85769 100644 --- a/Demos/OpenSource/WinFormsOpenSourceViewer/WinFormsOpenSource/WinFormsOpenSource.csproj +++ b/Demos/OpenSource/WinFormsOpenSourceViewer/WinFormsOpenSource/WinFormsOpenSource.csproj @@ -145,4 +145,4 @@ - + \ No newline at end of file diff --git a/Demos/Reports/Barcode.frx b/Demos/Reports/Barcode.frx index caac0143..22f87dc6 100644 --- a/Demos/Reports/Barcode.frx +++ b/Demos/Reports/Barcode.frx @@ -1,54 +1,55 @@  - + - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + @@ -62,8 +63,9 @@ + - + diff --git a/Demos/Reports/QR-Codes.frx b/Demos/Reports/QR-Codes.frx index 86e8179e..14f8994e 100644 --- a/Demos/Reports/QR-Codes.frx +++ b/Demos/Reports/QR-Codes.frx @@ -1,12 +1,13 @@  - + - + + @@ -25,10 +26,11 @@ - - - + + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj index ae2a0b5f..bf45c4b3 100644 --- a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj @@ -27,7 +27,7 @@ - + @@ -36,15 +36,13 @@ - - - UserControl - + + CouchbaseConnectionEditor.cs - + CouchbaseConnectionEditor.cs Designer diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj b/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj index 7bcc5967..648bee27 100644 --- a/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj @@ -38,9 +38,7 @@ - - UserControl - + JsonConnectionEditor.cs diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj index 219846a8..8e1e8597 100644 --- a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj @@ -1,6 +1,6 @@ - net4.5 + net4.5;net4.5.2 false ../../../FastReport.Plugins.snk true @@ -20,12 +20,12 @@ FastReport.Data fixed a bug with wrong database name - + all - + @@ -33,7 +33,7 @@ - + UserControl @@ -41,15 +41,20 @@ MongoDBConnectionEditor.cs - + MongoDBConnectionEditor.cs Designer - - - - + + + + + + + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs index bcd2f76a..bfe4bd79 100644 --- a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs @@ -37,12 +37,14 @@ private void InitializeComponent() this.lblUserName = new System.Windows.Forms.Label(); this.lblPassword = new System.Windows.Forms.Label(); this.gbServer = new System.Windows.Forms.GroupBox(); + this.cbUseSsl = new System.Windows.Forms.CheckBox(); + this.comboBoxScheme = new System.Windows.Forms.ComboBox(); this.lblPort = new System.Windows.Forms.Label(); this.tbPort = new System.Windows.Forms.TextBox(); this.lblHost = new System.Windows.Forms.Label(); this.tbHost = new System.Windows.Forms.TextBox(); + this.lblScheme = new System.Windows.Forms.Label(); this.label1 = new FastReport.Controls.LabelLine(); - this.cbUseSsl = new System.Windows.Forms.CheckBox(); this.gbDatabase.SuspendLayout(); this.gbServer.SuspendLayout(); this.SuspendLayout(); @@ -51,7 +53,7 @@ private void InitializeComponent() // this.gbDatabase.Controls.Add(this.lblDatabase); this.gbDatabase.Controls.Add(this.tbDatabase); - this.gbDatabase.Location = new System.Drawing.Point(8, 142); + this.gbDatabase.Location = new System.Drawing.Point(8, 179); this.gbDatabase.Name = "gbDatabase"; this.gbDatabase.Size = new System.Drawing.Size(320, 76); this.gbDatabase.TabIndex = 5; @@ -63,7 +65,7 @@ private void InitializeComponent() this.lblDatabase.AutoSize = true; this.lblDatabase.Location = new System.Drawing.Point(12, 20); this.lblDatabase.Name = "lblDatabase"; - this.lblDatabase.Size = new System.Drawing.Size(79, 19); + this.lblDatabase.Size = new System.Drawing.Size(57, 13); this.lblDatabase.TabIndex = 3; this.lblDatabase.Text = "Database:"; // @@ -71,7 +73,7 @@ private void InitializeComponent() // this.tbDatabase.Location = new System.Drawing.Point(12, 40); this.tbDatabase.Name = "tbDatabase"; - this.tbDatabase.Size = new System.Drawing.Size(296, 27); + this.tbDatabase.Size = new System.Drawing.Size(296, 20); this.tbDatabase.TabIndex = 0; // // btnAdvanced @@ -79,7 +81,7 @@ private void InitializeComponent() this.btnAdvanced.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.btnAdvanced.AutoSize = true; this.btnAdvanced.Enabled = false; - this.btnAdvanced.Location = new System.Drawing.Point(226, 219); + this.btnAdvanced.Location = new System.Drawing.Point(226, 256); this.btnAdvanced.Name = "btnAdvanced"; this.btnAdvanced.Size = new System.Drawing.Size(103, 29); this.btnAdvanced.TabIndex = 4; @@ -92,14 +94,14 @@ private void InitializeComponent() // this.tbUserName.Location = new System.Drawing.Point(81, 82); this.tbUserName.Name = "tbUserName"; - this.tbUserName.Size = new System.Drawing.Size(227, 27); + this.tbUserName.Size = new System.Drawing.Size(227, 20); this.tbUserName.TabIndex = 1; // // tbPassword // this.tbPassword.Location = new System.Drawing.Point(81, 106); this.tbPassword.Name = "tbPassword"; - this.tbPassword.Size = new System.Drawing.Size(227, 27); + this.tbPassword.Size = new System.Drawing.Size(227, 20); this.tbPassword.TabIndex = 2; this.tbPassword.UseSystemPasswordChar = true; // @@ -108,42 +110,65 @@ private void InitializeComponent() this.lblUserName.AutoSize = true; this.lblUserName.Location = new System.Drawing.Point(12, 86); this.lblUserName.Name = "lblUserName"; - this.lblUserName.Size = new System.Drawing.Size(91, 19); + this.lblUserName.Size = new System.Drawing.Size(62, 13); this.lblUserName.TabIndex = 0; this.lblUserName.Text = "User name:"; // // lblPassword // this.lblPassword.AutoSize = true; - this.lblPassword.Location = new System.Drawing.Point(12, 110); + this.lblPassword.Location = new System.Drawing.Point(12, 109); this.lblPassword.Name = "lblPassword"; - this.lblPassword.Size = new System.Drawing.Size(82, 19); + this.lblPassword.Size = new System.Drawing.Size(57, 13); this.lblPassword.TabIndex = 1; this.lblPassword.Text = "Password:"; // // gbServer // + this.gbServer.Controls.Add(this.cbUseSsl); + this.gbServer.Controls.Add(this.comboBoxScheme); this.gbServer.Controls.Add(this.lblPort); this.gbServer.Controls.Add(this.tbPort); this.gbServer.Controls.Add(this.lblHost); this.gbServer.Controls.Add(this.tbHost); this.gbServer.Controls.Add(this.tbUserName); this.gbServer.Controls.Add(this.tbPassword); + this.gbServer.Controls.Add(this.lblScheme); this.gbServer.Controls.Add(this.lblUserName); this.gbServer.Controls.Add(this.lblPassword); this.gbServer.Location = new System.Drawing.Point(8, 3); this.gbServer.Name = "gbServer"; - this.gbServer.Size = new System.Drawing.Size(320, 137); + this.gbServer.Size = new System.Drawing.Size(320, 170); this.gbServer.TabIndex = 7; this.gbServer.TabStop = false; this.gbServer.Text = "Server"; // + // cbUseSsl + // + this.cbUseSsl.AutoSize = true; + this.cbUseSsl.Location = new System.Drawing.Point(15, 138); + this.cbUseSsl.Name = "cbUseSsl"; + this.cbUseSsl.Size = new System.Drawing.Size(60, 17); + this.cbUseSsl.TabIndex = 8; + this.cbUseSsl.Text = "Use Ssl"; + this.cbUseSsl.UseVisualStyleBackColor = true; + // + // comboBoxScheme + // + this.comboBoxScheme.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxScheme.FormattingEnabled = true; + this.comboBoxScheme.Location = new System.Drawing.Point(194, 136); + this.comboBoxScheme.Name = "comboBoxScheme"; + this.comboBoxScheme.Size = new System.Drawing.Size(114, 21); + this.comboBoxScheme.TabIndex = 7; + this.comboBoxScheme.SelectedValueChanged += new System.EventHandler(this.comboBoxScheme_SelectedValueChanged); + // // lblPort // this.lblPort.AutoSize = true; this.lblPort.Location = new System.Drawing.Point(12, 53); this.lblPort.Name = "lblPort"; - this.lblPort.Size = new System.Drawing.Size(44, 19); + this.lblPort.Size = new System.Drawing.Size(31, 13); this.lblPort.TabIndex = 6; this.lblPort.Text = "Port:"; // @@ -151,7 +176,7 @@ private void InitializeComponent() // this.tbPort.Location = new System.Drawing.Point(81, 50); this.tbPort.Name = "tbPort"; - this.tbPort.Size = new System.Drawing.Size(227, 27); + this.tbPort.Size = new System.Drawing.Size(227, 20); this.tbPort.TabIndex = 5; // // lblHost @@ -159,7 +184,7 @@ private void InitializeComponent() this.lblHost.AutoSize = true; this.lblHost.Location = new System.Drawing.Point(12, 27); this.lblHost.Name = "lblHost"; - this.lblHost.Size = new System.Drawing.Size(47, 19); + this.lblHost.Size = new System.Drawing.Size(33, 13); this.lblHost.TabIndex = 4; this.lblHost.Text = "Host:"; // @@ -167,37 +192,35 @@ private void InitializeComponent() // this.tbHost.Location = new System.Drawing.Point(81, 24); this.tbHost.Name = "tbHost"; - this.tbHost.Size = new System.Drawing.Size(227, 27); + this.tbHost.Size = new System.Drawing.Size(227, 20); this.tbHost.TabIndex = 0; // + // lblScheme + // + this.lblScheme.AutoSize = true; + this.lblScheme.Location = new System.Drawing.Point(140, 139); + this.lblScheme.Name = "lblScheme"; + this.lblScheme.Size = new System.Drawing.Size(48, 13); + this.lblScheme.TabIndex = 1; + this.lblScheme.Text = "Scheme:"; + // // label1 // - this.label1.Location = new System.Drawing.Point(8, 243); + this.label1.Location = new System.Drawing.Point(8, 280); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(320, 17); this.label1.TabIndex = 6; // - // cbUseSsl - // - this.cbUseSsl.AutoSize = true; - this.cbUseSsl.Location = new System.Drawing.Point(20, 223); - this.cbUseSsl.Name = "cbUseSsl"; - this.cbUseSsl.Size = new System.Drawing.Size(86, 23); - this.cbUseSsl.TabIndex = 8; - this.cbUseSsl.Text = "Use Ssl"; - this.cbUseSsl.UseVisualStyleBackColor = true; - // // MongoDBConnectionEditor // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 19F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.cbUseSsl); this.Controls.Add(this.gbDatabase); this.Controls.Add(this.btnAdvanced); this.Controls.Add(this.gbServer); this.Controls.Add(this.label1); this.Name = "MongoDBConnectionEditor"; - this.Size = new System.Drawing.Size(504, 263); + this.Size = new System.Drawing.Size(336, 298); this.gbDatabase.ResumeLayout(false); this.gbDatabase.PerformLayout(); this.gbServer.ResumeLayout(false); @@ -224,5 +247,7 @@ private void InitializeComponent() private System.Windows.Forms.Label lblPort; private System.Windows.Forms.TextBox tbPort; private System.Windows.Forms.CheckBox cbUseSsl; + private System.Windows.Forms.Label lblScheme; + private System.Windows.Forms.ComboBox comboBoxScheme; } } diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs index ed19ce0d..e427f2d6 100644 --- a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs @@ -12,6 +12,7 @@ using MongoDB.Driver; using FastReport.Utils; using FastReport.Data; +using MongoDB.Driver.Core.Configuration; namespace FastReport.Data { @@ -30,23 +31,34 @@ private void btnAdvanced_Click(object sender, EventArgs e) } } + private void comboBoxScheme_SelectedValueChanged(object sender, EventArgs e) + { + if ((ConnectionStringScheme)comboBoxScheme.SelectedItem == ConnectionStringScheme.MongoDBPlusSrv) + tbPort.Enabled = false; + else tbPort.Enabled = true; + } + private void Localize() { MyRes res = new MyRes("ConnectionEditors,Common"); gbServer.Text = res.Get("ServerLogon"); - //lblHost.Text = res.Get("Server"); + lblHost.Text = Res.Get("ConnectionEditors,MongoDB,Host"); + lblPort.Text = Res.Get("ConnectionEditors,MongoDB,Port"); lblUserName.Text = res.Get("UserName"); lblPassword.Text = res.Get("Password"); + lblScheme.Text = Res.Get("ConnectionEditors,MongoDB,Scheme"); gbDatabase.Text = res.Get("Database"); lblDatabase.Text = res.Get("DatabaseName"); btnAdvanced.Text = Res.Get("Buttons,Advanced"); + cbUseSsl.Text = Res.Get("ConnectionEditors,MongoDB,UseSsl"); } protected override string GetConnectionString() { MongoUrlBuilder builder = new MongoUrlBuilder(); + builder.Scheme = (ConnectionStringScheme)comboBoxScheme.SelectedItem; if (!string.IsNullOrEmpty(FConnectionString)) builder = new MongoUrlBuilder(FConnectionString); builder.Server = new MongoServerAddress(tbHost.Text, int.Parse(tbPort.Text)); @@ -57,7 +69,17 @@ protected override string GetConnectionString() builder.UseSsl = cbUseSsl.Checked; } MongoDBDataConnection.dbName = builder.DatabaseName = tbDatabase.Text; +#if NET45 + string url = builder.ToString(); + if(builder.Scheme == ConnectionStringScheme.MongoDBPlusSrv && builder.Server.Port != 27017) + { + string portString = builder.Server.Port.ToString(); + url = url.Remove(url.IndexOf(portString) - 1, 1).Replace(portString, ""); + } + return url; +#else return builder.ToMongoUrl().Url; +#endif } protected override void SetConnectionString(string value) @@ -77,6 +99,7 @@ protected override void SetConnectionString(string value) public MongoDBConnectionEditor() { InitializeComponent(); + comboBoxScheme.DataSource = Enum.GetValues(typeof(ConnectionStringScheme)); Localize(); } } diff --git a/FastReport.Base/Barcode/Barcode2DBase.cs b/FastReport.Base/Barcode/Barcode2DBase.cs index 66b98543..162e8d5a 100644 --- a/FastReport.Base/Barcode/Barcode2DBase.cs +++ b/FastReport.Base/Barcode/Barcode2DBase.cs @@ -35,12 +35,15 @@ private void DrawBarcode(IGraphicsRenderer g, float width, float height) if (showText) { string data = StripControlCodes(text); - // When we print, .Net automatically scales the font. However, we need to handle this process. - // Downscale the font to the screen resolution, then scale by required value (ky). - float fontZoom = 18f / (int)g.MeasureString(data, FFont).Height * ky; - using (Font drawFont = new Font(FFont.Name, FFont.Size * fontZoom, FFont.Style)) + if (data.Length > 0) { - g.DrawString(data, drawFont, Brushes.Black, new RectangleF(0, height - 18 * ky, width, 18 * ky)); + // When we print, .Net automatically scales the font. However, we need to handle this process. + // Downscale the font to the screen resolution, then scale by required value (ky). + float fontZoom = 18f / (int)g.MeasureString(data, FFont).Height * ky; + using (Font drawFont = new Font(FFont.Name, FFont.Size * fontZoom, FFont.Style)) + { + g.DrawString(data, drawFont, Brushes.Black, new RectangleF(0, height - 18 * ky, width, 18 * ky)); + } } } } diff --git a/FastReport.Base/Barcode/Barcode2of5.cs b/FastReport.Base/Barcode/Barcode2of5.cs index 3eaeb54d..be7024aa 100644 --- a/FastReport.Base/Barcode/Barcode2of5.cs +++ b/FastReport.Base/Barcode/Barcode2of5.cs @@ -1,5 +1,7 @@ +using FastReport.Utils; using System; using System.Collections.Generic; +using System.Drawing; using System.Text; namespace FastReport.Barcode @@ -72,10 +74,148 @@ public Barcode2of5Interleaved() } } - /// - /// Generates the "2/5 Industrial" barcode. - /// - public class Barcode2of5Industrial : Barcode2of5Interleaved + /// + /// Generates the "ITF-14" barcode. + /// + public class BarcodeITF14 : Barcode2of5Interleaved + { + #region Fields + private bool drawVerticalBearerBars = true; + + #endregion + + #region Properties + /// + /// Gets or sets the value indicating that vertical bearer bars are needed to draw. + /// + [System.ComponentModel.DefaultValue(true)] + [System.ComponentModel.Category("Appearance")] + public bool DrawVerticalBearerBars + { + get + { + return this.drawVerticalBearerBars; + } + set + { + this.drawVerticalBearerBars = value; + } + } + + #endregion + + #region Internal Methods + internal override string GetPattern() + { + string result = ""; // Startcode + for(int i = 0; i < 14; i++)//10 for light margin and 4 for vertical bearer bar + { + result += "0"; + } + result += "5050"; + string c; + + if (CalcCheckSum) + { + base.text = DoCheckSumming(base.text, 14); + } + else base.text = SetLen(14); + + for (int i = 0; i < (base.text.Length / 2); i++) + { + for (int j = 0; j <= 4; j++) + { + if (tabelle_2_5[CharToInt(base.text[i * 2]), j] == 1) + c = "6"; + else + c = "5"; + result += c; + + if (tabelle_2_5[CharToInt(base.text[i * 2 + 1]), j] == 1) + c = "1"; + else + c = "0"; + result += c; + } + } + + result += "605"; //Stopcode + for (int i = 0; i < 14; i++)//10 for light margin and 4 for vertical bearer bar + { + result += "0"; + } + return result; + } + + internal override void DrawText(IGraphicsRenderer g, string data) + { + data = StripControlCodes(data); + DrawString(g, 0, drawArea.Width, data.Insert(1, " ").Insert(4, " ").Insert(10, " ").Insert(16, " ")); + } + + internal override void Serialize(FRWriter writer, string prefix, BarcodeBase diff) + { + base.Serialize(writer, prefix, diff); + BarcodeITF14 c = diff as BarcodeITF14; + + if (c == null || DrawVerticalBearerBars != c.DrawVerticalBearerBars) + writer.WriteValue(prefix + "DrawVerticalBearerBars", DrawVerticalBearerBars); + } + + #endregion + + #region Public Methods + /// + public override void Assign(BarcodeBase source) + { + base.Assign(source); + + BarcodeITF14 src = source as BarcodeITF14; + DrawVerticalBearerBars = src.DrawVerticalBearerBars; + } + + public override void DrawBarcode(IGraphicsRenderer g, RectangleF displayRect) + { + base.DrawBarcode(g, displayRect); + float bearerWidth = WideBarRatio * 2 * zoom; + using (Pen pen = new Pen(Color, bearerWidth)) + { + float x0 = displayRect.Left; + float x01 = displayRect.Left + bearerWidth / 2; + float y0 = displayRect.Top; + float y01 = displayRect.Top + bearerWidth / 2; + float x1 = displayRect.Left + displayRect.Width; + float x11 = displayRect.Left + displayRect.Width - bearerWidth / 2; + float y1 = displayRect.Top + barArea.Bottom * zoom; + float y11 = displayRect.Top + barArea.Bottom * zoom - bearerWidth / 2; + + g.DrawLine(pen, x0, y01 - 0.5F, x1, y01 - 0.5F); + g.DrawLine(pen, x0, y11, x1, y11); + if (this.drawVerticalBearerBars) + { + g.DrawLine(pen, x01 - 0.5F, y0, x01 - 0.5F, y1); + g.DrawLine(pen, x11, y0, x11, y1); + } + } + } + + #endregion + + /// + /// Initializes a new instance of the class with default settings. + /// + public BarcodeITF14() + { + ratioMin = 2.25F; + ratioMax = 3.0F; + WideBarRatio = 2.25F; + } + } + + /// + /// Generates the "2/5 Industrial" barcode. + /// + public class Barcode2of5Industrial : Barcode2of5Interleaved { internal override string GetPattern() { diff --git a/FastReport.Base/Barcode/BarcodeObject.cs b/FastReport.Base/Barcode/BarcodeObject.cs index bce816e6..11f8c81b 100644 --- a/FastReport.Base/Barcode/BarcodeObject.cs +++ b/FastReport.Base/Barcode/BarcodeObject.cs @@ -54,6 +54,28 @@ namespace FastReport.Barcode /// public partial class BarcodeObject : ReportComponentBase { + /// + /// Specifies the horizontal alignment of a Barcode object. Works only when autosize is on. + /// + public enum Alignment + { + /// + /// Specifies that the barcode is aligned to the left of the original layout. + /// + Left, + + /// + /// Specifies that the barcode is aligned to the center of the original layout. + /// + Center, + + /// + /// Specifies that the barcode is aligned to the right of the original layout. + /// + Right + } + + #region Fields private int angle; private bool autoSize; @@ -70,6 +92,8 @@ public partial class BarcodeObject : ReportComponentBase private bool allowExpressions; private string savedText; private bool asBitmap; + private Alignment horzAlign; + private RectangleF origRect; #endregion #region Properties @@ -89,6 +113,17 @@ public BarcodeBase Barcode } } + /// + /// Gets or sets the horizontal alignment of a Barcode object. + /// + [DefaultValue(Alignment.Left)] + [Category("Appearance")] + public Alignment HorzAlign + { + get { return horzAlign; } + set { horzAlign = value; } + } + /// /// Gets or sets the symbology name. /// @@ -359,7 +394,31 @@ public void UpdateAutoSize() if (size.Height > 0) Width = size.Height + Padding.Horizontal; } + RelocateAlign(); + } + } + + /// + /// Relocate BarcodeObject based on alignment + /// + public void RelocateAlign() + { + if (HorzAlign == Alignment.Left || origRect == RectangleF.Empty) + return; + switch( HorzAlign) + { + case Alignment.Center: + { + this.Left = origRect.Left + (origRect.Width / 2) - this.Width / 2; + break; + } + case Alignment.Right: + { + this.Left = origRect.Right - this.Width; + break; + } } + origRect = RectangleF.Empty; } /// @@ -382,6 +441,7 @@ public override void Assign(Base source) Brackets = src.Brackets; AllowExpressions = src.AllowExpressions; AsBitmap = src.AsBitmap; + HorzAlign = src.HorzAlign; } /// @@ -454,6 +514,8 @@ public override void Serialize(FRWriter writer) writer.WriteStr("Brackets", Brackets); if (AsBitmap != c.AsBitmap) writer.WriteBool("AsBitmap", AsBitmap); + if (HorzAlign != c.HorzAlign) + writer.WriteValue("HorzAlign", HorzAlign); Barcode.Serialize(writer, "Barcode.", c.Barcode); } @@ -543,6 +605,7 @@ public override void GetData() { try { + origRect = this.Bounds; UpdateAutoSize(); } catch @@ -593,6 +656,7 @@ public BarcodeItem(Type objType, string barcodeName) new BarcodeItem(typeof(Barcode2of5Interleaved), "2/5 Interleaved"), new BarcodeItem(typeof(Barcode2of5Industrial), "2/5 Industrial"), new BarcodeItem(typeof(Barcode2of5Matrix), "2/5 Matrix"), + new BarcodeItem(typeof(BarcodeITF14), "ITF-14"), new BarcodeItem(typeof(BarcodeCodabar), "Codabar"), new BarcodeItem(typeof(Barcode128), "Code128"), new BarcodeItem(typeof(Barcode39), "Code39"), diff --git a/FastReport.Base/Code/AssemblyDescriptor.cs b/FastReport.Base/Code/AssemblyDescriptor.cs index 5aafc705..d90ff99e 100644 --- a/FastReport.Base/Code/AssemblyDescriptor.cs +++ b/FastReport.Base/Code/AssemblyDescriptor.cs @@ -396,6 +396,11 @@ private void InternalCompile() if (Config.TempFolder != null) cp.TempFiles = new TempFileCollection(Config.TempFolder, false); + if (Config.WebMode && + Config.EnableScriptSecurity && + Config.ScriptSecurityProps.AddStubClasses) + AddStubClasses(); + string errors = string.Empty; CompilerResults cr; bool exception = !InternalCompile(cp, out cr); @@ -407,7 +412,7 @@ private void InternalCompile() if (exception) throw new CompilerException(errors); } - + private string GetAssemblyHash(CompilerParameters cp) { StringBuilder assemblyHashSB = new StringBuilder(); diff --git a/FastReport.Base/Code/StubClasses.cs b/FastReport.Base/Code/StubClasses.cs new file mode 100644 index 00000000..85a6f134 --- /dev/null +++ b/FastReport.Base/Code/StubClasses.cs @@ -0,0 +1,478 @@ + +namespace FastReport.Code +{ + internal partial class AssemblyDescriptor + { + private void AddStubClasses() + { + const string stubClassesCSharp = @" +namespace System +{ +internal static class Activator {} +internal static class AppContext {} +internal static class AppDomain {} +internal static class Environment {} +} + +namespace System.IO +{ +internal static class Directory {} +internal static class DirectoryInfo {} +internal static class DriveInfo {} +internal static class File {} +internal static class FileInfo {} +internal static class FileStream {} +internal static class FileSystemInfo {} +internal static class Path {} +} + +namespace System.Diagnostics +{ +internal static class FileVersionInfo {} +internal static class Process {} +internal static class ProcessModule {} +internal static class ProcessStartInfo {} +internal static class ProcessThread {} +internal static class ProcessThreadCollection {} +internal static class StackFrame {} +} + +namespace System.Reflection +{ +internal static class Assembly {} +internal static class AssemblyExtensions {} +internal static class Binder {} +internal static class ConstructorInfo {} +internal static class EventInfo {} +internal static class FieldInfo {} +internal static class LocalVariableInfo {} +internal static class MemberInfo {} +internal static class MethodBase {} +internal static class MethodInfo {} +internal static class Module {} +internal static class ParameterInfo {} +internal static class PropertyInfo {} +internal static class ReflectionContext {} +internal static class TypeInfo {} +} + +namespace System.Timers +{ +internal static class Timer {} +} + +namespace System.Windows.Forms +{ +internal static class Timer {} +} + +namespace System.Threading +{ +internal static class AsyncLocal {} +internal static class Barrier {} +internal static class Interlocked {} +internal static class Monitor {} +internal static class Mutex {} +internal static class Overlapped {} +internal static class Semaphore {} +internal static class SemaphoreSlim {} +internal static class SynchronizationContext {} +internal static class Thread {} +internal static class ThreadPool {} +internal static class Timer {} +internal static class Volatile {} +} + +namespace System.Threading.Tasks +{ +internal static class ConcurrentExclusiveSchedulerPair {} +internal static class Parallel {} +internal static class Task {} +internal static class Task {} +internal static class TaskCompletionSource {} +internal static class TaskFactory {} +internal static class TaskFactory {} +internal static class TaskScheduler {} +} + +namespace System.Net +{ +internal static class AuthenticationManager {} +internal static class Authorization {} +internal static class Cookie {} +internal static class Dns {} +internal static class DnsEndPoint {} +internal static class EndPoint {} +internal static class FileWebRequest {} +internal static class FileWebResponse {} +internal static class FtpWebRequest {} +internal static class FtpWebResponse {} +internal static class HttpListener {} +internal static class HttpListenerContext {} +internal static class HttpListenerRequest {} +internal static class HttpListenerResponse {} +internal static class HttpWebRequest {} +internal static class HttpWebResponse {} +internal static class IPAddress {} +internal static class NetworkCredential {} +internal static class ServicePoint {} +internal static class ServicePointManager {} +internal static class TransportContext {} +internal static class WebClient {} +internal static class WebProxy {} +internal static class WebRequest {} +internal static class WebResponse {} +internal static class Uri {} +} + +namespace System.Net.Http +{ +internal static class ByteArrayContent {} +internal static class FormUrlEncodedContent {} +internal static class HttpClient {} +internal static class HttpContent {} +internal static class HttpMethod {} +internal static class HttpRequestMessage {} +internal static class HttpResponseMessage {} +internal static class MultipartContent {} +internal static class MultipartFormDataContent {} +internal static class ReadOnlyMemoryContent {} +internal static class StreamContent {} +internal static class StringContent {} +} + +namespace System.Web.UI +{ +internal static class Timer {} +} + +namespace FastReport.Utils +{ +internal static class Config {} +} +"; + + const string stubClassesVBNet = @" +Namespace System + Friend Module Activator + End Module + + Friend Module AppContext + End Module + + Friend Module AppDomain + End Module + + Friend Module Environment + End Module +End Namespace + +Namespace System.IO + Friend Module Directory + End Module + + Friend Module DirectoryInfo + End Module + + Friend Module DriveInfo + End Module + + Friend Module File + End Module + + Friend Module FileInfo + End Module + + Friend Module FileStream + End Module + + Friend Module FileSystemInfo + End Module + + Friend Module Path + End Module +End Namespace + +Namespace System.Diagnostics + Friend Module FileVersionInfo + End Module + + Friend Module Process + End Module + + Friend Module ProcessModule + End Module + + Friend Module ProcessStartInfo + End Module + + Friend Module ProcessThread + End Module + + Friend Module ProcessThreadCollection + End Module + + Friend Module StackFrame + End Module +End Namespace + +Namespace System.Reflection + Friend Module Assembly + End Module + + Friend Module AssemblyExtensions + End Module + + Friend Module Binder + End Module + + Friend Module ConstructorInfo + End Module + + Friend Module EventInfo + End Module + + Friend Module FieldInfo + End Module + + Friend Module LocalVariableInfo + End Module + + Friend Module MemberInfo + End Module + + Friend Module MethodBase + End Module + + Friend Module MethodInfo + End Module + + Friend Module [Module] + End Module + + Friend Module ParameterInfo + End Module + + Friend Module PropertyInfo + End Module + + Friend Module ReflectionContext + End Module + + Friend Module TypeInfo + End Module +End Namespace + +Namespace System.Timers + Friend Module Timer + End Module +End Namespace + +Namespace System.Windows.Forms + Friend Module Timer + End Module +End Namespace + +Namespace System.Threading + Friend Module AsyncLocal + End Module + + Friend Module Barrier + End Module + + Friend Module Interlocked + End Module + + Friend Module Monitor + End Module + + Friend Module Mutex + End Module + + Friend Module Overlapped + End Module + + Friend Module Semaphore + End Module + + Friend Module SemaphoreSlim + End Module + + Friend Module SynchronizationContext + End Module + + Friend Module Thread + End Module + + Friend Module ThreadPool + End Module + + Friend Module Timer + End Module + + Friend Module Volatile + End Module +End Namespace + +Namespace System.Threading.Tasks + Friend Module ConcurrentExclusiveSchedulerPair + End Module + + Friend Module Parallel + End Module + + Friend Module Task + End Module + + Friend Module Task(Of TResult) + End Module + + Friend Module TaskCompletionSource(Of TResult) + End Module + + Friend Module TaskFactory + End Module + + Friend Module TaskFactory(Of TResult) + End Module + + Friend Module TaskScheduler + End Module +End Namespace + +Namespace System.Net + Friend Module AuthenticationManager + End Module + + Friend Module Authorization + End Module + + Friend Module Cookie + End Module + + Friend Module Dns + End Module + + Friend Module DnsEndPoint + End Module + + Friend Module EndPoint + End Module + + Friend Module FileWebRequest + End Module + + Friend Module FileWebResponse + End Module + + Friend Module FtpWebRequest + End Module + + Friend Module FtpWebResponse + End Module + + Friend Module HttpListener + End Module + + Friend Module HttpListenerContext + End Module + + Friend Module HttpListenerRequest + End Module + + Friend Module HttpListenerResponse + End Module + + Friend Module HttpWebRequest + End Module + + Friend Module HttpWebResponse + End Module + + Friend Module IPAddress + End Module + + Friend Module NetworkCredential + End Module + + Friend Module ServicePoint + End Module + + Friend Module ServicePointManager + End Module + + Friend Module TransportContext + End Module + + Friend Module WebClient + End Module + + Friend Module WebProxy + End Module + + Friend Module WebRequest + End Module + + Friend Module WebResponse + End Module + + Friend Module Uri + End Module +End Namespace + +Namespace System.Net.Http + Friend Module ByteArrayContent + End Module + + Friend Module FormUrlEncodedContent + End Module + + Friend Module HttpClient + End Module + + Friend Module HttpContent + End Module + + Friend Module HttpMethod + End Module + + Friend Module HttpRequestMessage + End Module + + Friend Module HttpResponseMessage + End Module + + Friend Module MultipartContent + End Module + + Friend Module MultipartFormDataContent + End Module + + Friend Module ReadOnlyMemoryContent + End Module + + Friend Module StreamContent + End Module + + Friend Module StringContent + End Module +End Namespace + +Namespace System.Web.UI + Friend Module Timer + End Module +End Namespace + +Namespace FastReport.Utils + Friend Module Config + End Module +End Namespace +"; + + if (Report.ScriptLanguage == Language.CSharp) + scriptText.Append(stubClassesCSharp); + else + scriptText.Append(stubClassesVBNet); + } + } +} diff --git a/FastReport.Base/Data/CsvDataConnection.cs b/FastReport.Base/Data/CsvDataConnection.cs index 44a14735..993917a5 100644 --- a/FastReport.Base/Data/CsvDataConnection.cs +++ b/FastReport.Base/Data/CsvDataConnection.cs @@ -5,6 +5,7 @@ using System.Data; using System.Data.Common; using System.IO; +using System.Net; namespace FastReport.Data { @@ -295,7 +296,39 @@ protected override DataSet CreateDataSet() if (!String.IsNullOrEmpty(CsvFile) && !String.IsNullOrEmpty(Separator)) { string allText = ""; - using (StreamReader reader = new StreamReader(CsvFile, Encoding.GetEncoding(Codepage))) + + WebRequest request; + WebResponse response = null; + try + { + Uri uri = new Uri(CsvFile); + + if (uri.IsFile) + { + request = (FileWebRequest)WebRequest.Create(uri); + request.Timeout = 5000; + response = (FileWebResponse)request.GetResponse(); + } + else if (uri.OriginalString.StartsWith("http")) + { + request = (HttpWebRequest)WebRequest.Create(uri); + request.Timeout = 5000; + response = (HttpWebResponse)request.GetResponse(); + } + else if (uri.OriginalString.StartsWith("ftp")) + { + request = (FtpWebRequest)WebRequest.Create(uri); + request.Timeout = 5000; + response = (FtpWebResponse)request.GetResponse(); + } + } + catch(Exception e) + { + throw e; + } + if (response == null) return dataset; + + using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(Codepage))) { allText = reader.ReadToEnd(); } diff --git a/FastReport.Base/Data/DataConnectionBase.cs b/FastReport.Base/Data/DataConnectionBase.cs index 97be1626..b4f9ab31 100644 --- a/FastReport.Base/Data/DataConnectionBase.cs +++ b/FastReport.Base/Data/DataConnectionBase.cs @@ -113,7 +113,10 @@ public string ConnectionString [Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))] public string ConnectionStringExpression { - get { return connectionStringExpression; } + get + { + return connectionStringExpression; + } set { connectionStringExpression = value; } } @@ -495,7 +498,7 @@ public DbConnection GetConnection() return null; } - + /// /// Opens a specified connection object. @@ -565,9 +568,9 @@ public void DisposeConnection(DbConnection connection) if (ShouldNotDispose(connection)) return; - - if (connection != null) - connection.Dispose(); + + if (connection != null) + connection.Dispose(); } /// diff --git a/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs index b2343ccc..28d28bfe 100644 --- a/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs +++ b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnection.cs @@ -2,8 +2,10 @@ using System; using System.Data; using System.Data.Common; +using System.Linq; using System.Net; using System.Text; +using System.Windows.Forms; namespace FastReport.Data.JsonConnection { @@ -182,22 +184,37 @@ private void InitConnection(bool rebuildSchema) JsonDataSourceConnectionStringBuilder builder = new JsonDataSourceConnectionStringBuilder(ConnectionString); JsonBase obj = null; string jsonText = builder.Json.Trim(); - if(jsonText.Length >0) + if (jsonText.Length > 0) { - if(!(jsonText[0] == '{' || jsonText[0] == '[')) + if (!(jsonText[0] == '{' || jsonText[0] == '[')) { - using (WebClient client = new WebClient()) + //using (WebClient client = new WebClient()) + //{ + // try + // { + // client.Encoding = Encoding.GetEncoding(builder.Encoding); + // } + // catch + // { + // client.Encoding = Encoding.UTF8; + // } + // jsonText = client.DownloadString(jsonText); + //} + + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(jsonText); + + foreach (var header in builder.Headers) { - try - { - client.Encoding = Encoding.GetEncoding(builder.Encoding); - } - catch - { - client.Encoding = Encoding.UTF8; - } - jsonText = client.DownloadString(jsonText); + req.Headers.Add(header.Key, header.Value); } + + using (var response = req.GetResponse()) + { + byte[] data = new byte[2048]; + response.GetResponseStream().Read(data, 0, data.Length); + jsonText = Encoding.UTF8.GetString(data); + } + } obj = JsonBase.FromString(jsonText) as JsonBase; } diff --git a/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs index 08c2018d..b5d83b51 100644 --- a/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs +++ b/FastReport.Base/Data/JsonConnection/JsonDataSourceConnectionStringBuilder.cs @@ -1,4 +1,9 @@ -using System.Data.Common; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; namespace FastReport.Data.JsonConnection { @@ -21,7 +26,14 @@ public string Json { object result; if (TryGetValue("Json", out result) && result != null) + { + if (Regex.IsMatch((string)result, @"^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)?$")) + { + var base64str = (Convert.FromBase64String(result.ToString())); + return System.Text.Encoding.UTF8.GetString(base64str); + } return (string)result; + } return ""; } set @@ -39,7 +51,14 @@ public string JsonSchema { object result; if (TryGetValue("JsonSchema", out result) && result != null) + { + if (Regex.IsMatch((string)result, @"^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)?$")) + { + var base64str = (Convert.FromBase64String(result.ToString())); + return System.Text.Encoding.UTF8.GetString(base64str); + } return (string)result; + } return ""; } set @@ -66,7 +85,9 @@ public string Encoding } } - + public Dictionary Headers { get; set; } + + #endregion Public Properties @@ -78,6 +99,7 @@ public string Encoding public JsonDataSourceConnectionStringBuilder() { ConnectionString = ""; + Headers = new Dictionary(); } /// @@ -89,8 +111,76 @@ public JsonDataSourceConnectionStringBuilder(string connectionString) : base() { ConnectionString = connectionString; + Headers = new Dictionary(); + //while (ConnectionString.Contains("Header=")) + //{ + object result; + string header = string.Empty; + string[] splittedHeader; + int headerIteration = 0; + while (TryGetValue("Header" + headerIteration.ToString(CultureInfo.InvariantCulture.NumberFormat), out result) && result != null) + { + header = (string)result; + + if (!string.IsNullOrWhiteSpace(header)) + { + splittedHeader = header.Split(':'); + + string headerKey = splittedHeader[0], headerVal = splittedHeader[1]; + + if (Regex.IsMatch(headerKey, @"^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)?$")) + { + var base64str = Convert.FromBase64String(headerKey); + headerKey = System.Text.Encoding.UTF8.GetString(base64str); + } + + if (Regex.IsMatch(headerVal, @"^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)?$")) + { + var base64str = Convert.FromBase64String(headerVal); + headerVal = System.Text.Encoding.UTF8.GetString(base64str); + } + + Headers.Add(headerKey, headerVal); + //ConnectionString = ConnectionString.Replace(header, string.Empty); + } + + headerIteration++; + } + //} } #endregion Public Constructors + + // escape / ; " : + public override string ToString() + { + //TODO: do via stringbuilder + //string connString = $"Json={Json};JsonSchema={JsonSchema};Encoding={Encoding}"; + StringBuilder builder = new StringBuilder(); + builder.Append("Json=").Append(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(Json))) + .Append(";JsonSchema=").Append(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(JsonSchema))) + .Append(";Encoding=").Append(Encoding); + //string connString = "Json=" + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(Json)) + // + ";JsonSchema=" + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(JsonSchema)) + ";Encoding=" + Encoding; + int headerIteration = 0; + foreach (var header in Headers) + { + var headerKey = header.Key; + var headerVal = header.Value; + if (headerKey.Contains(";") || headerKey.Contains(":") || headerKey.Contains("\"") || headerKey.Contains("\'")) + { + headerKey = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(headerKey)); + } + + if (headerVal.Contains(";") || headerVal.Contains(":") || headerVal.Contains("\"") || headerVal.Contains("\'")) + { + headerVal = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(headerVal)); + } + + builder.Append(";Header").Append(headerIteration.ToString(CultureInfo.InvariantCulture.NumberFormat)).Append("=").Append(headerKey).Append(":").Append(headerVal); + //connString += ";Header" + headerIteration + "=" + headerKey + ":" + headerVal; + } + return builder.ToString(); + } } } \ No newline at end of file diff --git a/FastReport.Base/Engine/ReportEngine.Bands.cs b/FastReport.Base/Engine/ReportEngine.Bands.cs index f7f9850d..b8feef34 100644 --- a/FastReport.Base/Engine/ReportEngine.Bands.cs +++ b/FastReport.Base/Engine/ReportEngine.Bands.cs @@ -87,7 +87,7 @@ private void AddToOutputBand(BandBase band, bool getData) private void ShowBandToPreparedPages(BandBase band, bool getData) { // handle "StartNewPage". Skip if it's the first row, avoid empty first page. - if (band.StartNewPage && band.FlagUseStartNewPage && (band.RowNo != 1 || band.FirstRowStartsNewPage) && + if ((band.StartNewPage && !(band.Parent is PageHeaderBand)) && band.FlagUseStartNewPage && (band.RowNo != 1 || band.FirstRowStartsNewPage) && !band.Repeated) { EndColumn(); diff --git a/FastReport.Base/Export/ExportBase.cs b/FastReport.Base/Export/ExportBase.cs index a56b13e9..dadf991e 100644 --- a/FastReport.Base/Export/ExportBase.cs +++ b/FastReport.Base/Export/ExportBase.cs @@ -30,6 +30,7 @@ public partial class ExportBase : Base private bool shiftNonExportable; private string saveInitialDirectory; private List generatedStreams; + protected bool webPreview; #region Properties @@ -479,7 +480,8 @@ internal void ExportPageNew(int pageNo) { (obj as BandBase).Top -= topShift; } - if ((obj as BandBase).Exportable) + if ((obj as BandBase).Exportable + || webPreview) ExportBand(obj); else if (obj != null) { diff --git a/FastReport.Base/Export/Html/HTMLExport.cs b/FastReport.Base/Export/Html/HTMLExport.cs index 951add34..40c1e11b 100644 --- a/FastReport.Base/Export/Html/HTMLExport.cs +++ b/FastReport.Base/Export/Html/HTMLExport.cs @@ -983,6 +983,16 @@ public HTMLExport() res = new MyRes("Export,Html"); embeddedImages = new Dictionary(); } + + /// + /// Initializes a new instance of the class for WebPreview mode. + /// + public HTMLExport(bool webPreview) : this() + { + this.webPreview = webPreview; + if (webPreview) + exportMode = ExportType.WebPreview; + } } /// diff --git a/FastReport.Base/Export/Html/HTMLExportLayers.cs b/FastReport.Base/Export/Html/HTMLExportLayers.cs index 7a1cecb7..052c2303 100644 --- a/FastReport.Base/Export/Html/HTMLExportLayers.cs +++ b/FastReport.Base/Export/Html/HTMLExportLayers.cs @@ -610,7 +610,7 @@ private void LayerShape(FastString Page, ShapeObject obj, FastString text) addstyle.Append(GetStyle()); - addstyle.Append("background: url('" + GetLayerPicture(obj, out Width, out Height) + "');"); + addstyle.Append("background: url('" + GetLayerPicture(obj, out Width, out Height) + "');no-repeat !important;-webkit-print-color-adjust:exact;"); float x = obj.Width > 0 ? obj.AbsLeft : (obj.AbsLeft + obj.Width); float y = obj.Height > 0 ? hPos + obj.AbsTop : (hPos + obj.AbsTop + obj.Height); diff --git a/FastReport.Base/PictureObjectBase.cs b/FastReport.Base/PictureObjectBase.cs index c2dea376..6ddd990b 100644 --- a/FastReport.Base/PictureObjectBase.cs +++ b/FastReport.Base/PictureObjectBase.cs @@ -84,6 +84,7 @@ public abstract partial class PictureObjectBase : ReportComponentBase private string dataColumn; private bool grayscale; private string imageLocation; + private string imageSourceExpression; private float maxHeight; private float maxWidth; private Padding padding; @@ -165,6 +166,42 @@ public string ImageLocation } } + /// + /// Gets or sets the expression that determines the source for the image to display in the PictureObject. + /// + /// + /// The result of the expression should be data column name or path to the image file. + /// The data column name will be saved to the property. + /// The path will be savetd to the property. + /// + [Category("Data")] + [Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))] + public string ImageSourceExpression + { + get { return imageSourceExpression; } + set + { + imageSourceExpression = value; + + if (!String.IsNullOrEmpty(ImageSourceExpression) && Report != null) + { + string expression = ImageSourceExpression; + if (ImageSourceExpression.StartsWith("[") && ImageSourceExpression.EndsWith("]")) + { + expression = ImageSourceExpression.Substring(1, ImageSourceExpression.Length - 2); + } + if (Data.DataHelper.IsValidColumn(Report.Dictionary, expression)) + { + DataColumn = expression; + } + if (Data.DataHelper.IsValidParameter(Report.Dictionary, expression)) + { + ImageLocation = Report.GetParameterValue(expression).ToString(); + } + } + } + } + /// /// Gets a value indicating that the image stored in the databases column /// @@ -324,6 +361,7 @@ public PictureObjectBase() padding = new Padding(); imageLocation = ""; dataColumn = ""; + imageSourceExpression = ""; } #endregion Public Constructors @@ -340,6 +378,7 @@ public override void Assign(Base source) { ImageLocation = src.ImageLocation; DataColumn = src.DataColumn; + ImageSourceExpression = src.ImageSourceExpression; Padding = src.Padding; SizeMode = src.SizeMode; MaxWidth = src.MaxWidth; @@ -718,6 +757,9 @@ public override void Serialize(FRWriter writer) if (DataColumn != c.DataColumn) writer.WriteStr("DataColumn", DataColumn); + if (ImageSourceExpression != c.ImageSourceExpression) + writer.WriteStr("ImageSourceExpression", ImageSourceExpression); + if (Padding != c.Padding) writer.WriteValue("Padding", Padding); if (SizeMode != c.SizeMode) @@ -917,6 +959,19 @@ public override string[] GetExpressions() expressions.AddRange(base.GetExpressions()); if (!String.IsNullOrEmpty(DataColumn)) expressions.Add(DataColumn); + + if (!String.IsNullOrEmpty(ImageSourceExpression)) + { + if (ImageSourceExpression.StartsWith("[") && ImageSourceExpression.EndsWith("]")) + { + expressions.Add(ImageSourceExpression.Substring(1, ImageSourceExpression.Length - 2)); + } + else + { + expressions.Add(ImageSourceExpression); + } + } + return expressions.ToArray(); } } diff --git a/FastReport.Base/Report.cs b/FastReport.Base/Report.cs index 38f7741c..93b32b3d 100644 --- a/FastReport.Base/Report.cs +++ b/FastReport.Base/Report.cs @@ -214,6 +214,7 @@ public partial class Report : Base, IParent, ISupportInitialize private ReportInfo reportInfo; private string baseReport; private Report baseReportObject; + private string baseReportAbsolutePath; private string fileName; private string scriptText; private Language scriptLanguage; @@ -373,6 +374,19 @@ public string BaseReport set { SetBaseReport(value); } } + /// + /// Gets or sets the absolute path to the parent report. + /// + /// + /// This property contains the absolute path to the parent report. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string BaseReportAbsolutePath + { + get { return baseReportAbsolutePath; } + set { baseReportAbsolutePath = value; } + } + /// /// Gets or sets the name of a file the report was loaded from. /// @@ -606,7 +620,14 @@ public StyleCollection Styles public string[] ReferencedAssemblies { get { return referencedAssemblies; } - set { referencedAssemblies = value; } + set { + // fix for old reports with "System.Windows.Forms.DataVisualization" in referenced assemblies + for (int i = 0; i < value.Length;i++) + { + value[i] = value[i].Replace("System.Windows.Forms.DataVisualization", "FastReport.DataVisualization"); + } + referencedAssemblies = value; + } } /// @@ -966,7 +987,13 @@ private void SetBaseReport(string value) { // convert the relative path to absolute path (based on the main report path). if (!Path.IsPathRooted(value)) + { value = Path.GetFullPath(Path.GetDirectoryName(FileName) + Path.DirectorySeparatorChar + value); + } + if (!File.Exists(value) && File.Exists(BaseReportAbsolutePath)) + { + value = BaseReportAbsolutePath; + } Load(value); } @@ -1020,6 +1047,7 @@ private void ClearReportProperties() } ScriptText = codeHelper.EmptyScript(); BaseReport = ""; + BaseReportAbsolutePath = ""; DoublePass = false; ConvertNulls = true; Compressed = false; @@ -1748,6 +1776,9 @@ public override void Serialize(FRWriter writer) // (based on the main report path). Do not convert when saving to the clipboard. string value = writer.SerializeTo != SerializeTo.Undo ? GetRelativePathToBaseReport() : BaseReport; writer.WriteStr("BaseReport", value); + // Fix bug with moving child report to another folder without parent report. + if (writer.SerializeTo == SerializeTo.Report) + writer.WriteStr("BaseReportAbsolutePath", BaseReport); } // always serialize ScriptLanguage because its default value depends on Config.ReportSettings.DefaultLanguage writer.WriteValue("ScriptLanguage", ScriptLanguage); @@ -1794,6 +1825,11 @@ public override void Serialize(FRWriter writer) /// public override void Deserialize(FRReader reader) { + if (reader.HasProperty("BaseReportAbsolutePath")) + { + BaseReportAbsolutePath = reader.ReadStr("BaseReportAbsolutePath"); + } + base.Deserialize(reader); // call OnAfterLoad method of each report object diff --git a/FastReport.Base/ReportPage.cs b/FastReport.Base/ReportPage.cs index 3bd8736c..375f30e7 100644 --- a/FastReport.Base/ReportPage.cs +++ b/FastReport.Base/ReportPage.cs @@ -53,6 +53,7 @@ public partial class ReportPage : PageBase, IParent #endregion // Constants #region Fields + private string exportAlias; private float paperWidth; private float paperHeight; private int rawPaperSize; @@ -122,6 +123,16 @@ public float PaperWidth set { paperWidth = value; } } + /// + /// Gets or sets the page name on export + /// + [Category("Paper")] + public string ExportAlias + { + get { return exportAlias; } + set { exportAlias = value; } + } + /// /// Gets or sets a height of the paper, in millimeters. /// @@ -835,6 +846,7 @@ public override void Assign(Base source) base.Assign(source); ReportPage src = source as ReportPage; + ExportAlias = src.ExportAlias; Landscape = src.Landscape; PaperWidth = src.PaperWidth; PaperHeight = src.PaperHeight; @@ -872,7 +884,8 @@ public override void Serialize(FRWriter writer) { ReportPage c = writer.DiffObject as ReportPage; base.Serialize(writer); - + if (ExportAlias != c.ExportAlias) + writer.WriteStr("ExportAlias", ExportAlias); if (Landscape != c.Landscape) writer.WriteBool("Landscape", Landscape); if (FloatDiff(PaperWidth, c.PaperWidth)) diff --git a/FastReport.Base/Utils/Config.cs b/FastReport.Base/Utils/Config.cs index 2aeaf486..7a5a9bdd 100644 --- a/FastReport.Base/Utils/Config.cs +++ b/FastReport.Base/Utils/Config.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Drawing; using System.Drawing.Text; using System.Globalization; @@ -39,6 +39,8 @@ public static partial class Config private static bool preparedCompressed = true; private static bool disableHotkeys = false; private static bool disableBacklight = false; + private static bool enableScriptSecurity = false; + private static ScriptSecurityProperties scriptSecurityProps = null; #endregion Private Fields @@ -187,6 +189,37 @@ public static PrivateFontCollection PrivateFontCollection { get { return FastReport.TypeConverters.FontConverter.PrivateFontCollection; } } + + /// + /// Enable report script validation. For WebMode only + /// + public static bool EnableScriptSecurity + { + get + { + return enableScriptSecurity; + } + set + { + if (OnEnableScriptSecurityChanged != null) + OnEnableScriptSecurityChanged.Invoke(null, null); + enableScriptSecurity = value; + } + } + + /// + /// Throws when property EnableScriptSecurity has been changed + /// + public static event EventHandler OnEnableScriptSecurityChanged; + + /// + /// Properties of report script validation + /// + public static ScriptSecurityProperties ScriptSecurityProps + { + get { return scriptSecurityProps; } + } + #endregion Public Properties #region Internal Methods @@ -220,8 +253,11 @@ internal static void Init() { #if !COMMUNITY RestoreExportOptions(); + enableScriptSecurity = true; // don't throw event + scriptSecurityProps = new ScriptSecurityProperties(); #endif } + //RestoreScriptSecurity(); LoadPlugins(); // init TextRenderingHint.SystemDefault @@ -438,6 +474,69 @@ private static void RestoreRightToLeft() } } + /// + /// Properties of ScriptSecurity + /// + public class ScriptSecurityProperties + { + private readonly string[] defaultBlackList = new[] + { + "GetType", + "typeof", + "TypeOf", // VB + "DllImport", + "LoadLibrary", + "GetProcAddress", + }; + + private string[] blackList; + + /// + /// Add stubs for the most dangerous classes (in System.IO, System.Reflection etc) + /// + public bool AddStubClasses { get; set; } = true; + + /// + /// List of keywords that shouldn't be declared in the report script + /// + public string[] BlackList + { + get { return (string[])blackList.Clone(); } + set + { + if(value != null) + { + OnBlackListChanged?.Invoke(this, null); + blackList = value; + } + } + } + + /// + /// Throws when has changed + /// + public event EventHandler OnBlackListChanged; + + internal ScriptSecurityProperties() + { + SetDefaultBlackList(); + } + + internal ScriptSecurityProperties(string[] blackList) + { + this.blackList = blackList; + } + + /// + /// Sets default value for + /// + public void SetDefaultBlackList() + { + BlackList = defaultBlackList; + } + + } + private static void SaveUIOptions() { XmlItem xi = Root.FindItem("UIOptions"); diff --git a/FastReport.Base/Utils/FRReader.cs b/FastReport.Base/Utils/FRReader.cs index 0476b358..7ea6c25c 100644 --- a/FastReport.Base/Utils/FRReader.cs +++ b/FastReport.Base/Utils/FRReader.cs @@ -351,10 +351,6 @@ private void DoReadProperties(object obj, XmlProperty[] properties) { if (pi.PropertyType == typeof(string)) { -#if true // Annoying mesage remover - if (value == "") - return; -#endif pi.SetValue(obj1, value, null); } else if (pi.PropertyType.IsClass && pi.PropertyType.IsSubclassOf(typeof(Base))) diff --git a/FastReport.Core.Web/Application/WebReport.cs b/FastReport.Core.Web/Application/WebReport.cs index 84e79e43..414159ee 100644 --- a/FastReport.Core.Web/Application/WebReport.cs +++ b/FastReport.Core.Web/Application/WebReport.cs @@ -119,7 +119,7 @@ public bool ReportPrepared tab.ReportPrepared = value; } } - + /// /// Total prepared pages of current report /// @@ -187,6 +187,12 @@ public WebReport() #endif } + static WebReport() + { + ScriptSecurity = new ScriptSecurity(new ScriptChecker()); + } + + public HtmlString RenderSync() { return Task.Run(() => Render()).Result; @@ -271,6 +277,12 @@ public void GotoPage(int value) CurrentPageIndex = value; } +#endregion + +#region Script Security + + private static ScriptSecurity ScriptSecurity = null; + #endregion } } diff --git a/FastReport.Core.Web/FastReport.OpenSource.Web.csproj b/FastReport.Core.Web/FastReport.OpenSource.Web.csproj index 95ca666f..531e3bd5 100644 --- a/FastReport.Core.Web/FastReport.OpenSource.Web.csproj +++ b/FastReport.Core.Web/FastReport.OpenSource.Web.csproj @@ -32,6 +32,11 @@ Various report objects will allow your report to look exactly how you want it to + + + + Application\%(Filename)%(Extension) + diff --git a/FastReport.Core.Web/FastReport.Web.csproj b/FastReport.Core.Web/FastReport.Web.csproj index dbe72a62..cc12cfd4 100644 --- a/FastReport.Core.Web/FastReport.Web.csproj +++ b/FastReport.Core.Web/FastReport.Web.csproj @@ -34,6 +34,11 @@ $(DemoDescription) + + + Application\%(Filename)%(Extension) + + diff --git a/FastReport.Web.Base/ScriptSecurity.cs b/FastReport.Web.Base/ScriptSecurity.cs new file mode 100644 index 00000000..a9c29d33 --- /dev/null +++ b/FastReport.Web.Base/ScriptSecurity.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FastReport.Utils; +using System.Text.RegularExpressions; + +namespace FastReport.Web +{ + partial class WebReport + { + /// + /// Sets custom class for checking the report script. + /// + /// + public static void SetScriptSecurity(IScriptChecker scriptChecker) + { + ScriptSecurity.Dispose(); + ScriptSecurity = new ScriptSecurity(scriptChecker); + } + + } + + internal class ScriptSecurity : IDisposable + { + private IScriptChecker ScriptChecker; + + internal ScriptSecurity(IScriptChecker checker) + { + ScriptChecker = checker; + Config.ScriptCompile += Config_ScriptCompile; + } + + internal void Config_ScriptCompile(object sender, ScriptSecurityEventArgs e) + { + if(Config.EnableScriptSecurity) + e.IsValid = ScriptChecker.IsValid(e.ReportLanguage, e.ReportScript, e.References, e.Report); + } + + public void Dispose() + { + Config.ScriptCompile -= Config_ScriptCompile; + } + } + + /// + /// Interface for overriding the standard check of the report script + /// + /// + public interface IScriptChecker + { + /// + /// Method for checking the report script + /// + /// Report script language + /// Report script + /// Referenced assemblies + /// Report + /// Returns true if the report passed the validation check + bool IsValid(Language lang, string reportScript, string[] references, Report report); + } + + internal class ScriptChecker : IScriptChecker + { + public bool IsValid(Language lang, string reportScript, string[] references, Report report) + { + // LOGIC + foreach(string reference in references) + { + // in .Net Core need to add reference + if (reference.IndexOf("System.IO.FileSystem") != -1) + return false; + + if (reference.IndexOf("Microsoft.AspNetCore") != -1) + return false; + + if(reference.IndexOf("System.Net") != -1) + return false; + } + + foreach (string pattern in Config.ScriptSecurityProps.BlackList) + { + if (reportScript.IndexOf(pattern) != -1) + return false; + + //regex = new Regex(pattern); + //if (regex.IsMatch(reportScript)) + } + + return true; + } + } +} diff --git a/FastReport/Resources/en.xml b/FastReport/Resources/en.xml index 9ddbbf87..96f28b48 100644 --- a/FastReport/Resources/en.xml +++ b/FastReport/Resources/en.xml @@ -1988,7 +1988,7 @@ - + @@ -2019,8 +2019,17 @@ + + + + + + + + + @@ -2121,30 +2130,31 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UsedPackages.version b/UsedPackages.version index b855082c..f5d9f505 100644 --- a/UsedPackages.version +++ b/UsedPackages.version @@ -5,20 +5,20 @@ 2020.3.7 - 2020.3.1 + 2020.3.8 - 2020.3.4 + 2020.3.17 - 2020.3.4 + 2020.3.17 - 2020.3.4 + 2020.3.17 - 2020.3.4 + 2020.3.17