C2018-039: Upgrade – User Control of Format

This commit is contained in:
2018-12-12 15:34:25 +00:00
parent ddf01e9f9a
commit bbcb638024
29 changed files with 4656 additions and 133 deletions

View File

@@ -0,0 +1,277 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Design;
using System.Windows.Forms.Design;
namespace Volian.Base.Library
{
public class FlagCheckedListBox : CheckedListBox
{
private System.ComponentModel.Container components = null;
public FlagCheckedListBox()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
private void InitializeComponent()
{
//
// FlaggedCheckedListBox
//
this.CheckOnClick = true;
}
#endregion
// Adds an integer value and its associated description
public FlagCheckedListBoxItem Add(uint v, string c)
{
FlagCheckedListBoxItem item = new FlagCheckedListBoxItem(v, c);
Items.Add(item);
return item;
}
public FlagCheckedListBoxItem Add(FlagCheckedListBoxItem item)
{
Items.Add(item);
return item;
}
protected override void OnItemCheck(ItemCheckEventArgs e)
{
base.OnItemCheck(e);
if (isUpdatingCheckStates)
return;
// Get the checked/unchecked item
FlagCheckedListBoxItem item = Items[e.Index] as FlagCheckedListBoxItem;
// Update other items
UpdateCheckedItems(item, e.NewValue);
}
// Checks/Unchecks items depending on the give bitvalue
protected void UpdateCheckedItems(uint value)
{
isUpdatingCheckStates = true;
// Iterate over all items
for (int i = 0; i < Items.Count; i++)
{
FlagCheckedListBoxItem item = Items[i] as FlagCheckedListBoxItem;
if (item.value == 0)
{
SetItemChecked(i, value == 0);
}
else
{
// If the bit for the current item is on in the bitvalue, check it
if ((item.value & value) == item.value && item.value != 0)
SetItemChecked(i, true);
// Otherwise uncheck it
else
SetItemChecked(i, false);
}
}
isUpdatingCheckStates = false;
}
// Updates items in the checklistbox
// composite = The item that was checked/unchecked
// cs = The check state of that item
protected void UpdateCheckedItems(FlagCheckedListBoxItem composite, CheckState cs)
{
// If the value of the item is 0, call directly.
if (composite.value == 0)
UpdateCheckedItems(0);
// Get the total value of all checked items
uint sum = 0;
for (int i = 0; i < Items.Count; i++)
{
FlagCheckedListBoxItem item = Items[i] as FlagCheckedListBoxItem;
// If item is checked, add its value to the sum.
if (GetItemChecked(i))
sum |= item.value;
}
// If the item has been unchecked, remove its bits from the sum
if (cs == CheckState.Unchecked)
sum = sum & (~composite.value);
// If the item has been checked, combine its bits with the sum
else
sum |= composite.value;
// Update all items in the checklistbox based on the final bit value
UpdateCheckedItems(sum);
}
private bool isUpdatingCheckStates = false;
// Gets the current bit value corresponding to all checked items
public uint GetCurrentValue()
{
uint sum = 0;
for (int i = 0; i < Items.Count; i++)
{
FlagCheckedListBoxItem item = Items[i] as FlagCheckedListBoxItem;
if (GetItemChecked(i))
sum |= item.value;
}
return sum;
}
Type enumType;
Enum enumValue;
// Adds items to the checklistbox based on the members of the enum
private void FillEnumMembers()
{
foreach (string name in Enum.GetNames(enumType))
{
object val = Enum.Parse(enumType, name);
uint intVal = (uint)Convert.ChangeType(val, typeof(uint));
Add(intVal, name);
}
}
// Checks/unchecks items based on the current value of the enum variable
private void ApplyEnumValue()
{
uint intVal = (uint)Convert.ChangeType(enumValue, typeof(uint));
UpdateCheckedItems(intVal);
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
public Enum EnumValue
{
get
{
object e = Enum.ToObject(enumType, GetCurrentValue());
return (Enum)e;
}
set
{
Items.Clear();
enumValue = value; // Store the current enum value
enumType = value.GetType(); // Store enum type
FillEnumMembers(); // Add items for enum members
ApplyEnumValue(); // Check/uncheck items depending on enum value
}
}
}
// Represents an item in the checklistbox
public class FlagCheckedListBoxItem
{
public FlagCheckedListBoxItem(uint v, string c)
{
value = v;
caption = c;
}
public override string ToString()
{
return caption;
}
// Returns true if the value corresponds to a single bit being set
public bool IsFlag
{
get
{
return ((value & (value - 1)) == 0);
}
}
// Returns true if this value is a member of the composite bit value
public bool IsMemberFlag(FlagCheckedListBoxItem composite)
{
return (IsFlag && ((value & composite.value) == value));
}
public uint value;
public string caption;
}
// UITypeEditor for flag enums
public class FlagEnumUIEditor : UITypeEditor
{
// The checklistbox
private FlagCheckedListBox flagEnumCB;
public FlagEnumUIEditor()
{
flagEnumCB = new FlagCheckedListBox();
flagEnumCB.BorderStyle = BorderStyle.None;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null
&& context.Instance != null
&& provider != null)
{
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc != null)
{
Enum e = (Enum)Convert.ChangeType(value, context.PropertyDescriptor.PropertyType);
flagEnumCB.EnumValue = e;
edSvc.DropDownControl(flagEnumCB);
return flagEnumCB.EnumValue;
}
}
return null;
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
}
}

