Click here to Skip to main content
15,892,927 members
Articles / Programming Languages / C#

EasiReports

Rate me:
Please Sign up or sign in to vote.
4.87/5 (64 votes)
13 Feb 2006CPOL6 min read 481.7K   9.7K   219  
A library to add reports to your application.
using System.Diagnostics;
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;
using System.Runtime.Serialization;
using EasiReports.Report;

namespace EasiReports
{
	/// <summary>
	/// Summary description for DesignControl.
	/// </summary>
	internal class CDesignControl : System.Windows.Forms.UserControl
	{
		public bool FitToPage = false;
		public float ScaleX = 1.0f;
		public float ScaleY = 1.0f;

		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		private System.Windows.Forms.HScrollBar HScrollBar;
		private System.Windows.Forms.VScrollBar VScrollBar;
		private System.Windows.Forms.Panel Panel;

		private HelpProvider HelpProvider = new HelpProvider();

		private EasiReport _Report = null;

		private SectionControlCollection SectionControls = new SectionControlCollection();

		private int m_iMaxY = 0;

		private bool m_bDragging = false;
		private int m_iDragSection = -1;
		private int m_iDragY = 0;
		private int m_iDragAutoScrollPositionY = 0;

		public CDesignControl( EasiReport r )
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			HelpProvider.HelpNamespace = Glob.HelpNamespace;
			HelpProvider.SetHelpNavigator( this, Glob.HelpNavigator );
			HelpProvider.SetHelpKeyword( this, "EasiReporter.Views.Design.htm" );

			_Report = r;

			SetFromReport();
		}

		/// <summary>Clean up any resources being used.</summary>
		/// <param name="disposing"><b>true</b> to release both managed and unmanaged resources; <b>false</b> to release only unmanaged resources.</param>
		/// <remarks>Releases the unmanaged resources and optionally releases the managed resources.</remarks>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.HScrollBar = new System.Windows.Forms.HScrollBar();
			this.VScrollBar = new System.Windows.Forms.VScrollBar();
			this.Panel = new System.Windows.Forms.Panel();
			this.SuspendLayout();
			// 
			// HScrollBar
			// 
			this.HScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.HScrollBar.Location = new System.Drawing.Point(0, 304);
			this.HScrollBar.Name = "HScrollBar";
			this.HScrollBar.Size = new System.Drawing.Size(424, 17);
			this.HScrollBar.TabIndex = 0;
			this.HScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.HScrollBar_Scroll);
			// 
			// VScrollBar
			// 
			this.VScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.VScrollBar.Location = new System.Drawing.Point(423, 0);
			this.VScrollBar.Name = "VScrollBar";
			this.VScrollBar.Size = new System.Drawing.Size(17, 303);
			this.VScrollBar.TabIndex = 1;
			this.VScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.VScrollBar_Scroll);
			// 
			// Panel
			// 
			this.Panel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.Panel.Location = new System.Drawing.Point(424, 304);
			this.Panel.Name = "Panel";
			this.Panel.Size = new System.Drawing.Size(16, 16);
			this.Panel.TabIndex = 2;
			// 
			// CDesignControl
			// 
			this.Controls.Add(this.Panel);
			this.Controls.Add(this.VScrollBar);
			this.Controls.Add(this.HScrollBar);
			this.Name = "CDesignControl";
			this.Size = new System.Drawing.Size(440, 320);
			this.ResumeLayout(false);

		}
		#endregion

//-----------------------------------------------------------------------------

		public void InvalidateSection( CSectionControl c )
		{
			Rectangle r = new Rectangle( c.Location, c.Size );
			r.Offset( ScrollPosition.X, ScrollPosition.Y );
			
			r.X      = (int) ( ( r.X      - 2 ) * ScaleX );
			r.Width  = (int) ( ( r.Width  + 4 ) * ScaleX );
			r.Y      = (int) ( ( r.Y      - 2 ) * ScaleY );
			r.Height = (int) ( ( r.Height + 4 ) * ScaleY );

			Invalidate( r );
		}

		public void InvalidateSection( CSectionControl c, Rectangle r )
		{
			r.Offset( c.Location.X, c.Location.Y );
			r.Offset( ScrollPosition.X, ScrollPosition.Y );

			r.X      = (int) ( ( r.X      - 2 ) * ScaleX );
			r.Width  = (int) ( ( r.Width  + 4 ) * ScaleX );
			r.Y      = (int) ( ( r.Y      - 2 ) * ScaleY );
			r.Height = (int) ( ( r.Height + 4 ) * ScaleY );

			Invalidate( r );
		}

