using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.Text;
using FastReport.Utils;
using FastReport.Data;
using FastReport.Forms;
using FastReport.Controls;
#if !MONO
using FastReport.DevComponents.DotNetBar;
#endif
namespace FastReport.Design.ToolWindows
{
///
/// Represents the "Data Dictionary" window.
///
public class DictionaryWindow : FilterableToolWindow
{
#region Fields
#if !MONO
private ButtonItem btnActions;
private ButtonItem btnEdit;
private ButtonItem btnDelete;
private ButtonItem btnView;
private ButtonItem miNew;
private ButtonItem miOpen;
private ButtonItem miMerge;
private ButtonItem miSave;
private ButtonItem miChooseData;
private ButtonItem miNewDataSource;
private ButtonItem miSortDataSources;
private ButtonItem miNewRelation;
private ButtonItem miNewParameter;
private ButtonItem miNewTotal;
private ButtonItem miNewCalculatedColumn;
private ContextMenuBar mnuContext;
private ButtonItem mnuContextRoot;
private ButtonItem miRename;
private ButtonItem miEdit;
private ButtonItem miDelete;
private ButtonItem miDeleteAlias;
private ButtonItem miView;
private ButtonItem miViewJson;
private ButtonItem miSortDataFields;
private ButtonItem miCopyDataSource;
#else
private ToolStripDropDownButton btnActions;
private ToolStripButton btnEdit;
private ToolStripButton btnDelete;
private ToolStripButton btnView;
private ToolStripMenuItem miNew;
private ToolStripMenuItem miOpen;
private ToolStripMenuItem miMerge;
private ToolStripMenuItem miSave;
private ToolStripMenuItem miChooseData;
private ToolStripMenuItem miNewDataSource;
private ToolStripMenuItem miSortDataSources;
private ToolStripMenuItem miNewRelation;
private ToolStripMenuItem miNewParameter;
private ToolStripMenuItem miNewTotal;
private ToolStripMenuItem miNewCalculatedColumn;
private ToolStripMenuItem miCopyDataSource;
private ContextMenuStrip mnuContext;
private ToolStripMenuItem miNewDataSource1;
private ToolStripMenuItem miNewParameter1;
private ToolStripMenuItem miNewTotal1;
private ToolStripMenuItem miNewCalculatedColumn1;
private ToolStripMenuItem miRename;
private ToolStripMenuItem miEdit;
private ToolStripMenuItem miDelete;
private ToolStripMenuItem miDeleteAlias;
private ToolStripMenuItem miView;
private ToolStripMenuItem miViewJson;
private ToolStripMenuItem miSortDataFields;
#endif
private Splitter splitter;
private DescriptionControl lblDescription;
private Report report;
private List expandedNodes;
private static DraggedItemCollection draggedItems = new DraggedItemCollection();
#endregion
#region Properties
private bool IsDataComponent
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is DataComponentBase; }
}
private bool IsVariable
{
get
{
return tree.SelectedNode != null && tree.SelectedNode.Tag is Parameter &&
!(tree.SelectedNode.Parent.Tag is SystemVariables);
}
}
private bool IsTotal
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is Total; }
}
private bool IsConnection
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is DataConnectionBase; }
}
private bool IsTable
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is DataSourceBase; }
}
private bool IsJsonTable
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is FastReport.Data.JsonConnection.JsonTableDataSource; }
}
private bool IsRelation
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is Relation; }
}
private bool IsEditableColumn
{
get
{
TreeNode node = tree.SelectedNode;
bool result = node != null && node.Tag is Column;
if (result)
{
// check if column belongs to the datasource, not relation.
while (node != null)
{
if (node.Tag is Relation)
{
result = false;
break;
}
else if (node.Tag is DataSourceBase)
break;
node = node.Parent;
}
}
return result;
}
}
private bool IsCube
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag is CubeSourceBase; }
}
private bool IsDataSources
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag == report.Dictionary.DataSources; }
}
private bool IsVariables
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag == report.Dictionary.Parameters; }
}
private bool IsSystemVariables
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag == report.Dictionary.SystemVariables; }
}
private bool IsTotals
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag == report.Dictionary.Totals; }
}
private bool IsCubeSources
{
get { return tree.SelectedNode != null && tree.SelectedNode.Tag == report.Dictionary.CubeSources; }
}
private bool CanEdit
{
get
{
return (IsDataComponent || IsVariable || IsTotal) &&
!Designer.Restrictions.DontEditData &&
(tree.SelectedNode.Tag as Base).HasFlag(Flags.CanEdit) &&
!(tree.SelectedNode.Tag as Base).HasRestriction(Restrictions.DontEdit);
}
}
private bool CanDelete
{
get
{
return (IsDataComponent || IsVariable || IsTotal) &&
!Designer.Restrictions.DontEditData &&
(tree.SelectedNode.Tag as Base).HasFlag(Flags.CanDelete) &&
!(tree.SelectedNode.Tag as Base).HasRestriction(Restrictions.DontDelete);
}
}
private bool CanCreateCalculatedColumn
{
get
{
return tree.SelectedNode != null && tree.SelectedNode.Tag is DataSourceBase;
}
}
private bool IsAliased
{
get
{
return tree.SelectedNode != null && tree.SelectedNode.Tag is DataComponentBase &&
(tree.SelectedNode.Tag as DataComponentBase).IsAliased;
}
}
#endregion
#region Private Methods
private TreeNode FindNode(TreeNodeCollection parent, string text)
{
foreach (TreeNode node in parent)
{
if (node.Text == text)
return node;
}
return null;
}
private void NavigateTo(string path)
{
string[] parts = path.Split('.');
TreeNodeCollection parent = tree.Nodes;
TreeNode node = null;
foreach (string part in parts)
{
node = FindNode(parent, part);
if (node == null)
break;
parent = node.Nodes;
}
tree.SelectedNode = node;
}
private void GetExpandedNodes(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
if (node.IsExpanded)
expandedNodes.Add(node.FullPath);
GetExpandedNodes(node.Nodes);
}
}
private bool CompareNodes(TreeNodeCollection fromNodes, TreeNodeCollection toNodes)
{
if (fromNodes.Count != toNodes.Count)
return false;
for (int i = 0; i < fromNodes.Count; i++)
{
if (fromNodes[i].Text != toNodes[i].Text || fromNodes[i].ImageIndex != toNodes[i].ImageIndex)
return false;
toNodes[i].Tag = fromNodes[i].Tag;
if (!CompareNodes(fromNodes[i].Nodes, toNodes[i].Nodes))
return false;
}
return true;
}
private void CopyNodes(TreeNodeCollection fromNodes, TreeNodeCollection toNodes)
{
foreach (TreeNode fromNode in fromNodes)
{
TreeNode toNode = toNodes.Add(fromNode.Text);
toNode.Tag = fromNode.Tag;
toNode.ImageIndex = fromNode.ImageIndex;
toNode.SelectedImageIndex = fromNode.SelectedImageIndex;
CopyNodes(fromNode.Nodes, toNode.Nodes);
if (expandedNodes.Contains(fromNode.FullPath))
toNode.Expand();
}
}
protected override void UpdateTree()
{
expandedNodes.Clear();
GetExpandedNodes(tree.Nodes);
TreeView buffer = new TreeView();
if (report != null)
{
bool canShowData = report.Dictionary.Connections.Count > 0;
foreach (DataSourceBase data in report.Dictionary.DataSources)
{
if (data.Enabled)
{
canShowData = true;
break;
}
}
bool canShowCube = report.Dictionary.CubeSources.Count > 0;
TreeNode rootNode = null;
if (canShowData)
{
rootNode = buffer.Nodes.Add(Res.Get("Designer,ToolWindow,Dictionary,DataSources"));
rootNode.Tag = report.Dictionary.DataSources;
rootNode.ImageIndex = 53;
rootNode.SelectedImageIndex = rootNode.ImageIndex;
DataTreeHelper.CreateDataTree(report.Dictionary, rootNode.Nodes, true, true, true, true);
}
// system variables
rootNode = buffer.Nodes.Add(Res.Get("Designer,ToolWindow,Dictionary,SystemVariables"));
rootNode.Tag = report.Dictionary.SystemVariables;
rootNode.ImageIndex = 60;
rootNode.SelectedImageIndex = rootNode.ImageIndex;
DataTreeHelper.CreateVariablesTree(report.Dictionary.SystemVariables, rootNode.Nodes);
// totals
rootNode = buffer.Nodes.Add(Res.Get("Designer,ToolWindow,Dictionary,Totals"));
rootNode.Tag = report.Dictionary.Totals;
rootNode.ImageIndex = 132;
rootNode.SelectedImageIndex = rootNode.ImageIndex;
DataTreeHelper.CreateTotalsTree(report.Dictionary.Totals, rootNode.Nodes);
// parameters
rootNode = buffer.Nodes.Add(Res.Get("Designer,ToolWindow,Dictionary,Parameters"));
rootNode.Tag = report.Dictionary.Parameters;
rootNode.ImageIndex = 234;
rootNode.SelectedImageIndex = rootNode.ImageIndex;
DataTreeHelper.CreateParametersTree(report.Dictionary.Parameters, rootNode.Nodes);
// functions
rootNode = buffer.Nodes.Add(Res.Get("Designer,ToolWindow,Dictionary,Functions"));
rootNode.ImageIndex = 52;
rootNode.SelectedImageIndex = rootNode.ImageIndex;
DataTreeHelper.CreateFunctionsTree(report, rootNode.Nodes);
if (canShowCube)
{
rootNode = buffer.Nodes.Add(Res.Get("Designer,ToolWindow,Dictionary,CubeSources"));
rootNode.Tag = report.Dictionary.CubeSources;
rootNode.ImageIndex = 248;
rootNode.SelectedImageIndex = rootNode.ImageIndex;
DataTreeHelper.CreateCubeTree(report.Dictionary, rootNode.Nodes, false);
}
}
if (!CompareNodes(buffer.Nodes, tree.Nodes))
{
tree.BeginUpdate();
tree.Nodes.Clear();
CopyNodes(buffer.Nodes, tree.Nodes);
tree.EndUpdate();
}
buffer.Dispose();
UpdateControls();
}
private void Change()
{
Designer.SetModified(this, "EditData");
}
private void UpdateControls()
{
btnEdit.Enabled = CanEdit;
btnDelete.Enabled = CanDelete;
btnView.Enabled = IsTable && !IsJsonTable;
}
private void miNew_Click(object sender, EventArgs e)
{
report.Dictionary.Clear();
report.Dictionary.ReRegisterData();
UpdateTree();
Change();
}
private void miOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = Res.Get("FileFilters,Dictionary");
if (dialog.ShowDialog() == DialogResult.OK)
{
report.Dictionary.Load(dialog.FileName);
UpdateTree();
Change();
}
}
}
private void miSave_Click(object sender, EventArgs e)
{
using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Filter = Res.Get("FileFilters,Dictionary");
dialog.DefaultExt = "frd";
dialog.FileName = "Dictionary.frd";
if (dialog.ShowDialog() == DialogResult.OK)
report.Dictionary.Save(dialog.FileName);
}
}
private void miMerge_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = Res.Get("FileFilters,Dictionary");
if (dialog.ShowDialog() == DialogResult.OK)
{
Dictionary dict = new Dictionary();
dict.Load(dialog.FileName);
report.Dictionary.Merge(dict);
UpdateTree();
Change();
}
}
}
#if !MONO
private void btnActions_PopupOpen(object sender, PopupOpenEventArgs e)
{
while (btnActions.SubItems[btnActions.SubItems.Count - 1] != miChooseData)
{
btnActions.SubItems.RemoveAt(btnActions.SubItems.Count - 1);
}
btnActions.SubItems.AddRange(new ButtonItem[] {
#else
private void btnActions_DropDownOpening(object sender, EventArgs e)
{
while (!(btnActions.DropDownItems[btnActions.DropDownItems.Count - 1] is ToolStripSeparator))
{
btnActions.DropDownItems.RemoveAt(btnActions.DropDownItems.Count - 1);
}
btnActions.DropDownItems.AddRange(new ToolStripItem[] {
#endif
miNewDataSource, miNewRelation, miNewCalculatedColumn, miNewParameter, miNewTotal });
miNew.Enabled = Designer.cmdChooseData.Enabled;
miOpen.Enabled = Designer.cmdChooseData.Enabled;
miMerge.Enabled = Designer.cmdChooseData.Enabled;
miSave.Enabled = Designer.cmdChooseData.Enabled;
miChooseData.Enabled = Designer.cmdChooseData.Enabled;
miNewDataSource.Enabled = Designer.cmdAddData.Enabled;
miSortDataSources.Enabled = Designer.cmdSortDataSources.Enabled;
miNewRelation.Enabled = Designer.cmdChooseData.Enabled;
miNewParameter.Enabled = Designer.cmdChooseData.Enabled;
miNewTotal.Enabled = Designer.cmdChooseData.Enabled;
miNewCalculatedColumn.Enabled = Designer.cmdChooseData.Enabled && CanCreateCalculatedColumn;
}
#if !MONO
private void mnuContextRoot_PopupOpen(object sender, PopupOpenEventArgs e)
{
mnuContextRoot.SubItems.Clear();
if (!Designer.cmdChooseData.Enabled)
{
e.Cancel = true;
return;
}
if ((IsDataSources || IsConnection) && Designer.cmdAddData.Enabled)
{
mnuContextRoot.SubItems.Add(miNewDataSource);
// If data sources more than 1 and enabled at least 2 data sources, then it's possible to sort them.
if (report.Dictionary.DataSources.Count > 1)
{
int enabledDataSources = 0;
for (int i = 0; enabledDataSources < 2 && i < report.Dictionary.DataSources.Count; i++)
{
if (report.Dictionary.DataSources[i].Enabled)
{
enabledDataSources++;
}
}
if (enabledDataSources > 1)
{
mnuContextRoot.SubItems.Add(miSortDataSources);
}
}
}
else if (IsVariables || IsVariable)
mnuContextRoot.SubItems.Add(miNewParameter);
else if (IsTotals || IsTotal)
mnuContextRoot.SubItems.Add(miNewTotal);
else if (CanCreateCalculatedColumn)
{
mnuContextRoot.SubItems.Add(miNewCalculatedColumn);
miNewCalculatedColumn.Enabled = true;
}
if (CanEdit)
mnuContextRoot.SubItems.Add(miEdit);
if (IsConnection)
mnuContextRoot.SubItems.Add(miCopyDataSource);
if (IsTable || IsEditableColumn || IsVariable || IsTotal)
mnuContextRoot.SubItems.Add(miRename);
if (CanDelete)
mnuContextRoot.SubItems.Add(miDelete);
if (IsAliased)
mnuContextRoot.SubItems.Add(miDeleteAlias);
if (IsJsonTable)
{
mnuContextRoot.SubItems.Add(miViewJson);
DataSourceBase data = tree.SelectedNode.Tag as DataSourceBase;
if (data != null && data.Columns.Count > 1)
{
mnuContextRoot.SubItems.Add(miSortDataFields);
}
}
else if (IsTable)
{
mnuContextRoot.SubItems.Add(miView);
DataSourceBase data = tree.SelectedNode.Tag as DataSourceBase;
if (data != null && data.Columns.Count > 1)
{
mnuContextRoot.SubItems.Add(miSortDataFields);
}
}
if (mnuContextRoot.SubItems.Count == 0)
e.Cancel = true;
}
#else
private void mnuContext_Opening(object sender, CancelEventArgs e)
{
mnuContext.Items.Clear();
if (!Designer.cmdChooseData.Enabled)
{
e.Cancel = true;
return;
}
if ((IsDataSources || IsConnection) && Designer.cmdAddData.Enabled)
mnuContext.Items.Add(miNewDataSource1);
else if (IsVariables || IsVariable)
mnuContext.Items.Add(miNewParameter1);
else if (IsTotals || IsTotal)
mnuContext.Items.Add(miNewTotal1);
else if (CanCreateCalculatedColumn)
mnuContext.Items.Add(miNewCalculatedColumn1);
if (CanEdit)
mnuContext.Items.Add(miEdit);
if (IsConnection)
mnuContext.Items.Add(miCopyDataSource);
if (IsTable || IsEditableColumn || IsVariable || IsTotal)
mnuContext.Items.Add(miRename);
if (CanDelete)
mnuContext.Items.Add(miDelete);
if (IsAliased)
mnuContext.Items.Add(miDeleteAlias);
if (IsJsonTable)
{
mnuContext.Items.Add(miViewJson);
}
else if (IsTable)
{
mnuContext.Items.Add(miView);
}
if (mnuContext.Items.Count == 0)
e.Cancel = true;
}
#endif
private void miNewRelation_Click(object sender, EventArgs e)
{
Relation relation = new Relation();
report.Dictionary.Relations.Add(relation);
using (RelationEditorForm form = new RelationEditorForm(relation))
{
if (form.ShowDialog() == DialogResult.OK)
{
relation.Name = report.Dictionary.CreateUniqueName(relation.ParentDataSource.Name + "_" +
relation.ChildDataSource.Name);
UpdateTree();
Change();
}
else
relation.Dispose();
}
}
private void miNewCalculatedColumn_Click(object sender, EventArgs e)
{
DataSourceBase data = tree.SelectedNode.Tag as DataSourceBase;
Column c = new Column();
c.Name = data.Columns.CreateUniqueName("Column");
c.Alias = data.Columns.CreateUniqueAlias(c.Alias);
c.Calculated = true;
data.Columns.Add(c);
UpdateTree();
string navigatePath = Res.Get("Designer,ToolWindow,Dictionary,DataSources");
if (data.Parent is DataConnectionBase)
navigatePath += "." + data.Parent.Name + "." + data.Alias;
else
navigatePath += GetPath(data);
navigatePath += "." + c.Alias;
NavigateTo(navigatePath);
Change();
}
private string GetPath(Base data)
{
if (data == null || data.Name == "")
return "";
if (data.Parent is DataConnectionBase && data.Parent.Parent == null)
return data.Parent.Alias;
else
return GetPath(data.Parent) + "." + data.Name;
}
private void miNewParameter_Click(object sender, EventArgs e)
{
Parameter p = new Parameter();
ParameterCollection parent = null;
if (IsVariable)
parent = (tree.SelectedNode.Tag as Parameter).Parameters;
else
parent = report.Dictionary.Parameters;
p.Name = parent.CreateUniqueName("Parameter");
parent.Add(p);
UpdateTree();
NavigateTo(Res.Get("Designer,ToolWindow,Dictionary,Parameters") + "." + p.FullName);
Change();
}
private void miNewTotal_Click(object sender, EventArgs e)
{
using (TotalEditorForm form = new TotalEditorForm(Designer))
{
if (form.ShowDialog() == DialogResult.OK)
{
report.Dictionary.Totals.Add(form.Total);
UpdateTree();
NavigateTo(Res.Get("Designer,ToolWindow,Dictionary,Totals") + "." + form.Total.Name);
Change();
}
}
}
private void miRename_Click(object sender, EventArgs e)
{
if (tree.SelectedNode == null)
return;
tree.SelectedNode.BeginEdit();
}
private void miEdit_Click(object sender, EventArgs e)
{
if (!CanEdit)
return;
IHasEditor c = tree.SelectedNode.Tag as IHasEditor;
if (c != null && c.InvokeEditor())
{
UpdateTree();
Change();
}
}
private void miDelete_Click(object sender, EventArgs e)
{
if (!CanDelete)
return;
(tree.SelectedNode.Tag as Base).Delete();
TreeNode parentNode = tree.SelectedNode.Parent;
int index = parentNode.Nodes.IndexOf(tree.SelectedNode);
tree.SelectedNode.Remove();
if (index < parentNode.Nodes.Count)
tree.SelectedNode = parentNode.Nodes[index];
else if (index > 0)
tree.SelectedNode = parentNode.Nodes[index - 1];
Change();
}
private void miDeleteAlias_Click(object sender, EventArgs e)
{
if (!IsAliased)
return;
DataComponentBase c = tree.SelectedNode.Tag as DataComponentBase;
c.Alias = c.Name;
tree.SelectedNode.Text = c.Name;
Change();
}
private void miView_Click(object sender, EventArgs e)
{
if (!IsTable)
return;
DataSourceBase data = tree.SelectedNode.Tag as DataSourceBase;
if (data == null)
return;
try
{
data.Init();
}
catch (Exception ex)
{
FRMessageBox.Error(ex.Message);
return;
}
object dataSource = null;
if (data is TableDataSource)
{
dataSource = (data as TableDataSource).Table;
}
else
dataSource = data.Rows;
if (dataSource == null)
return;
using (DataViewForm form = new DataViewForm(data))
{
form.ShowDialog();
}
}
private void miViewJson_Click(object sender, EventArgs e)
{
if (!IsJsonTable)
return;
Data.JsonConnection.JsonTableDataSource data = tree.SelectedNode.Tag as Data.JsonConnection.JsonTableDataSource;
if (data == null)
return;
try
{
data.Init();
}
catch (Exception ex)
{
FRMessageBox.Error(ex.Message);
return;
}
using (JsonEditorForm jsonEditorForm = new JsonEditorForm())
{
StringBuilder sb = new StringBuilder();
data.Json.WriteTo(sb, 2);
jsonEditorForm.JsonText = sb.ToString();
jsonEditorForm.SetToReadOnly();
jsonEditorForm.ShowDialog();
}
}
private void miCopyDataSource_Click(object sender, EventArgs e)
{
if(tree.SelectedNode.Tag is DataConnectionBase)
{
DataConnectionBase data = tree.SelectedNode.Tag as DataConnectionBase;
data.Clone();
}
Change();
UpdateTree();
Refresh();
//Designer.SetModified();
}
private void miSortDataFields_Click(object sender, EventArgs e)
{
if (!IsTable)
return;
TableDataSource data = tree.SelectedNode.Tag as TableDataSource;
if (data == null)
return;
if (data.Columns.Count > 1)
{
data.Columns.Sort();
UpdateTree();
Change();
}
}
private void FTree_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.F2)
miRename_Click(this, null);
else if (e.KeyCode == Keys.Delete)
miDelete_Click(this, null);
else if (e.Control)
{
TreeNode node = tree.SelectedNode;
if (node != null && (node.Tag is Parameter) && !(node.Tag is SystemVariable))
{
Parameter par = node.Tag as Parameter;
TreeNode parentNode = node.Parent;
ParameterCollection parCollection = null;
if (parentNode.Tag is ParameterCollection)
parCollection = parentNode.Tag as ParameterCollection;
else
parCollection = (parentNode.Tag as Parameter).Parameters;
if (e.KeyCode == Keys.Up)
{
parCollection.MoveUp(par);
e.Handled = true;
}
else if (e.KeyCode == Keys.Down)
{
parCollection.MoveDown(par);
e.Handled = true;
}
if (e.Handled)
{
// update all designer plugins (this one too)
Designer.SetModified(null, "EditData");
NavigateTo(Res.Get("Designer,ToolWindow,Dictionary,Parameters") + "." + par.FullName);
}
}
}
}
private void FTree_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
TreeNode node = tree.GetNodeAt(e.Location);
if (tree.SelectedNode != node)
tree.SelectedNode = node;
}
}
private void FTree_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
{
bool canEdit = (IsTable || IsEditableColumn || IsVariable || IsTotal) &&
!Designer.Restrictions.DontEditData &&
!(tree.SelectedNode.Tag as Base).HasRestriction(Restrictions.DontModify);
if (!canEdit)
e.CancelEdit = true;
}
private void FTree_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
string newLabel = e.Label == null ? tree.SelectedNode.Text : e.Label;
if (newLabel == tree.SelectedNode.Text)
return;
Base obj = tree.SelectedNode.Tag as Base;
bool duplicateName = false;
if (obj is DataSourceBase)
{
if (report.Dictionary.FindByAlias(newLabel) != null)
duplicateName = true;
else
{
(obj as DataSourceBase).Alias = newLabel;
}
}
else if (obj is Column)
{
// get column name, take parent columns into account
string columnName = newLabel;
TreeNode node = tree.SelectedNode;
while (true)
{
node = node.Parent;
if (node.Tag is DataSourceBase)
break;
columnName = node.Text + "." + columnName;
}
DataSourceBase data = obj.Parent as DataSourceBase;
if (data.Columns.FindByAlias(columnName) != null)
duplicateName = true;
else
(obj as Column).Alias = columnName;
}
else if (obj is Parameter)
{
TreeNode parentNode = tree.SelectedNode.Parent;
ParameterCollection parent = null;
if (parentNode.Tag is Parameter)
parent = (parentNode.Tag as Parameter).Parameters;
else
parent = report.Dictionary.Parameters;
if (parent.FindByName(newLabel) != null)
duplicateName = true;
else
obj.Name = newLabel;
}
else if (obj is Total)
{
if (report.Dictionary.FindByName(newLabel) != null)
duplicateName = true;
else
obj.Name = newLabel;
}
if (duplicateName)
{
e.CancelEdit = true;
FRMessageBox.Error(Res.Get("Designer,ToolWindow,Dictionary,DuplicateName"));
}
else
Change();
}
private void FTree_AfterSelect(object sender, TreeViewEventArgs e)
{
if (tree.SelectedNode == null)
return;
object selected = tree.SelectedNode.Tag;
Designer.SelectedObjects.Clear();
if (selected is Base)
Designer.SelectedObjects.Add(selected as Base);
Designer.SelectionChanged(this);
UpdateControls();
bool descrVisible = selected is MethodInfo || selected is SystemVariable;
splitter.Visible = descrVisible;
lblDescription.Visible = descrVisible;
if (descrVisible)
lblDescription.ShowDescription(report, selected);
}
private void FTree_ItemDrag(object sender, ItemDragEventArgs e)
{
List selectedNodes;
draggedItems.Clear();
if (tree.SelectedNodes.Contains(e.Item as TreeNode))
{
selectedNodes = tree.SelectedNodes;
}
else
{
tree.SelectedNode = e.Item as TreeNode;
//selectedNodes = new List() { FTree.SelectedNode }; //.net 2 compatibility code
selectedNodes = new List();
selectedNodes.Add(tree.SelectedNode);
}
foreach (TreeNode n in selectedNodes)
{
string selectedItem = "";
TreeNode node = n;
if (node == null)
continue;
if (node.Tag is Column && !(node.Tag is DataSourceBase))
{
while (true)
{
if (node.Tag is DataSourceBase)
{
selectedItem = (node.Tag as DataSourceBase).FullName + "." + selectedItem;
break;
}
selectedItem = node.Text + (selectedItem == "" ? "" : ".") + selectedItem;
node = node.Parent;
}
}
else if (node.Tag is Parameter || node.Tag is Total)
{
while (node != null && node.Tag != null)
{
if (node.Tag is Parameter || node.Tag is Total)
selectedItem = node.Text + (selectedItem == "" ? "" : ".") + selectedItem;
node = node.Parent;
}
}
else if (node.Tag is MethodInfo)
{
MethodInfo info = node.Tag as MethodInfo;
ParameterInfo[] pars = info.GetParameters();
int parsLength = pars.Length;
if (parsLength > 0 && pars[0].Name == "thisReport")
parsLength--;
selectedItem = info.Name + "(" + (parsLength > 1 ? "".PadRight(parsLength - 1, ',') : "") + ")";
}
if (selectedItem != "")
draggedItems.Add(new DraggedItem(n.Tag, selectedItem));
}
if (draggedItems.Count > 0)
tree.DoDragDrop(draggedItems, DragDropEffects.Move);
else
tree.DoDragDrop(e.Item, DragDropEffects.None);
}
private void FTree_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.None;
TreeNode targetNode = tree.GetNodeAt(tree.PointToClient(new Point(e.X, e.Y)));
if (draggedItems.Count == 0 ||
targetNode == null ||
targetNode.Tag is SystemVariable ||
targetNode.Tag is SystemVariables)
return;
int allow = 0;
foreach (DraggedItem draggedItem in draggedItems)
{
if (draggedItem.obj is Parameter &&
!(draggedItem.obj is SystemVariable) &&
!(draggedItem.obj is SystemVariables))
{
if (targetNode.Tag is ParameterCollection ||
(targetNode.Tag is Parameter &&
targetNode.Tag != draggedItem.obj &&
!(targetNode.Tag as Parameter).HasParent(draggedItem.obj as Parameter)))
{
allow++;
}
}
}
if (allow != 0 && allow == draggedItems.Count)
e.Effect = e.AllowedEffect;
}
private void FTree_DragDrop(object sender, DragEventArgs e)
{
TreeNode targetNode = tree.GetNodeAt(tree.PointToClient(new Point(e.X, e.Y)));
if (targetNode == null)
return;
Object targetComponent = targetNode.Tag;
if ((targetComponent is SystemVariable) || (targetComponent is SystemVariables))
return;
if (draggedItems.Count == 0)
return;
string draggedName = "";
foreach (DraggedItem draggedItem in draggedItems)
{
if ((draggedItem.obj is SystemVariable) || (draggedItem.obj is SystemVariables))
continue;
Parameter draggedComponent = draggedItem.obj as Parameter;
if (targetComponent is ParameterCollection)
{
ParameterCollection collection = targetComponent as ParameterCollection;
if (collection.IndexOf(draggedComponent) != -1)
{
collection.Remove(draggedComponent);
collection.Insert(0, draggedComponent);
}
else
{
collection.Add(draggedComponent);
}
}
else if (targetComponent is Parameter)
{
if ((targetComponent as Parameter).Parameters.IndexOf(draggedComponent) != -1)
{
draggedComponent.ZOrder = 0;
}
else
{
draggedComponent.Parent = targetComponent as Parameter;
}
}
draggedName = draggedComponent.FullName;
}
tree.SelectedNode = targetNode;
// update all designer plugins (this one too)
Designer.SetModified(null, "EditData");
NavigateTo(Res.Get("Designer,ToolWindow,Dictionary,Parameters") + "." + draggedName);
}
#endregion
#region Public Methods
///
public override void SelectionChanged()
{
base.SelectionChanged();
if (Designer.SelectedObjects.Count == 0 || Designer.SelectedObjects[0] is ComponentBase)
{
tree.SelectedNode = null;
UpdateControls();
}
}
///
public override void UpdateContent()
{
report = Designer.ActiveReport;
UpdateTree();
}
///
public override void Localize()
{
base.Localize();
MyRes res = new MyRes("Designer,ToolWindow,Dictionary");
Text = res.Get("");
btnActions.Text = Res.Get("Buttons,Actions");
#if !MONO
btnEdit.Tooltip = res.Get("Edit");
btnDelete.Tooltip = res.Get("Delete");
btnView.Tooltip = res.Get("View");
#else
btnEdit.ToolTipText = res.Get("Edit");
btnDelete.ToolTipText = res.Get("Delete");
btnView.ToolTipText = res.Get("View");
#endif
miNew.Text = res.Get("New");
miOpen.Text = res.Get("Open");
miMerge.Text = res.Get("Merge");
miSave.Text = res.Get("Save");
miChooseData.Text = Res.Get("Designer,Menu,Data,Choose");
miNewDataSource.Text = res.Get("NewDataSource");
miSortDataSources.Text = res.Get("SortDataSources");
miNewRelation.Text = res.Get("NewRelation");
miNewParameter.Text = res.Get("NewParameter");
miNewTotal.Text = res.Get("NewTotal");
miNewCalculatedColumn.Text = res.Get("NewCalculatedColumn");
miRename.Text = res.Get("Rename");
miEdit.Text = res.Get("Edit");
miDelete.Text = res.Get("Delete");
miDeleteAlias.Text = res.Get("DeleteAlias");
miView.Text = res.Get("View");
miViewJson.Text = res.Get("ViewJson");
miSortDataFields.Text = res.Get("SortDataFields");
miCopyDataSource.Text = res.Get("CopyDataSource");
#if MONO
miNewDataSource1.Text = miNewDataSource.Text;
miNewParameter1.Text = miNewParameter.Text;
miNewTotal1.Text = miNewTotal.Text;
miNewCalculatedColumn1.Text = miNewCalculatedColumn.Text;
#endif
UpdateTree();
}
///
public override void UpdateUIStyle()
{
base.UpdateUIStyle();
#if !MONO
toolbar.Style = UIStyleUtils.GetDotNetBarStyle(Designer.UIStyle);
mnuContext.Style = toolbar.Style;
splitter.BackColor = UIStyleUtils.GetControlColor(Designer.UIStyle);
#else
toolbar.Renderer = UIStyleUtils.GetToolStripRenderer(Designer.UIStyle);
mnuContext.Renderer = toolbar.Renderer;
splitter.BackColor = UIStyleUtils.GetColorTable(Designer.UIStyle).ControlBackColor;
#endif
}
///
public override void UpdateDpiDependencies()
{
base.UpdateDpiDependencies();
Image = Designer.GetImage(72);
tree.ImageList = Designer.GetImages();
toolbar.Font = Designer.LogicalToDevice(DrawUtils.DefaultFont);
#if !MONO
ImageIndex = 72;
toolbar.UpdateDpiDependencies();
UpdateImages(toolbar.Items);
#endif
}
///
public override void SaveState()
{
XmlItem xi = Config.Root.FindItem("Designer").FindItem(Name);
xi.SetProp("DescriptionHeight", lblDescription.Height.ToString());
}
///
public override void RestoreState()
{
XmlItem xi = Config.Root.FindItem("Designer").FindItem(Name);
string s = xi.GetProp("DescriptionHeight");
if (s != "")
lblDescription.Height = int.Parse(s);
}
#endregion
///
/// Initializes a new instance of the class with default settings.
///
/// The report designer.
public DictionaryWindow(Designer designer)
: base(designer)
{
Name = "DictionaryWindow";
#if !MONO
btnActions = new ButtonItem();
btnActions.AutoExpandOnClick = true;
btnActions.Name = "Actions";
btnEdit = AddButton(68, miEdit_Click);
btnDelete = AddButton(51, miDelete_Click);
btnView = AddButton(54, miView_Click);
toolbar.Items.InsertRange(0, new ButtonItem[] { btnActions, btnEdit, btnDelete, btnView });
miNew = AddButton(0, miNew_Click);
miOpen = AddButton(1, miOpen_Click);
miMerge = AddButton(miMerge_Click);
miSave = AddButton(2, miSave_Click);
miChooseData = AddButton(Designer.cmdChooseData.Invoke);
miChooseData.BeginGroup = true;
miNewDataSource = AddButton(137, Designer.cmdAddData.Invoke);
miNewDataSource.BeginGroup = true;
miCopyDataSource = AddButton(6, miCopyDataSource_Click);
miSortDataSources = AddButton(Designer.cmdSortDataSources.Invoke);
miNewRelation = AddButton(139, miNewRelation_Click);
miNewCalculatedColumn = AddButton(55, miNewCalculatedColumn_Click);
miNewParameter = AddButton(56, miNewParameter_Click);
miNewTotal = AddButton(65, miNewTotal_Click);
btnActions.SubItems.AddRange(new ButtonItem[] { miNew, miOpen, miMerge, miSave, miChooseData, miNewDataSource,
miSortDataSources, miNewRelation, miNewCalculatedColumn, miNewParameter, miNewTotal });
btnActions.PopupOpen += btnActions_PopupOpen;
mnuContext = new ContextMenuBar();
mnuContext.Font = DrawUtils.DefaultFont;
mnuContextRoot = new ButtonItem();
mnuContext.Items.Add(mnuContextRoot);
miRename = AddButton(miRename_Click);
miRename.Shortcuts.Add(eShortcut.F2);
miEdit = AddButton(68, miEdit_Click);
miDelete = AddButton(51, miDelete_Click);
miDeleteAlias = AddButton(miDeleteAlias_Click);
miView = AddButton(54, miView_Click);
miViewJson = AddButton(54, miViewJson_Click);
miSortDataFields = AddButton(miSortDataFields_Click);
mnuContextRoot.SubItems.AddRange(new ButtonItem[] {
miRename, miEdit, miCopyDataSource, miDelete, miDeleteAlias, miView, miViewJson, miSortDataFields });
mnuContextRoot.PopupOpen += mnuContextRoot_PopupOpen;
tree.LabelEdit = true;
tree.HideSelection = false;
tree.AllowDrop = true;
tree.MouseDown += FTree_MouseDown;
tree.BeforeLabelEdit += FTree_BeforeLabelEdit;
tree.AfterLabelEdit += FTree_AfterLabelEdit;
tree.KeyDown += FTree_KeyDown;
tree.AfterSelect += FTree_AfterSelect;
tree.DoubleClick += miEdit_Click;
tree.ItemDrag += FTree_ItemDrag;
tree.DragOver += FTree_DragOver;
tree.DragDrop += FTree_DragDrop;
mnuContext.SetContextMenuEx(tree, mnuContextRoot);
splitter = new Splitter();
splitter.Visible = false;
lblDescription = new DescriptionControl();
lblDescription.Dock = DockStyle.Bottom;
lblDescription.Height = 70;
lblDescription.Visible = false;
ParentControl.Controls.AddRange(new Control[] { lblDescription });
#else
toolbar.Font = DrawUtils.DefaultFont;
toolbar.GripStyle = ToolStripGripStyle.Hidden;
toolbar.Padding = new Padding(2, 0, 0, 0);
btnActions = new ToolStripDropDownButton();
btnEdit = AddButton(68, miEdit_Click);
btnDelete = AddButton(51, miDelete_Click);
btnView = AddButton(54, miView_Click);
// mono fix
btnView.AutoSize = false;
btnView.Size = new Size(23, 22);
toolbar.Items.AddRange(new ToolStripItem[] { btnActions, btnEdit, btnDelete, btnView });
miNew = AddMenuItem(0, miNew_Click);
miOpen = AddMenuItem(1, miOpen_Click);
miMerge = AddMenuItem(miMerge_Click);
miSave = AddMenuItem(2, miSave_Click);
miChooseData = AddMenuItem(Designer.cmdChooseData.Invoke);
miSortDataSources = AddMenuItem(Designer.cmdSortDataSources.Invoke);
miNewDataSource = AddMenuItem(137, Designer.cmdAddData.Invoke);
miNewRelation = AddMenuItem(139, miNewRelation_Click);
miNewCalculatedColumn = AddMenuItem(55, miNewCalculatedColumn_Click);
miNewParameter = AddMenuItem(56, miNewParameter_Click);
miCopyDataSource = AddMenuItem(6, miCopyDataSource_Click);
miNewTotal = AddMenuItem(65, miNewTotal_Click);
btnActions.DropDownItems.AddRange(new ToolStripItem[] {
miNew, miOpen, miMerge, miSave, miChooseData, new ToolStripSeparator(),
miNewDataSource, miSortDataSources, miNewRelation, miNewCalculatedColumn, miNewParameter, miNewTotal });
btnActions.DropDownOpening += btnActions_DropDownOpening;
btnActions.DropDown.ImageList = this.GetImages();
miNewDataSource.Visible = false;
mnuContext = new ContextMenuStrip();
mnuContext.Font = DrawUtils.DefaultFont;
miNewDataSource1 = AddMenuItem(137, Designer.cmdAddData.Invoke);
miNewCalculatedColumn1 = AddMenuItem(55, miNewCalculatedColumn_Click);
miNewParameter1 = AddMenuItem(56, miNewParameter_Click);
miNewTotal1 = AddMenuItem(65, miNewTotal_Click);
miRename = AddMenuItem(miRename_Click);
miRename.ShortcutKeys = Keys.F2;
miEdit = AddMenuItem(68, miEdit_Click);
miDelete = AddMenuItem(51, miDelete_Click);
miDeleteAlias = AddMenuItem(miDeleteAlias_Click);
miView = AddMenuItem(54, miView_Click);
miViewJson = AddMenuItem(54, miViewJson_Click);
miSortDataFields = AddMenuItem(miSortDataFields_Click);
mnuContext.Items.AddRange(new ToolStripItem[] {
miRename, miEdit, miDelete, miDeleteAlias, miView, miCopyDataSource, miViewJson, miSortDataFields });
mnuContext.Opening += mnuContext_Opening;
mnuContext.ImageList = this.GetImages();
tree.ImageList = this.GetImages();
tree.HideSelection = false;
tree.AllowDrop = true;
tree.ContextMenuStrip = mnuContext;
tree.MouseDown += FTree_MouseDown;
tree.BeforeLabelEdit += FTree_BeforeLabelEdit;
tree.AfterLabelEdit += FTree_AfterLabelEdit;
tree.KeyDown += FTree_KeyDown;
tree.AfterSelect += FTree_AfterSelect;
tree.DoubleClick += miEdit_Click;
tree.ItemDrag += FTree_ItemDrag;
tree.DragOver += FTree_DragOver;
tree.DragDrop += FTree_DragDrop;
splitter = new Splitter();
splitter.Visible = false;
lblDescription = new DescriptionControl();
lblDescription.Dock = DockStyle.Bottom;
lblDescription.Height = 70;
lblDescription.Visible = false;
Controls.AddRange(new Control[] { lblDescription });
#endif
expandedNodes = new List();
Localize();
UpdateDpiDependencies();
}
///
/// Describes an item dragged from the "Data Dictionary" window.
///
public class DraggedItem
{
///
/// The dragged object.
///
public Object obj;
///
/// The text of dragged object.
///
public string text;
internal DraggedItem(Object obj, string text)
{
this.obj = obj;
this.text = text;
}
}
///
/// Collection of dragged items.
///
public class DraggedItemCollection : List
{
internal DraggedItemCollection() : base() { }
}
internal static class DragUtils
{
public static DraggedItemCollection GetAll(DragEventArgs e)
{
// holding dragged objects data in DragEventArgs does not work in Mono. Use simpler way
//DraggedItemCollection items = (DraggedItemCollection)e.Data.GetData(typeof(DraggedItemCollection));
DraggedItemCollection items = DictionaryWindow.draggedItems;
if (items == null || items.Count == 0)
return null;
return items;
}
public static DraggedItem GetOne(DragEventArgs e)
{
DraggedItemCollection items = DictionaryWindow.draggedItems;
if (items == null || items.Count == 0)
return null;
return items[items.Count - 1];
}
}
}
}