View File

@@ -0,0 +1,300 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Reflection;
namespace Volian.Base.Library
{
// The PropGridCollEditor expands the functionality of the CollectionEditor (the collection editor comes up when in a
// property grid, and the current selected item is a collection, and the user selects the '...'.
public class PropGridCollEditor : CollectionEditor
{
// Define a static event to expose the inner PropertyGrid's
// PropertyValueChanged event args...
public delegate void MyPropertyValueChangedEventHandler(object sender, PropertyValueChangedEventArgs e);
public static event MyPropertyValueChangedEventHandler MyPropertyValueChanged;
private bool AllowAddDel = false; // flags whether the Add/Delete buttons should be displayed:
// Inherit the default constructor from the standard
// Collection Editor...
private Type _origType;
public PropGridCollEditor(Type type)
: base(type)
{
AllowAddDel = false;
_origType = type;
if (type.Name == "ReplaceStrData") AllowAddDel = true; // Defaults to not having the 'Add' & 'Remove' buttons.
}
protected override Type CreateCollectionItemType()
{
return base.CreateCollectionItemType();
}
private Button resetbtn = null;
// Override this method in order to access the containing user controls
// from the default Collection Editor form or to add new ones...
protected override CollectionForm CreateCollectionForm()
{
// Getting the default layout of the Collection Editor...
CollectionForm collectionForm = base.CreateCollectionForm();
Form frmCollectionEditorForm = collectionForm as Form;
// The Add/Remove buttons are made invisible:
if (!AllowAddDel) HideAddRemoveButtons(0, frmCollectionEditorForm);
Button okbtn = FindOkButton(frmCollectionEditorForm);
if (!AllowAddDel)
{
// add a reset button and put next to ok button:
resetbtn = new Button();
resetbtn.Text = "Reset";
resetbtn.Location = new System.Drawing.Point(okbtn.Location.X - 20, okbtn.Location.Y);
resetbtn.Width = 250;
resetbtn.Visible = true;
resetbtn.Enabled = false; // only enabled on data change
resetbtn.Click += resetbtn_Click;
okbtn.Parent.Controls.Add(resetbtn);
}
SetMembersLabel(collectionForm);
TableLayoutPanel tlpLayout = frmCollectionEditorForm.Controls[0] as TableLayoutPanel;
if (tlpLayout != null)
{
// Get a reference to the inner PropertyGrid and hook an event handler to it.
if (tlpLayout.Controls[5] is PropertyGrid)
{
propertyGrid = tlpLayout.Controls[5] as PropertyGrid;
propertyGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(propertyGrid_PropertyValueChanged);
propertyGrid.SelectedGridItemChanged += PG_SelectedGridItemChanged;
}
}
return collectionForm;
}
// when the reset button is clicked the data will be reset to the data from the original format file. Note that if
// data is added to the UCF that is part of a collection, code will need to be added here to reset the value.
void resetbtn_Click(object sender, EventArgs e)
{
resetbtn.Text = "Reset";
resetbtn.Enabled = false;
if (SelectedGridField.Contains("Left Margin"))
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "LeftMargin");
else if (SelectedGridField.Contains("Page Length"))
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "PageLength");
else if (SelectedGridField.Contains("WindowsFont"))
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "WindowsFont");
else if (SelectedGridField.Contains("Inactive CheckOff Header"))
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "Inactive");
else if (SelectedGridField.Contains("Inactive CheckOff"))
ResetValue(propertyGrid.SelectedGridItem.Parent.Parent.Value, "Inactive");
}
private void ShowReflection(Object data)
{
if (data == null) return;
//Object data = new A();
FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance);
String str = "";
foreach (FieldInfo f in fields)
{
str += f.Name + " = " + f.GetValue(data) + "\r\n";
}
Console.WriteLine("reflection = {0}", str);
}
PropertyGrid propertyGrid = null;
private string SelectedGridField = "";
// The following method is used to enable and set text on the 'Reset' button. When a grid item is selected, if it has
// UCF data, then put the original value as part of the button text & enable it:
void PG_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
{
if (resetbtn == null) return;
if (propertyGrid != null) Console.WriteLine(LabelPath(propertyGrid.SelectedGridItem)); // PG.SelectedGridItem.Label + " : " + PG.SelectedGridItem.Value;
// see if data has changed, and if so, enable the Reset button.
bool enabled = false;
resetbtn.Text = "Reset";
SelectedGridField = LabelPath(propertyGrid.SelectedGridItem);
if (SelectedGridField.Contains("WindowsFont"))
{
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Value, "WindowsFont");
if (origForButton != null)
{
resetbtn.Text = "Reset to " + origForButton;
enabled = true;
}
}
else if (SelectedGridField.Contains("Left Margin"))
{
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Value, "LeftMargin");
if (origForButton != null)
{
resetbtn.Text = "Reset to " + origForButton;
enabled = true;
}
}
else if (SelectedGridField.Contains("Page Length"))
{
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Value, "PageLength");
if (origForButton != null)
{
resetbtn.Text = "Reset to " + origForButton;
enabled = true;
}
}
else if (SelectedGridField.Contains("Active CheckOff Header"))
{
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Parent.Value, "Active");
if (origForButton != null)
{
resetbtn.Text = "Reset to " + origForButton;
enabled = true;
}
}
else if (SelectedGridField.Contains("Active CheckOff"))
{
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Parent.Value, "Active");
if (origForButton != null)
{
resetbtn.Text = "Reset to " + origForButton;
enabled = true;
}
}
else enabled = false;
resetbtn.Enabled = enabled;
}
// This code,using data reflection, will determine the if there is UCF (changed) data, and if so
// will return its value as a string for concatenation of Reset button text.
private string OrigValue(object data, string fieldName)
{
FieldInfo fldVal = null;
FieldInfo fldOrig = null;
if (data == null) return null;
FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance);
// Go through the fields in the data structure, looking to match that passed in. Also look for the original
// field to compare the 2 to see if a change was made, i.e. UCF data exists.
foreach (FieldInfo f in fields)
{
if (f.Name == "_" + fieldName) fldVal = f;
if (f.Name == "_Orig" + fieldName) fldOrig = f;
}
if (fldVal != null && fldOrig != null)
{
try
{
// see if values are different:
string orig = fldOrig.GetValue(data).ToString();
string newv = fldVal.GetValue(data).ToString();
string retval = fldOrig.GetValue(data).ToString();
if (retval.StartsWith("[Font:"))
{
retval = retval.Replace("[Font: Name=", "").Replace(", Size=", ",");
}
if (orig != newv) return retval;
else return null;
}
catch (Exception ex)
{
return null;
}
}
return null;
}
// The following Resets the format variable's value from the original format (as stored in the 'OrigXXX' field in FormatConfig
private void ResetValue(object data, string fieldName)
{
FieldInfo fldVal = null;
FieldInfo fldOrig = null;
if (data == null) return;
FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance);
foreach (FieldInfo f in fields)
{
if (f.Name == "_" + fieldName) fldVal = f;
if (f.Name == "_Orig" + fieldName) fldOrig = f;
}
if (fldVal != null && fldOrig != null)
{
fldVal.SetValue(data, fldOrig.GetValue(data));
propertyGrid.Refresh();
}
}
// Remove this on release, and any uses of it.
private string LabelPath(GridItem gi)
{
return (gi.Parent == null ? "" : LabelPath(gi.Parent) + ":" + gi.Label);
}
// set the 'members' label to better reflect what is displayed:
private bool SetMembersLabel(Control myControl)
{
if (myControl is Label && myControl.Text.ToUpper().Contains("MEMBER"))
{
string dt = myControl.TopLevelControl.Text;
if (dt.ToUpper().Contains("DOCSTYL")) myControl.Text = "Section Types";
else if (dt.ToUpper().Contains("REPLACE")) myControl.Text = "Replace Words";
else if (dt.ToUpper().Contains("CHECKOFFHEADER")) myControl.Text = "CheckOff Headers";
else if (dt.ToUpper().Contains("CHECKOFF")) myControl.Text = "CheckOffs";
else if (dt.ToUpper().Contains("STEP")) myControl.Text = "Steps";
return true;
}
if (myControl.Controls != null && myControl.Controls.Count > 0)
{
foreach (Control con in myControl.Controls)
{
bool found = SetMembersLabel(con);
if (found == true) return true;
}
}
return false;
}
// This code looks for the 'OK' button, so that the 'Reset' button can be placed by it.
private Button FindOkButton(Control myControl)
{
if (myControl is Button && myControl.Text == "OK")
{
return myControl as Button;
}
if (myControl.Controls != null && myControl.Controls.Count > 0)
{
foreach (Control con in myControl.Controls)
{
Button found = FindOkButton(con);
if (found != null) return found;
}
}
return null;
}
// Find the 'Add' & 'Remove' buttons based on their text, and then make invisible.
private void HideAddRemoveButtons(int level, Control myControl)
{
if (myControl.Text == "&Add" || myControl.Text == "&Remove")
{
myControl.Visible = false;
return;
}
if (myControl.Controls != null && myControl.Controls.Count > 0)
{
foreach (Control con in myControl.Controls)
HideAddRemoveButtons(level + 1, con);
}
}
void propertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
{
// Fire our customized collection event...
if (PropGridCollEditor.MyPropertyValueChanged != null)
{
PropGridCollEditor.MyPropertyValueChanged(this, e);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System;
namespace Volian.Base.Library
{
// The RtfEditor inherits from the UITypeEditor and is used to edit Rtf fields. This provides the interface for fields in FormatConfig
// and uses the frmRtfEdit to provide a mechanism to do basic editing of text with a subset of rtf command support.
public class RtfEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
IWindowsFormsEditorService svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
string rw = value as string;
if (svc != null && rw != null)
{
using (frmRtfEdit form = new frmRtfEdit())
{
form.Value = rw;
if (svc.ShowDialog(form) == DialogResult.OK)
{
rw = form.Value; // update object
}
}
}
return rw;
}
}
}