//-----------------------------------------------------------------------------

		protected override void OnPaintBackground( PaintEventArgs e )
		{
//			base.OnPaintBackground( pe );

			Matrix mOld = e.Graphics.Transform;
			Matrix mNew = mOld.Clone();
			mNew.Scale( ScaleX, ScaleY );
			mNew.Translate( ScrollPosition.X, ScrollPosition.Y );
			e.Graphics.Transform = mNew;

			Region rOld = e.Graphics.Clip;
			Region rNew = e.Graphics.Clip.Clone();
			rNew.Exclude( new Rectangle( 0, 0, _Report.Width, m_iMaxY - 1 ) );
			e.Graphics.Clip = rNew;

			SolidBrush b = new SolidBrush( BackColor );
			using ( b ) e.Graphics.FillRegion( b, rNew );

			e.Graphics.Clip = rOld;
			rNew.Dispose();

			foreach ( CSectionControl sc in SectionControls )
				sc.OnPaintBackground( e );

			e.Graphics.Transform = mOld;
			mNew.Dispose();
		}

		protected override void OnPaint( PaintEventArgs e )
		{
			base.OnPaint( e );

			Matrix mOld = e.Graphics.Transform;
			Matrix mNew = mOld.Clone();
			mNew.Scale( ScaleX, ScaleY );
			mNew.Translate( ScrollPosition.X, ScrollPosition.Y );
			e.Graphics.Transform = mNew;

			int y = 0;

			foreach ( CSectionControl sc in SectionControls )
			{
				string sDisplayText = sc.section.DisplayText;
				if ( sc.Focused ) sDisplayText += " +";
				DrawButton( e.Graphics, 0, y, sDisplayText, sc.Focused );
				
				Region rOld = e.Graphics.Clip;
				Region rNew = e.Graphics.Clip.Clone();
				Rectangle r = new Rectangle( sc.Location, sc.Size );
				r.X -= 0;
				r.Width += 0;
				r.Y -= 1;
				r.Height += 1;
				rNew.Intersect( r );
				e.Graphics.Clip = rNew;

//				e.Graphics.FillRegion( Brushes.Red, e.Graphics.Clip );
				sc.OnPaint( e );

				e.Graphics.Clip = rOld;
				rNew.Dispose();

				y += 22 + sc.Height;
			}

			DrawButton( e.Graphics, 0, y, "End", false );

			e.Graphics.Transform = mOld;
			mNew.Dispose();
		}

		protected void DrawButton( Graphics g, int x, int y, string text, bool bFocused )
		{
			Rectangle r = new Rectangle( x, y, _Report.Width, 21 );
//			r.Inflate( -1, -1 );
//			r.X += 1; r.Y += 1; r.Width -= 1; r.Height -= 1;
//			ControlPaint.DrawButton( g, r, ButtonState.Normal | ( bFocused ? ButtonState.Pushed : ButtonState.Normal ) );
			
			SolidBrush b;

			if ( !bFocused )
			{
				b = new SolidBrush( Color.FromKnownColor( KnownColor.Control ) );
				using ( b ) g.FillRectangle( b, r );
			}
			else
				g.FillRectangle( Brushes.AliceBlue, r );

			Pen p = new Pen( ForeColor, 1 );
			using( p ) g.DrawRectangle( p, r );

			r.Inflate( -2, -2 );

			b = new SolidBrush( ForeColor );

			FontEX f = Font; if ( bFocused ) f.Bold = true;

			using ( b )
			using ( f )
				g.DrawString( text, f, b, r );
		}

//-----------------------------------------------------------------------------

		protected override void OnKeyDown( KeyEventArgs e )
		{
			base.OnKeyDown( e );

			ReportControl p = Parent as ReportControl;
			if ( p == null ) { Debug.Assert( false ); return; }
			p.OnKeyDownFromChild( e );

			foreach ( CSectionControl c in SectionControls )
				if ( c.Focused )
					c.OnKeyDown( e );
		}

