123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Windows.Forms;
- using FastReport.Utils;
- namespace FastReport.Forms
- {
- #if !COMMUNITY
- public partial class ExportsOptionsEditorForm : BaseDialogForm
- {
- #region Helper functions
- private void Init()
- {
- tvExportsMenu.BeginUpdate();
- tvExportsMenu.Nodes.Clear();
- List<ExportsOptions.ExportsTreeNode> menu = new List<ExportsOptions.ExportsTreeNode>();
- foreach (var node in options.ExportsMenu.Nodes)
- menu.Add(node);
- options.CloudMenu.Enabled = false;
- foreach (var node in options.CloudMenu.Nodes)
- {
- if (node.Enabled)
- {
- options.CloudMenu.Enabled = true;
- break;
- }
- }
- menu.Add(options.CloudMenu);
- options.MessengerMenu.Enabled = false;
- foreach (var node in options.MessengerMenu.Nodes)
- {
- if (node.Enabled)
- {
- options.MessengerMenu.Enabled = true;
- break;
- }
- }
- //menu.Add(options.MessengerMenu);
- fillExportsMenu(menu, tvExportsMenu.Nodes);
- tvExportsMenu.ExpandAll();
- tvExportsMenu.EndUpdate();
- }
- private TreeNode createTreeNode(ExportsOptions.ExportsTreeNode node)
- {
- TreeNode newNode = new TreeNode(node.ToString());
- // Using out of range index because there is no other way to draw node without image
- newNode.ImageIndex = node.ImageIndex == -1 ? 1000 : node.ImageIndex;
- newNode.SelectedImageIndex = newNode.ImageIndex;
- newNode.Tag = node;
- setChecked(newNode, node.Enabled);
- return newNode;
- }
- private void fillExportsMenu(IList<ExportsOptions.ExportsTreeNode> nodes, TreeNodeCollection currentTreeLayer)
- {
- for (int i = 0; i < nodes.Count; ++i)
- {
- currentTreeLayer.Add(createTreeNode(nodes[i]));
- if (nodes[i].Nodes.Count > 0)
- {
- fillExportsMenu(nodes[i].Nodes, currentTreeLayer[i].Nodes);
- }
- }
- }
- private bool isCategory(TreeNode node)
- {
- return (node.Tag as ExportsOptions.ExportsTreeNode).IsCategory;
- }
- private bool isDraggable(TreeNode node)
- {
- return (node.Tag as ExportsOptions.ExportsTreeNode).Root == ExportsOptions.GetInstance().ExportsMenu;
- }
- private bool containsNode(TreeNode targetNode, TreeNode draggedNode)
- {
- while (targetNode != null)
- {
- if (targetNode.Equals(draggedNode))
- {
- return true;
- }
- targetNode = targetNode.Parent;
- }
- return false;
- }
- private bool arePathsEqual(List<int> lhs, List<int> rhs)
- {
- if (lhs == null || rhs == null || lhs.Count != rhs.Count)
- {
- return false;
- }
- for (int i = 0; i < lhs.Count; ++i)
- {
- if (lhs[i] != rhs[i])
- {
- return false;
- }
- }
- return true;
- }
- private List<int> getNodePath(TreeNode node)
- {
- List<int> res = new List<int>();
- while (node != null)
- {
- res.Insert(0, node.Index);
- node = node.Parent;
- }
- return res;
- }
- private InsertionPosition getInsertionPosition(TreeNode targetNode, Point cursorPoint)
- {
- int offsetY = cursorPoint.Y - targetNode.Bounds.Y;
- if (isCategory(targetNode))
- {
- if (offsetY < targetNode.Bounds.Height / 3)
- {
- return InsertionPosition.Top;
- }
- else if (offsetY < (2 * targetNode.Bounds.Height) / 3)
- {
- return InsertionPosition.Inside;
- }
- else
- {
- return InsertionPosition.Bottom;
- }
- }
- else
- {
- if (offsetY < targetNode.Bounds.Height / 2)
- {
- return InsertionPosition.Top;
- }
- else
- {
- return InsertionPosition.Bottom;
- }
- }
- }
- private void drawInsertionLine(InsertionPosition insertionPosition, List<int> treeNodePath)
- {
- tvExportsMenu.Refresh();
- using (Graphics g = tvExportsMenu.CreateGraphics())
- {
- if (insertionPosition == InsertionPosition.Inside)
- {
- return;
- }
- TreeNode treeNode = null;
- TreeNodeCollection nodes = tvExportsMenu.Nodes;
- foreach (int index in treeNodePath)
- {
- treeNode = nodes[index];
- nodes = treeNode.Nodes;
- }
- if (treeNode != null)
- {
- int lineStartX = treeNode.Bounds.X - 50;
- int lineEndX = tvExportsMenu.Bounds.Width;
- int lineY = treeNode.Bounds.Y;
- if (insertionPosition == InsertionPosition.Bottom)
- {
- lineY += treeNode.Bounds.Height;
- }
- using (Pen pen = new Pen(Brushes.Black, 2))
- {
- g.DrawLine(pen, new Point(lineStartX, lineY), new Point(lineEndX, lineY));
- }
- }
- }
- }
- private void passChanges(TreeNodeCollection tvNodes, ExportsOptions.ExportsTreeNode.ExportsTreeNodeCollection menuNodes)
- {
- foreach (TreeNode node in tvNodes)
- {
- ExportsOptions.ExportsTreeNode menuNode = node.Tag as ExportsOptions.ExportsTreeNode;
- menuNode.Enabled = node.Checked;
- menuNode.Nodes.Clear();
- menuNodes.Add(menuNode);
- if (node.Nodes.Count > 0)
- {
- passChanges(node.Nodes, menuNode.Nodes);
- }
- }
- }
- private void passChanges(TreeNodeCollection tvNodes)
- {
- foreach (TreeNode node in tvNodes)
- {
- ExportsOptions.ExportsTreeNode menuNode = node.Tag as ExportsOptions.ExportsTreeNode;
- if (menuNode.Name == "Cloud")
- {
- options.CloudMenu.Enabled = node.Checked;
- options.CloudMenu.Nodes.Clear();
- passChanges(node.Nodes, menuNode.Nodes);
- }
- else if (menuNode.Name == "Messengers")
- {
- options.MessengerMenu.Enabled = node.Checked;
- options.MessengerMenu.Nodes.Clear();
- passChanges(node.Nodes, menuNode.Nodes);
- }
- else
- {
- menuNode.Enabled = node.Checked;
- menuNode.Nodes.Clear();
- options.ExportsMenu.Nodes.Add(menuNode);
- if (node.Nodes.Count > 0)
- {
- passChanges(node.Nodes, menuNode.Nodes);
- }
- }
- }
- }
- private bool isSingleChecked(TreeNode testedNode)
- {
- if (testedNode.Parent != null)
- {
- foreach (TreeNode node in testedNode.Parent.Nodes)
- {
- if (node != testedNode && node.Checked)
- {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- // Because seting Checked property raises AfterCheck event
- private void setChecked(TreeNode node, bool isChecked)
- {
- tvExportsMenu.AfterCheck -= tvExportsMenu_AfterCheck;
- node.Checked = isChecked;
- tvExportsMenu.AfterCheck += tvExportsMenu_AfterCheck;
- }
- private void checkAllChilds(TreeNode node, bool isChecked)
- {
- Queue<TreeNode> queue = new Queue<TreeNode>();
- queue.Enqueue(node);
- while (queue.Count > 0)
- {
- TreeNode currentNode = queue.Dequeue();
- setChecked(currentNode, isChecked);
- foreach (TreeNode item in currentNode.Nodes)
- {
- queue.Enqueue(item);
- }
- }
- }
- #endregion
- private enum InsertionPosition
- {
- Top,
- Inside,
- Bottom
- }
- private ExportsOptions options = ExportsOptions.GetInstance();
- private InsertionPosition currentInsertionPosition;
- private List<int> prevNodePath;
- /// <summary>
- /// Editor for rearrangement Exports Menu elements
- /// </summary>
- public ExportsOptionsEditorForm()
- {
- InitializeComponent();
- Localize();
- Init();
- UIUtils.CheckRTL(this);
- UpdateDpiDependencies();
- }
- /// <inheritdoc/>
- public override void UpdateDpiDependencies()
- {
- base.UpdateDpiDependencies();
- tvExportsMenu.ImageList = this.GetImages();
- }
- /// <inheritdoc/>
- public override void Localize()
- {
- base.Localize();
- MyRes res = new MyRes("Export,Editor");
- this.Text = res.Get("");
- gbExportsMenu.Text = res.Get("ExportsMenu");
- btnDefaultSettings.Text = res.Get("DefaultMenu");
- }
- private void tvExportsMenu_ItemDrag(object sender, ItemDragEventArgs e)
- {
- DoDragDrop(e.Item, DragDropEffects.Move);
- }
- private void tvExportsMenu_DragEnter(object sender, DragEventArgs e)
- {
- if (e.Data.GetDataPresent(typeof(TreeNode)) && isDraggable(e.Data.GetData(typeof(TreeNode)) as TreeNode))
- {
- e.Effect = e.AllowedEffect;
- }
- else
- {
- e.Effect = DragDropEffects.None;
- }
- }
- private void tvExportsMenu_DragOver(object sender, DragEventArgs e)
- {
- Point point = tvExportsMenu.PointToClient(new Point(e.X, e.Y));
- TreeNode targetNode = tvExportsMenu.GetNodeAt(point) as TreeNode;
- TreeNode draggedNode = e.Data.GetData(typeof(TreeNode)) as TreeNode;
- if (targetNode != null && !containsNode(targetNode, draggedNode) && isDraggable(draggedNode) && isDraggable(targetNode))
- {
- e.Effect = DragDropEffects.Move;
- List<int> nodePath = getNodePath(targetNode);
- InsertionPosition insertionPosition = getInsertionPosition(targetNode, point);
- if (arePathsEqual(nodePath, prevNodePath) && insertionPosition == currentInsertionPosition)
- {
- return;
- }
- currentInsertionPosition = insertionPosition;
- prevNodePath = nodePath;
- drawInsertionLine(insertionPosition, nodePath);
- }
- else
- {
- e.Effect = DragDropEffects.None;
- tvExportsMenu.Refresh();
- }
- }
- private void tvExportsMenu_DragDrop(object sender, DragEventArgs e)
- {
- Point targetPoint = tvExportsMenu.PointToClient(new Point(e.X, e.Y));
- TreeNode targetNode = tvExportsMenu.GetNodeAt(targetPoint);
- TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
- if (targetNode == null)
- {
- draggedNode.Remove();
- tvExportsMenu.Nodes.Add(draggedNode);
- }
- else if (!containsNode(targetNode, draggedNode))
- {
- if (e.Effect == DragDropEffects.Move)
- {
- if (draggedNode.Checked == true && isSingleChecked(draggedNode))
- {
- setChecked(draggedNode.Parent, false);
- }
- draggedNode.Remove();
- TreeNodeCollection nodes = targetNode.Parent != null ? targetNode.Parent.Nodes : tvExportsMenu.Nodes;
- switch (currentInsertionPosition)
- {
- case InsertionPosition.Top:
- nodes.Insert(targetNode.Index, draggedNode);
- break;
- case InsertionPosition.Inside:
- targetNode.Nodes.Add(draggedNode);
- break;
- case InsertionPosition.Bottom:
- nodes.Insert(targetNode.Index + 1, draggedNode);
- break;
- }
- if (draggedNode.Checked == true && isSingleChecked(draggedNode))
- {
- setChecked(draggedNode.Parent, true);
- }
- }
- targetNode.Expand();
- }
- }
- private void btnOk_Click(object sender, EventArgs e)
- {
- options.ExportsMenu.Nodes.Clear();
- passChanges(tvExportsMenu.Nodes);
- options.SaveState();
- }
- private void btnDefaultSettings_Click(object sender, EventArgs e)
- {
- options.ResetToDefault();
- Init();
- }
- private void tvExportsMenu_AfterCheck(object sender, TreeViewEventArgs e)
- {
- if (e.Node.Checked)
- {
- TreeNode node = e.Node;
- while (node.Parent != null)
- {
- node = node.Parent;
- setChecked(node, true);
- }
- }
- else
- {
- if (isSingleChecked(e.Node))
- {
- setChecked(e.Node.Parent, false);
- }
- }
- checkAllChilds(e.Node, e.Node.Checked);
- }
- }
- #endif
- }
|