diff options
author | AlexKlimenkov <shurick.klimenkov@gmail.com> | 2017-02-17 13:45:02 +0300 |
---|---|---|
committer | AlexKlimenkov <shurick.klimenkov@gmail.com> | 2017-02-17 13:45:02 +0300 |
commit | e495105f25efd2b401c79a1be1b2abd0264b4226 (patch) | |
tree | b4386cefc590345e669dddee95c326feab17084c | |
download | scheduler-export-net-e495105f25efd2b401c79a1be1b2abd0264b4226.zip scheduler-export-net-e495105f25efd2b401c79a1be1b2abd0264b4226.tar.gz scheduler-export-net-e495105f25efd2b401c79a1be1b2abd0264b4226.tar.bz2 |
[add] initial commitHEADorigin/masterorigin/HEADmaster
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | DHTMLX.Export.PDF.sln | 22 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/DHTMLX.Export.PDF.csproj | 76 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/MonthRow.cs | 13 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/PDFImages.cs | 33 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/PDFPage.cs | 27 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/PDFWriter.cs | 2141 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/Properties/AssemblyInfo.cs | 36 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/RGBColor.cs | 75 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/Resizer.cs | 68 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/SchedulerEvent.cs | 161 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/SchedulerMonth.cs | 60 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/TreeTimelineParser.cs | 61 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/XMLParser.cs | 344 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/lib/ExtendLib.cs | 489 | ||||
-rw-r--r-- | DHTMLX.Export.PDF/packages.config | 5 | ||||
-rw-r--r-- | README.md | 84 | ||||
-rw-r--r-- | packages/repositories.config | 4 |
18 files changed, 3704 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b2fc13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin +obj +*.suo +**/packages/* +!**/packages/repositories.config
\ No newline at end of file diff --git a/DHTMLX.Export.PDF.sln b/DHTMLX.Export.PDF.sln new file mode 100644 index 0000000..901de5c --- /dev/null +++ b/DHTMLX.Export.PDF.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2013 for Web +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DHTMLX.Export.PDF", "DHTMLX.Export.PDF/DHTMLX.Export.PDF.csproj", "{11B5A6CD-281E-4BC3-BC54-425BD7B467EA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {11B5A6CD-281E-4BC3-BC54-425BD7B467EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {11B5A6CD-281E-4BC3-BC54-425BD7B467EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11B5A6CD-281E-4BC3-BC54-425BD7B467EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {11B5A6CD-281E-4BC3-BC54-425BD7B467EA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DHTMLX.Export.PDF/DHTMLX.Export.PDF.csproj b/DHTMLX.Export.PDF/DHTMLX.Export.PDF.csproj new file mode 100644 index 0000000..b3ef1d8 --- /dev/null +++ b/DHTMLX.Export.PDF/DHTMLX.Export.PDF.csproj @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{11B5A6CD-281E-4BC3-BC54-425BD7B467EA}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>DHTMLX.Export.PDF</RootNamespace> + <AssemblyName>DHTMLX.Export.PDF.Scheduler</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <TargetFrameworkProfile /> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <ItemGroup> + <Reference Include="HtmlAgilityPack"> + <HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath> + </Reference> + <Reference Include="PdfSharp"> + <HintPath>..\packages\PDFsharp.1.32.3057.0\lib\net20\PdfSharp.dll</HintPath> + </Reference> + <Reference Include="PdfSharp.Charting"> + <HintPath>..\packages\PDFsharp.1.32.3057.0\lib\net20\PdfSharp.Charting.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Web" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="lib\ExtendLib.cs" /> + <Compile Include="MonthRow.cs" /> + <Compile Include="PDFImages.cs" /> + <Compile Include="PDFPage.cs" /> + <Compile Include="PDFWriter.cs" /> + <Compile Include="Resizer.cs" /> + <Compile Include="SchedulerEvent.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="RGBColor.cs" /> + <Compile Include="SchedulerMonth.cs" /> + <Compile Include="TreeTimelineParser.cs" /> + <Compile Include="XMLParser.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/MonthRow.cs b/DHTMLX.Export.PDF/MonthRow.cs new file mode 100644 index 0000000..0b5d60e --- /dev/null +++ b/DHTMLX.Export.PDF/MonthRow.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace DHTMLX.Export.PDF +{ + public class MonthRow + { + public double Height { get; set; } + public string[] Cells { get; set; } + } +} diff --git a/DHTMLX.Export.PDF/PDFImages.cs b/DHTMLX.Export.PDF/PDFImages.cs new file mode 100644 index 0000000..8411f37 --- /dev/null +++ b/DHTMLX.Export.PDF/PDFImages.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.IO; +using PdfSharp.Drawing; +using System.Drawing; + +using DHTMLX.Export.PDF.Scheduler; +namespace DHTMLX.Export.PDF.Scheduler +{ + public class PDFImages + { + + private Dictionary<string, XImage> _cache = new Dictionary<string, XImage>(); + public XImage Get(string path) + { + if (_cache.ContainsKey(path)) + { + return _cache[path]; + } + + if (File.Exists(path)) + { + FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read); + var img = new Bitmap(fileStream, false); + _cache.Add(path, (XImage)img); + + return _cache[path]; + } + + return null; + } + + } +} diff --git a/DHTMLX.Export.PDF/PDFPage.cs b/DHTMLX.Export.PDF/PDFPage.cs new file mode 100644 index 0000000..ad2a91e --- /dev/null +++ b/DHTMLX.Export.PDF/PDFPage.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using DHTMLX.Export.PDF.Scheduler; +using System.Xml; + +namespace DHTMLX.Export.PDF +{ + public class PDFPage + { + public List<SchedulerEvent> Multiday { get; set; } + public List<SchedulerEvent> Events { get; set; } + public PDFPage() + { + Multiday = new List<SchedulerEvent>(); + Events = new List<SchedulerEvent>(); + } + public ColorProfile Profile { get; set; } + public bool Header { get; set; } + public bool Footer { get; set; } + public string Mode { get; set; } + public string TodayLabel { get; set; } + public XmlNode Node { get; set; } + public string[][] Cols { get; set; } + public string[,] Rows { get; set; } + public List<MonthRow> RowObs { get; set; } + + } +} diff --git a/DHTMLX.Export.PDF/PDFWriter.cs b/DHTMLX.Export.PDF/PDFWriter.cs new file mode 100644 index 0000000..f4ce115 --- /dev/null +++ b/DHTMLX.Export.PDF/PDFWriter.cs @@ -0,0 +1,2141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using PdfSharp; +using System.IO; +using PdfSharp.Drawing; +using System.Web; +using PdfSharp.Pdf; + +using PdfSharp.Drawing.Layout; +using DHTMLX.Export.PDF.Formatter; +using DHTMLX.Export.PDF.Scheduler; + +using HtmlAgilityPack; + +namespace DHTMLX.Export.PDF +{ + public enum Orientation + { + Default, + Landscape, + Portrait + } + public class SchedulerPDFWriter + { + + public Orientation Orientation = Orientation.Default; + public string HeaderImgPath = "header.png"; + public string FooterImgPath = "footer.png"; + public double HeaderImgHeight = 100; + public double FooterImgHeight = 100; + public double BaseFontSize = 7.0; + public double WeekAgendarDayFont = 9.4; + + public bool TrimContentStrings = true; + public bool TrimLayoutStrings = true; + public bool MultipageMonthLayout = false; + public double HeaderFontSize = 7.0; + public double TimelineRowMinHeight = 50; + public double BorderWidth = 0.5; + + protected XMLParser Parser; + protected PdfDocument Pdf; + protected PdfPage Page; + protected List<PdfPage> Pages; + protected List<XGraphics> Graphics; + protected XGraphics Gfx; + protected XFont F1; + protected PDFImages Images = new PDFImages(); + protected bool NeedPagesNums; + + private Resizer _resizer; + private double _pageWidth; + private double _pageHeight; + + private double _initialOffsetTop = 30; + private double _initialOffsetBottom = 30; + private double _initialOffsetLeft = 30; + private double _initialOffsetRight = 30; + + private double _offsetTop = 30; + private double _offsetBottom = 30; + private double _offsetLeft = 30; + private double _offsetRight = 30; + private double _headHeight = 20; + private double _monthDayHeaderHeight = 20; + private double _monthEventHeight = 12; + private double _leftScaleWidth = 80; + private double _timelineLeft = 80; + private double _monthEventOffsetLeft = 2; + private double _monthEventOffsetTop = 2; + private double _yearMonthOffsetLeft = 10; + private double _yearMonthOffsetTop = 10; + private double _yearMonthLabelHeight = 20; + private double _weekEventHeaderHeight = 10; + private double _agendaColOneWidth = 150; + private double _multidayLineHeight = 14; + private double _weekAgendaEventHeight = 20; + + private string _pageNumTemplate = "Page {pageNum}/{allNum}"; + + private double _monthDayWidth; + private double _monthDayHeight; + private double _contHeight; + private double _contWidth; + + private double _weekDayWidth; + private double _weekDayHeight; + private double _headerHeight; + private double _multiHeight; + + private ColorProfile _profile; + + private double _cellOffset = 3; + + private string _bgColor = "C2D5FC"; + private string _lineColor = "586A7E"; + private string _headerLineColor = "FFFFFF"; + + private string _dayHeaderColor = "EBEFF4"; + private string _watermarkTextColor = "8b8b8b"; + private string _dayBodyColor = "FFFFFF"; + private string _dayHeaderColorInactive = "E2E3E6"; + private string _dayBodyColorInactive = "ECECEC"; + private string _eventColor = "FFE763"; + private string _eventTextColor = "887A2E"; + private string _scaleOneColor = "FCFEFC"; + private string _scaleTwoColor = "DCE6F4"; + private string _timelineTreeColor = "969394"; + private string _eventBorderColor = "B7A543"; + private string _textColor = "000000"; + private string _yearDayActiveColor = "EBEFF4"; + private string _yearDayInactiveColor = "D6D6D6"; + private string _multidayColor = "E1E6FF"; + private string _matrixEventColor = "FFFFFF"; + private string _view; + private string _watermark; + + public string ContentType { get { return "application/pdf"; } } + protected PDFPage CurrentPage { get; set; } + + private double[] SelectColor(string fullColor, double[] def) + { + if ((fullColor != "transparent") + && ((_profile == ColorProfile.FullColor) || (_profile == ColorProfile.Color))) + { + return RGBColor.GetColor(fullColor); + } + return def; + } + + + private string StripHtml(string html) + { + return HtmlEntity.DeEntitize(html); + } + private string TextWrap(string text, double width, XFont f, bool actuallyDo) + { + text = StripHtml(text); + + if (!actuallyDo) + return text; + return TextWrap(text, width, f); + } + + private string TextWrap(string text, double width, XFont f) + { + text = StripHtml(text); + + width = _resizer.ResizeX(width); + if ((Gfx.MeasureString(text, f).Width <= width) || (text.Length == 0)) + { + return text; + } + while ((Gfx.MeasureString(text + "...", f).Width > width) && (text.Length > 0)) + { + text = text.Substring(0, text.Length - 1); + } + return text + "..."; + } + public double[] GetSizes(PageOrientation orientation, PageSize size) + { + var sizes = new double[2]; + var siz = PageSizeConverter.ToSize(size); + + if (orientation == PageOrientation.Landscape) + { + + sizes[0] = siz.Height; + sizes[1] = siz.Width; + } + else + { + sizes[1] = siz.Height; + sizes[0] = siz.Width; + } + + return sizes; + + } + private void SetColorProfile(ColorProfile profile) + { + if ((profile == ColorProfile.Color) || (profile == ColorProfile.FullColor)) + { + _bgColor = "C2D5FC"; + _lineColor = "c1d4fc"; + _headerLineColor = "FFFFFF"; + _dayHeaderColor = "EBEFF4"; + _dayBodyColor = "FFFFFF"; + _dayHeaderColorInactive = "E2E3E6"; + _dayBodyColorInactive = "ECECEC"; + _eventColor = "FFE763"; + _eventTextColor = "887A2E"; + _scaleOneColor = "FCFEFC"; + _scaleTwoColor = "DCE6F4"; + + _timelineTreeColor = "969394"; + + _eventBorderColor = "B7A543"; + _textColor = "000000"; + _yearDayActiveColor = "EBEFF4"; + _yearDayInactiveColor = "D6D6D6"; + _multidayColor = "E1E6FF"; + _matrixEventColor = "FFFFFF"; + _watermarkTextColor = "8b8b8b"; + } + else + { + if (profile == ColorProfile.Gray) + { + _bgColor = "D3D3D3"; + _lineColor = "666666"; + _headerLineColor = "FFFFFF"; + _dayHeaderColor = "EEEEEE"; + _dayBodyColor = "FFFFFF"; + _dayHeaderColorInactive = "E3E3E3"; + _dayBodyColorInactive = "ECECEC"; + _eventColor = "DFDFDF"; + _eventTextColor = "000000"; + _scaleOneColor = "FFFFFF"; + + _timelineTreeColor = "BBBBBB"; + + _scaleTwoColor = "E4E4E4"; + _eventBorderColor = "9F9F9F"; + _textColor = "000000"; + _yearDayActiveColor = "EBEFF4"; + _yearDayInactiveColor = "E2E3E6"; + _multidayColor = "E7E7E7"; + _matrixEventColor = "FFFFFF"; + _watermarkTextColor = "8b8b8b"; + } + else + { + _bgColor = "FFFFFF"; + _lineColor = "000000"; + _headerLineColor = "000000"; + _dayHeaderColor = "FFFFFF"; + _dayBodyColor = "FFFFFF"; + _dayHeaderColorInactive = "FFFFFF"; + _dayBodyColorInactive = "FFFFFF"; + _eventColor = "FFFFFF"; + _eventTextColor = "000000"; + + _timelineTreeColor = "FFFFFF"; + + _scaleOneColor = "FFFFFF"; + _scaleTwoColor = "FFFFFF"; + _eventBorderColor = "000000"; + _textColor = "000000"; + _yearDayActiveColor = "FFFFFF"; + _yearDayInactiveColor = "FFFFFF"; + _multidayColor = "FFFFFF"; + _matrixEventColor = "FFFFFF"; + _watermarkTextColor = "000000"; + } + } + } + private void CreatePdf(PageOrientation orientation, PageSize size) + { + _resizer = new Resizer(orientation, Orientation); + + if (Pdf == default(PdfDocument)) + { + Pdf = new PdfDocument(); + F1 = CreateFont("Helvetica", 10); + Pdf.Version = 14; + Pages = new List<PdfPage>(); + } + NewPage(_resizer.Orient, size); + } + + protected PdfPage NewPage(PageOrientation orient, PageSize size) + { + Page = new PdfPage(Pdf); + Pdf.AddPage(Page); + + Gfx = XGraphics.FromPdfPage(Page, XGraphicsPdfPageOptions.Replace); + if (Graphics == null) + Graphics = new List<XGraphics>(); + Graphics.Add(Gfx); + Pages.Add(Page); + + Page.Size = size; + Page.Orientation = orient; + + TodayLabelDraw(Gfx); + + _headerHeight = _headHeight; + _offsetTop = _initialOffsetTop; + _offsetBottom = _initialOffsetBottom; + _offsetLeft = _initialOffsetLeft; + _offsetRight = _initialOffsetRight; + + var sizes = GetSizes(_resizer.Orient, size); + _pageWidth = sizes[0] - _offsetLeft - _offsetRight; + _pageHeight = sizes[1] - _offsetTop - _offsetBottom; + + PrintHeader(); + PrintFooter(); + return Page; + } + protected XFont CreateFont(string name, double size) + { + var fontSettings = new XPdfFontOptions(PdfFontEncoding.Unicode); + return new XFont(name, size, new XFontStyle(), fontSettings); + } + + + public MemoryStream Generate(string xml) + { + var data = new MemoryStream(); + + Generate(xml, data); + return data; + } + public void Generate(string xml, HttpResponse resp) + { + if (resp == default(HttpResponse)) + { + throw new ArgumentNullException("resp", "HttpResponse is null"); + } + var data = new MemoryStream(); + + resp.ContentType = ContentType; + resp.HeaderEncoding = Encoding.UTF8; + + resp.AppendHeader("Cache-Control", "max-age=0"); + Generate(xml, data); + + try + { + data.WriteTo(resp.OutputStream); + } + catch (Exception e) + { + throw new Exception("Can't write to the output stream:" + e.Message); + } + + } + public void PrintPage(PDFPage page) + { + _view = page.Mode; + _profile = page.Profile; + SetColorProfile(_profile); + + + CurrentPage = page; + switch (_view) + { + case "month": + PrintMonth(page); + break; + case "year": + PrintYear(page); + break; + case "agenda": + case "map": + PrintAgenda(page); + break; + case "treetimeline": + case "timeline": + PrintTimeline(page); + break; + case "matrix": + PrintMatrix(page); + break; + case "week_agenda": + PrintWeekAgenda(page); + break; + default: + PrintWeek(page); + break; + } + + PrintWatermark(); + } + + public void PrintPages() + { + foreach (var i in Parser.Pages) + { + PrintPage(i); + } + } + + public void Generate(string xml, Stream resp) + { + if (string.IsNullOrEmpty(xml)) + { + throw new ArgumentException("Input string is null or empty!", "xml"); + } + Parser = new XMLParser(); + + try + { + + var pages = Parser.GetPages(xml); + foreach (var page in pages) + { + Parser.SetXML(page); + PrintPages(); + } + if (NeedPagesNums) + { + AgendaPagesDraw(); + } + OutputPdf(resp); + } + catch (Exception e) + { + throw; + } + } + + private void OutputPdf(Stream resp) + { + Pdf.Save(resp, false); + } + + private void PrintMonth(PDFPage page) + { + CreatePdf(PageOrientation.Landscape, PageSize.A4); + MonthHeaderDraw(); + MonthContainerDraw(); + MonthEventsDraw(page); + + } + + private void PrintYear(PDFPage page) + { + CreatePdf(PageOrientation.Landscape, PageSize.A4); + YearDraw(page); + } + + private void PrintAgenda(PDFPage page) + { + CreatePdf(PageOrientation.Portrait, PageSize.A4); + AgendaHeaderDraw(); + AgendaEventDraw(page); + NeedPagesNums = true; + } + + private void PrintTimeline(PDFPage page) + { + _leftScaleWidth = _timelineLeft; + var size = PageSize.A4; + CreatePdf(PageOrientation.Landscape, size); + + var rows = Parser.WeekRowsParsing(CurrentPage); + var blocksNumber = (int)((_pageHeight - _headerHeight) / TimelineRowMinHeight); + + var pages = (int)Math.Ceiling((double)rows.Length / (double)blocksNumber); + NeedPagesNums = true; + for (var i = 0; i < pages; i++) + { + var currentPageRows = rows.Skip(i * blocksNumber).Take(blocksNumber).ToArray(); + WeekHeaderDraw(); + TimelineContainerDraw(currentPageRows); + TimelineEventsDraw(page, i + 1, blocksNumber); + if (i != pages - 1) + { + NewPage(_resizer.Orient, size); + } + } + } + + private void PrintMatrix(PDFPage page) + { + _leftScaleWidth = _timelineLeft; + CreatePdf(PageOrientation.Landscape, PageSize.A4); + WeekHeaderDraw(); + MatrixContainerDraw(page); + } + + private void PrintWeek(PDFPage page) + { + CreatePdf(PageOrientation.Portrait, PageSize.A4); + WeekHeaderDraw(); + WeekMultidayDraw(page); + WeekContainerDraw(); + WeekEventsDraw(page); + if (_profile == ColorProfile.BW) + WeekBwBordersDraw(); + } + + private void PrintWeekAgenda(PDFPage page) + { + + CreatePdf(PageOrientation.Portrait, PageSize.A4); + var events = page.Events.ToArray(); + WeekAgendaContainerDraw(); + while (events.Length > 0) + { + + events = WeekAgendaEventsDraw(events); + if (events.Length > 0) + { + Page = NewPage(PageOrientation.Portrait, PageSize.A4); + WeekAgendaContainerDraw(); + } + } + } + + private void PrintWatermark() + { + if (_watermark == null) return; + + F1 = CreateFont(F1.FontFamily.Name, 10); + + for (var i = 1; i <= Pages.Count; i++) + { + var graph = Graphics[i - 1]; + + var text = new XTextFormatter(graph); + var x = _offsetLeft; + var y = _pageHeight + _offsetTop + F1.Size; + text.DrawString(_watermark, F1, new XSolidBrush(RGBColor.GetXColor(_watermarkTextColor)), _resizer.Rect(x, y, graph.MeasureString(_watermark, F1).Width, F1.Size)); + } + } + + private void MonthHeaderDraw() + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_headerLineColor); + var cols = Parser.MonthColsParsing(CurrentPage); + var width = _pageWidth / cols[0].Length; + var height = _headerHeight; + var x = _offsetLeft; + var y = _offsetTop; + + var font = new XFont(F1.FontFamily.Name, F1.Size); + + for (var i = 0; i < cols[0].Length; i++) + { + XRect cell = _resizer.Rect(x, y, width, height); + + Gfx.DrawRectangle(new XSolidBrush(RGBColor.GetXColor(bgColor)), cell); + + if (i > 0) + { + var points = new XPoint[4]; + points[0] = _resizer.Point(x, y); + points[1] = _resizer.Point(x, y + height); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), 1), points[0], points[1]); + } + + var text = new XTextFormatter(Gfx); + var content = TextWrap(cols[0][i], width - 2 * _cellOffset, font, TrimLayoutStrings); + var textX = x + (width - Gfx.MeasureString(content, F1).Width) / 2; + var textY = y + (height - F1.Size) / 2; + + text.DrawString(content, font, new XSolidBrush(RGBColor.GetXColor(RGBColor.GetColor(_textColor))), _resizer.Rect(textX, textY, Gfx.MeasureString(content, F1).Width, font.Size)); + + x += width; + } + } + + private void MonthContainerDraw() + { + var borderColor = RGBColor.GetColor(_lineColor); + var dayHeaderColor = RGBColor.GetColor(_dayHeaderColor); + var dayBodyColor = RGBColor.GetColor(_dayBodyColor); + var dayHeaderColorInactive = RGBColor + .GetColor(_dayHeaderColorInactive); + var dayBodyColorInactive = RGBColor + .GetColor(_dayBodyColorInactive); + var rows = Parser.MonthRowsParsing(CurrentPage); + var width = _pageWidth / 7; + var height = (_pageHeight - _headerHeight) / rows.GetLength(0); + _monthDayWidth = width; + _monthDayHeight = height; + var x = _offsetLeft; + var y = _offsetTop + _headerHeight; + for (var i = 0; i < rows.GetLength(0); i++) + { + + for (var j = 0; j < rows.GetLength(1); j++) + { + var activeDay = GetActiveDay(rows, i, j); + + var cell = _resizer.Rect(x, y, width, height); + var cellIn = _resizer.Rect(x, y, width, _monthDayHeaderHeight); + XBrush cellInBrush, cellBrush; + if (activeDay) + { + cellBrush = new XSolidBrush(RGBColor.GetXColor(dayBodyColor)); + cellInBrush = new XSolidBrush(RGBColor.GetXColor(dayHeaderColor)); + } + else + { + cellBrush = new XSolidBrush(RGBColor.GetXColor(dayBodyColorInactive)); + cellInBrush = new XSolidBrush(RGBColor.GetXColor(dayHeaderColorInactive)); + } + + + Gfx.DrawRectangle(cellBrush, cell); + Gfx.DrawRectangle(cellInBrush, cellIn); + + var points = new XPoint[3]; + points[0] = _resizer.Point(x, y); + points[1] = _resizer.Point(x + width, y); + points[2] = _resizer.Point(x, y + height); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[0], points[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[0], points[1]); + + + + var label = rows[i, j]; + var textX = x + width - Gfx.MeasureString(label, F1).Width - _cellOffset; + + var textY = y + (_monthDayHeaderHeight + F1.Size) / 2; + + Gfx.DrawString(label, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(textX, textY)); + x += width; + } + x = _offsetLeft; + + y += height; + } + + + var points2 = new XPoint[3]; + points2[0] = _resizer.Point(_offsetLeft + _pageWidth, _offsetTop); + points2[1] = _resizer.Point(_offsetLeft + _pageWidth, _offsetTop + _pageHeight); + points2[2] = _resizer.Point(_offsetLeft, _offsetTop + _pageHeight); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points2[0], points2[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points2[1], points2[2]); + + + } + + private void MonthEventsDraw(PDFPage page) + { + var rowObjects = Parser.GetRowsObjects(page); + + var eventColor = RGBColor.GetColor(_eventColor); + var eventBorderColor = RGBColor.GetColor(_eventBorderColor); + var textColor = RGBColor.GetColor(_eventTextColor); + var events = page.Events; + var minHeight = events.Count != 0 ? events.Min(e => e.Y) : 0; + var footenote = 1; + var eventsGrid = new int[6][]; + + for (var i = 0; i < 6; i++) + { + eventsGrid[i] = new int[7]; + for (var j = 0; j < 7; j++) + { + eventsGrid[i][j] = 0; + } + } + + var evHeight = events.Sum(e => e.Height) / (double)events.Count + 3; + + for (var i = 0; i < events.Count; i++) + { + var eventText = events[i].Text; + var day = events[i].Day; + var week = events[i].Week - 1; + + eventsGrid[week][day] = (int)Math.Floor((events[i].Y - rowObjects.Where((r, ind) => ind < week).Sum(r => r.Height)) / (evHeight));//todo: remove magic with event indexes + + var width = (events[i].Width * _monthDayWidth) / 100; + var type = events[i].Type; + var bgColor = events[i].BackgroundColor; + var color = events[i].Color; + if (type == "event_line") + { + + var cellX = _offsetLeft + day * _monthDayWidth + + _monthEventOffsetLeft; + var cellY = _offsetTop; + cellY += _headerHeight; + cellY += week * _monthDayHeight; + cellY += _monthDayHeaderHeight; + cellY += eventsGrid[week][day] + * (_monthEventHeight + _monthEventOffsetTop); + cellY += _monthEventOffsetTop; + + + var height = _monthEventHeight; + var cellPen = new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth); + + var borders = new XPoint[4]; + borders[0] = _resizer.Point(cellX, cellY); + borders[1] = _resizer.Point(cellX + width, cellY); + borders[2] = _resizer.Point(cellX + width, cellY + height); + borders[3] = _resizer.Point(cellX, cellY + height); + + + var cellIn = _resizer.Rect(cellX, cellY, width, height); + var cellInBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(bgColor, eventColor))); + + F1 = CreateFont(F1.FontFamily.Name, 8); + + var label = TextWrap(eventText, width - 2 * _cellOffset, F1, TrimContentStrings); + var textX = cellX + _cellOffset; + + var textY = cellY + (height + F1.Size) / 2; + var textBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + if ((cellY + height) >= (_offsetTop + _headerHeight + (week + 1) + * _monthDayHeight)) + { + var eventFootenote = GetFootenoteExists(events, week, day); + if (eventFootenote > 0) + { + events[i].Footenote = eventFootenote; + } + else + { + events[i].Footenote = footenote; + footenote++; + } + } + else + { + + Gfx.DrawRectangle(cellInBrush, cellIn); + Gfx.DrawLine(cellPen, borders[0], borders[1]); + Gfx.DrawLine(cellPen, borders[1], borders[2]); + Gfx.DrawLine(cellPen, borders[2], borders[3]); + Gfx.DrawLine(cellPen, borders[3], borders[0]); + + Gfx.DrawString(label, F1, textBrush, _resizer.Point(textX, textY)); + } + } + else + { + var cellX = _offsetLeft + day * _monthDayWidth + + _monthEventOffsetLeft; + var cellY = _offsetTop; + cellY += _headerHeight; + cellY += week * _monthDayHeight; + cellY += _monthDayHeaderHeight; + cellY += eventsGrid[week][day] + * (_monthEventHeight + _monthEventOffsetTop); + cellY += _monthEventOffsetTop; + var height = _monthEventHeight; + F1 = CreateFont(F1.FontFamily.Name, 8); + + var text = TextWrap(eventText, width - 2 * _cellOffset, F1, TrimContentStrings); + + XSolidBrush textBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + var textX = cellX + _cellOffset; + var textY = cellY + (height + F1.Size) / 2; + + if (cellY + height >= _offsetTop + _headerHeight + (week + 1) + * _monthDayHeight) + { + var eventFootenote = GetFootenoteExists(events, week, day); + if (eventFootenote > 0) + { + events[i].Footenote = eventFootenote; + } + else + { + events[i].Footenote = footenote; + footenote++; + } + } + else + { + Gfx.DrawString(text, F1, textBrush, _resizer.Point(textX, textY)); + + } + } + } + if (_profile == ColorProfile.BW) + MonthBwBordersDraw(); + MonthFootenotesDraw(events, footenote, page, minHeight); + } + + private int GetFootenoteExists(IList<SchedulerEvent> events, int week, int day) + { + var result = -1; + for (var i = 0; i < events.Count; i++) + { + var ev = events[i]; + var eventWeek = ev.Week - 1; + var eventDay = ev.Day; + if (eventWeek == week && eventDay == day) + { + var foote = ev.Footenote; + if (foote > 0) + { + result = ev.Footenote; + } + } + } + return result; + } + + private void MonthFootenotesDraw(IList<SchedulerEvent> events, int footenotes, PDFPage exportPage, double minHeight) + { + if (footenotes > 1) + { + NeedPagesNums = true; + Page = NewPage(PageOrientation.Landscape, PageSize.A4); + } + else + { + return; + } + + if (MultipageMonthLayout) + { + + var evs = new List<SchedulerEvent>(); + for (var i = 1; i < footenotes; i++) + { + var block = getFootenoteEvents(events, i).ToList(); + var offset = block.Min(e => e.Y) - minHeight; + foreach (var ev in block) + { + ev.Y -= offset; + } + evs.AddRange(block); + } + evs.ForEach(e => e.Footenote = 0); + + CurrentPage.Events = evs; + + MonthHeaderDraw(); + MonthContainerDraw(); + MonthEventsDraw(exportPage); + } + else + { + + var rows = Parser.MonthRowsParsing(CurrentPage); + var borderColor = RGBColor.GetColor(_lineColor); + var eventColor = RGBColor.GetColor(_eventColor); + var eventTextColor = RGBColor.GetColor(_eventTextColor); + + var labelHeight = 20; + var height = 20; + var width = 160; + var offsetLeft = 20; + var x = _offsetLeft; + var y = _offsetTop; + for (var i = 1; i < footenotes; i++) + { + var footEvents = getFootenoteEvents(events, i); + + + var day = footEvents[0].Day; + var week = footEvents[0].Week - 1; + if (y + labelHeight + height > _offsetTop + _pageHeight) + { + x += width + offsetLeft; + if (x + width > _offsetLeft + _pageWidth) + { + Page = NewPage(PageOrientation.Landscape, PageSize.A4); + + x = _offsetLeft; + } + y = _offsetTop; + } + var label = rows[week, day] + "[" + i.ToString() + "]"; + + + var labelX = x + (width - Gfx.MeasureString(label, F1).Width) / 2; + var labelY = y + labelHeight - _cellOffset; + Gfx.DrawString(label, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(labelX, labelY)); + + y += labelHeight; + for (var j = 0; j < footEvents.Count; j++) + { + if (y + height > _offsetTop + _pageHeight) + { + x += width + offsetLeft; + if (x + width > _offsetLeft + _pageWidth) + { + Page = NewPage(PageOrientation.Landscape, PageSize.A4); + x = _offsetLeft; + } + y = _offsetTop; + labelX = x + (width - Gfx.MeasureString(label, F1).Width) / 2; + labelY = y + labelHeight - _cellOffset; + + Gfx.DrawString(label, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(labelX, labelY)); + + y += labelHeight; + } + + var borders = new XPoint[4]; + borders[0] = _resizer.Point(x, y); + borders[1] = _resizer.Point(x + width, y); + borders[2] = _resizer.Point(x + width, y + height); + borders[3] = _resizer.Point(x, y + height); + var contBg = _resizer.Rect(x, y, width, height); + + var evBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(footEvents[j].BackgroundColor, eventColor))); + + Gfx.DrawRectangle(evBrush, contBg); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[3], borders[0]); + + var text = TextWrap(footEvents[j].Text, width - 2 * _cellOffset, F1, TrimContentStrings); + + var textX = x + _cellOffset; + var textY = y + (height + F1.Size) / 2; + + Gfx.DrawString(text, F1, new XSolidBrush(RGBColor.GetXColor(SelectColor(footEvents[j].Color, eventTextColor))), _resizer.Point(textX, textY)); + + y += height; + } + } + } + } + + private IList<SchedulerEvent> getFootenoteEvents(IList<SchedulerEvent> events, + int footenote) + { + var nums = 0; + for (var i = 0; i < events.Count; i++) + { + if (events[i].Footenote == footenote) + { + nums++; + } + } + var footEvents = new List<SchedulerEvent>(nums); + for (var i = 0; i < events.Count; i++) + { + if (events[i].Footenote == footenote) + { + footEvents.Add(events[i]); + } + } + return footEvents; + } + + private void MonthBwBordersDraw() + { + var borderColor = RGBColor.GetColor(_lineColor); + var x = _offsetLeft; + var y = _offsetTop; + Line(borderColor, x, y, x + _pageWidth, y); + Line(borderColor, x, y, x, y + _headerHeight); + + x = _offsetLeft + _pageWidth; + Line(borderColor, x, y, x, y + _headerHeight); + } + + private void WeekHeaderDraw() + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_headerLineColor); + var cols = Parser.WeekColsParsing(CurrentPage); + + _weekDayWidth = (_pageWidth - _leftScaleWidth) / cols[0].Length; + var defHeight = _headerHeight; + _headerHeight = defHeight * cols.Length; + + var ratios = Parser.ScaleRatios(CurrentPage).Select(r => (double)r).ToList(); + + + for (var scale = 0; scale < cols.Length && scale < 2; scale++) + { + var x = _offsetLeft + _leftScaleWidth; + var height = defHeight; + + var y = _offsetTop + defHeight * scale; + + + var width = (_pageWidth - _leftScaleWidth) / cols[scale].Length; + + + if (_weekDayWidth > width) + _weekDayWidth = width; + for (var col = 0; col < cols[scale].Length; col++) + { + if (scale == 0 && ratios.Count > 0 && cols[1].Length > 0 && col < ratios.Count) + { + width = (_pageWidth - _leftScaleWidth) / cols[1].Length * ratios[col]; + } + else + { + width = (_pageWidth - _leftScaleWidth) / cols[scale].Length; + } + + var cell = _resizer.Rect(x, y, width, height); + + var cellBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + Gfx.DrawRectangle(cellBrush, cell); + + var points = new XPoint[3]; + points[0] = _resizer.Point(x, y); + points[1] = _resizer.Point(x + width, y); + points[2] = _resizer.Point(x, y + height); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[0], points[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[0], points[1]); + + + F1 = new XFont(F1.FontFamily.Name, HeaderFontSize); + + var text = TextWrap(cols[scale][col], width + - 2 * _cellOffset, F1, TrimLayoutStrings); + + var textX = x + (width - Gfx.MeasureString(text, F1).Width) / 2; + var textY = y + (height + F1.Size) / 2; + Gfx.DrawString(text, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(textX, textY)); + + x += width; + } + + } + } + + private void WeekMultidayDraw(PDFPage page) + { + var bgColor = RGBColor.GetColor(_multidayColor); + var borderColor = RGBColor.GetColor(_headerLineColor); + + _multiHeight = GetMultidayHeight(page); + var x = _offsetLeft; + var y = _offsetTop + _headerHeight; + var cell = _resizer.Rect(x, y, _pageWidth, _multiHeight); + + var cellBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + Gfx.DrawRectangle(cellBrush, cell); + + var points = new XPoint[4]; + points[0] = _resizer.Point(x + _leftScaleWidth, y + 0); + points[1] = _resizer.Point(x + _leftScaleWidth, y + _multiHeight); + points[2] = _resizer.Point(x + 0, y + 0); + points[3] = _resizer.Point(x + _pageWidth, y + 0); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[0], points[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[2], points[3]); + + _headerHeight += _multiHeight; + } + + private double GetMultidayHeight(PDFPage page) + { + var cols = Parser.WeekColsParsing(page); + var events = page.Multiday; + var scheme = new int[cols[0].Length]; + for (var i = 0; i < scheme.Length; i++) + scheme[i] = 0; + for (var i = 0; i < events.Count; i++) + { + var day = events[i].Day; + var len = events[i].Len; + for (var j = day; j < day + len; j++) + scheme[j]++; + } + var max = scheme[0]; + for (var i = 1; i < scheme.Length; i++) + { + if (scheme[i] > max) + max = scheme[i]; + } + return max * _multidayLineHeight; + } + + private void WeekContainerDraw() + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_lineColor); + var headerLineColor = RGBColor.GetColor(_headerLineColor); + var scaleOneColor = RGBColor.GetColor(_scaleOneColor); + var scaleTwoColor = RGBColor.GetColor(_scaleTwoColor); + var rows = Parser.WeekRowsParsing(CurrentPage); + var width = _leftScaleWidth; + var height = (_pageHeight - _headerHeight) / rows.Length; + _weekDayHeight = height; + var x = _offsetLeft; + var y = _offsetTop + _headerHeight; + for (var i = 0; i < rows.Length; i++) + { + + var cell = _resizer.Rect(x, y, width, height); + var cellBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + + var scaleOne = _resizer.Rect(x + width, y, _pageWidth - width, height / 2); + var scaleOneBrush = new XSolidBrush(RGBColor.GetXColor(scaleOneColor)); + + var scaleTwo = _resizer.Rect(x + width, y + height / 2, _pageWidth - width, height / 2); + var scaleTwoBrush = new XSolidBrush(RGBColor.GetXColor(scaleTwoColor)); + + Gfx.DrawRectangle(cellBrush, cell); + Gfx.DrawRectangle(scaleOneBrush, scaleOne); + Gfx.DrawRectangle(scaleTwoBrush, scaleTwo); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(headerLineColor), BorderWidth), _resizer.Point(x, y), _resizer.Point(x + width, y)); + + var text = TextWrap(rows[i], width - 2 * _cellOffset, F1, TrimLayoutStrings); + var textX = x + (width - Gfx.MeasureString(text, F1).Width) / 2; + var textY = y + (height + F1.Size) / 2; + + Gfx.DrawString(text, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(textX, textY)); + + y += height; + } + + var cols = Parser.WeekColsParsing(CurrentPage); + width = (_pageWidth - _leftScaleWidth) / cols[0].Length; + x = _offsetLeft + _leftScaleWidth; + y = _offsetTop + _headerHeight; + for (var scale = 0; scale < cols.Length; scale++) + { + for (var col = 0; col < cols[scale].Length; col++) + { + var points = new XPoint[2]; + points[0] = _resizer.Point(x, y); + points[1] = _resizer.Point(x, _pageHeight + _offsetTop); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points[0], points[1]); + + x += width; + } + y += _headerHeight; + } + + var points2 = new XPoint[2]; + points2[0] = _resizer.Point(x, y - _multiHeight); + points2[1] = _resizer.Point(x, _offsetTop + _pageHeight); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), points2[0], points2[1]); + } + + private void WeekEventsDraw(PDFPage page) + { + var eventBorderColor = RGBColor.GetColor(_eventBorderColor); + var eventColor = RGBColor.GetColor(_eventColor); + + var textColor = RGBColor.GetColor(_eventTextColor); + var textFormatter = new DHXTextFormatter(Gfx); + var events = page.Events; + var defAlign = textFormatter.Alignment; + + for (var i = 0; i < events.Count; i++) + { + var x = _offsetLeft + _leftScaleWidth + events[i].X + * _weekDayWidth / 100; + var y = _offsetTop + _headerHeight + events[i].Y + * _weekDayHeight / 100; + var width = events[i].Width * _weekDayWidth / 100; + var height = events[i].Height * _weekDayHeight / 100; + var text = events[i].Text; + var headerText = events[i].HeaderText; + var bgColor = events[i].BackgroundColor; + var color = events[i].Color; + + + var borders = new XPoint[4]; + borders[0] = _resizer.Point(x, y); + borders[1] = _resizer.Point(x + width, y); + borders[2] = _resizer.Point(x + width, y + height); + borders[3] = _resizer.Point(x, y + height); + + + var eventBg = _resizer.Rect(x, y, width, height); + var evBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(bgColor, eventColor))); + + F1 = new XFont(F1.FontFamily.Name, BaseFontSize); + + var textY = y + (_weekEventHeaderHeight - F1.Size) / 2; + var headTxtBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + var bodyTxt = text; + var bodyTextX = x; + var bodyTextWidth = width; + if (width > 3 * _cellOffset) + { + bodyTextX = x + _cellOffset; + bodyTextWidth = width - 2 * _cellOffset; + } + var bodyTextY = y; + var bodyTextHeight = height; + if (height > 3 * _cellOffset) + { + bodyTextY = y + _cellOffset + _weekEventHeaderHeight; + bodyTextHeight = height - 2 * _cellOffset; + } + + + + var bodyTxtBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + Gfx.DrawRectangle(evBrush, eventBg); + var borderPen = new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth); + Gfx.DrawLine(borderPen, borders[0], borders[1]); + Gfx.DrawLine(borderPen, borders[1], borders[2]); + Gfx.DrawLine(borderPen, borders[2], borders[3]); + Gfx.DrawLine(borderPen, borders[3], borders[0]); + + Gfx.DrawLine(borderPen, _resizer.Point(x, y + _weekEventHeaderHeight), _resizer.Point(x + width, y + _weekEventHeaderHeight)); + + textFormatter.Alignment = XParagraphAlignment.Center; + textFormatter.DrawString(headerText, F1, headTxtBrush, _resizer.Rect(x, textY, width, _weekEventHeaderHeight)); + + textFormatter.Alignment = defAlign; + + textFormatter.DrawString(bodyTxt, F1, bodyTxtBrush, _resizer.Rect(bodyTextX, bodyTextY, bodyTextWidth, bodyTextHeight)); + + } + + // preparing scheme to calculate multiday position + var cols = Parser.WeekColsParsing(CurrentPage); + var scheme = new int[cols[0].Length]; + for (var i = 0; i < scheme.Length; i++) + scheme[i] = 0; + + events = page.Multiday; + var offset = 1; + for (var i = 0; i < events.Count; i++) + { + var ev = events[i]; + var day = ev.Day; + var len = ev.Len; + var text = ev.Text; + var bgColor = ev.BackgroundColor; + var color = ev.Color; + + var width = len * _weekDayWidth - 2 * offset; + var height = _monthEventHeight; + var x = _offsetLeft + _leftScaleWidth + day + * _weekDayWidth + offset; + var y = _offsetTop + _headHeight + scheme[day] + * _multidayLineHeight; + + var cont = _resizer.Rect(x, y, width, height); + var evBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(bgColor, eventColor))); + + F1 = new XFont(F1.FontFamily.Name, BaseFontSize); + var txtX = x + _cellOffset; + var txtY = y + (_weekEventHeaderHeight - F1.Size) / 2; + var textBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + Gfx.DrawRectangle(evBrush, cont); + var borders = new XPoint[4]; + borders[0] = _resizer.Point(x, y); + borders[1] = _resizer.Point(x + width, y); + borders[2] = _resizer.Point(x + width, y + height); + borders[3] = _resizer.Point(x, y + height); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[3], borders[0]); + textFormatter.DrawString(text, F1, textBrush, _resizer.Rect(txtX, txtY, width, height)); + for (var j = day; j < day + len; j++) + scheme[j]++; + } + } + + private void WeekBwBordersDraw() + { + var borderColor = RGBColor.GetColor(_lineColor); + + var x = _offsetLeft; + var y = _offsetTop; + Line(borderColor, x + _leftScaleWidth, y, x + _pageWidth, + y); + + if (_multiHeight > 0) + { + y = _offsetTop + _headerHeight - _multiHeight; + Line(borderColor, x + _leftScaleWidth, y, x + + _pageWidth, y); + Line(borderColor, x, y, x, y + _pageHeight + - (_headerHeight - _multiHeight)); + } + + y = _offsetTop + _headerHeight; + Line(borderColor, x, y, x + _pageWidth, y); + + y = _offsetTop + _pageHeight; + Line(borderColor, x, y, x + _pageWidth, y); + + x = _offsetLeft + _leftScaleWidth; + Line(borderColor, x, y, x, y + _headerHeight); + + x = _offsetLeft + _pageWidth; + Line(borderColor, x, y, x, y + _headerHeight); + + } + + private void Line(double[] color, double x1, double y1, double x2, double y2) + { + Gfx.DrawLine(new XPen(RGBColor.GetXColor(color), BorderWidth), _resizer.Point(x1, y1), _resizer.Point(x2, y2)); + } + private void Line(double[] color, double x1, double y1, double x2, double y2, XRect cell) + { + Gfx.DrawLine(new XPen(RGBColor.GetXColor(color), BorderWidth), _resizer.Point(cell.Location.X + x1, cell.Location.Y + y1), _resizer.Point(cell.Location.X + x2, cell.Location.Y + y2)); + } + + private void _drawTimelineContainerPart(string[] rows) + { + var headerLineColor = RGBColor.GetColor(_headerLineColor); + var x = _offsetLeft; + var y = _offsetTop + _headerHeight; + var width = _leftScaleWidth; + var height = TimelineRowMinHeight; + for (var i = 0; i < rows.Length; i++) + { + var cell = _resizer.Rect(x, y, width, height); + var cellBrush = new XSolidBrush(RGBColor.GetXColor(_bgColor)); + + var scaleOne = _resizer.Rect(x + width, y, _pageWidth - width, height); + var scaleOneBrush = new XSolidBrush(RGBColor.GetXColor(_scaleOneColor)); + + Gfx.DrawRectangle(cellBrush, cell); + Gfx.DrawRectangle(scaleOneBrush, scaleOne); + + Line(headerLineColor, x, y, x + width, y); + + var text = TextWrap(rows[i], width - 2 * _cellOffset, F1, TrimLayoutStrings); + var textX = x + (width - Gfx.MeasureString(text, F1).Width) / 2; + var textY = y + (height + F1.Size) / 2; + Gfx.DrawString(text, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(textX, textY)); + + y += height; + } + } + + + private double _getPadding(TreeTimelineCategory row) + { + double levelPadding = 0.0; + for (var lev = 0; lev < row.Level; lev++) + { + levelPadding += Gfx.MeasureString("ww", F1).Width; + } + if (row.IsExpandable) + levelPadding -= Gfx.MeasureString("+ ", F1).Width; + if (levelPadding < 0) + levelPadding = 0.0; + return levelPadding; + } + private void _drawTreeLevelScales(string[] rows) + { + var x = _offsetLeft; + var y = _offsetTop + _headerHeight; + var width = _leftScaleWidth; + var height = (_pageHeight - _headerHeight) / rows.Length; + var pars = new TreeTimelineParser(); + F1 = new XFont(F1.FontFamily.Name, F1.Size, XFontStyle.Bold); + for (var i = 0; i < rows.Length; i++) + { + + var row = pars.Parse(rows[i]); + if (row.IsExpandable) + { + var levelPadding = _getPadding(row); + var scaleOne = _resizer.Rect(x + width, y, _pageWidth - width, height); + var scaleOneBrush = new XSolidBrush(RGBColor.GetXColor(_timelineTreeColor)); + + + Gfx.DrawRectangle(scaleOneBrush, scaleOne); + + + var textX = levelPadding + x; + var textY = y + (height + F1.Size) / 2; + var text = (row.Expanded ? " - " : " + ") + row.Text; + text = TextWrap(text, _pageWidth, F1, TrimLayoutStrings); + Gfx.DrawString(text, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(textX, textY)); + } + y += height; + } + F1 = new XFont(F1.FontFamily.Name, F1.Size, XFontStyle.Regular); + } + private void _drawTreeTimelineContainerPart(string[] rows) + { + var headerLineColor = RGBColor.GetColor(_headerLineColor); + var y = _offsetTop + _headerHeight; + var width = _leftScaleWidth; + var height = (_pageHeight - _headerHeight) / rows.Length; + + var pars = new TreeTimelineParser(); + + for (var i = 0; i < rows.Length; i++) + { + var x = _offsetLeft; + var row = pars.Parse(rows[i]); + + var levelPadding = _getPadding(row); + + XRect cell; + XBrush cellBrush; + + if (row.IsExpandable) + { + F1 = new XFont(F1.FontFamily.Name, F1.Size, XFontStyle.Bold); + cell = _resizer.Rect(x, y, width, height); + cellBrush = new XSolidBrush(RGBColor.GetXColor(_timelineTreeColor)); + Gfx.DrawRectangle(cellBrush, cell); + } + else + { + F1 = new XFont(F1.FontFamily.Name, F1.Size, XFontStyle.Regular); + + cell = _resizer.Rect(x, y, width, height); + cellBrush = new XSolidBrush(RGBColor.GetXColor(_bgColor)); + + var scaleOne = _resizer.Rect(x + width, y, _pageWidth - width, height); + var scaleOneBrush = new XSolidBrush(RGBColor.GetXColor(_scaleOneColor)); + + var text = TextWrap(row.Text, width - 2 * _cellOffset - levelPadding, F1, TrimLayoutStrings); + var textX = levelPadding + x; + var textY = y + (height + F1.Size) / 2; + Gfx.DrawRectangle(cellBrush, cell); + Gfx.DrawRectangle(scaleOneBrush, scaleOne); + Gfx.DrawString(text, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(textX, textY)); + } + + Line(headerLineColor, x, y, x + width, y); + + y += height; + } + + } + + private void TimelineContainerDraw(string[] rows) + { + var borderColor = RGBColor.GetColor(_lineColor); + + var isTree = false; + if (rows.Length > 0) + { + isTree = TreeTimelineParser.IsTreeRow(rows[0]); + } + + if (isTree) + { + _drawTreeTimelineContainerPart(rows); + } + else + { + _drawTimelineContainerPart(rows); + } + + var cols = Parser.WeekColsParsing(CurrentPage); + var width = double.MaxValue; + var height = TimelineRowMinHeight; + _weekDayHeight = height; + var colCount = -1; + for (var i = 0; i < cols.Length; i++) + { + var scale = (_pageWidth - _leftScaleWidth) / cols[i].Length; + if (width > scale) + width = scale; + if (colCount < cols[i].Length) + colCount = cols[i].Length; + } + + var x = _offsetLeft + _leftScaleWidth; + var y = _offsetTop + _headerHeight; + + var colHeight = height * rows.Length + _offsetTop + _headerHeight; + for (var i = 0; i < colCount; i++) + { + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), + _resizer.Point(x, y), _resizer.Point(x, colHeight)); + + x += width; + } + + if (isTree) + _drawTreeLevelScales(rows); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), + _resizer.Point(_offsetLeft + _leftScaleWidth, y), _resizer.Point(_offsetLeft + _leftScaleWidth + width, y)); + + y = _offsetTop + _headerHeight + height; + for (var i = 0; i < rows.Length; i++) + { + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), + _resizer.Point(_offsetLeft + _leftScaleWidth, y), _resizer.Point(_offsetLeft + _pageWidth, y)); + y += height; + } + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), + _resizer.Point(_offsetLeft + _leftScaleWidth, _offsetTop + _headerHeight), + _resizer.Point(_offsetLeft + _pageWidth, _offsetTop + _headerHeight)); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), + _resizer.Point(x, _offsetTop), + _resizer.Point(x, colHeight)); + } + + private void MatrixContainerDraw(PDFPage page) + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_lineColor); + var headerLineColor = RGBColor.GetColor(_headerLineColor); + var matrixEventColor = RGBColor.GetColor(_matrixEventColor); + var textColor = RGBColor.GetColor(_textColor); + var rows = Parser.WeekRowsParsing(CurrentPage); + var height = (_pageHeight - _headerHeight) / rows.Length; + var cols = Parser.WeekColsParsing(CurrentPage); + var events = page.Events; + var columns = cols[0]; + for (var i = 0; i < rows.Length; i++) + { + for (var j = 0; j <= columns.Length; j++) + { + var ev = events[i * (columns.Length + 1) + j]; + var evBgColor = ev.BackgroundColor; + var evTextColor = ev.Color; + var text = ev.Text; + var x = _offsetLeft + Math.Max(j - 1, 0) + * _weekDayWidth + (j != 0 ? 1 : 0) + * _leftScaleWidth; + var y = _offsetTop + _headerHeight + i * height; + + var width = (j == 0) ? _leftScaleWidth : _weekDayWidth; + + + var cell = _resizer.Rect(x, y, width, height); + var cellBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(evBgColor, matrixEventColor))); + + + + if (j == 0) + cellBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + Gfx.DrawRectangle(cellBrush, cell); + + + // draw cell text + F1 = new XFont(F1.FontFamily.Name, (j == 0) ? BaseFontSize : 8.4); + var txt = TextWrap(text, width - 2 * _cellOffset, F1, TrimContentStrings); + var textX = x + (width - Gfx.MeasureString(txt, F1).Width) / 2; + var textY = y + (height - F1.Size) / 2; + var txtBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(evTextColor, textColor))); + + Gfx.DrawString(txt, F1, txtBrush, _resizer.Point(textX, textY)); + + // draw borders + if (j == 0) + { + Line(headerLineColor, x, y, x + width, y); + } + else + { + Line(borderColor, x, y, x + width, y); + Line(borderColor, x, y, x, y + height); + } + } + } + + // border right + Line(borderColor, _offsetLeft + _pageWidth, _offsetTop, _offsetLeft + _pageWidth, _offsetTop + + _pageHeight); + + Line(borderColor, _offsetLeft, _offsetTop + _pageHeight, _offsetLeft + _pageWidth, _offsetTop + + _pageHeight); + } + + private void TimelineEventsDraw(PDFPage page, int pageNumber, int blocksNumber) + { + var eventBorderColor = RGBColor.GetColor(_eventBorderColor); + var eventColor = RGBColor.GetColor(_eventColor); + var textColor = RGBColor.GetColor(_eventTextColor); + var events = page.Events; + + var offset = 1; + for (var i = 0; i < events.Count; i++) + { + var ev = events[i]; + var text = ev.Text; + var bgColor = ev.BackgroundColor; + var color = ev.Color; + + if (ev.Week >= pageNumber * blocksNumber) continue; + if (ev.Week < (pageNumber - 1) * blocksNumber) continue; + + var x = _offsetLeft + _leftScaleWidth + ev.X + * _weekDayWidth / 100 + offset; + var y = _offsetTop + _headerHeight + ev.Y + * _weekDayHeight / 100 + ((ev.Week - (pageNumber - 1) * blocksNumber) + * _weekDayHeight); + + var width = ev.Width * _weekDayWidth / 100; + var height = _monthEventHeight; + + var cell = _resizer.Rect(x, y, width, height); + + var cellBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(bgColor, eventColor))); + + F1 = new XFont(F1.FontFamily.Name, BaseFontSize); + var txt = TextWrap(text, width, F1, TrimContentStrings); + var txtX = x + _cellOffset; + var txtY = y + (_weekEventHeaderHeight + F1.Size) / 2; + var txtBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + + Gfx.DrawRectangle(cellBrush, cell); + + var borders = new XPoint[4]; + borders[0] = _resizer.Point(x, y); + borders[1] = _resizer.Point(x + width, y); + borders[2] = _resizer.Point(x + width, y + height); + borders[3] = _resizer.Point(x, y + height); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(eventBorderColor), BorderWidth), borders[3], borders[0]); + + Gfx.DrawString(txt, F1, txtBrush, _resizer.Point(txtX, txtY)); + } + } + + private void YearDraw(PDFPage page) + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_lineColor); + var headerLineColor = RGBColor.GetColor(_headerLineColor); + var textColor = RGBColor.GetColor(_textColor); + var eventColor = RGBColor.GetColor(_eventColor); + var yearDayActiveColor = RGBColor.GetColor(_yearDayActiveColor); + var yearDayInactiveColor = RGBColor.GetColor(_yearDayInactiveColor); + var monthes = Parser.YearParsing(CurrentPage); + var events = page.Events; + var width = (_pageWidth - _yearMonthOffsetLeft * 3) / 4; + var height = (_pageHeight - _yearMonthOffsetTop * 2) / 3; + var monthX = _offsetLeft; + var monthY = _offsetTop; + for (var i = 0; i < 3; i++) + { + for (var j = 0; j < 4; j++) + { + var mon = monthes[i * 4 + j]; + var label = mon.GetLabel(); + var rows = mon.GetRows(); + var onlyDays = mon.GetOnlyDays(); + + var monthCont = _resizer.Rect(monthX, monthY, width, height); + var monthContBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + + + var labelText = TextWrap(label, width, F1, TrimLayoutStrings); + var labelTextX = monthX + (width - Gfx.MeasureString(label, F1).Width) / 2; + var labelTextY = monthY + (_yearMonthLabelHeight + F1.Size) / 2; + var labelTextBrush = new XSolidBrush(RGBColor.GetXColor(textColor)); + + Gfx.DrawRectangle(monthContBrush, monthCont); + Gfx.DrawString(labelText, F1, labelTextBrush, _resizer.Point(labelTextX, labelTextY)); + + + var cellWidth = width / 7; + var cellHeight = (height - _yearMonthLabelHeight) + / rows.GetLength(0); + var cellX = monthX; + var cellY = monthY + _yearMonthLabelHeight; + for (var k = 0; k < rows.GetLength(0); k++) + { + for (var l = 0; l < 7; l++) + { + + var cell = _resizer.Rect(cellX, cellY, cellWidth, cellHeight); + XBrush cellBrush; + + var ind = GetEventIndex(events, l, k - 1, i * 4 + j); + if (k == 0) + { + cellBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + } + else + { + if (GetActiveDay(onlyDays, k - 1, l)) + { + if (ind == -1) + { + cellBrush = new XSolidBrush(RGBColor.GetXColor(yearDayActiveColor)); + } + else + { + var ev = events[ind]; + var color = ev.BackgroundColor; + cellBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, eventColor))); + + } + } + else + { + cellBrush = new XSolidBrush(RGBColor.GetXColor(yearDayInactiveColor)); + + } + } + Gfx.DrawRectangle(cellBrush, cell); + + if (k == 0) + Line(headerLineColor, 0, 0, cellWidth, 0, + cell); + else + Line(borderColor, 0, 0, cellWidth, 0, cell); + if (l > 0) + if (k == 0) + Line(headerLineColor, 0, 0, 0, + cellHeight, cell); + else + Line(borderColor, 0, 0, 0, cellHeight, + cell); + + var cellText = rows[k, l]; + var cellTextX = cellX + (cellWidth - Gfx.MeasureString(cellText, F1).Width) / 2; + var cellTextY = cellY + (cellHeight + F1.Size) / 2; + XSolidBrush evBrush; + + if (ind > -1) + { + var ev = events[ind]; + var color = ev.Color; + evBrush = new XSolidBrush(RGBColor.GetXColor(SelectColor(color, textColor))); + + } + else + evBrush = new XSolidBrush(RGBColor.GetXColor(textColor)); + Gfx.DrawString(cellText, F1, evBrush, _resizer.Point(cellTextX, cellTextY)); + cellX += cellWidth; + } + cellX = monthX; + cellY += cellHeight; + } + if (_profile == ColorProfile.BW) + { + Line(headerLineColor, 0, 0, 0, height, monthCont); + Line(headerLineColor, 0, 0, width, 0, monthCont); + Line(headerLineColor, 0, height, width, height, + monthCont); + Line(headerLineColor, width, 0, width, height, + monthCont); + } + monthX += _yearMonthOffsetLeft + width; + } + monthX = _offsetLeft; + monthY += _yearMonthOffsetTop + height; + } + } + + private void AgendaHeaderDraw() + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_headerLineColor); + var textColor = RGBColor.GetColor(_textColor); + var cols = Parser.AgendaColsParsing(CurrentPage); + + var width = _pageWidth; + var height = _headerHeight; + var x = _offsetLeft; + var y = _offsetTop; + + var headerBg = _resizer.Rect(x, y, width, height); + + var monthContBrush = new XSolidBrush(RGBColor.GetXColor(bgColor)); + Gfx.DrawRectangle(monthContBrush, headerBg); + + var dateWidth = _agendaColOneWidth; + var nameWidth = width - _agendaColOneWidth; + + var sep = new[] { _resizer.Point(x + dateWidth, y), _resizer.Point(x + dateWidth, y + _headerHeight) }; + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), 0.3), sep[0], sep[1]); + + + F1 = new XFont(F1.FontFamily.Name, BaseFontSize); + var dateText = cols[0]; + + var textBrush = new XSolidBrush(RGBColor.GetXColor(textColor)); + var dateTextX = x + (dateWidth - Gfx.MeasureString(dateText, F1).Width) / 2; + var dateTextY = y + (height + F1.Size) / 2; + Gfx.DrawString(dateText, F1, textBrush, _resizer.Point(dateTextX, dateTextY)); + + + + var nameText = cols[1]; + var nameTextX = x + dateWidth + (nameWidth - Gfx.MeasureString(nameText, F1).Width) / 2; + var nameTextY = y + (height + F1.Size) / 2; + Gfx.DrawString(nameText, F1, textBrush, _resizer.Point(nameTextX, nameTextY)); + + + var borders = new[]{ + _resizer.Point(x, y), + _resizer.Point(x + width, y), + _resizer.Point(x + width, y + height), + _resizer.Point(x, y + height)}; + Gfx.DrawLine(new XPen(RGBColor.GetXColor(_lineColor), 0.3), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(_lineColor), 0.3), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(_lineColor), 0.3), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(_lineColor), 0.3), borders[3], borders[0]); + + } + + private void AgendaEventDraw(PDFPage page) + { + var scaleOneColor = RGBColor.GetColor(_scaleOneColor); + var scaleTwoColor = RGBColor.GetColor(_scaleTwoColor); + var borderColor = RGBColor.GetColor(_lineColor); + var textColor = RGBColor.GetColor(_textColor); + var events = page.Events; + var width = _pageWidth; + var height = _headerHeight; + var x = _offsetLeft; + var y = _offsetTop + _headerHeight; + + var linePen = new XPen(RGBColor.GetXColor(_eventBorderColor), BorderWidth); + + F1 = new XFont(F1.FontFamily.Name, BaseFontSize); + for (var i = 0; i < events.Count; i++) + { + if (y + height > _offsetTop + _pageHeight) + { + + Gfx.DrawLine(linePen, _resizer.Point(x, y), _resizer.Point(x + width, y)); + + + Page = NewPage(PageOrientation.Portrait, PageSize.A4); + + AgendaHeaderDraw(); + y = _offsetTop + _headerHeight; + } + + + + var headerCont = _resizer.Rect(x, y, width, height); + XBrush headerBrush; + if (i % 2 == 0) + { + headerBrush = new XSolidBrush(RGBColor.GetXColor(scaleOneColor)); + } + else + { + headerBrush = new XSolidBrush(RGBColor.GetXColor(scaleTwoColor)); + } + + var dateWidth = _agendaColOneWidth; + + Gfx.DrawRectangle(headerBrush, headerCont); + + var borders = new[]{ + _resizer.Point(x, y), + _resizer.Point(x + dateWidth, y), + _resizer.Point(x + dateWidth, y + height), + _resizer.Point(x, y + height)}; + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[3], borders[0]); + + var headerText = events[i].HeaderAgendaText; + var text = events[i].Text; + + var textBrush = new XSolidBrush(RGBColor.GetXColor(textColor)); + + var dateTextX = x + (dateWidth - Gfx.MeasureString(headerText, F1).Width) / 2; + var dateTextY = y + (height + F1.Size) / 2; + Gfx.DrawString(headerText, F1, textBrush, _resizer.Point(dateTextX, dateTextY)); + + + + var nameTextX = x + dateWidth + _cellOffset; + var nameTextY = y + (height + F1.Size) / 2; + Gfx.DrawString(text, F1, textBrush, _resizer.Point(nameTextX, nameTextY)); + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), _resizer.Point(x, y), _resizer.Point(x, y + height)); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), _resizer.Point(x, y), _resizer.Point(x + width, y)); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), _resizer.Point(x + width, y), _resizer.Point(x + width, y + height)); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), _resizer.Point(x + dateWidth, y), _resizer.Point(x + dateWidth, y + height)); + + + y += height; + } + + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), _resizer.Point(x, y), _resizer.Point(x + width, y)); + + + } + + private void PrintFooter() + { + if (CurrentPage.Footer) + { + var im = Images.Get(FooterImgPath); + if (im != null) + { + Gfx.DrawImage(im, _resizer.Point(_offsetLeft, _pageHeight + _offsetTop - FooterImgHeight)); + _pageHeight -= FooterImgHeight; + _offsetBottom += FooterImgHeight; + } + } + } + + private void AgendaPagesDraw() + { + for (var i = 1; i <= Pages.Count; i++) + { + var graph = Graphics[i - 1]; + if (_profile == ColorProfile.BW + && CurrentPage.Mode != "month") + MonthBwBordersDraw(); + var str = _pageNumTemplate; + str = str.Replace("{pageNum}", i.ToString()); + str = str.Replace("{allNum}", Pages.Count.ToString()); + + var text = new XTextFormatter(graph); + var x = _pageWidth + _offsetLeft - graph.MeasureString(str, F1).Width; + + var y = _pageHeight + _offsetTop + F1.Size; + if (CurrentPage.Footer && Images.Get(FooterImgPath) != null) + y += FooterImgHeight; + + text.DrawString(str, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Rect(x, y, graph.MeasureString(str, F1).Width, F1.Size)); + } + + } + + + private void WeekAgendaContainerDraw() + { + var cols = Parser.AgendaColsParsing(CurrentPage); + var x = _offsetLeft; + var contWidth = (_pageWidth) / 2; + var contHeight = (_pageHeight) / 3; + _contWidth = contWidth; + _contHeight = contHeight; + + + for (var i = 0; i < 3; i++) + { + var y = _offsetTop + contHeight * i; + WeekAgendarDayDraw(cols[i], contWidth, contHeight, x, y); + } + x += contWidth; + for (var i = 0; i < 2; i++) + { + var y = _offsetTop + contHeight * i; + WeekAgendarDayDraw(cols[i + 3], contWidth, contHeight, x, y); + } + + var tallContHeight = contHeight / 2; + for (var i = 0; i < 2; i++) + { + var y = _offsetTop + contHeight * 2 + tallContHeight * i; + WeekAgendarDayDraw(cols[i + 5], contWidth, tallContHeight, x, y); + } + var headerLineColor = RGBColor.GetColor(_headerLineColor); + for (var i = 0; i < 3; i++) + { + var y = _offsetTop + contHeight * i; + Line(headerLineColor, x, y, x, y + _monthDayHeaderHeight); + } + } + + private void WeekAgendarDayDraw(string name, double width, double height, double x, double y) + { + var bgColor = RGBColor.GetColor(_bgColor); + var borderColor = RGBColor.GetColor(_lineColor); + var textColor = RGBColor.GetColor(_textColor); + F1 = new XFont(F1.FontFamily.Name, WeekAgendarDayFont); + var dayCont = _resizer.Rect(x, y, width, height); + + var borders = new[]{ + _resizer.Point(x, y), + _resizer.Point(x + width, y), + _resizer.Point(x + width, y + height), + _resizer.Point(x, y + height)}; + Gfx.DrawLine(new XPen(RGBColor.GetXColor(bgColor), BorderWidth), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(bgColor), BorderWidth), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(bgColor), BorderWidth), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(bgColor), BorderWidth), borders[3], borders[0]); + + Line(borderColor, 0, 0, width, 0, dayCont); + Line(borderColor, 0, 0, 0, height, dayCont); + Line(borderColor, width, 0, width, height, dayCont); + Line(borderColor, 0, height, width, height, dayCont); + + var labelCont = _resizer.Rect(x, y, width, _monthDayHeaderHeight); + Gfx.DrawRectangle(new XSolidBrush(RGBColor.GetXColor(bgColor)), labelCont); + + var txt = name; + x = x + _cellOffset + (width - _cellOffset - Gfx.MeasureString(name, F1).Width) / 2; + y = y + (_monthDayHeaderHeight + F1.Size) / 2; + Gfx.DrawString(txt, F1, new XSolidBrush(RGBColor.GetXColor(textColor)), _resizer.Point(x, y)); + } + + private SchedulerEvent[] WeekAgendaEventsDraw(SchedulerEvent[] events) + { + var borderColor = RGBColor.GetColor(_lineColor); + var textColor = RGBColor.GetColor(_textColor); + var offsets = new int[7]; + for (var i = 0; i < offsets.Length; i++) + offsets[i] = 0; + var rest = new List<SchedulerEvent>(); + + for (var i = 0; i < events.Length; i++) + { + var ev = events[i]; + var day = ev.Day; + var contHeight = (day < 5) ? _contHeight : _contHeight / 2; + var contWidth = _contWidth; + double x; + switch (day) + { + case 0: + case 2: + case 4: + x = _offsetLeft; + break; + default: + x = _offsetLeft + contWidth; + break; + } + var contStartY = _offsetTop + Math.Floor(day / 2.0) * _contHeight - (day > 5 ? contHeight : 0); + var offset = offsets[day] * _weekAgendaEventHeight; + var y = contStartY + _monthDayHeaderHeight + offset; + + if (contStartY + contHeight < y + _weekAgendaEventHeight) + { + rest.Add(ev); + continue; + } + + + var borders = new[]{ + _resizer.Point(x, y), + _resizer.Point(x + _contWidth, y), + _resizer.Point(x + _contWidth, y + _weekAgendaEventHeight), + _resizer.Point(x, y + _weekAgendaEventHeight)}; + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[0], borders[1]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[1], borders[2]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[2], borders[3]); + Gfx.DrawLine(new XPen(RGBColor.GetXColor(borderColor), BorderWidth), borders[3], borders[0]); + + F1 = new XFont(F1.FontFamily.Name, 9); + + x = x + _cellOffset; + y = y + (_weekAgendaEventHeight + F1.Size) / 2; + Gfx.DrawString(ev.Text, F1, new XSolidBrush(RGBColor.GetXColor(textColor)), _resizer.Point(x, y)); + + offsets[day]++; + } + var eventsList = new SchedulerEvent[rest.Count]; + for (var i = 0; i < rest.Count; i++) + eventsList[i] = rest[i]; + return eventsList; + } + + private void TodayLabelDraw() + { + var g1 = Graphics[0]; + TodayLabelDraw(g1); + } + + private void TodayLabelDraw(XGraphics p1) + { + F1 = new XFont(F1.FontFamily.Name, 10); + + var today = CurrentPage.TodayLabel; + var todayText = today; + var todayX = _offsetLeft; + var todayY = _offsetTop - _cellOffset; + p1.DrawString(todayText, F1, new XSolidBrush(RGBColor.GetXColor(_textColor)), _resizer.Point(todayX, todayY)); + } + + private int GetEventIndex(IList<SchedulerEvent> events, int day, int week, int month) + { + for (var i = 0; i < events.Count; i++) + { + var evDay = events[i].Day; + var evWeek = events[i].Week; + var evMonth = events[i].Month; + if ((evDay == day) && (evWeek == week) && (evMonth == month)) + { + return i; + } + } + return -1; + } + + private bool GetActiveDay(string[,] rows, int row, int col) + { + bool flag; + var flagCount = 0; + if (int.Parse(rows[0, 0]) == 1) + { + flag = true; + flagCount = 1; + } + else + { + flag = false; + } + + var prevDay = int.Parse(rows[0, 0]); + for (var i = 0; i < rows.Length; i++) + { + for (var j = 0; j < rows.GetLength(1); j++) + { + if (int.Parse(rows[i, j]) < prevDay && flagCount < 2) + { + flag = !flag; + flagCount++; + } + if (i == row && j == col) + { + return flag; + } + prevDay = int.Parse(rows[i, j]); + } + } + return flag; + } + + public string GetView() + { + return _view; + } + + + + private void PrintHeader() + { + if (CurrentPage.Header) + { + var im = Images.Get(HeaderImgPath); + if (im != null) + { + Gfx.DrawImage(im, _resizer.Point(_offsetLeft, _offsetTop)); + _pageHeight -= HeaderImgHeight; + _offsetTop += HeaderImgHeight; + } + } + } + + public void SetWatermark(string mark) + { + _watermark = mark; + } + } +}
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/Properties/AssemblyInfo.cs b/DHTMLX.Export.PDF/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7ad7f96 --- /dev/null +++ b/DHTMLX.Export.PDF/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("scheduler-pdf-net")] +[assembly: AssemblyDescription("Tool for exporting dhtmlxScheduler v4.x to pdf")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Dinamenta, UAB")] +[assembly: AssemblyProduct("scheduler-pdf-net")] +[assembly: AssemblyCopyright("Copyright © 2017 Dinamenta, UAB")] +[assembly: AssemblyTrademark("DHTMLX")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e8777cf2-7f63-4dc4-81e6-6dbc788e5af6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/DHTMLX.Export.PDF/RGBColor.cs b/DHTMLX.Export.PDF/RGBColor.cs new file mode 100644 index 0000000..58e1a43 --- /dev/null +++ b/DHTMLX.Export.PDF/RGBColor.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using PdfSharp.Drawing; +namespace DHTMLX.Export.PDF.Scheduler +{ + public class RGBColor + { + private static Dictionary<string, double[]> _parsedColors = new Dictionary<string, double[]>(); + + public static double[] GetColor(string color) + { + if (_parsedColors.ContainsKey(color)) + return (double[])_parsedColors[color]; + var original = color; + color = RGBColor.ProcessColorForm(color); + var result = new double[3]; + var r = color.Substring(0, 2); + var g = color.Substring(2, 2); + var b = color.Substring(4, 2); + + result[0] = int.Parse(r, System.Globalization.NumberStyles.HexNumber) / 255.0; + result[1] = int.Parse(g, System.Globalization.NumberStyles.HexNumber) / 255.0; + result[2] = int.Parse(b, System.Globalization.NumberStyles.HexNumber) / 255.0; + _parsedColors.Add(original, result); + return result; + } + + public static XColor GetXColor(string color) + { + var dblColor = GetColor(color); + return XColor.FromArgb((int)Math.Floor(dblColor[0] * 255), (int)Math.Floor(dblColor[1] * 255), (int)Math.Floor(dblColor[2] * 255)); + } + + public static XColor GetXColor(double[] dblColor) + { + return XColor.FromArgb((int)Math.Floor(dblColor[0] * 255), (int)Math.Floor(dblColor[1] * 255), (int)Math.Floor(dblColor[2] * 255)); + } + + public static string ProcessColorForm(string color) + { + if (color.Equals("transparent")) + { + return ""; + } + if (Regex.IsMatch(color, "#[0-9A-Fa-f]{6}")) + { + return color.Substring(1); + } + + if (Regex.IsMatch(color, "[0-9A-Fa-f]{6}")) + { + return color; + } + + var m3 = Regex.Match(color, "rgb\\s?\\(\\s?(\\d{1,3})\\s?,\\s?(\\d{1,3})\\s?,\\s?(\\d{1,3})\\s?\\)"); + + if (m3.Length > 0) + { + var r = m3.Groups[1].Value; + var g = m3.Groups[2].Value; + var b = m3.Groups[3].Value; + r = int.Parse(r).ToString("x"); + r = (r.Length == 1) ? "0" + r : r; + g = int.Parse(g).ToString("x"); + g = (g.Length == 1) ? "0" + g : g; + b = int.Parse(b).ToString("x"); + b = (b.Length == 1) ? "0" + b : b; + color = r + g + b; + return color; + } + return ""; + } + } +}
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/Resizer.cs b/DHTMLX.Export.PDF/Resizer.cs new file mode 100644 index 0000000..4f9ef0e --- /dev/null +++ b/DHTMLX.Export.PDF/Resizer.cs @@ -0,0 +1,68 @@ +using PdfSharp.Drawing; +using PdfSharp; + + +namespace DHTMLX.Export.PDF +{ + internal class Resizer + { + private double _xRatio = 1; + private double _yRatio = 1; + public PageOrientation Orient { get; set; } + private bool _keep = true; + private void _CalcRatio(Orientation actual, Orientation desired) + { + if (desired == Orientation.Default || actual == desired) + return; + + _keep = false; + + _yRatio = 1.0 / _xRatio; + } + + public Resizer(PageOrientation from, Orientation to) + { + _CalcRatio(ToDHXOrient(from), to); + if (_keep) + Orient = from; + else + Orient = ToPDFOrient(to); + } + + public PageOrientation ToPDFOrient(Orientation orient) + { + return orient == Orientation.Landscape ? PageOrientation.Landscape : PageOrientation.Portrait; + } + + public Orientation ToDHXOrient(PageOrientation orient) + { + return orient == PageOrientation.Landscape ? Orientation.Landscape : Orientation.Portrait; + } + + public XPoint Point(double x, double y) + { + return new XPoint(ResizeX(x), ResizeY(y)); + } + + public double ResizeX(double x) + { + if (_keep) + return x; + + return x * _xRatio; + } + + public double ResizeY(double y) + { + if (_keep) + return y; + + return y * _yRatio; + } + + public XRect Rect(double x, double y, double width, double height) + { + return new XRect(ResizeX(x), ResizeY(y), ResizeX(width), ResizeY(height)); + } + } +}
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/SchedulerEvent.cs b/DHTMLX.Export.PDF/SchedulerEvent.cs new file mode 100644 index 0000000..45b5b6d --- /dev/null +++ b/DHTMLX.Export.PDF/SchedulerEvent.cs @@ -0,0 +1,161 @@ +using System; +using System.Xml; +using System.Text.RegularExpressions; + +namespace DHTMLX.Export.PDF.Scheduler +{ + public class SchedulerEvent + { + private string _backgroundColor; + private string _text = ""; + private string _color; + + public SchedulerEvent(){ + Footenote = -1; + } + + public string Text + { + get { return _text ?? (_text = ""); } + protected set { _text = value; } + } + public int Day { get; protected set; } + public int Week { get; protected set; } + public int Month { get; protected set; } + public int Len { get; protected set; } + public double X { get; protected set; } + public double Y { get; set; } + public string Type { get; protected set; } + public double Width { get; protected set; } + public double Height { get; protected set; } + public string HeaderText { get; protected set; } + public string HeaderAgendaText { get; protected set; } + + public string BackgroundColor + { + get + { + _backgroundColor = ProcessColor(_backgroundColor); + return _backgroundColor; + } + protected set { _backgroundColor = value; } + } + + public string Color + { + get + { + _color = ProcessColor(_color); + return _color; + } + protected set { _color = value; } + } + + public int Footenote { get; set; } + + private string GetNodeValue(XmlNode node) + { + var txt = node.FirstChild != null ? node.FirstChild.Value : ""; + if (string.IsNullOrEmpty(txt)) + txt = node.InnerText; + + if (string.IsNullOrEmpty(txt)) + txt = ""; + return txt; + } + private int GetNumAttributeValue(XmlNode node, string attr) + { + string val = node.Attributes[attr] != null ? node.Attributes[attr].Value : "0"; + int result = 0; + if (!string.IsNullOrEmpty(val) && val != "undefined") + int.TryParse(val, out result); + return result; + } + private string GetAttributeValue(XmlNode node, string attr) + { + return node.Attributes[attr] != null ? node.Attributes[attr].Value : "0"; + + } + private double GetDoublAttributeValue(XmlNode node, string attr) + { + string val = node.Attributes[attr] != null ? node.Attributes[attr].Value : "0"; + double result = 0; + + if (!string.IsNullOrEmpty(val) && val != "undefined") + double.TryParse(val, System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out result); + return result; + } + public void Parse(XmlNode parent) + { + var children = parent.ChildNodes; + var bgProcessed = false; + for (var i = 0; i < children.Count; i++) + { + switch (children[i].LocalName) + { + case "body": + Text = GetNodeValue(children[i]); + BackgroundColor = GetAttributeValue(children[i], "backgroundColor"); + Color = GetAttributeValue(children[i], "color"); + bgProcessed = true; + break; + case "header": + HeaderText = GetNodeValue(children[i]); + break; + case "head": + HeaderAgendaText = GetNodeValue(children[i]); + break; + } + } + if (!bgProcessed) + { + BackgroundColor = GetAttributeValue(parent, "backgroundColor"); + Color = GetAttributeValue(parent, "color"); + } + + Day = GetNumAttributeValue(parent, "day"); + Week = GetNumAttributeValue(parent, "week"); + Len = GetNumAttributeValue(parent, "len"); + Month = GetNumAttributeValue(parent, "month"); + + X = GetDoublAttributeValue(parent, "x"); + Y = GetDoublAttributeValue(parent, "y"); + Width = GetDoublAttributeValue(parent, "width"); + Height = GetDoublAttributeValue(parent, "height"); + + Type = GetAttributeValue(parent, "type"); + } + + private string ProcessColor(string color) + { + + if (Regex.IsMatch(color, "#[0-9A-Fa-f]{6}")) + { + return color.Substring(1); + } + + if (Regex.IsMatch(color, "[0-9A-Fa-f]{6}")) + { + return color; + } + + var m3 = Regex.Match(color, "rgb\\s?\\(\\s?(\\d{1,3})\\s?,\\s?(\\d{1,3})\\s?,\\s?(\\d{1,3})\\s?\\)"); + + if (m3.Length > 0) + { + var r = m3.Groups[1].Value; + var g = m3.Groups[2].Value; + var b = m3.Groups[3].Value; + r = int.Parse(r).ToString("x"); + r = (r.Length == 1) ? "0" + r : r; + g = int.Parse(g).ToString("x"); + g = (g.Length == 1) ? "0" + g : g; + b = int.Parse(b).ToString("x"); + b = (b.Length == 1) ? "0" + b : b; + color = r + g + b; + return color; + } + return "transparent"; + } + } +}
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/SchedulerMonth.cs b/DHTMLX.Export.PDF/SchedulerMonth.cs new file mode 100644 index 0000000..e23bc88 --- /dev/null +++ b/DHTMLX.Export.PDF/SchedulerMonth.cs @@ -0,0 +1,60 @@ +using System; +using System.Xml; + +namespace DHTMLX.Export.PDF.Scheduler +{ + public class SchedulerMonth + { + private string _monthName; + private string[,] _rows; + + public void Parse(XmlNode parent) + { + _monthName = parent.Attributes["label"].Value; + var parsRows = XMLParser.GetElementsByTagName(parent, "row"); + var cols = XMLParser.GetElementsByTagName(parent, "column"); + + if ((parsRows.Count != 0) && (cols.Count != 0)) + { + _rows = new string[parsRows.Count + 1, 7]; + for (var i = 0; i < cols.Count; i++) + { + _rows[0, i] = cols[i].FirstChild.Value; + } + for (var i = 1; i <= parsRows.Count; i++) + { + var values = parsRows[i - 1].FirstChild.Value.Split(new[] { "|" }, StringSplitOptions.None); + for (var j = 0; j < values.Length; j++) + { + _rows[i, j] = values[j]; + } + } + } + } + + public string GetLabel() + { + return _monthName; + } + + public string[,] GetRows() + { + return _rows; + } + + public string[,] GetOnlyDays() + { + var days = new string[_rows.GetLength(0) - 1, 7]; + + + for (var i = 1; i < _rows.GetLength(0); i++) + { + for (var j = 0; j < 7; j++) + { + days[i - 1, j] = _rows[i, j]; + } + } + return days; + } + } +}
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/TreeTimelineParser.cs b/DHTMLX.Export.PDF/TreeTimelineParser.cs new file mode 100644 index 0000000..70d97b6 --- /dev/null +++ b/DHTMLX.Export.PDF/TreeTimelineParser.cs @@ -0,0 +1,61 @@ +using System.Text.RegularExpressions; + +namespace DHTMLX.Export.PDF +{ + public class TreeTimelineCategory + { + public bool Expanded { get; set; } + public int Level { get; set; } + public bool IsExpandable { get; set; } + public string Text { get; set; } + public TreeTimelineCategory(string text, int level, bool allowchild, bool expanded) + { + Level = level; + Expanded = expanded; + IsExpandable = allowchild; + Text = text; + } + public TreeTimelineCategory() : this("", 0, false, false) + { + + } + } + + + public class TreeTimelineParser + { + + /* + * Html tree timeline rows, e.g.: + <div class=\"dhx_scell_level0\"> + <div class=\"dhx_scell_expand\">-</div><div class=\"dhx_scell_name\">Web Testing Dep.</div> + </div> + <div class=\"dhx_scell_level1\"> + <div class=\"dhx_scell_expand\"> </div><div class=\"dhx_scell_name\">Managers</div> + </div> + <div class=\"dhx_scell_level1\"> + <div class=\"dhx_scell_name\">Elizabeth Taylor</div> + </div>" + */ + public static bool IsTreeRow(string item) + { + var treeRowRegex = "^<div.*dhx_scell_level.*>.*(dhx_scell_expand|dhx_scell_name).*<\\/div>$"; + return (Regex.IsMatch(item.Trim(), treeRowRegex)); + } + public TreeTimelineCategory Parse(string item) + { + var levelReg = "dhx_scell_level([0-9]+)"; + var isExpandable = "dhx_scell_expand"; + var state = "dhx_scell_expand.*?>(-| )<\\/div"; + var text = "dhx_scell_name.*?>(.+?)<\\/div"; + var expandable = Regex.IsMatch(item, isExpandable); + var level = 0; + int.TryParse(Regex.Match(item, levelReg).Groups[1].Value, out level); + var expanded = Regex.Match(item, state).Groups[1].Value == "-"; + var value = Regex.Match(item, text).Groups[1].Value; + return new TreeTimelineCategory(value, level, expandable, expanded); + + + } + } +} diff --git a/DHTMLX.Export.PDF/XMLParser.cs b/DHTMLX.Export.PDF/XMLParser.cs new file mode 100644 index 0000000..fff6a7b --- /dev/null +++ b/DHTMLX.Export.PDF/XMLParser.cs @@ -0,0 +1,344 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; + +namespace DHTMLX.Export.PDF.Scheduler +{ + public enum ColorProfile + { + Color, + FullColor, + Gray, + BW, + Custom + } + + public class XMLParser + { + public List<PDFPage> Pages { get; set; } + + public ColorProfile StringToColorProfile(string profile) + { + if (profile == null) + return ColorProfile.Color; + switch (profile.ToLower()) + { + case "gray": + return ColorProfile.Gray; + case "full_color": + return ColorProfile.FullColor; + case "color": + return ColorProfile.Color; + case "bw": + return ColorProfile.BW; + case "custom": + return ColorProfile.Custom; + default: + return ColorProfile.Color; + } + } + + public static List<XmlNode> GetElementsByTagName(XmlNode parent, string name) + { + var list = new List<XmlNode>(); + foreach (XmlNode node in parent.ChildNodes) + { + if (node.LocalName == name) + { + list.Add(node); + } + else + { + list.AddRange(GetElementsByTagName(node, name)); + } + } + return list; + } + + public void ParsePages(XmlNode root) + { + + if (root.Name == "pages") + { + var n1 = GetElementsByTagName(root, "page"); + if (n1 != null && n1.Count > 0) + { + + for (var i = 0; i < n1.Count; i++) + { + var page = new PDFPage { Node = n1[i] }; + Pages.Add(page); + ParseConfig(page); + EventsParsing(page); + } + } + } + else + { + var page = new PDFPage { Node = root }; + Pages.Add(page); + ParseConfig(page); + EventsParsing(page); + } + + } + public void ParseConfig(PDFPage page) + { + XmlNode scale = null; + var root = page.Node; + foreach (XmlNode nod in root.ChildNodes) + { + if (nod.LocalName == "scale") + { + scale = nod; + break; + } + } + + var toCheck = new List<XmlNode> { root }; + if (scale != null) + toCheck.Add(scale); + if (root.ParentNode != null && root.ParentNode.NodeType != XmlNodeType.Document && root.ParentNode.Name != "data") + { + toCheck.Add(root.ParentNode); + } + + for (var i = 0; i < toCheck.Count; i++) + { + if (toCheck[i].Attributes["profile"] != null && page.Profile == default(ColorProfile)) + { + page.Profile = StringToColorProfile(toCheck[i].Attributes["profile"].Value); + } + if (toCheck[i].Attributes["header"] != null && page.Header == default(bool)) + { + page.Header = (toCheck[i].Attributes["header"].Value == "true"); + } + if (toCheck[i].Attributes["footer"] != null && page.Footer == default(bool)) + { + page.Footer = (toCheck[i].Attributes["footer"].Value == "true"); + } + + if (toCheck[i].Attributes["mode"] != null && page.Mode == default(string)) + page.Mode = toCheck[i].Attributes["mode"] != null ? toCheck[i].Attributes["mode"].Value : ""; + + if (toCheck[i].Attributes["today"] != null && page.TodayLabel == default(string)) + page.TodayLabel = toCheck[i].Attributes["today"] != null ? toCheck[i].Attributes["today"].Value : ""; + + } + + + } + + public IEnumerable<XmlNode> GetPages(string xml) + { + var dom = new XmlDocument(); + dom.LoadXml(xml); + var root = dom.DocumentElement; + var res = new List<XmlNode>(); + + if (root.FirstChild.Name != "data") + { + res.Add(root); + } + else + { + foreach (var nod in root.ChildNodes) + res.Add(nod as XmlNode); + } + return res; + } + + + public void SetXML(XmlNode root) + { + Pages = new List<PDFPage>(); + ParsePages(root); + } + + public string[][] MonthColsParsing(PDFPage page) + { + + var n1 = GetElementsByTagName(page.Node, "column"); + if (n1 != null && n1.Count > 0) + { + page.Cols = new[] { new string[n1.Count] }; + + for (var i = 0; i < n1.Count; i++) + { + var col = n1[i]; + page.Cols[0][i] = col.FirstChild.Value; + } + } + return page.Cols; + } + + public IList<MonthRow> GetRowsObjects(PDFPage page) + { + if (page.RowObs == null) + { + var n1 = GetElementsByTagName(page.Node, "row"); + if (n1 != null && n1.Count > 0) + { + page.RowObs = new List<MonthRow>(7); + for (var i = 0; i < n1.Count; i++) + { + var r = new MonthRow(); + page.RowObs.Add(r); + + var node = n1[i]; + + double height; + var hght = node.Attributes["height"].Value; + + if (double.TryParse(hght, out height)) + r.Height = height; + else + r.Height = default(double); + + var week = node.FirstChild.Value; + r.Cells = week.Split(new[] { "|" }, StringSplitOptions.None); + + } + } + } + return page.RowObs; + } + + public string[,] MonthRowsParsing(PDFPage page) + { + var n1 = GetElementsByTagName(page.Node, "row"); + if (n1 != null && n1.Count > 0) + { + page.Rows = new string[n1.Count, 7]; + for (var i = 0; i < n1.Count; i++) + { + var row = n1[i]; + var week = row.FirstChild.Value; + var days = week.Split(new[] { "|" }, StringSplitOptions.None); + for (var j = 0; j < days.Length; j++) + page.Rows[i, j] = days[j]; + } + } + return page.Rows; + } + + public void EventsParsing(PDFPage page) + { + var n1 = GetElementsByTagName(page.Node, "event"); + if (n1 != null && n1.Count > 0) + { + for (var i = 0; i < n1.Count; i++) + { + var ev = n1[i]; + SchedulerEvent oEv = new SchedulerEvent(); + oEv.Parse(ev); + if ((oEv.Type == "event_line") && (page.Mode != "month") && (page.Mode != "timeline") && (page.Mode != "treetimeline")) + { + page.Multiday.Add(oEv); + } + else + { + page.Events.Add(oEv); + } + } + } + } + + public int[] ScaleRatios(PDFPage page) + { + var n1 = GetElementsByTagName(page.Node, "column"); + return n1.Where(n => n.Attributes["second_scale"] != null).GroupBy(n => n.Attributes["second_scale"].Value).Select(g => g.Count()).ToArray(); + } + + public string[][] WeekColsParsing(PDFPage page) + { + if (page.Cols != null) + return page.Cols; + var n1 = GetElementsByTagName(page.Node, "column"); + + if (n1 != null && n1.Count > 0) + { + + var scale1 = n1.Where(n => n.Attributes["second_scale"] == null).ToList(); + var scale2 = n1.Where(n => n.Attributes["second_scale"] != null).ToList(); + + string[][] scales; + if (scale2.Count > 0) + { + scales = new string[2][]; + scales[0] = new string[scale1.Count]; + scales[1] = new string[scale2.Count]; + } + else + { + scales = new string[1][]; + scales[0] = new string[scale1.Count]; + } + + for (var i = 0; i < scale1.Count; i++) + { + scales[0][i] = scale1[i].FirstChild.Value; + } + + for (var i = 0; i < scale2.Count; i++) + { + scales[1][i] = scale2[i].FirstChild.Value; + } + page.Cols = scales; + + } + return page.Cols; + } + + public string[] WeekRowsParsing(PDFPage page) + { + string[] rows = null; + var n1 = GetElementsByTagName(page.Node, "row"); + if (n1 != null && n1.Count > 0) + { + rows = new string[n1.Count]; + for (var i = 0; i < n1.Count; i++) + { + var row = n1[i]; + rows[i] = row.FirstChild.Value; + } + } + return rows; + } + + public SchedulerMonth[] YearParsing(PDFPage page) + { + SchedulerMonth[] monthes = null; + var n1 = GetElementsByTagName(page.Node, "month"); + if (n1 != null && n1.Count > 0) + { + monthes = new SchedulerMonth[n1.Count]; + for (var i = 0; i < n1.Count; i++) + { + monthes[i] = new SchedulerMonth(); + var mon = n1[i]; + monthes[i].Parse(mon); + } + } + return monthes; + } + + public string[] AgendaColsParsing(PDFPage page) + { + string[] cols = null; + var n1 = GetElementsByTagName(page.Node, "column"); + if (n1 != null && n1.Count > 0) + { + cols = new string[n1.Count]; + for (var i = 0; i < n1.Count; i++) + { + var col = n1[i]; + cols[i] = col.FirstChild.Value; + } + } + return cols; + } + + } +}
\ No newline at end of file diff --git a/DHTMLX.Export.PDF/lib/ExtendLib.cs b/DHTMLX.Export.PDF/lib/ExtendLib.cs new file mode 100644 index 0000000..98832b8 --- /dev/null +++ b/DHTMLX.Export.PDF/lib/ExtendLib.cs @@ -0,0 +1,489 @@ +#region PDFsharp - A .NET library for processing PDF +// +// Authors: +// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com) +// +// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany) +// +// http://www.pdfsharp.com +// http://sourceforge.net/projects/pdfsharp +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +#endregion + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Collections; +using System.Text; +using PdfSharp.Drawing; +using PdfSharp.Pdf.IO; +using PdfSharp.Drawing.Layout; +namespace DHTMLX.Export.PDF.Formatter +{ + /// <summary> + /// Represents a very simple text formatter. + /// If this class does not satisfy your needs on formatting paragraphs I recommend to take a look + /// at MigraDoc Foundation. Alternatively you should copy this class in your own source code and modify it. + /// </summary> + public class DHXTextFormatter + { + /// <summary> + /// Initializes a new instance of the <see cref="XTextFormatter"/> class. + /// </summary> + public DHXTextFormatter(XGraphics gfx) + { + if (gfx == null) + throw new ArgumentNullException("gfx"); + this.gfx = gfx; + } + XGraphics gfx; + + /// <summary> + /// Gets or sets the text. + /// </summary> + /// <value>The text.</value> + public string Text + { + get { return this.text; } + set { this.text = value; } + } + string text; + + /// <summary> + /// Gets or sets the font. + /// </summary> + public XFont Font + { + get { return this.font; } + set + { + if (value == null) + throw new ArgumentNullException("font"); + this.font = value; + + this.lineSpace = font.GetHeight(this.gfx); + + var family = this.Font.FontFamily; + + var cellSpace = family.GetLineSpacing(font.Style); + var cellAscent = family.GetCellAscent(font.Style); + var cellDescent = family.GetCellDescent(font.Style); + + this.cyAscent = lineSpace * cellAscent / cellSpace; + this.cyDescent = lineSpace * cellDescent / cellSpace; + + // HACK in XTextFormatter + this.spaceWidth = gfx.MeasureString("x x", value).Width; + this.spaceWidth -= gfx.MeasureString("xx", value).Width; + } + } + XFont font; + double lineSpace; + double cyAscent; + double cyDescent; + double spaceWidth; + + /// <summary> + /// Gets or sets the bounding box of the layout. + /// </summary> + public XRect LayoutRectangle + { + get { return this.layoutRectangle; } + set { this.layoutRectangle = value; } + } + XRect layoutRectangle; + + /// <summary> + /// Gets or sets the alignment of the text. + /// </summary> + public XParagraphAlignment Alignment + { + get { return this.alignment; } + set { this.alignment = value; } + } + XParagraphAlignment alignment = XParagraphAlignment.Left; + + /// <summary> + /// Draws the text. + /// </summary> + /// <param name="text">The text to be drawn.</param> + /// <param name="font">The font.</param> + /// <param name="brush">The text brush.</param> + /// <param name="layoutRectangle">The layout rectangle.</param> + public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectangle) + { + DrawString(text, font, brush, layoutRectangle, XStringFormats.TopLeft); + } + + /// <summary> + /// Draws the text. + /// </summary> + /// <param name="text">The text to be drawn.</param> + /// <param name="font">The font.</param> + /// <param name="brush">The text brush.</param> + /// <param name="layoutRectangle">The layout rectangle.</param> + /// <param name="format">The format. Must be <c>XStringFormat.TopLeft</c></param> + public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format) + { + if (text == null) + throw new ArgumentNullException("text"); + if (font == null) + throw new ArgumentNullException("font"); + if (brush == null) + throw new ArgumentNullException("brush"); + if (format.Alignment != XStringAlignment.Near || format.LineAlignment!= XLineAlignment.Near) + throw new ArgumentException("Only TopLeft alignment is currently implemented."); + + Text = text; + Font = font; + LayoutRectangle = layoutRectangle; + + if (text.Length == 0) + return; + + CreateBlocks(layoutRectangle.Width); + + CreateLayout(); + + double dx = layoutRectangle.Location.X; + double mWidth = layoutRectangle.Size.Width; + double dy = layoutRectangle.Location.Y + cyAscent; + int count = this.blocks.Count; + for (int idx = 0; idx < count; idx++) + { + Block block = (Block)this.blocks[idx]; + if (block.Stop) + break; + if (block.Type == BlockType.LineBreak) + continue; + + + if (idx +1 < count) + { + if (this.blocks[idx + 1].Stop) + { + if (block.Text.Length > 3) + { + block.Text = block.Text.Substring(0, block.Text.Length - 3) + "..."; + } + else + { + int dots = 0; + while (dots < 3 && gfx.MeasureString(block.Text, font).Width < mWidth) + { + block.Text += "."; + dots++; + } + } + } + } + gfx.DrawString(block.Text, font, brush, dx + block.Location.X, dy + block.Location.Y); + } + } + + void CreateBlocks(double maxWidth) + { + this.blocks.Clear(); + int length = this.text.Length; + bool inNonWhiteSpace = false; + int startIndex = 0, blockLength = 0; + for (int idx = 0; idx < length; idx++) + { + char ch = text[idx]; + + // Treat CR and CRLF as LF + if (ch == Chars.CR) + { + if (idx < length - 1 && text[idx + 1] == Chars.LF) + idx++; + ch = Chars.LF; + } + if (ch == Chars.LF) + { + if (blockLength != 0) + { + string token = text.Substring(startIndex, blockLength); + this.blocks.Add(new Block(token, BlockType.Text, + this.gfx.MeasureString(token, this.font).Width)); + } + startIndex = idx + 1; + blockLength = 0; + this.blocks.Add(new Block(BlockType.LineBreak)); + } + else if (Char.IsWhiteSpace(ch)) + { + if (inNonWhiteSpace) + { + string token = text.Substring(startIndex, blockLength); + this.blocks.Add(new Block(token, BlockType.Text, + this.gfx.MeasureString(token, this.font).Width)); + startIndex = idx + 1; + blockLength = 0; + } + else + { + blockLength++; + } + } + else + { + inNonWhiteSpace = true; + blockLength++; + if (startIndex + blockLength < length) + { + if (this.gfx.MeasureString(text.Substring(startIndex, blockLength + 1), this.font).Width >= maxWidth) + { + string token = text.Substring(startIndex, blockLength); + this.blocks.Add(new Block(token, BlockType.Text, + this.gfx.MeasureString(token, this.font).Width)); + startIndex = startIndex + blockLength; + blockLength = 0; + inNonWhiteSpace = false; + } + } + + } + } + if (blockLength != 0) + { + string token = text.Substring(startIndex, blockLength); + this.blocks.Add(new Block(token, BlockType.Text, + this.gfx.MeasureString(token, this.font).Width)); + } + } + + void CreateLayout() + { + double rectWidth = this.layoutRectangle.Width; + double rectHeight = this.layoutRectangle.Height - this.cyAscent - this.cyDescent; + int firstIndex = 0; + double x = 0, y = 0; + int count = this.blocks.Count; + for (int idx = 0; idx < count; idx++) + { + Block block = (Block)this.blocks[idx]; + if (block.Type == BlockType.LineBreak) + { + if (Alignment == XParagraphAlignment.Justify) + ((Block)this.blocks[firstIndex]).Alignment = XParagraphAlignment.Left; + AlignLine(firstIndex, idx - 1, rectWidth); + firstIndex = idx + 1; + x = 0; + y += this.lineSpace; + } + else + { + double width = block.Width; //!!!modTHHO 19.11.09 don't add this.spaceWidth here + if ((x + width <= rectWidth || x == 0) && block.Type != BlockType.LineBreak) + { + block.Location = new XPoint(x, y); + x += width + spaceWidth; //!!!modTHHO 19.11.09 add this.spaceWidth here + } + else + { + AlignLine(firstIndex, idx - 1, rectWidth); + firstIndex = idx; + y += lineSpace; + if (y > rectHeight) + { + block.Stop = true; + break; + } + block.Location = new XPoint(0, y); + x = width + spaceWidth; //!!!modTHHO 19.11.09 add this.spaceWidth here + } + } + } + if (firstIndex < count && Alignment != XParagraphAlignment.Justify) + AlignLine(firstIndex, count - 1, rectWidth); + } + + /// <summary> + /// Align center, right or justify. + /// </summary> + void AlignLine(int firstIndex, int lastIndex, double layoutWidth) + { + XParagraphAlignment blockAlignment = ((Block)(this.blocks[firstIndex])).Alignment; + if (this.alignment == XParagraphAlignment.Left || blockAlignment == XParagraphAlignment.Left) + return; + + int count = lastIndex - firstIndex + 1; + if (count == 0) + return; + + double totalWidth = -this.spaceWidth; + for (int idx = firstIndex; idx <= lastIndex; idx++) + totalWidth += ((Block)(this.blocks[idx])).Width + this.spaceWidth; + + double dx = Math.Max(layoutWidth - totalWidth, 0); + //Debug.Assert(dx >= 0); + if (this.alignment != XParagraphAlignment.Justify) + { + if (this.alignment == XParagraphAlignment.Center) + dx /= 2; + for (int idx = firstIndex; idx <= lastIndex; idx++) + { + Block block = (Block)this.blocks[idx]; + block.Location += new XSize(dx, 0); + } + } + else if (count > 1) // case: justify + { + dx /= count - 1; + for (int idx = firstIndex + 1, i = 1; idx <= lastIndex; idx++, i++) + { + Block block = (Block)this.blocks[idx]; + block.Location += new XSize(dx * i, 0); + } + } + } + + readonly List<Block> blocks = new List<Block>(); + + enum BlockType + { + Text, Space, Hyphen, LineBreak, + } + + /// <summary> + /// Represents a single word. + /// </summary> + class Block + { + /// <summary> + /// Initializes a new instance of the <see cref="Block"/> class. + /// </summary> + /// <param name="text">The text of the block.</param> + /// <param name="type">The type of the block.</param> + /// <param name="width">The width of the text.</param> + public Block(string text, BlockType type, double width) + { + Text = text; + Type = type; + Width = width; + } + + /// <summary> + /// Initializes a new instance of the <see cref="Block"/> class. + /// </summary> + /// <param name="type">The type.</param> + public Block(BlockType type) + { + Type = type; + } + + /// <summary> + /// The text represented by this block. + /// </summary> + public string Text; + + /// <summary> + /// The type of the block. + /// </summary> + public BlockType Type; + + /// <summary> + /// The width of the text. + /// </summary> + public double Width; + + /// <summary> + /// The location relative to the upper left corner of the layout rectangle. + /// </summary> + public XPoint Location; + + /// <summary> + /// The alignment of this line. + /// </summary> + public XParagraphAlignment Alignment; + + /// <summary> + /// A flag indicating that this is the last bock that fits in the layout rectangle. + /// </summary> + public bool Stop; + } + // TODO: + // - more XStringFormat variations + // - calculate bounding box + // - left and right indent + // - first line indent + // - margins and paddings + // - background color + // - text background color + // - border style + // - hyphens, soft hyphens, hyphenation + // - kerning + // - change font, size, text color etc. + // - line spacing + // - underine and strike-out variation + // - super- and sub-script + // - ... + } + + + + /// <summary> + /// Character table by name. + /// </summary> + internal sealed class Chars + { + // ReSharper disable InconsistentNaming + public const char EOF = (char)65535; //unchecked((char)(-1)); + public const char NUL = '\0'; // EOF + public const char CR = '\x0D'; // ignored by lexer + public const char LF = '\x0A'; // Line feed + public const char BEL = '\a'; // Bell + public const char BS = '\b'; // Backspace + public const char FF = '\f'; // Form feed + public const char HT = '\t'; // Horizontal tab + public const char VT = '\v'; // Vertical tab + public const char NonBreakableSpace = (char)160; // char(160) + + // The following names come from "PDF Reference Third Edition" + // Appendix D.1, Latin Character Set and Encoding + public const char SP = ' '; + public const char QuoteDbl = '"'; + public const char QuoteSingle = '\''; + public const char ParenLeft = '('; + public const char ParenRight = ')'; + public const char BraceLeft = '{'; + public const char BraceRight = '}'; + public const char BracketLeft = '['; + public const char BracketRight = ']'; + public const char Less = '<'; + public const char Greater = '>'; + public const char Equal = '='; + public const char Period = '.'; + public const char Semicolon = ';'; + public const char Colon = ':'; + public const char Slash = '/'; + public const char Bar = '|'; + public const char BackSlash = '\\'; + public const char Percent = '%'; + public const char Dollar = '$'; + public const char At = '@'; + public const char NumberSign = '#'; + public const char Question = '?'; + public const char Hyphen = '-'; // char(45) + public const char SoftHyphen = ''; // char(173) + public const char Currency = '¤'; + // ReSharper restore InconsistentNaming + } +} diff --git a/DHTMLX.Export.PDF/packages.config b/DHTMLX.Export.PDF/packages.config new file mode 100644 index 0000000..4a69c7b --- /dev/null +++ b/DHTMLX.Export.PDF/packages.config @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" /> + <package id="PDFsharp" version="1.32.3057.0" targetFramework="net461" /> +</packages>
\ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..65aee71 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +dhtmlxScheduler v4.x to PDF print tool for .NET +---------------------------------------------------------- + +This project can be used to print dhtmlxScheduler to PDF using legacy export extension + +Docs : + + - http://docs.dhtmlx.com/scheduler/pdf_v4.html + +Demo: + + - http://docs.dhtmlx.com/scheduler/samples/04_export/05_standalone_export.html + +### Disclaimer +This version of the export tool won't be actively developed. We encourage you to use the new version of the export tool instead: + + - https://dhtmlx.com/docs/products/dhtmlxGantt/export.shtml + - http://docs.dhtmlx.com/scheduler/pdf.html + + +### Usage + +- Add DHTMLX.Export.PDF project to the solution. +- Add reference to it from your web project and create a backend handler. +- Call the handler using client side extension of dhtmlxScheduler http://docs.dhtmlx.com/scheduler/pdf_v4.html#triggeringtheexport + +### Sample backend implementation + +#### ASP.NET WebForms + +~~~cs +//Generate.ashx + +using System.Web; +using DHTMLX.Export.PDF; +using System.Web.Configuration; + +public class Generate : IHttpHandler +{ + + public void ProcessRequest(HttpContext context) + { + PagesSection pageSection = new PagesSection(); + pageSection.ValidateRequest = false; + + var generator = new SchedulerPDFWriter(); + var xml = context.Server.UrlDecode(context.Request.Form["mycoolxmlbody"]); + generator.Generate(xml, context.Response); + } + + public bool IsReusable { get { return false; } } +} +~~~ + +#### ASP.NET MVC + +~~~cs +using System.IO; +using System.Web; +using System.Web.Mvc; +using DHTMLX.Export.PDF; + +namespace scheduler2pdf.Controllers +{ + [HandleError] + public class GeneratorController : Controller + { + [ValidateInput(false)] + public ActionResult Export() + { + var generator = new SchedulerPDFWriter(); + var xml = this.Server.UrlDecode(this.Request.Form["mycoolxmlbody"]); + MemoryStream pdf = generator.Generate(xml); + return File(pdf.ToArray(), generator.ContentType); + } + } +} + +~~~ + +### License + +Distributed under the MIT software license +Copyright (c) 2017 Dinamenta UAB
\ No newline at end of file diff --git a/packages/repositories.config b/packages/repositories.config new file mode 100644 index 0000000..1a885d6 --- /dev/null +++ b/packages/repositories.config @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<repositories> + <repository path="..\DHTMLX.Export.PDF\packages.config" /> +</repositories>
\ No newline at end of file |