View File

@@ -0,0 +1,179 @@
namespace Volian.Base.Library
{
partial class frmRtfEdit
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.rtfBox = new System.Windows.Forms.RichTextBox();
this.btnBold = new DevComponents.DotNetBar.ButtonX();
this.btnItalics = new DevComponents.DotNetBar.ButtonX();
this.btnUnderline = new DevComponents.DotNetBar.ButtonX();
this.btnSubscript = new DevComponents.DotNetBar.ButtonX();
this.btnSuperscript = new DevComponents.DotNetBar.ButtonX();
this.btnHardspace = new DevComponents.DotNetBar.ButtonX();
this.SuspendLayout();
//
// btnOK
//
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(38, 144);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 3;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(143, 144);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 4;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// rtfBox
//
this.rtfBox.Location = new System.Drawing.Point(38, 73);
this.rtfBox.Name = "rtfBox";
this.rtfBox.Size = new System.Drawing.Size(214, 50);
this.rtfBox.TabIndex = 5;
this.rtfBox.Text = "";
this.rtfBox.SelectionChanged += new System.EventHandler(this.rtfBox_SelectionChanged);
//
// btnBold
//
this.btnBold.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.btnBold.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.btnBold.Location = new System.Drawing.Point(12, 12);
this.btnBold.Name = "btnBold";
this.btnBold.Size = new System.Drawing.Size(31, 24);
this.btnBold.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnBold.TabIndex = 6;
this.btnBold.Text = "B";
this.btnBold.Click += new System.EventHandler(this.btnBold_Click);
//
// btnItalics
//
this.btnItalics.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.btnItalics.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.btnItalics.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnItalics.Location = new System.Drawing.Point(43, 12);
this.btnItalics.Name = "btnItalics";
this.btnItalics.Size = new System.Drawing.Size(31, 24);
this.btnItalics.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnItalics.TabIndex = 7;
this.btnItalics.Text = "I";
this.btnItalics.Click += new System.EventHandler(this.btnItalics_Click);
//
// btnUnderline
//
this.btnUnderline.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.btnUnderline.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.btnUnderline.Location = new System.Drawing.Point(74, 12);
this.btnUnderline.Name = "btnUnderline";
this.btnUnderline.Size = new System.Drawing.Size(31, 24);
this.btnUnderline.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnUnderline.TabIndex = 8;
this.btnUnderline.Text = "U";
this.btnUnderline.Click += new System.EventHandler(this.btnUnderline_Click);
//
// btnSubscript
//
this.btnSubscript.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.btnSubscript.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.btnSubscript.Location = new System.Drawing.Point(12, 42);
this.btnSubscript.Name = "btnSubscript";
this.btnSubscript.Size = new System.Drawing.Size(75, 23);
this.btnSubscript.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnSubscript.TabIndex = 9;
this.btnSubscript.Text = "Subscript";
this.btnSubscript.Click += new System.EventHandler(this.btnSubscript_Click);
//
// btnSuperscript
//
this.btnSuperscript.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.btnSuperscript.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.btnSuperscript.Location = new System.Drawing.Point(90, 42);
this.btnSuperscript.Name = "btnSuperscript";
this.btnSuperscript.Size = new System.Drawing.Size(75, 23);
this.btnSuperscript.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnSuperscript.TabIndex = 10;
this.btnSuperscript.Text = "Superscript";
this.btnSuperscript.Click += new System.EventHandler(this.btnSuperscript_Click);
//
// btnHardspace
//
this.btnHardspace.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
this.btnHardspace.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
this.btnHardspace.Location = new System.Drawing.Point(150, 10);
this.btnHardspace.Name = "btnHardspace";
this.btnHardspace.Size = new System.Drawing.Size(37, 26);
this.btnHardspace.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
this.btnHardspace.TabIndex = 11;
this.btnHardspace.Text = "HS";
this.btnHardspace.Click += new System.EventHandler(this.btnHardspace_Click);
//
// frmRtfEdit
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(282, 198);
this.Controls.Add(this.btnHardspace);
this.Controls.Add(this.btnSuperscript);
this.Controls.Add(this.btnSubscript);
this.Controls.Add(this.btnUnderline);
this.Controls.Add(this.btnItalics);
this.Controls.Add(this.btnBold);
this.Controls.Add(this.rtfBox);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.Name = "frmRtfEdit";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Rich Text Edit";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.RichTextBox rtfBox;
private DevComponents.DotNetBar.ButtonX btnBold;
private DevComponents.DotNetBar.ButtonX btnItalics;
private DevComponents.DotNetBar.ButtonX btnUnderline;
private DevComponents.DotNetBar.ButtonX btnSubscript;
private DevComponents.DotNetBar.ButtonX btnSuperscript;
private DevComponents.DotNetBar.ButtonX btnHardspace;
}
}

