using FastReport.RichTextParser;
using FastReport.Utils;
using System;
using System.Drawing;
using System.Text;
namespace FastReport.Export.OoXML
{
///
/// Save
///
public class RTF_ToDocX : IDisposable
{
private RichDocument doc;
private Rectangle ext_padding = new Rectangle();
#region Private methods
private string Quoted(long p)
{
return String.Concat("\"", p.ToString(), "\" ");
}
private string Quoted(string p)
{
return String.Concat("\"", p, "\" ");
}
private string GetRGBString(Color c)
{
return "\"#" + /*ExportUtils.ByteToHex(c.A) +*/ ExportUtils.ByteToHex(c.R) + ExportUtils.ByteToHex(c.G) + ExportUtils.ByteToHex(c.B) + "\"";
}
private string TranslateText(string text)
{
StringBuilder TextStrings = new StringBuilder();
int start_idx = 0;
while (true)
{
int idx = text.IndexOfAny("&<>".ToCharArray(), start_idx);
if (idx != -1)
{
TextStrings.Append(text.Substring(start_idx, idx - start_idx));
switch (text[idx])
{
case '&': TextStrings.Append("&"); break;
case '<': TextStrings.Append("<"); break;
case '>': TextStrings.Append(">"); break;
}
start_idx = ++idx;
continue;
}
TextStrings.Append(text.Substring(start_idx));
break;
}
return TextStrings.ToString();
}
#endregion
///
public void Dispose()
{
}
///
public RTF_ToDocX(RichDocument doc)
{
this.doc = doc;
}
private void SaveDocumentBody(StringBuilder s)
{
foreach (Page p in doc.pages)
SavePage(s, p, false);
}
private void SavePage(StringBuilder s, Page page, bool v)
{
SaveSequence(s, page.sequence, false);
}
private string GetFontName(RunFormat format)
{
string Name = "Arial";
int font_idx = (int)format.font_idx;
if (font_idx < doc.font_list.Count)
{
RFont rf = doc.font_list[font_idx];
Name = rf.FontName;
}
return Name;
}
private void SaveRun(StringBuilder s, Run r)
{
s.Append("");
string FontName = GetFontName(r.format);
s.Append(" ");
if (r.format.bold)
s.Append("");
if (r.format.strike)
s.Append("");
if (r.format.italic)
s.Append("");
if (r.format.underline)
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("").Append(this.TranslateText(r.text)).Append("");
s.Append("");
}
private void SavePargraph(StringBuilder s, RichTextParser.Paragraph par, bool InTable)
{
s.AppendLine("");
string halign = "";
switch (par.format.align)
{
case RichTextParser.ParagraphFormat.HorizontalAlign.Left: halign = "left"; break;
case RichTextParser.ParagraphFormat.HorizontalAlign.Right: halign = "right"; break;
case RichTextParser.ParagraphFormat.HorizontalAlign.Centered: halign = "center"; break;
case RichTextParser.ParagraphFormat.HorizontalAlign.Justified:
default:
halign = "both";
break;
}
//switch (par.format.Valign)
//{
// case RichTextParser.ParagraphFormat.VerticalAlign.Top: halign = "top"; break;
// case RichTextParser.ParagraphFormat.VerticalAlign.Center: halign = "center"; break;
// case RichTextParser.ParagraphFormat.VerticalAlign.Bottom: halign = "bottom"; break;
// default:
// halign = "top";
// break;
//}
s.Append("");
if (par.format.first_line_indent > 0)
s.Append("");
#region Paragraph spacing
int before_space = par.format.space_before + ext_padding.Top;
int after_space = par.format.space_after + ext_padding.Bottom;
s.Append("");
#endregion
#region Paragraph indent
if (ext_padding.Right + ext_padding.Left != 0)
{
s.Append("");
}
#endregion
s.Append(""); ;
foreach (Run r in par.runs)
SaveRun(s, r);
s.AppendLine("");
}
private void SaveTable(StringBuilder s, RichTextParser.Table tbl, bool InTable)
{
s.Append("");
// Table properties
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
s.Append("");
// Table grid
s.Append("");
foreach (Column column in tbl.columns)
{
s.Append("");
}
s.Append("");
foreach (TableRow row in tbl.rows)
SaveRow(s, row);
s.Append("");
}
private void SaveRow(StringBuilder s, TableRow row)
{
s.Append("");
s.Append("");
foreach (RichObjectSequence seq in row.cells)
{
s.Append("");
s.Append(""); // Fix cell width
s.AppendLine("");
SaveSequence(s, seq, true);
s.AppendLine("");
}
s.AppendLine("");
}
private void SaveSequence(StringBuilder s, RichObjectSequence seq, bool InTable)
{
foreach (RichTextParser.RichObject robj in seq.objects)
{
switch (robj.type)
{
case RichTextParser.RichObject.Type.Paragraph:
SavePargraph(s, robj.paragraph, InTable);
break;
case RichTextParser.RichObject.Type.Picture:
// SkipPicture
break;
case RichTextParser.RichObject.Type.Table:
SaveTable(s, robj.table, InTable);
break;
}
}
}
///
/// Padding over ridh object
///
public Rectangle Padding
{
get { return ext_padding; }
set { ext_padding = value; }
}
///
/// This prperty keep RTF to DOC translation result, i.e. DOCX XML fragment
///
public string DocX
{
get
{
StringBuilder s = new StringBuilder();
SaveDocumentBody(s);
return s.ToString();
}
}
}
}