//-----------------------------------------------------------------------------
// Scrolling

		protected override void OnSizeChanged( EventArgs e )
		{
			base.OnSizeChanged( e );

			SetScrollLimits();
		}

		public void SetScrollLimits()
		{
			if ( _Report == null ) return;

			if ( FitToPage )
			{
				float f = Size.Width / (float) ( _Report.Width + 69 );
				if ( f < 0.5 ) f = 0.5f;
				ScaleX = f;
				ScaleY = f;
			}

			int dx = _Report.Width - (int)( Size.Width / ScaleX ) + 69;
			if ( dx < 0 ) dx = 0;
			if ( HScrollBar.Value > dx ) HScrollBar.Value = dx;
			HScrollBar.Maximum = dx;

			int dy = 0;
			foreach ( CSectionControl sc in SectionControls )
				dy += 22 + sc.Height;
			dy += 9;
			if ( VScrollBar.Value > dy ) VScrollBar.Value = dy;
			VScrollBar.Maximum = dy;

			Invalidate( true );
		}

		private void HScrollBar_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e)
		{
			Invalidate();
		}

		private void VScrollBar_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e)
		{
			Invalidate();
		}


		public Point ScrollPosition
		{
			get
			{
				return new Point( - HScrollBar.Value, - VScrollBar.Value );
			}
		}