View File

@@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using DevComponents.DotNetBar;
namespace Volian.Base.Library
{
// this is the form used in the UCF (User Control of Format) feature that displays text and allows the user to modify it to
// add/remove various text attributes: Underline, bold, italics, super/sub script & Hard space.
public partial class frmRtfEdit : Form
{
public frmRtfEdit()
{
InitializeComponent();
}
private static Regex regHyphen = new Regex(@"(?<!\\)(\\u8208\?|\\u8210\?|\\u8211\?|\\u8212\?|\\u8213\?|\\_|\\endash|\\emdash)");
// Value is used by the UITypeEditor, RtfEditor, to set/return the text that is being edited.
public string Value
{
get
{
string rtbString = regHyphen.Replace(RtfToDbText(rtfBox.Rtf).Replace("<BackSlash>", "\\\\"), @"\u8209?");
int indx = rtbString.IndexOf('-');
while (indx > -1)
{
if (indx > 2)
{
if (rtbString[indx - 1] != 'i' || rtbString[indx - 2] != 'f' || rtbString[indx - 3] != '\\')
{
rtbString = rtbString.Remove(indx, 1);
rtbString = rtbString.Insert(indx, @"\u8209?");
}
if (indx + 1 > rtbString.Length) indx = -1;
else indx = rtbString.IndexOf('-', indx + 1);
}
}
return rtbString;
}
set
{
string makeRtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}\viewkind4\uc1\pard\f0\fs16 " + value + @"\par}";
makeRtf = makeRtf.Replace(@"\xa0", "'");
rtfBox.Rtf = makeRtf;
}
}
// when saving text, keep all of the necessary rtf commands that are used to define the text attributes. The rest are removed
public static string StaticReplaceRTFClause(Match m)
{
try
{
string token = m.Groups[1].Value;
switch (token[1])
{
case '\\':
return token;
case 'u':
if (Regex.IsMatch(token, @"^\\u[0-9]+$"))
return token; // Special Charcaters
if (Regex.IsMatch(token, @"^\\ulnone ?$"))
return token;
if (Regex.IsMatch(token, @"^\\ul.*$"))
return token; // Underline
if (Regex.IsMatch(token, @"^\\up[0-9] ?$"))
return token; // shift up (superscript)
break;
case 'd':
if (Regex.IsMatch(token, @"^\\dn[0-9] ?$"))
return token; // shift down (subscript)
break;
case '\'': // Special Character
return token;
case 'b': // Bold
return token;
case 'i': // Italics
return token;
case '{': // look for escape for curly braces:
return token;
case '}':
return token;
case 'l':
if (Regex.IsMatch(token, @"^\\line ?$")) return token;
if (Regex.IsMatch(token, @"^\\li[-0-9]+ ?$")) return token; // line indent
break;
case 'f':
if (Regex.IsMatch(token, @"^\\fi[-0-9]+ ?$")) return token; // first line indent
break;
case 'p':
if (Regex.IsMatch(token, @"^\\par ?$")) return @"{\par}";
break;
}
}
catch (Exception ex)
{
Console.WriteLine("StaticReplaceRTFClause {0} - {1}", ex.GetType().Name, ex.Message);
}
return "";//Strip All
}
// remove all of the rtf commands that are not needed to define the attributes of text that are supported:
private static Regex reg1 = new Regex(@"\\par\r\n(?!\\)");
private static Regex reg2 = new Regex(@"[\r\n]", RegexOptions.Singleline); // Strip Carriage Returns and Newlines
private static Regex reg3 = new Regex(@"^\{(.*)\}$", RegexOptions.Singleline); // Strip Opening and Closing Braces
private static Regex reg4 = new Regex(@"\{[^{]*?\}", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
private static Regex reg5 = new Regex(@"\{[^{]*?\}", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
private static Regex reg6 = new Regex(@"(\\[^' \\?\r\n\t]+)(?=\\)"); // add space after token if followed by token
private static Regex reg7 = new Regex(@"(\\[^' \\?\r\n\t]+ )"); // take backslash xyz and evaluates them
private static Regex reg8 = new Regex(@"(\\[^' \\?\r\n\t]+) (?=\\)"); // remove space between tokens
private static Regex reg9 = new Regex(@"(\\[^' \\?\r\n\t]+) (?=\r\n)"); // remove space before /r/n
private static Regex reg10 = new Regex(@"(\\[0-9a-z]+)$"); // end of text attribute needs a 'space'
private string RtfToDbText(string rtf)
{
// replace \{ & \} with (![ & (!] respectively and then redo at end. The curly braces
// are rtf so were getting removed and/or not handled correctly.
string retval = rtf.Replace(@"\{", @" (![");
retval = retval.Replace(@"\}", @" (!]");
// remove carriage return/newlines after \par commands (these are introduced by rtb
// for hard returns, goes into rtb as \par and comes out as \par\r\n):
retval = reg1.Replace(retval, "\\par ");
retval = retval.Replace("\\v0\r\n", "\\v0 "); // Replace Carriage Return and Newline after comment
retval = reg2.Replace(retval, ""); // Strip Carriage Returns and Newlines
retval = reg3.Replace(retval, "$1"); // Strip Opening and Closing Braces
retval = reg4.Replace(retval, ""); // Strip Clauses - remove anything from curly braces
retval = reg5.Replace(retval, ""); // Strip Clauses - remove anything from curly braces
retval = reg6.Replace(retval, "$1 "); // add space after token if followed by token
retval = reg7.Replace(retval, new MatchEvaluator(StaticReplaceRTFClause)); // take backslash xyz and evaluates them
retval = reg8.Replace(retval, "$1"); // remove space between tokens
retval = reg9.Replace(retval, "$1"); // remove space before /r/n
if (retval.EndsWith(@"{\par}")) retval = retval.Remove(retval.Length - 6, 6);
retval = reg10.Replace(retval, "$1 ");
// remove \r\n at end of string if the string has 2 or more characters
if (retval.EndsWith("\r\n")) retval = retval.Remove(retval.Length - 2, 2);
if (retval.Length == 0) return "";
if (retval.EndsWith(@"\v")) retval = retval.Remove(retval.Length - 2, 2);
retval = retval.Replace(@" (![", @"\{");
retval = retval.Replace(@" (!]", @"\}");
retval = retval.Replace("`",@"\xA0");
return retval;
}
private void btnBold_Click(object sender, EventArgs e)
{
RTBAPI.ToggleBold(!RTBAPI.IsBold(rtfBox), rtfBox, rtfBox.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION);
btnBold.Checked = RTBAPI.IsBold(rtfBox);
}
private void btnItalics_Click(object sender, EventArgs e)
{
RTBAPI.ToggleItalic(!RTBAPI.IsItalic(rtfBox), rtfBox, rtfBox.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION);
btnItalics.Checked = RTBAPI.IsItalic(rtfBox);
}
private void btnUnderline_Click(object sender, EventArgs e)
{
RTBAPI.ToggleUnderline(!RTBAPI.IsUnderline(rtfBox), rtfBox, rtfBox.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION);
btnUnderline.Checked = RTBAPI.IsUnderline(rtfBox);
}
private void btnSubscript_Click(object sender, EventArgs e)
{
RTBAPI.ToggleSubscript(!RTBAPI.IsSubScript(rtfBox), rtfBox, rtfBox.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION);
btnSubscript.Checked = RTBAPI.IsSubScript(rtfBox);
}
private void btnSuperscript_Click(object sender, EventArgs e)
{
RTBAPI.ToggleSuperscript(!RTBAPI.IsSuperScript(rtfBox), rtfBox, rtfBox.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION);
btnSuperscript.Checked = RTBAPI.IsSuperScript(rtfBox);
}
private void btnOK_Click(object sender, EventArgs e)
{
}
private void btnCancel_Click(object sender, EventArgs e)
{
}
private void rtfBox_SelectionChanged(object sender, EventArgs e)
{
btnBold.Checked = RTBAPI.IsBold(rtfBox);
btnItalics.Checked = RTBAPI.IsItalic(rtfBox);
btnUnderline.Checked = RTBAPI.IsUnderline(rtfBox);
}
private void btnHardspace_Click(object sender, EventArgs e)
{
AddText("`");
}
private void AddText(string str)
{
// See comments in AddRtf(string str) to explain the font style setting
RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(rtfBox);
int positionStart = rtfBox.SelectionStart;
rtfBox.SelectedText = str;
int positionAfter = rtfBox.SelectionStart;
rtfBox.Select(positionStart, positionAfter - positionStart);
RTBAPI.SetFontStyle(rtfBox, fs);
rtfBox.Select(positionAfter, 0);
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>