123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643 |
- using System;
- using System.Collections.Generic;
- using System.Windows.Forms;
- using System.Drawing;
- using FastReport.Utils;
- using FastReport.Controls;
- namespace FastReport.Design.ToolWindows
- {
- /// <summary>
- /// Represents the "Report Tree" window.
- /// </summary>
- public class ReportTreeWindow : FilterableToolWindow
- {
- #region Fields
- //private TreeView tree;
- private Button collapseExpButton = new Button();
- private List<Base> components;
- private List<TreeNode> nodes;
- private List<TreeNode> nodesSelected;
- private TreeNode nodeTree;
- private int lastFromitem;
- private int lastToitem;
- private bool lastNeedReverse;
- private bool updating;
- private bool LastData;
- private bool passSelection = false;
- private bool cancelNextSelection = false;
- private bool ShiftNonSelect = false;
- private bool RewriteSelect = false;
- private bool mouseButtonRight = false;
- #endregion
- #region Private Methods
- protected override void UpdateTree()
- {
- // if there was no changes in the report structure, do nothing
- if (Designer.ActiveReport != null && tree.Nodes.Count > 0)
- {
- if (CheckChanges(Designer.ActiveReport, tree.Nodes[0]))
- return;
- }
- updating = true;
- tree.BeginUpdate();
- tree.Nodes.Clear();
- components.Clear();
- nodes.Clear();
- if (Designer.ActiveReport != null)
- EnumComponents(Designer.ActiveReport, tree.Nodes);
- tree.ExpandAll();
- tree.EndUpdate();
- updating = false;
- }
- private void UpdateSelection()
- {
- if (updating)
- return;
- if (Designer.SelectedObjects == null || Designer.SelectedObjects.Count == 0)
- return;
- Base c = Designer.SelectedObjects[Designer.SelectedObjects.Count - 1];
- int i = components.IndexOf(c);
- if (i != -1)
- {
- unpaintSelectedNodes();
- updating = true;
- tree.SelectedNode = nodes[i];
- nodesSelected.Clear();
- foreach (Base b in Designer.SelectedObjects)
- {
- nodesSelected.Add(nodes[components.IndexOf(b)]);
- }
- updating = false;
- paintSelectedNodes();
- }
- }
- void paintSelectedNodes()
- {
- Color backColor = SystemColors.Highlight;
- Color foreColor = SystemColors.HighlightText;
- foreach (TreeNode node in nodesSelected)
- {
- node.BackColor = backColor;
- node.ForeColor = foreColor;
- }
- }
- void unpaintSelectedNodes()
- {
- foreach (TreeNode node in nodesSelected)
- {
- node.BackColor = tree.BackColor;
- node.ForeColor = tree.ForeColor;
- }
- }
- private void EnumComponents(Base rootComponent, TreeNodeCollection rootNode)
- {
- string name = rootComponent is Report ?
- "Report - " + Designer.ActiveReportTab.ReportName : rootComponent.Name;
- TreeNode node = rootNode.Add(name);
- node.Tag = rootComponent;
- components.Add(rootComponent);
- nodes.Add(node);
- ObjectInfo objItem = RegisteredObjects.FindObject(rootComponent);
- if (objItem != null)
- {
- int imageIndex = objItem.ImageIndex;
- node.ImageIndex = imageIndex;
- node.SelectedImageIndex = imageIndex;
- }
- if (rootComponent.HasFlag(Flags.CanShowChildrenInReportTree))
- {
- foreach (Base component in rootComponent.ChildObjects)
- EnumComponents(component, node.Nodes);
- }
- }
- private bool CheckChanges(Base rootComponent, TreeNode rootNode)
- {
- if (rootNode.Tag != rootComponent)
- return false;
- if (!(rootComponent is Report))
- {
- if (rootNode.Text != rootComponent.Name)
- return false;
- }
- if (!rootComponent.HasFlag(Flags.CanShowChildrenInReportTree))
- return true;
- ObjectCollection childObjects = rootComponent.ChildObjects;
- if (childObjects.Count != rootNode.Nodes.Count)
- return false;
- for (int i = 0; i < childObjects.Count; i++)
- {
- if (!CheckChanges(childObjects[i], rootNode.Nodes[i]))
- return false;
- }
- return true;
- }
- private void tree_AfterSelect(object sender, TreeViewEventArgs e)
- {
- if (passSelection)
- return;
- if (updating)
- return;
- if (Designer.SelectedObjects != null)
- {
- if (Control.ModifierKeys == Keys.Control && !mouseButtonRight)
- {
- if (Designer.SelectedObjects[0] is BandBase || Designer.SelectedObjects[0] is ReportPage)
- {
- Designer.SelectedObjects.Clear();
- }
- if (Designer.SelectedObjects.Contains(e.Node.Tag as Base))
- {
- Designer.SelectedObjects.Remove(e.Node.Tag as Base);
- LastData = false;
- Designer.SelectionChanged(this);
- UpdateSelection();
- return;
- }
- else
- {
- if (e.Node.Tag is BandBase)
- {
- return;
- }
- Designer.SelectedObjects.Add(e.Node.Tag as Base);
- nodeTree = e.Node;
- LastData = false;
- Designer.SelectionChanged(this);
- UpdateSelection();
- return;
- }
- }
- Base c = e.Node.Tag as Base;
- if (Control.ModifierKeys == Keys.Shift)
- {
- if (nodeTree != null && isSameLevel(nodeTree, e.Node))
- {
- List<TreeNode> nodeBas = nodes;
- int nodeTreeIndex = getNodeIndexInNodes(nodeTree);
- int eNodeTreeIndex = getNodeIndexInNodes(e.Node);
- int from = Math.Min(nodeTreeIndex, eNodeTreeIndex);
- int to = Math.Max(nodeTreeIndex, eNodeTreeIndex);
- bool needReverse = nodeTreeIndex > eNodeTreeIndex;
- if (!(c is Report))
- Designer.ActiveReportTab.ActivePage = c.Page;
- if (RewriteSelect)
- {
- Designer.SelectedObjects.Clear();
- RewriteSelect = false;
- }
- if (from == lastFromitem && LastData)
- {
- if (to < lastToitem)
- {
- Designer.SelectedObjects.Clear();
- for (int i = from; i <= to; i++)
- {
- if (nodeBas[i].Tag is BandBase || nodeBas[i].Tag is ReportPage || nodeBas[i].Tag is Report)
- {
- continue;
- }
- Designer.SelectedObjects.Add(nodeBas[i].Tag as Base);
- }
- }
- else
- {
- for (int i = lastToitem + 1; i <= to; i++)
- {
- if (nodeBas[i].Tag is BandBase || nodeBas[i].Tag is ReportPage || nodeBas[i].Tag is Report)
- {
- continue;
- }
- Designer.SelectedObjects.Add(nodeBas[i].Tag as Base);
- }
- }
- }
- if (to == lastToitem && LastData)
- {
- if (needReverse)
- {
- if (from > lastFromitem)
- {
- Designer.SelectedObjects.Clear();
- for (int i = to; i >= from; i--)
- {
- if (nodeBas[i].Tag is BandBase || nodeBas[i].Tag is ReportPage || nodeBas[i].Tag is Report)
- {
- continue;
- }
- Designer.SelectedObjects.Add(nodeBas[i].Tag as Base);
- }
- }
- else
- {
- for (int i = lastFromitem - 1; i >= from; i--)
- {
- if (nodeBas[i].Tag is BandBase || nodeBas[i].Tag is ReportPage || nodeBas[i].Tag is Report)
- continue;
- Designer.SelectedObjects.Add(nodeBas[i].Tag as Base);
- }
- }
- }
- }
- if (LastData == false || lastNeedReverse != needReverse)
- {
- Designer.SelectedObjects.Clear();
- if (needReverse)
- {
- for (int i = to; i >= from; i--)
- {
- if (nodeBas[i].Tag is BandBase || nodeBas[i].Tag is ReportPage || nodeBas[i].Tag is Report)
- continue;
- Designer.SelectedObjects.Add(nodeBas[i].Tag as Base);
- }
- }
- else
- {
- for (int i = from; i <= to; i++)
- {
- if (nodeBas[i].Tag is BandBase || nodeBas[i].Tag is ReportPage || nodeBas[i].Tag is Report)
- continue;
- Designer.SelectedObjects.Add(nodeBas[i].Tag as Base);
- }
- }
- }
- if (Designer.SelectedObjects.Count == 0)
- {
- Designer.SelectedObjects.Add(nodeTree.Tag as Base);
- tree.SelectedNode = nodeTree;
- RewriteSelect = true;
- }
- LastData = true;
- lastFromitem = from;
- lastToitem = to;
- lastNeedReverse = needReverse;
- tree.SelectedNode = nodes[(components.IndexOf(Designer.SelectedObjects[Designer.SelectedObjects.Count - 1]))];
- Designer.SelectionChanged(this);
- UpdateSelection();
- }
- }
- else
- {
- LastData = false;
- updating = true;
- if (!(c is Report))
- Designer.ActiveReportTab.ActivePage = c.Page;
- updating = false;
- nodeTree = e.Node;
- Designer.SelectedObjects.Clear();
- Designer.SelectedObjects.Add(c);
- Designer.SelectionChanged(null);
- }
- }
- }
- private int getNodeIndexInNodes(TreeNode node1)
- {
- int i = 0;
- foreach (TreeNode itemNode in nodes)
- {
- if (itemNode == node1)
- {
- return i;
- }
- i++;
- }
- return 0;
- }
- private bool isSameLevel(TreeNode node1, TreeNode node2)
- {
- foreach (TreeNode element in nodes)
- {
- if (element == node2)
- {
- return true;
- }
- }
- return false;
- }
- private void tree_ItemDrag(object sender, ItemDragEventArgs e)
- {
- SelectedObjectCollection draggedComponent = Designer.SelectedObjects;
- foreach (Base itemDragComp in draggedComponent)
- {
- if (itemDragComp is ComponentBase &&
- (itemDragComp.IsAncestor || itemDragComp.HasFlag(Flags.CanChangeParent)))
- {
- tree.DoDragDrop(draggedComponent, DragDropEffects.Move);
- }
- else
- {
- tree.DoDragDrop(draggedComponent, DragDropEffects.None);
- }
- }
- }
- private void tree_DragDrop(object sender, DragEventArgs e)
- {
- TreeNode targetNode = tree.GetNodeAt(tree.PointToClient(new Point(e.X, e.Y)));
- Base targetComponent = targetNode.Tag as Base;
- // cases:
- // - target can contain dragged. Just change parent.
- // - target cannot contain dragged. Change creation order (Z-order).
- foreach (Base item in Designer.SelectedObjects)
- {
- if (targetComponent is IParent && (targetComponent as IParent).CanContain(item))
- {
- item.Parent = targetComponent;
- }
- else
- {
- Base parent = targetComponent.Parent;
- item.Parent = parent;
- item.ZOrder = targetComponent.ZOrder;
- }
- }
- // update all designer plugins (this one too)
- Designer.SetModified(null, "ChangeParent");
- Base b = Designer.SelectedObjects[Designer.SelectedObjects.Count - 1];
- int i = components.IndexOf(b);
- nodeTree = nodes[i];
- UpdateSelection();
- }
- private void tree_DragOver(object sender, DragEventArgs e)
- {
- List<TreeNode> draggedNode = (List<TreeNode>)e.Data.GetData(typeof(List<TreeNode>));
- TreeNode targetNode = (tree.GetNodeAt(tree.PointToClient(new Point(e.X, e.Y))));
- if (targetNode == null)
- {
- return;
- }
- SelectedObjectCollection draggedComponent = Designer.SelectedObjects;
- Base targetComponent = targetNode.Tag as Base;
- // allowed moves are:
- // - target is not dragged
- // - target is not child of dragged
- // - target can contain dragged, or
- // parent of target can contain dragged
- foreach (Base itemDragComp in draggedComponent)
- {
- if (itemDragComp != targetComponent &&
- !targetComponent.HasParent(itemDragComp) &&
- (((targetComponent is IParent) && (targetComponent as IParent).CanContain(itemDragComp) ||
- (targetComponent.Parent != null && (targetComponent.Parent as IParent).CanContain(itemDragComp)))))
- {
- e.Effect = e.AllowedEffect;
- }
- else
- {
- e.Effect = DragDropEffects.None;
- }
- }
- // disable the Designer.OnSelectionChanged
- updating = true;
- tree.SelectedNode = targetNode;
- updating = false;
- }
- private void tree_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Delete)
- Designer.cmdDelete.Invoke();
- }
- private void tree_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
- {
- if (Designer.SelectedObjects.Count == 1 && Control.ModifierKeys == Keys.None)
- {
- Base c = e.Node.Tag as Base;
- if (c is Report)
- e.CancelEdit = false;
- }
- else
- {
- e.CancelEdit = true;
- }
- }
- private void tree_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
- {
- if (Designer.SelectedObjects.Count == 1 && Control.ModifierKeys == Keys.None)
- {
- if (e.Label != null)
- {
- Base c = e.Node.Tag as Base;
- string saveName = c.Name;
- try
- {
- c.Name = e.Label;
- Designer.SetModified(this, "Change");
- }
- catch (Exception ex)
- {
- FRMessageBox.Error(ex.Message);
- e.CancelEdit = true;
- }
- }
- }
- else
- {
- e.CancelEdit = true;
- }
- }
- private void FTree_MouseUp(object sender, TreeNodeMouseClickEventArgs e)
- {
- if (e.Button == MouseButtons.Right)
- {
- mouseButtonRight = true;
- }
- else
- {
- mouseButtonRight = false;
- }
- if (Control.ModifierKeys == Keys.Control && e.Button != MouseButtons.Right)
- {
- if (e.Node.Tag is BandBase || e.Node.Tag is ReportPage || e.Node.Tag is Report)
- {
- ShiftNonSelect = true;
- Designer.SelectionChanged(this);
- UpdateSelection();
- cancelNextSelection = true;
- return;
- }
- if (tree.SelectedNode == e.Node && Designer.SelectedObjects.Count > 1 && Designer.SelectedObjects.Contains(e.Node.Tag as Base))
- {
- passSelection = true;
- tree.SelectedNode = nodes[(components.IndexOf(Designer.SelectedObjects[Designer.SelectedObjects.Count - 2]))];
- nodeTree = nodes[(components.IndexOf(Designer.SelectedObjects[Designer.SelectedObjects.Count - 2]))];
- LastData = false;
- passSelection = false;
- Designer.SelectedObjects.Remove(e.Node.Tag as Base);
- Designer.SelectionChanged(this);
- UpdateSelection();
- cancelNextSelection = true;
- }
- return;
- }
- else
- {
- if (Designer.SelectedObjects.Count > 1 && e.Node == tree.SelectedNode && e.Button != MouseButtons.Right)
- {
- Designer.SelectedObjects.Clear();
- Designer.SelectedObjects.Add(e.Node.Tag as Base);
- nodeTree = e.Node;
- LastData = false;
- Designer.SelectionChanged(null);
- UpdateSelection();
- }
- }
- if (e.Button == MouseButtons.Right)
- {
- tree.SelectedNode = tree.GetNodeAt(e.Location);
- if (tree.SelectedNode != null)
- {
- ContextMenuBase menu = (tree.SelectedNode.Tag as Base).GetContextMenu();
- if (menu != null)
- {
- menu.Show(tree, e.Location);
- }
- }
- }
- }
- private void tree_BeforeSelect(object sender, TreeViewCancelEventArgs e)
- {
- if (updating || passSelection)
- return;
- if (cancelNextSelection)
- {
- e.Cancel = true;
- cancelNextSelection = false;
- return;
- }
- if (Control.ModifierKeys == Keys.Control && Designer.SelectedObjects.Contains(e.Node.Tag as Base) && !ShiftNonSelect)
- {
- e.Cancel = true;
- Designer.SelectedObjects.Remove(e.Node.Tag as Base);
- Designer.SelectionChanged(null);
- UpdateSelection();
- return;
- }
- }
- #endregion
- #region Public Methods
- /// <inheritdoc/>
- public override void SelectionChanged()
- {
- UpdateSelection();
- }
- /// <inheritdoc/>
- public override void UpdateContent()
- {
- UpdateTree();
- UpdateSelection();
- }
- /// <inheritdoc/>
- public override void Localize()
- {
- base.Localize();
- Text = Res.Get("Designer,ToolWindow,ReportTree");
- }
- /// <inheritdoc/>
- public override void UpdateDpiDependencies()
- {
- base.UpdateDpiDependencies();
- Image = Designer.GetImage(189);
- tree.ImageList = Designer.GetImages();
- #if !MONO
- ImageIndex = 189;
- #endif
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="ReportTreeWindow"/> class with default settings.
- /// </summary>
- /// <param name="designer">The report designer.</param>
- public ReportTreeWindow(Designer designer) : base(designer)
- {
- Name = "ReportTreeWindow";
- components = new List<Base>();
- nodes = new List<TreeNode>();
- nodesSelected = new List<TreeNode>();
- tree.ShowRootLines = false;
- tree.HideSelection = true;
- tree.LabelEdit = true;
- tree.AllowDrop = true;
- tree.AfterSelect += tree_AfterSelect;
- tree.BeforeSelect += tree_BeforeSelect;
- tree.ItemDrag += tree_ItemDrag;
- tree.DragOver += tree_DragOver;
- tree.DragDrop += tree_DragDrop;
- tree.KeyDown += tree_KeyDown;
- tree.BeforeLabelEdit += tree_BeforeLabelEdit;
- tree.AfterLabelEdit += tree_AfterLabelEdit;
- tree.NodeMouseClick += FTree_MouseUp;
- Localize();
- UpdateDpiDependencies();
- }
- }
- }
|