//-----------------------------------------------------------------------------
// Drag sections

		private int iFocusedSection
		{
			get
			{
				for ( int i = 0 ; i < SectionControls.Count ; i++ )
					if ( SectionControls[ i ].Focused )
						return i;

				return -1;
			}
		}

		protected override void OnGotFocus( EventArgs e )
		{
			base.OnGotFocus( e );

			if ( iFocusedSection >= 0 ) return;

			if ( SectionControls.Count > 0 )
				SetFocus( 0 );
		}

		private void SetFocus( int index )
		{
			for ( int i = 0 ; i < SectionControls.Count ; i++ )
			{
				bool b = ( i == index );

				if ( SectionControls[ i ].Focused != b )
					 SectionControls[ i ].Focused  = b ;
			}

			Invalidate();
		}

		protected override void OnMouseDown( MouseEventArgs e )
		{
			base.OnMouseDown( e );

			int x = (int) ( e.X / ScaleX );
			int y = (int) ( e.Y / ScaleY );

			int iSection = GetSectionIncludingBars( x - ScrollPosition.X, y - ScrollPosition.Y );
			if ( iSection >= 0 ) SetFocus( iSection );

			if ( e.Button == MouseButtons.Left )
			{
				m_iDragSection = GetSectionBarsOnly( x - ScrollPosition.X, y - ScrollPosition.Y ) - 1;
				if ( m_iDragSection >= 0 )
				{
					m_bDragging = true;
					CSectionControl c = SectionControls[ m_iDragSection ];
					m_iDragY = y - ScrollPosition.Y - c.Location.Y - c.Size.Height;
					m_iDragAutoScrollPositionY = ScrollPosition.Y;
				}
			}
			else
			{
				foreach ( CSectionControl sc in SectionControls )
					if ( sc.Focused )
						ContextMenu = sc.ContextMenu;
			}

			iSection = GetSectionExcludingBars( x - ScrollPosition.X, y - ScrollPosition.Y );
			if ( iSection >= 0 && iSection < SectionControls.Count )
				SectionControls[ iSection ].OnMouseDown( new MouseEventArgs( e.Button, e.Clicks, x, y, e.Delta ) );
		}

		protected override void OnMouseHover( EventArgs e )
		{
			base.OnMouseHover( e );

			Point p = PointToClient( Control.MousePosition );

			int x = (int) ( p.X / ScaleX );
			int y = (int) ( p.Y / ScaleY );

			int iSection = GetSectionExcludingBars( x - ScrollPosition.X, y - ScrollPosition.Y );
			if ( iSection >= 0 && iSection < SectionControls.Count )
				SectionControls[ iSection ].OnMouseHover( e );
		}
		
		protected override void OnMouseMove( MouseEventArgs e )
		{
			base.OnMouseMove( e );

			int x = (int) ( e.X / ScaleX );
			int y = (int) ( e.Y / ScaleY );

			if ( m_bDragging )
			{
//				AutoScrollPosition = new Point( -AutoScrollPosition.X, -m_iDragAutoScrollPositionY );

				CSectionControl c = SectionControls[ m_iDragSection ];
				Section s = c.section;

				int dy = y - m_iDragAutoScrollPositionY - c.Location.Y - m_iDragY;
				if ( dy < 0 ) dy = 0;
				if ( s.Grid.UseGrid ) dy = s.Grid.ToGridY( dy );

//				c.Size = new Size( c.Width, dy );
				c.Height = dy;
				s.Height = dy;

				LayoutSectionsNoSetScrollLimits();
				Invalidate();
			}

//			int iSection = GetSectionExcludingBars( e.X - ScrollPosition.X, e.Y - ScrollPosition.Y );
//			if ( iSection >= 0 && iSection < SectionControls.Count )
//				SectionControls[ iSection ].OnMouseMove( e );

			MouseEventArgs e2 = new MouseEventArgs( e.Button, e.Clicks, x, y, e.Delta );
			foreach ( CSectionControl c in SectionControls )
				c.OnMouseMove( e2 );
		}

		protected override void OnMouseUp( MouseEventArgs e )
		{
			base.OnMouseUp( e );

			int x = (int) ( e.X / ScaleX );
			int y = (int) ( e.Y / ScaleY );

			if ( m_bDragging ) SetScrollLimits();

			m_bDragging = false;
			m_iDragSection = -1;
			m_iDragY = 0;
			m_iDragAutoScrollPositionY = 0;

			//			int iSection = GetSectionExcludingBars( e.X - ScrollPosition.X, e.Y - ScrollPosition.Y );
			//			if ( iSection >= 0 && iSection < SectionControls.Count )
			//				SectionControls[ iSection ].OnMouseUp( e );

			MouseEventArgs e2 = new MouseEventArgs( e.Button, e.Clicks, x, y, e.Delta );
			foreach ( CSectionControl c in SectionControls )
				c.OnMouseUp( e2 );
		}

		protected override void OnDoubleClick( EventArgs e )
		{
			base.OnDoubleClick( e );

			Point p = PointToClient( MousePosition );

			int x = (int) ( p.X / ScaleX );
			int y = (int) ( p.Y / ScaleY );

			int iSection = GetSectionIncludingBars( x - ScrollPosition.X, y - ScrollPosition.Y );

			if ( iSection >= 0 )
				SectionControls[ iSection ].OnDoubleClick( e );
			else
				ShowReportProperties();
		}

		protected int GetSectionIncludingBars( int x, int y )
		{
			if ( x > _Report.Width ) return -1;

			int cy = 0;
			int i = 0;

			foreach ( CSectionControl sc in SectionControls )
			{
				cy += sc.Height + 22;
				if ( y < cy ) return i;
				i++;
			}

			return -1;
		}

		protected int GetSectionExcludingBars( int x, int y )
		{
			if ( x > _Report.Width ) return -1;

			int cy = 0;
			int i = 0;

			foreach ( CSectionControl sc in SectionControls )
			{
				cy += 22;
				if ( y < cy ) return -1;

				cy += sc.Height;
				if ( y < cy ) return i;

				i++;
			}

			return -1;
		}

		protected int GetSectionBarsOnly( int x, int y )
		{
			if ( x > _Report.Width ) return -1;

			int cy = 0;
			int i = 0;

			foreach ( CSectionControl sc in SectionControls )
			{
				cy += 22;
				if ( y < cy ) return i;

				cy += sc.Height;
				if ( y < cy ) return -1;

				i++;
			}

			cy += 22;
			if ( y < cy ) return i;

			return -1;
		}

//-----------------------------------------------------------------------------

		internal bool ChildControlIsSelected
		{
			get
			{
				foreach ( CSectionControl sc in SectionControls )
					if ( sc.ChildControlIsSelected )
						return true;

				return false;
			}
		}

		internal void RaiseSelectionChanged()
		{
			ReportControl p = Parent as ReportControl;
			if ( p == null ) { Debug.Assert( true ); return; }

			p.RaiseSelectionChanged();
		}

		internal bool PasteIsAvailable
		{
			get
			{
				IDataObject d = null;

				try
				{
					d = Clipboard.GetDataObject();
				}
				catch ( SerializationException )
				{
					Debug.Assert( false );
					return false;
				}
				catch
				{
					Debug.Assert( false );
					return false;
				}

				if ( d == null ) { Debug.Assert( false ); return false; }

				if ( d.GetDataPresent( typeof( LineDesignControl      ) ) ) return true;
				if ( d.GetDataPresent( typeof( LabelDesignControl     ) ) ) return true;
				if ( d.GetDataPresent( typeof( DataDesignControl      ) ) ) return true;
				if ( d.GetDataPresent( typeof( AggregateDesignControl ) ) ) return true;
				if ( d.GetDataPresent( typeof( AlgorithmDesignControl ) ) ) return true;

				return false;
			}
		}

		internal void Cut()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.Cut();
		}

		internal void Copy()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.Copy();
		}

		internal void Paste()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.Paste();
		}

		internal void Delete()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.Delete();
		}

		internal void NewLine()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.NewLine();
		}

		internal void NewLable()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.NewLabel();
		}

		internal void NewData()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.NewData();
		}

		internal void NewAggregate()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.NewAggregate();
		}

		[ Obsolete ]
		internal void NewAlgorithm()
		{
			Debug.Assert( false );

//			foreach ( CSectionControl sc in SectionControls )
//				if ( sc.Focused )
//					sc.NewAlgorithm();
		}

		internal void BringSelectedToFront()
		{
			foreach ( CSectionControl sc in SectionControls )
				sc.BringSelectedToFront();
		}

		internal void SendSelectedToBack()
		{
			foreach ( CSectionControl sc in SectionControls )
				sc.SendSelectedToBack();
		}

		internal bool SectionPropertiesIsAvailable
		{
			get
			{
				foreach ( CSectionControl sc in SectionControls )
					if ( sc.Focused )
						return true;

				return false;
			}
		}

		internal bool ControlPropertiesIsAvailable
		{
			get
			{
				return ChildControlIsSelected;
			}
		}


//-----------------------------------------------------------------------------

		public void ShowReportProperties()
		{
			CDlgReport dlg = new CDlgReport( _Report );
			if ( dlg.ShowDialog( this ) != DialogResult.OK ) return;

			SetFromReport();
		}

		public void ShowSectionProperties()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.ShowSectionProperties();
		}

		public void ShowControlProperties()
		{
			foreach ( CSectionControl sc in SectionControls )
				if ( sc.Focused )
					sc.ShowControlProperties();
		}

//-----------------------------------------------------------------------------

		protected void NewSectionControl( int index, Section section )
		{
			CSectionControl sc = new CSectionControl( this, section );
			SectionControls.Insert( index, sc );
//			SectionControls.SetChildIndex( sc, index );

			LayoutSections();
		}

		public void LayoutSections()
		{
			LayoutSectionsNoSetScrollLimits();

			SetScrollLimits();
		}

		private void LayoutSectionsNoSetScrollLimits()
		{
			int y = 0;

			foreach ( CSectionControl sc in SectionControls )
			{
				sc.Location = new Point( 0, y + 22 );
				y += 22 + sc.Height;
			}

			m_iMaxY = y + 22;
		}

		private void SetFromReport()
		{
			int iOldFocusedSection = iFocusedSection;
			SectionControls.Clear();

			if ( _Report == null ) { Debug.Assert(false); return; }

			SuspendLayout();

			NewSectionControl( 0, _Report.ReportSectionPair.Header );
			NewSectionControl( 1, _Report.PageSectionPair.Header );
			foreach( SectionPair sp in _Report.SectionPairs ) NewSectionControl( 2, sp.Header );
			int i = _Report.SectionPairs.Count + 2;
			NewSectionControl( i++, _Report.DetailsSection );
			foreach( SectionPair sp in _Report.SectionPairs ) NewSectionControl( i++, sp.Footer );
			NewSectionControl( i++, _Report.PageSectionPair.Footer );
			NewSectionControl( i++, _Report.ReportSectionPair.Footer );

			LayoutSections();

			ResumeLayout();

			if ( iOldFocusedSection >= 0 && iOldFocusedSection < SectionControls.Count )
				SetFocus( iOldFocusedSection );
			else
				SetFocus( 0 );

			Invalidate();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
I discovered C# and .NET 1.0 Beta 1 in late 2000 and loved them immediately.
I have been writing software professionally in C# ever since

In real life, I have spent 3 years travelling abroad,
I have held a UK Private Pilots Licence for 20 years,
and I am a PADI Divemaster.

I now live near idyllic Bournemouth in England.

I can work 'virtually' anywhere!

Comments and Discussions