Sfall-ScriptEditor
1460 строк · 56.7 Кб
1using System;2using System.Collections.Generic;3using System.Drawing;4using System.IO;5using System.Linq;6using System.Windows.Forms;7
8using System.Xml;9using System.Xml.XPath;10
11using ICSharpCode.ClassDiagram;12using ICSharpCode.Diagrams.Drawables;13using ICSharpCode.TextEditor.Document;14
15using ScriptEditor.CodeTranslation;16using ScriptEditor.TextEditorUI;17using ScriptEditor.TextEditorUI.ToolTips;18using ScriptEditor.TextEditorUI.Nodes;19using ScriptEditor.TextEditorUtilities;20
21namespace ScriptEditor22{
23public partial class NodeDiagram : Form24{25public event EventHandler ChangeNodes; // event for parse script editor26
27private ClassCanvas nodesCanvas = new ClassCanvas();28
29// List of names of all used nodes in script30private List<string> nodesProcedureName = new List<string>();31// List of hidden nodes32private Dictionary<string, NodeCanvasItem> HideNodes = new Dictionary<string, NodeCanvasItem>();33// List of all used nodes with parser data34private Dictionary<string, List<DialogueParser>> NodesData = new Dictionary<string, List<DialogueParser>>();35
36private List<ContentBody> NodeBody;37private List<string> linkFrom;38private List<LinkTo> linkToList;39
40private string[] MessagesData;41
42private TabInfo sourceTab;43private IDocument scriptText;44private Procedure[] scriptProc;45
46private string fcdFilePath = null; // путь и файл для сохранения47
48private string scriptName;49private bool shiftDown;50private bool needUpdate;51private bool autoUpdate; // save setting52private bool woExitNode; // save setting53private bool fсClosed; // закрытие основной формы диаграмм54
55private bool shouldUpdate = true; // нужно ли обновление холста после изменения в коде скрипта, используетя для предотвращения не нужного обновления.56
57public bool NeedUpdate58{59private get { return needUpdate; }60set {61if (shouldUpdate) needUpdate = value;62shouldUpdate = true;63UpdateProceduresInfo();64}65}66
67#region Form Initialize68
69private const string help = "Управление:\n" +70"Shift + Левый Щелчек на строке текта сообщения - Быстрое редактирования сообщения.\n" +71"Ctrl + Левый Щелчек - Добавляет или снимает выделение ноды.\n" +72"Средняя кнопка Мыши - Премещение хоста.\n" +73"Колесеко Мышки - Увеличить/Уменьшить маштаб.\n" +74"Правая кнопка Мышки - Вызвать контекстное меню.";75
76public NodeDiagram(TabInfo tabInfo)77{78InitializeComponent();79
80if (Settings.hintsLang != 0) HelptoolStripButton.ToolTipText = help;81
82// set settings83autoUpdate = autoUpdateNodesToolStripMenuItem.Checked = Settings.autoUpdate;84woExitNode = ShowExitNodeToolStripMenuItem.Checked = Settings.woExitNode;85autoArrangeToolStripMenuItem.Checked = Settings.autoArrange;86autoSaveOnExitToolStripMenuItem.Checked = Settings.autoSaveChart;87autoHideNodesToolStripMenuItem.Checked = Settings.autoHideNodes;88
89this.Text += tabInfo.filename;90
91this.sourceTab = tabInfo;92this.scriptText = tabInfo.textEditor.Document;93this.scriptProc = tabInfo.parseInfo.procs;94
95nodesCanvas.KeyDown += NodeDiagram_KeyDown;96nodesCanvas.KeyUp += NodeDiagram_KeyUp;97
98this.Controls.Add(nodesCanvas);99toolStrip.SendToBack();100nodesCanvas.Dock = DockStyle.Fill;101nodesCanvas.ContextMenuStrip = contextMenuStrip;102
103// Canvas Events104nodesCanvas.CanvasItemHover += CanvasItemHover;105nodesCanvas.CanvasItemSelected += CanvasItemSelected;106nodesCanvas.CanvasItemUnSelected += CanvasItemUnSelected;107nodesCanvas.LayoutChanged += LayoutChanged;108nodesCanvas.Scroll += ScrollChanged;109nodesCanvas.CanvasMouseWheel += CanvasMouseWheel;110nodesCanvas.ZoomChanged += new EventHandler(CanvasZoomChanged);111//nodesCanvas.ContextMenuStrip.Closed112
113scriptName = scriptProc[tabInfo.parseInfo.GetProcedureIndex("talk_p_proc")].filename;114
115InitData();116}117
118private void NodeDiagram_Shown(object sender, EventArgs e)119{120nodesCanvas.Visible = false;121
122string ext = "." + saveFileDialog.DefaultExt;123string fcd = Path.ChangeExtension(sourceTab.filepath, ext);124if (File.Exists(fcd)) {125fcdFilePath = fcd;126LoadFlowchartDiagram();127} else { // fcd sub folder128fcd = Path.Combine(Path.GetDirectoryName(sourceTab.filepath), saveFileDialog.DefaultExt,129Path.GetFileNameWithoutExtension(sourceTab.filepath) + ext);130if (File.Exists(fcd)) {131fcdFilePath = fcd;132LoadFlowchartDiagram();133} else {134#if DEBUG135CreateCanvasNodes();136#endif137}138}139}140#endregion141
142#region Create Nodes143/// <summary>144/// Main Init145/// </summary>146private void InitData()147{148// получить имена всех Node процедур из скрипта149nodesProcedureName = DialogueParser.GetAllNodesName(scriptProc);150if (nodesProcedureName.Count == 0)151return;152
153ReadMessageData(sourceTab.msgFilePath);154
155// распарсить полученный блок Node процедуры, проанализировав связи, получить тексты сообщений.156foreach (var name in nodesProcedureName)157{158if (woExitNode && name.Equals("node999", StringComparison.OrdinalIgnoreCase))159continue;160
161int index = sourceTab.parseInfo.GetProcedureIndex(name, scriptProc);162string nodeCode = Utilities.GetProcedureCode(scriptText, scriptProc[index]);163if (nodeCode == null)164continue;165
166ParseNodeCode(name, nodeCode);167}168}169
170private List<DialogueParser> ParseNodeCode(string nodeName, string nodeCode)171{172List<DialogueParser> DialogNode = new List<DialogueParser>();173DialogueParser.PrepareNodeCode(nodeCode, DialogNode, sourceTab.parseInfo, !tsbShowCommentCode.Checked);174
175// Имя ноды и данные176NodesData.Add(nodeName, DialogNode);177
178return DialogNode;179}180
181/// <summary>182/// Добавление для отображения нод на холсте, из подготовленных данных NodesData183/// </summary>184private void CreateCanvasNodes()185{186int shiftY = 0;187int shiftX = 0;188
189foreach (var node in NodesData)190AddNodeToCanvas(node, ref shiftY, ref shiftX);191
192nodesCanvas.Visible = true;193nodesCanvas.Refresh();194MessageFile.ShowMissingFiles();195}196
197private void AddNodeToCanvas(KeyValuePair<string, List<DialogueParser>> node, ref int shiftY, ref int shiftX)198{199INode nodeData; // this not used200NodeCanvasItem nodeItem = CreateNodeItem(node, out nodeData);201
202if (!nodeData.ShowCodeNodeButton) nodeItem.RemoveItemContex(); // удаляет строки с кодом203
204if (Settings.autoHideNodes && nodeItem.GetNodeData.NodeType == NodesType.Unused) {205nodeItem.Hidden = true;206HideNodes.Add(node.Key, nodeItem);207} else {208nodeItem.X = 25 + shiftX;209nodeItem.Y = 25 + shiftY;210nodesCanvas.AddCanvasItem(nodeItem);211
212int height = (int)nodeItem.Height;213if (height > 500) {214shiftX += 50 + (int)nodeItem.Width;215} else {216shiftY += 25 + height;217shiftX += 25 + ((int)nodeItem.Width / 2);218}219}220}221
222/// <summary>223///224/// </summary>225/// <param name="node"></param>226/// <param name="nodeData"></param>227/// <returns></returns>228private NodeCanvasItem CreateNodeItem(KeyValuePair<string, List<DialogueParser>> node, out INode nodeData)229{230nodeData = GetNodeData(node);231
232nodeData.ShowCodeNodeButton = tsbShowAllCode.Checked;233
234// создать ноду для отображения из сформированных данных DataNode235NodeCanvasItem nodeItem = ClassCanvas.CreateItemFromType(nodeData);236
237nodeItem.ContentClick += ClickContentText;238nodeItem.ShowCodeButtonClick += nodeItem_ShowCodeButtonClick;239
240return nodeItem;241}242
243void nodeItem_ShowCodeButtonClick(NodeCanvasItem item)244{245UpdateAllNodes();246}247
248/// <summary>249/// Подготовить и получить данные для дальнейшего отображения ноды на холсте250/// </summary>251/// <param name="node"></param>252/// <returns></returns>253private INode GetNodeData(KeyValuePair<string, List<DialogueParser>> node)254{255List<DialogueParser> value = node.Value;256NodeBody = new List<ContentBody>();257
258// node link to node, and message text259linkToList = new List<LinkTo>();260
261for (int n = 0; n < value.Count; n++)262{263if (value[n].opcode == OpcodeType.Option || value[n].opcode == OpcodeType.giq_option ||264value[n].opcode == OpcodeType.gsay_option || value[n].opcode == OpcodeType.call)265{266linkToList.Add(new LinkTo(value[n].toNode, n + 1));267}268
269string msgText = (value[n].opcode != OpcodeType.None && value[n].opcode != OpcodeType.call)270? GetMessageText(value[n].numberMsgFile, value[n].numberMsgLine)271: null;272
273//поместить распарсенные данные из Node процедуры в List<ContentBody>274NodeBody.Add(new ContentBody((value[n].code.StartsWith(new string(' ', Settings.tabSize))) ? value[n].code.Remove(0, Settings.tabSize): value[n].code,275msgText, value[n].opcode, value[n].numberMsgLine, value[n].numberMsgFile, n));276}277
278// получить список имен: link from nodes279List<string> linklist = new List<string>();280
281foreach (var data in NodesData)282{283foreach (var nd in data.Value)284{285if (nd.toNode == null || linklist.Contains(data.Key)) continue;286
287if (nd.toNode.Equals(node.Key, StringComparison.OrdinalIgnoreCase)) linklist.Add(data.Key);288}289}290
291int i = 0;292linkFrom = new List<string>() { String.Empty, String.Empty };293foreach (var link in linklist)294{295linkFrom[i] += ((linkFrom[i].Length > 0) ? " : " : String.Empty) + link;296i = 1 - i;297}298
299NodesType type = NodesType.Default;300if (node.Key.Equals("talk_p_proc", StringComparison.OrdinalIgnoreCase))301type = NodesType.DialogStart;302else if (linkToList.Count == 0 && linklist.Count > 0)303type = NodesType.DialogEnd;304else if (linkToList.Count > 0 && linklist.Count == 0)305type = NodesType.NoFromLink;306else if (linkToList.Count == 0 && linklist.Count == 0)307type = NodesType.Unused;308
309return new DataNode(node.Key, linkToList, linkFrom, NodeBody, type);310}311
312/// <summary>313/// Получить и подготовить данные для указанной ноды314/// (метод используется при загрузке сохраненных данных из XML файла)315/// </summary>316/// <param name="nodeName">Имя ноды</param>317private INode GetNodeData(string nodeName)318{319if (NodesData.ContainsKey(nodeName))320return GetNodeData(new KeyValuePair<string, List<DialogueParser>>(nodeName, NodesData[nodeName]));321else322return null;323}324
325// UNDONE:326/*private void UpdateNode(string name)327{
328if (!NodesData.ContainsKey(name))
329return;
330
331//UpdateProceduresInfo();
332
333///
334int index = sourceTab.parseInfo.GetProcedureIndex(name, scriptProc);
335string nodeProcedureText = Utilities.GetProcedureCode(scriptText, scriptProc[index]);
336if (nodeProcedureText == null)
337return;
338
339List<DialogueParser> DialogNode = new List<DialogueParser>();
340DialogueParser.PrepareNodeCode(nodeProcedureText, DialogNode, sourceTab.parseInfo, !tsbShowCommentCode.Checked);
341//
342
343NodesData.Remove(name); // удалить данные существующей ноды
344
345// Имя ноды и данные
346NodesData.Add(name, DialogNode);
347
348int dummy = 0;
349var node = new KeyValuePair<string, List<DialogueParser>>(name, NodesData[name]);
350ReCreateNodeCanvas(node, ref dummy);
351}*/
352
353/// <summary>354/// Обновить данные для всех созданных нод на холсте355/// </summary>356private void UpdateAllNodes()357{358NodesData.Clear();359nodesProcedureName.Clear();360
361UpdateProceduresInfo();362
363InitData();364
365bool focused = (nodesCanvas.GetLastFocusItem() != null);366int shift = 0;367
368List<INode> Nodes = new List<INode>();369foreach (var node in NodesData)370Nodes.Add(ReCreateNodeCanvas(node, ref shift));371
372//373nodesCanvas.RemoveUnusedNodes(Nodes);374
375if (focused)376nodesCanvas.SetJustLastFocus();377}378
379/// <summary>380/// Пересоздание уже существующей ноды на холсте381/// </summary>382/// <param name="node"></param>383/// <returns></returns>384private INode ReCreateNodeCanvas(KeyValuePair<string, List<DialogueParser>> node, ref int shift)385{386// проверить не скрыта ли нода стаким именем387bool IsHide = HideNodes.ContainsKey(node.Key);388
389INode nodeData;390NodeCanvasItem newNodeItem = CreateNodeItem(node, out nodeData);391
392CanvasItem existNodeItem;393//получить данные из уже созданной ноды394if (IsHide)395existNodeItem = HideNodes[node.Key];396else397existNodeItem = nodesCanvas.GetNodeCanvasItem(nodeData.Name);398
399if (existNodeItem != null) {400// установить расположение и размеры ноды на холсте401newNodeItem.X = existNodeItem.X;402newNodeItem.Y = existNodeItem.Y;403newNodeItem.Width = existNodeItem.Width;404
405// установить cостояния406newNodeItem.Collapsed = ((NodeCanvasItem)existNodeItem).Collapsed;407
408INode _nodeData = ((NodeCanvasItem)existNodeItem).GetNodeData;409if (_nodeData.GetStateShowNodeCodeButton()) {410nodeData.SetStateShowNodeCodeButton();411nodeData.ShowCodeNodeButton = _nodeData.ShowCodeNodeButton;412newNodeItem.ViewAllNodeCode = _nodeData.ShowCodeNodeButton;413}414
415for (int l = 0; l < newNodeItem.NodeContentsCount; l++)416newNodeItem.SetContentCollapsed(l.ToString(), ((NodeCanvasItem)existNodeItem).ContentIsCollapsed(l.ToString()));417
418} else if (!IsHide) {419//уст. позицию вслучае если ноды на холсте несуществует420newNodeItem.X = 100 + shift;421newNodeItem.Y = 100;422
423shift += 350;424}425
426if (nodeData.GetStateShowNodeCodeButton()) {427if (!nodeData.ShowCodeNodeButton)428newNodeItem.RemoveItemContex();429} else if (!tsbShowAllCode.Checked) {430newNodeItem.RemoveItemContex();431}432
433//добавляем обновленную и удаляем существующую ноду434if (IsHide) {435HideNodes.Remove(node.Key);436newNodeItem.Hidden = true;437HideNodes.Add(node.Key, newNodeItem);438} else {439nodesCanvas.AddCanvasItem(newNodeItem, existNodeItem);440nodesCanvas.RemoveCanvasItem(existNodeItem);441}442return nodeData;443}444
445/// <summary>446/// Создать новую ноду на холсте447/// </summary>448/// <param name="nodeName"></param>449/// <param name="nodeCode"></param>450private void CreateNewNode(string nodeName, string nodeCode)451{452nodesProcedureName.Add(nodeName);453
454INode nodeData;455List<DialogueParser> DialogNode = ParseNodeCode(nodeName, nodeCode);456NodeCanvasItem nodeItem = CreateNodeItem(new KeyValuePair<string, List<DialogueParser>>(nodeName, DialogNode), out nodeData);457
458// Установить позицию для новой ноды459int x = nodesCanvas.HorizontalScroll.Value + (nodesCanvas.Width / 2);460int y = nodesCanvas.VerticalScroll.Value + (nodesCanvas.Height / 2);461nodeItem.X = (x - (nodeItem.Width / 2)) / nodesCanvas.Zoom;462nodeItem.Y = (y - (nodeItem.Height / 2)) / nodesCanvas.Zoom;463
464nodeItem.Collapsed = false;465
466if (!nodeData.ShowCodeNodeButton) nodeItem.RemoveItemContex(); // удаляет строки с кодом467
468nodesCanvas.AddCanvasItem(nodeItem);469nodesCanvas.SetFocusedCanvasItem(nodeItem);470
471#region Simple example add new node472/*473* List<LinkTo> linkList;
474* List<ContentBody> ProcedureBody;
475* List<string> linkfrom = new List<string>();
476* linkList = new List<LinkTo>();
477*
478* linkfrom.Add("Start");
479* linkfrom.Add("End");
480* linkList.Add(new LinkTo("Node001",4));
481* linkList.Add(new LinkTo("Node002",6));
482*
483* ProcedureBody = new List<ContentBody>();
484* ProcedureBody.Add(new ContentBody("If <condition>", null, OpcodeType.None));
485* ProcedureBody.Add(new ContentBody("reply", "Я только прошу не трогать ее и, э-э, не фотографировать со вспышкой.", OpcodeType.Reply));
486* ProcedureBody.Add(new ContentBody("else", null, OpcodeType.None));
487* ProcedureBody.Add(new ContentBody("options", "Как твое имя?", OpcodeType.Option));
488* ProcedureBody.Add(new ContentBody("end", null, OpcodeType.None));
489* ProcedureBody.Add(new ContentBody("options", "Проваливай!", OpcodeType.Option));
490* NodeCanvasItem item = ClassCanvas.CreateItemFromType(new DataNode(nodeName, linkList, linkfrom, ProcedureBody, NodesType.Unused));
491*/
492#endregion493}494#endregion495
496#region Hide/Unhide nodes497private void HideNode(NodeCanvasItem node)498{499string key = node.GetNodeData.Name;500node.Hidden = true;501HideNodes.Add(key, node);502nodesCanvas.RemoveCanvasItem(node);503}504
505private void UnHideNode(string key)506{507NodeCanvasItem item = HideNodes[key];508if (item.X == 0 && item.Y == 0)509item.Y = item.X = 25;510item.Hidden = false;511nodesCanvas.ReAddedCanvasItem(item);512HideNodes.Remove(key);513
514//nodesCanvas.ClearAllItemsFocus();515nodesCanvas.Refresh();516}517
518private void UnHideAll()519{520int shift = 20;521foreach (NodeCanvasItem item in HideNodes.Values) {522if (item.X == 0 && item.Y == 0) {523item.Y = 20;524item.X = shift;525shift += (int)item.Width + 20;526}527item.Hidden = false;528nodesCanvas.ReAddedCanvasItem(item);529}530HideNodes.Clear();531
532nodesCanvas.ClearAllItemsFocus();533nodesCanvas.Refresh();534}535#endregion536
537// Update data procedures538private void UpdateProceduresInfo()539{540scriptProc = ParserInternal.GetProcsData(scriptText.TextContent, sourceTab.filepath);541}542
543private void ReadMessageData(string msgfilePath)544{545MessagesData = File.ReadAllLines(msgfilePath, Settings.EncCodePage);546if (msgfilePath == sourceTab.msgFilePath)547MessageFile.ParseMessages(sourceTab, MessagesData);548}549
550private string GetMessageText(int msgNum, int msgLineNum)551{552string msg = null;553if (msgLineNum > 0) {554if (msgNum > 0) {555string path;556if (MessageFile.GetPath(sourceTab, msgNum, out path, true)) {557string[] MsgData = File.ReadAllLines(path, Settings.EncCodePage);558msg = MessageFile.GetMessages(MsgData, msgLineNum);559} else560msg = String.Format(MessageFile.msgfileError, msgNum);561}562else if (sourceTab.messages.ContainsKey(msgLineNum)) {563msg = sourceTab.messages[msgLineNum];564}565if (msg == null) msg = MessageFile.messageError;566} else567msg = "ParseCode: <Could not get line number of this code>";568
569return msg;570}571
572private bool NodeIsEditing(NodeCanvasItem node)573{574if (node.IsEditing) return true;575
576foreach (var fcTE in sourceTab.nodeFlowchartTE)577{578if (fcTE.NodeName == node.GetNodeData.Name) return true;579}580return false;581}582
583private void CanvasItemHover(object sender, CanvasItemEventArgs e)584{585if (e.CanvasItem is NodeCanvasItem) {586editNodeToolStripMenuItem.Enabled = true;587editNodeToolStripMenuItem.Tag = e.CanvasItem;588editNodeToolStripMenuItem.Text = "Edit Node: " + e.CanvasItem.ToString();589
590if (((NodeCanvasItem)e.CanvasItem).GetNodeData.Name.Equals("talk_p_proc", StringComparison.OrdinalIgnoreCase) == false) {591renameNodeToolStripMenuItem.Enabled = !NodeIsEditing(((NodeCanvasItem)e.CanvasItem));592renameNodeToolStripMenuItem.Tag = e.CanvasItem;593} else594renameNodeToolStripMenuItem.Enabled = false;595renameNodeToolStripMenuItem.Text = "Rename Node: " + e.CanvasItem.ToString();596} else {597editNodeToolStripMenuItem.Enabled = false;598editNodeToolStripMenuItem.Tag = null;599editNodeToolStripMenuItem.Text = "Edit Node";600
601renameNodeToolStripMenuItem.Enabled = false;602renameNodeToolStripMenuItem.Tag = null;603renameNodeToolStripMenuItem.Text = "Rename Node";604}605}606
607private void CanvasItemSelected(object sender, CanvasItemEventArgs e)608{609if (e.CanvasItem is NodeCanvasItem) {610NodeCanvasItem NodeItem = (NodeCanvasItem)e.CanvasItem;611contextMenuStrip.Tag = e.CanvasItem;612
613hideNodeToolStripMenuItem.Enabled = true;614deleteNoteToolStripMenuItem.Enabled = !NodeIsEditing(NodeItem); //!NodeItem.IsEditing;615
616JumpNodeToolStripMenuItem.Enabled = true;617JumpNodeToolStripMenuItem.Text = "Jump from: " + NodeItem.ToString() + " to";618
619if (JumpNodeToolStripMenuItem.Tag != e.CanvasItem) {620JumpNodeToolStripMenuItem.DropDownItems.Clear();621if (NodeItem.GetNodeData.LinkedToNodes.Count > 0) {622JumpNodeToolStripMenuItem.DropDownItems.Add("-- Link To --");623JumpNodeToolStripMenuItem.DropDownItems[0].Enabled = false;624}625}626else if (JumpNodeToolStripMenuItem.Tag != null)627return;628
629JumpNodeToolStripMenuItem.Tag = e.CanvasItem;630
631foreach (var linkTo in NodeItem.GetNodeData.LinkedToNodes)632{633JumpNodeToolStripMenuItem.DropDownItems.Add(linkTo.NameTo, null, new EventHandler(JumpClick));634int count = JumpNodeToolStripMenuItem.DropDownItems.Count - 1;635
636JumpNodeToolStripMenuItem.DropDownItems[count].ForeColor = (HideNodes.ContainsKey(linkTo.NameTo))637? Color.Gray : Color.OrangeRed;638}639
640string linkLine = String.Join(":", NodeItem.GetNodeData.LinkedFromNodes);641string[] linkFrom = linkLine.Split(new char[] {':'}, StringSplitOptions.RemoveEmptyEntries);642if (linkFrom.Length > 0) {643JumpNodeToolStripMenuItem.DropDownItems.Add("-- Link From --");644JumpNodeToolStripMenuItem.DropDownItems[645JumpNodeToolStripMenuItem.DropDownItems.Count - 1].Enabled = false;646
647foreach (var link in linkFrom)648{649JumpNodeToolStripMenuItem.DropDownItems.Add(link.Trim(), null, new EventHandler(JumpClick));650int count = JumpNodeToolStripMenuItem.DropDownItems.Count - 1;651JumpNodeToolStripMenuItem.DropDownItems[count].ForeColor = (HideNodes.ContainsKey(link.Trim()))652? Color.Gray : Color.Blue;653}654}655} else {656CanvasItemUnSelected(null, e);657if (e.CanvasItem is NoteCanvasItem)658deleteNoteToolStripMenuItem.Enabled = true;659}660}661
662private void CanvasItemUnSelected(object sender, EventArgs e)663{664JumpNodeToolStripMenuItem.Enabled = false;665JumpNodeToolStripMenuItem.Text = "Jump from: --- to";666JumpNodeToolStripMenuItem.DropDownItems.Clear();667JumpNodeToolStripMenuItem.DropDownItems.Add("-- Link To --");668JumpNodeToolStripMenuItem.DropDownItems[0].Enabled = false;669JumpNodeToolStripMenuItem.Tag = contextMenuStrip.Tag = null;670
671hideNodeToolStripMenuItem.Enabled = false;672deleteNoteToolStripMenuItem.Enabled = false;673}674
675private void JumpClick(object sender, EventArgs e)676{677string name = ((ToolStripItem)sender).Text;678
679if (HideNodes.ContainsKey(name))680UnHideNode(name);681
682NodeCanvasItem NodeItem = (NodeCanvasItem)nodesCanvas.GetNodeCanvasItem(name);683if (NodeItem == null)684return;685
686JumpToNode(NodeItem);687nodesCanvas.SetFocusedCanvasItem(NodeItem);688}689
690private void JumpToNode(NodeCanvasItem NodeItem)691{692float zoom = nodesCanvas.Zoom;693Point position = new Point((int)(NodeItem.X * zoom), (int)(NodeItem.Y * zoom));694
695// центрируем положение696int w = ((int)(NodeItem.Width * zoom)) / 2;697int h = ((int)(NodeItem.Height * zoom)) / 2;698Size cs = nodesCanvas.ClientSize;699position.Offset(-(cs.Width / 2) + w, -(cs.Height / 2) + h);700
701nodesCanvas.SetCanvasScrollPosition = position;702}703
704private void ClickContentText(object sender, TextSegment ts)705{706if (ts.IndexContent == -1) return;707
708if (shiftDown) {709ContentBody cbData = ((NodeCanvasItem)sender).GetNodeData.NodeContent[ts.IndexContent];710if (cbData.msgNum == -1)711return;712EditContenText(cbData.msgNum, cbData.msgFileNum, ts);713} else714ShowContentText(ts);715}716
717private void EditContenText(int msgNum, int msgFileNum, TextSegment ts)718{719string msgfile = null;720string message = null;721shiftDown = false;722
723if (msgFileNum != -1) {724if (!MessageFile.GetPath(sourceTab, msgFileNum, out msgfile)) {725MessageBox.Show("The requested message file: " + msgfile + "\ncould not be found.", "Missing messages file");726return;727}728} else729msgfile = sourceTab.msgFilePath;730
731ReadMessageData(msgfile);732
733if (msgFileNum != -1)734message = MessageFile.GetMessages(MessagesData, msgNum);735else if (sourceTab.messages.ContainsKey(msgNum))736message = sourceTab.messages[msgNum];737
738if (message == null) {739MessageBox.Show("The requested message line number in: " + msgfile + "\nfile, could not be found.", "Message missing");740return;741}742
743if (InputBox.ShowDialog("Message file: " + msgfile, ref message) == DialogResult.OK) {744if (MessageFile.SaveToMessageFile(ref MessagesData, msgfile, message, msgNum)) {745if (msgFileNum == -1)746sourceTab.messages[msgNum] = message;747ts.Text = "\"" + message + "\"";748}749}750}751
752private void ShowContentText(TextSegment ts)753{754int x = (int)(ts.AbsoluteX * nodesCanvas.Zoom) - nodesCanvas.HorizontalScroll.Value;755int y = (int)(ts.AbsoluteY * nodesCanvas.Zoom) - nodesCanvas.VerticalScroll.Value;756
757int lines = ts.GetTextLines();758switch (lines) {759case 3:760y += 2;761break;762case 2:763y += (int)(ts.TextHeight * nodesCanvas.Zoom) - 5;764break;765case 1:766y += (int)(ts.TextHeight * nodesCanvas.Zoom);767break;768default:769y -= 2;770break;771}772
773string message = ts.Text;774int len = message.Length;775if ((lines > 0 && ts.TextWidth > ts.ActualWidth) ||776(lines == 0 && len > 100 && (ts.TextWidth > ts.ActualWidth))) {777int loop = 1; // количество частей: 1 - строка поделена на две части778int divPos = len / 2; // делим строку пополам779
780if (divPos > 75) {781loop++;782divPos = len / 3;783if (divPos > 75) {784loop++;785divPos = len / 4;786}787}788
789int incPos = divPos;790int i, j;791
792for (int l = loop; l > 0; l--)793{794int insertPos = i = j = divPos;795while (j > 0 && i < len)796{797if (Char.IsWhiteSpace(message[--j])) { // назад798insertPos = j;799divPos -= (divPos - j);800break;801}802else if (Char.IsWhiteSpace(message[i])) { // вперед803insertPos = i;804divPos += (i - divPos);805break;806}807i++;808}809message = message.Insert(insertPos, Environment.NewLine);810divPos += incPos; // следующая позиция вставки811}812}813// popup show814msgPopup.RemoveAll();815msgPopup.Tag = message;816msgPopup.Show(message, nodesCanvas, x, y, 1000 + (len * 50));817}818
819private void CreatetoolStripButton_Click(object sender, EventArgs e)820{821if (nodesCanvas.NodesTotalCount > 0)822if (MessageBox.Show("Do you want to clean up the existing flowchart and create a new one?", "Create New",823MessageBoxButtons.YesNo) == DialogResult.No)824return;825
826nodesCanvas.ClearCanvas();827HideNodes.Clear();828CreateCanvasNodes();829
830if (autoArrangeToolStripMenuItem.Checked)831nodesCanvas.AutoArrange();832else833nodesCanvas.Refresh();834
835HelpTip.Show(@"NOTE: Save the flowchart file to the folder (or subfolder \fcd) of the source script, so that the editor next time automatically opens the flowchart file.", nodesCanvas, 10, 10, 10000);836
837nodesCanvas.Select();838}839
840private void renameNodeToolStripMenuItem_Click(object sender, EventArgs e)841{842string nName = ((NodeCanvasItem)(renameNodeToolStripMenuItem.Tag)).GetNodeData.Name;843nName = Refactor.RenameProcedure(nName, scriptText, sourceTab);844if (nName != null) {845if (nName.IndexOf("node", StringComparison.OrdinalIgnoreCase) == -1) {846MessageBox.Show("The name of the procedure must contain the word 'Node'");847scriptText.UndoStack.Undo();848scriptText.UndoStack.ClearRedoStack();849return;850}851((NodeCanvasItem)(renameNodeToolStripMenuItem.Tag)).GetNodeData.Name = nName;852UpdateAllNodes();853}854}855
856private void deleteNoteToolStripMenuItem_Click(object sender, EventArgs e)857{858if (nodesCanvas.ActiveControl is TextBox) {859// удаление текста в TextBox860TextBox editBox = nodesCanvas.ActiveControl as TextBox;861if (editBox.Text.Length > 0) {862int posCaret = editBox.SelectionStart;863if (posCaret >= editBox.Text.Length) return;864
865editBox.Text = editBox.Text.Remove(posCaret, 1);866editBox.SelectionStart = posCaret;867}868return;869}870if (MessageBox.Show("Are you sure you want to delete the all selected nodes/notes?\n(When delete a node, the corresponding procedure in the script will be deleted).", "Deleting",871MessageBoxButtons.YesNo) == DialogResult.No)872return;873
874List<string> removeProcName = new List<string>();875
876do {877CanvasItem item = nodesCanvas.GetLastFocusItem();878if (item == null)879break;880
881if (item is NoteCanvasItem) {882nodesCanvas.RemoveCanvasItem(item);883continue;884}885
886string name = ((NodeCanvasItem)item).GetNodeData.Name;887if (name.Equals("talk_p_proc", StringComparison.OrdinalIgnoreCase)) {888MessageBox.Show("You cannot delete the procedural handler 'talk_p_proc' from the flowchart editor.");889break; //don't delete talk_p_proc890}891
892if (NodeIsEditing((NodeCanvasItem)item)) {893MessageBox.Show("You cannot delete a node procedure: " + name + " that is edited at the current time.");894break;895}896
897nodesCanvas.RemoveCanvasItem(item);898NodesData.Remove(name);899nodesProcedureName.Remove(name);900removeProcName.Add(name);901
902} while (true);903
904if (removeProcName.Count > 0) {905Utilities.DeleteProcedure(removeProcName, scriptText);906
907if (ChangeNodes != null)908ChangeNodes(this, EventArgs.Empty); //event909}910
911nodesCanvas.ClearDragItems();912
913CanvasItemUnSelected(null, EventArgs.Empty);914UpdateAllNodes();915
916nodesCanvas.Refresh();917}918
919private void addNodeToolStripMenuItem_Click(object sender, EventArgs e)920{921TemplateNode tNode = new TemplateNode();922tNode.CreateClick += new TemplateNode.CreateClickHandler(CreateClick);923tNode.ShowForm();924}925
926private bool CreateClick(object sender, string nodeName, string nodeCode)927{928string defName = "Node";929if (nodeName.IndexOf(defName, StringComparison.OrdinalIgnoreCase) < 0)930nodeName = defName + nodeName;931
932if (sourceTab.parseInfo.CheckExistsName(nodeName, NameType.Proc)) {933MessageBox.Show("The procedure/variable or declared macro with this name already exists.", "Unable to rename");934return false;935}936
937CreateNewNode(nodeName, nodeCode);938
939shouldUpdate = false; // не обновлять другие ноды на холсте940
941//Создать процедуру в скрипте942int dummy = 0;943ParserInternal.UpdateParseBuffer(scriptText.TextContent);944int declrLine = ParserInternal.GetEndLineProcDeclaration();945int procLine = scriptText.TotalNumberOfLines - 1;946string procblock = "\r\nprocedure " + nodeName + " begin\r\n" + nodeCode + "\r\nend\r\n";947Utilities.InsertProcedure(sourceTab.textEditor.ActiveTextAreaControl,948nodeName, procblock, declrLine, procLine, ref dummy);949
950nodesCanvas.Refresh();951
952if (ChangeNodes != null)953ChangeNodes(this, EventArgs.Empty); //event954
955return true; //close dialog956}957
958private void addNoteToolStripMenuItem_Click(object sender, EventArgs e)959{960NoteCanvasItem note = new NoteCanvasItem();961note.X = (40 + nodesCanvas.HorizontalScroll.Value) / nodesCanvas.Zoom;962note.Y = (40 + nodesCanvas.VerticalScroll.Value) / nodesCanvas.Zoom;963note.Width = 200;964note.Height = 50;965nodesCanvas.AddCanvasItem(note);966
967nodesCanvas.Refresh();968}969
970private void CanvasZoomChanged(object sender, EventArgs e)971{972int zoom = (int)Math.Round(nodesCanvas.Zoom * 100f);973if (e == null) {974Zoom.Value = zoom; // не изменять маштаб975return;976}977PercentLabel.Text = zoom + "%";978if (Zoom.Value != zoom)979Zoom.Value = zoom;980}981
982private void Zoom_ValueChanged(object sender, EventArgs e)983{984nodesCanvas.Zoom = Zoom.Value / 100.0f;985}986
987private void CanvasMouseWheel(object sender, MouseEventArgs e)988{989int value = 2; //inc/dec zoom value990
991int zm = Zoom.Value;992
993if (e.Delta > 0)994zm += value;995else996zm -= value;997
998if (zm < 5)999zm = 5;1000else if (zm > 200)1001zm = 200;1002
1003Zoom.Value = zm;1004
1005#if DEBUG1006//ZoomLabel.Text = string.Format("X:{0}% : Y:{1}%", nodesCanvas.Percent.X, nodesCanvas.Percent.Y);1007#endif1008}1009
1010private void editNodeToolStripMenuItem_Click(object sender, EventArgs e)1011{1012NodeCanvasItem node = (CanvasItem)editNodeToolStripMenuItem.Tag as NodeCanvasItem;1013if (node == null)1014return;1015
1016foreach (var fcTE in sourceTab.nodeFlowchartTE)1017{1018if (fcTE.NodeName.Equals(node.GetNodeData.Name, StringComparison.OrdinalIgnoreCase)) {1019fcTE.Activate();1020return;1021}1022}1023
1024((NodeCanvasItem)editNodeToolStripMenuItem.Tag).StartEditingNode(); //set node edit status1025
1026int index = sourceTab.parseInfo.GetProcedureIndex(node.GetNodeData.Name, scriptProc);1027if (index == -1)1028return;1029FlowchartTE nodeEditor = new FlowchartTE(scriptProc[index], sourceTab, nodesProcedureName, true);1030sourceTab.nodeFlowchartTE.Add(nodeEditor);1031
1032nodeEditor.ApplyCode += nodeEditor_ApplyCode;1033nodeEditor.Disposed += new EventHandler(nodeEditor_Disposed);1034nodeEditor.ShowEditor(this, nodeEditLink: (NodeCanvasItem)editNodeToolStripMenuItem.Tag);1035
1036renameNodeToolStripMenuItem.Enabled = deleteNoteToolStripMenuItem.Enabled = false;1037}1038
1039void nodeEditor_Disposed(object sender, EventArgs e)1040{1041if (fсClosed)1042return;1043
1044foreach (var fcTE in sourceTab.nodeFlowchartTE)1045{1046if (fcTE.NodeName.Equals(((FlowchartTE)sender).NodeName, StringComparison.OrdinalIgnoreCase)) {1047sourceTab.nodeFlowchartTE.Remove(fcTE);1048break;1049}1050}1051}1052
1053void nodeEditor_ApplyCode(object sender, FlowchartTE.CodeArgs e)1054{1055if (e.Change) {1056if (Utilities.ReplaceProcedureCode(scriptText, sourceTab.parseInfo, e.Name, e.Code)) {1057MessageBox.Show("In the source script, there is no dialog node with this name.", "Apply error");1058return;1059}1060
1061if (ChangeNodes != null)1062ChangeNodes(this, EventArgs.Empty); //event1063
1064if (!fсClosed)1065UpdateAllNodes();1066//else1067// UpdateProceduresInfo();1068
1069e.Change = false;1070}1071if (!fсClosed)1072e.Close = true;1073}1074
1075private void CollapsetoolStripButton_Click(object sender, EventArgs e)1076{1077nodesCanvas.CollapseAll(shiftDown);1078}1079
1080private void ExpandtoolStripButton_Click(object sender, EventArgs e)1081{1082nodesCanvas.ExpandAll(shiftDown);1083}1084
1085private void ShrinkAlltoolStripButton_Click(object sender, EventArgs e)1086{1087nodesCanvas.ShrinkAllWidths();1088}1089
1090private void MatchAlltoolStripButton_Click(object sender, EventArgs e)1091{1092nodesCanvas.MatchAllWidths();1093}1094
1095private void HidePopUp()1096{1097msgPopup.Hide(nodesCanvas);1098HelpTip.Hide(nodesCanvas);1099}1100
1101void ScrollChanged(object sender, EventArgs e)1102{1103HidePopUp();1104}1105
1106void LayoutChanged(object sender, EventArgs e)1107{1108HidePopUp();1109}1110
1111void NodeDiagram_KeyUp(object sender, KeyEventArgs e)1112{1113if (e.KeyCode == Keys.ShiftKey)1114shiftDown = false;1115}1116
1117void NodeDiagram_KeyDown(object sender, KeyEventArgs e)1118{1119if (e.KeyCode == Keys.ShiftKey)1120shiftDown = true;1121}1122
1123private void highQualityToolStripMenuItem_Click(object sender, EventArgs e)1124{1125nodesCanvas.HighQuality = highQualityToolStripMenuItem.Checked;1126nodesCanvas.Refresh();1127}1128
1129private void ArrangetoolStripButton_Click(object sender, EventArgs e)1130{1131nodesCanvas.AutoArrange();1132}1133
1134private void UpdatetoolStripButton_Click(object sender, EventArgs e)1135{1136UpdateNodes();1137}1138
1139private void UpdateNodes()1140{1141NeedUpdate = false;1142UpdateAllNodes();1143nodesCanvas.Refresh();1144}1145
1146private void NodeDiagram_FormClosing(object sender, FormClosingEventArgs e)1147{1148fсClosed = true;1149foreach (FlowchartTE fcTE in sourceTab.nodeFlowchartTE)1150{1151if (fcTE.OpenFromDiagram)1152fcTE.CloseEditor(true);1153}1154
1155if (autoSaveOnExitToolStripMenuItem.Checked && fcdFilePath != null)1156WriteToXml().Save(fcdFilePath);1157}1158
1159private void NodeDiagram_Activated(object sender, EventArgs e)1160{1161if (autoUpdate && NeedUpdate) {1162UpdateAllNodes();1163NeedUpdate = false;1164} else if (NeedUpdate) {1165HelpTip.Show("You need to update the nodes. The script source code has been changed.", nodesCanvas, 10, 10, 5000);1166}1167}1168
1169private void toolStripButton1_Click(object sender, EventArgs e)1170{1171nodesCanvas.WireOnlySelect = toolStripButton1.Checked;1172nodesCanvas.Refresh();1173}1174
1175private void autoUpdateNodesToolStripMenuItem_Click(object sender, EventArgs e)1176{1177autoUpdate = Settings.autoUpdate = autoUpdateNodesToolStripMenuItem.Checked;1178}1179
1180private void ShowExitNodeToolStripMenuItem_Click(object sender, EventArgs e)1181{1182woExitNode = Settings.woExitNode = ShowExitNodeToolStripMenuItem.Checked;1183}1184
1185private void Zoom_MouseLeave(object sender, EventArgs e)1186{1187if (Zoom.Focused)1188nodesCanvas.Focus();1189}1190
1191private void Zoom_MouseEnter(object sender, EventArgs e)1192{1193if (nodesCanvas.Focused && !Zoom.Focused)1194Zoom.Focus();1195}1196
1197private void autoArrangeToolStripMenuItem_Click(object sender, EventArgs e)1198{1199Settings.autoArrange = autoArrangeToolStripMenuItem.Checked;1200}1201
1202private void autoSaveOnExitToolStripMenuItem_Click(object sender, EventArgs e)1203{1204Settings.autoSaveChart = autoSaveOnExitToolStripMenuItem.Checked;1205}1206
1207private void lowDetailsToolStripMenuItem_Click(object sender, EventArgs e)1208{1209ClassCanvas.NodeLowDetails = lowDetailsToolStripMenuItem.Checked;1210UpdateNodes();1211}1212
1213private void tsbShowCommentCode_Click(object sender, EventArgs e)1214{1215if (tsbShowCommentCode.Checked)1216tsbShowCommentCode.ForeColor = Color.Red;1217else1218tsbShowCommentCode.ForeColor = SystemColors.ControlText;1219UpdateAllNodes();1220nodesCanvas.Refresh();1221}1222
1223private void HelptoolStripButton_Click(object sender, EventArgs e)1224{1225HelpTip.Show(HelptoolStripButton.ToolTipText, nodesCanvas, nodesCanvas.Width - 300, 10, 10000);1226}1227
1228private void contextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)1229{1230if (!Program.KeyHook(Keys.ControlKey))1231nodesCanvas.CtrlDown = false;1232}1233
1234private void autoHideNodesToolStripMenuItem_Click(object sender, EventArgs e)1235{1236Settings.autoHideNodes = autoHideNodesToolStripMenuItem.Checked;1237}1238
1239private void contextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)1240{1241if (unhideNodeToolStripMenuItem.HasDropDownItems)1242return;1243
1244foreach (var key in HideNodes.Keys)1245unhideNodeToolStripMenuItem.DropDownItems.Add(key, null, new EventHandler(UnHideNode_Click));1246}1247
1248private void UnHideNode_Click(object sender, EventArgs e)1249{1250UnHideNode(((ToolStripItem)sender).Text);1251unhideNodeToolStripMenuItem.DropDownItems.Clear();1252}1253
1254private void unhideAllToolStripMenuItem_Click(object sender, EventArgs e)1255{1256UnHideAll();1257unhideNodeToolStripMenuItem.DropDownItems.Clear();1258}1259
1260private void hideToolStripMenuItem_Click(object sender, EventArgs e)1261{1262NodeCanvasItem item = (NodeCanvasItem)contextMenuStrip.Tag;1263do {1264HideNode(item);1265item = (NodeCanvasItem)nodesCanvas.GetLastFocusItem();1266} while (item != null);1267
1268CanvasItemUnSelected(null, EventArgs.Empty);1269nodesCanvas.Refresh();1270unhideNodeToolStripMenuItem.DropDownItems.Clear();1271}1272
1273private void closeToolStripMenuItem_Click(object sender, EventArgs e)1274{1275this.Close();1276}1277
1278private void addEditRulesToolStripMenuItem_Click(object sender, EventArgs e)1279{1280new ScriptEditor.TextEditorUI.Function.FunctionsRules().ShowDialog(this);1281}1282
1283private void showAllCode_Click(object sender, EventArgs e)1284{1285tsbShowAllCode.Checked = !tsbShowAllCode.Checked;1286UpdateNodes();1287}1288
1289#region Save/Load Diagram1290private void openDiagramToolStripMenuItem_Click(object sender, EventArgs e)1291{1292string path = fcdFilePath ?? sourceTab.filepath;1293openFileDialog.InitialDirectory = Path.GetDirectoryName(path);1294
1295if (openFileDialog.ShowDialog() == DialogResult.OK) {1296fcdFilePath = openFileDialog.FileName;1297LoadFlowchartDiagram();1298}1299}1300
1301private void saveDiagramToolStripMenuItem_Click(object sender, EventArgs e)1302{1303if (fcdFilePath == null) {1304saveFileDialog.InitialDirectory = Path.GetDirectoryName(sourceTab.filepath);1305saveFileDialog.FileName = Path.ChangeExtension(scriptName, saveFileDialog.DefaultExt);1306if (saveFileDialog.ShowDialog() == DialogResult.OK)1307fcdFilePath = saveFileDialog.FileName;1308else1309return;1310}1311WriteToXml().Save(fcdFilePath);1312}1313
1314private void saveImageToolStripMenuItem_Click(object sender, EventArgs e)1315{1316SaveFileDialog sfd = new SaveFileDialog();1317sfd.DefaultExt = "png";1318sfd.AddExtension = true;1319sfd.Filter = "PNG Image (.png)|*.png";1320if (sfd.ShowDialog() == DialogResult.OK)1321nodesCanvas.SaveToImage(sfd.FileName);1322}1323
1324[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XmlNode")]1325private XmlDocument WriteToXml ()1326{1327XmlDocument doc = new XmlDocument();1328doc.LoadXml("<NodesDiagram/>");1329
1330XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");1331doc.InsertBefore(decl, doc.FirstChild);1332
1333XmlAttribute script = doc.CreateAttribute("ScriptName");1334script.Value = scriptName;1335doc.DocumentElement.Attributes.Append(script);1336
1337XmlAttribute zoom = doc.CreateAttribute("Zoom");1338zoom.Value = nodesCanvas.Zoom.ToString(System.Globalization.CultureInfo.InvariantCulture);1339doc.DocumentElement.Attributes.Append(zoom);1340
1341XmlAttribute positionX = doc.CreateAttribute("PositionX");1342positionX.Value = nodesCanvas.HorizontalScroll.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);1343doc.DocumentElement.Attributes.Append(positionX);1344
1345XmlAttribute positionY = doc.CreateAttribute("PositionY");1346positionY.Value = nodesCanvas.VerticalScroll.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);1347doc.DocumentElement.Attributes.Append(positionY);1348
1349//Save hidden nodes1350foreach (var item in HideNodes)1351item.Value.WriteToXml(doc);1352
1353return nodesCanvas.WriteToXml(doc);1354}1355
1356private void LoadFlowchartDiagram()1357{1358XmlDocument doc = new XmlDocument();1359doc.Load(fcdFilePath);1360LoadFromXml(doc);1361
1362// Check and create new node1363int shiftX = 0;1364foreach (var item in NodesData)1365{1366int shiftY = 0;1367if (!HideNodes.ContainsKey(item.Key) && !nodesCanvas.Contains(item.Key)) {1368MessageBox.Show("Added new node from the script: " + item.Key, "Loading...");1369AddNodeToCanvas(item, ref shiftY, ref shiftX);1370}1371}1372
1373nodesCanvas.Visible = true;1374nodesCanvas.Refresh();1375MessageFile.ShowMissingFiles();1376nodesCanvas.Select();1377}1378
1379private void LoadFromXml (IXPathNavigable doc)1380{1381XPathNavigator nav = doc.CreateNavigator();1382
1383XPathNodeIterator ni = nav.Select(@"/NodesDiagram");1384ni.MoveNext();1385string nameScript = ni.Current.GetAttribute("ScriptName", "");1386if (!scriptName.Equals(nameScript, StringComparison.OrdinalIgnoreCase)) {1387MessageBox.Show("This flowchart file was saved for another script file.", "Wrong Flowchart: " + nameScript);1388return;1389}1390
1391float zoom = float.Parse(ni.Current.GetAttribute("Zoom", ""), System.Globalization.CultureInfo.InvariantCulture);1392int positionX = int.Parse(ni.Current.GetAttribute("PositionX", ""), System.Globalization.CultureInfo.InvariantCulture);1393int positionY = int.Parse(ni.Current.GetAttribute("PositionY", ""), System.Globalization.CultureInfo.InvariantCulture);1394
1395nodesCanvas.ClearCanvas();1396HideNodes.Clear();1397
1398ni = nav.Select(@"/NodesDiagram/Node");1399while (ni.MoveNext())1400{1401string nodeName = ni.Current.GetAttribute("Name", "");1402INode nd = GetNodeData(nodeName);1403
1404NodeCanvasItem canvasitem = ClassCanvas.CreateItemFromType(nd);1405if (canvasitem != null) {1406canvasitem.LoadFromXml(ni.Current);1407canvasitem.ContentClick += ClickContentText;1408canvasitem.ShowCodeButtonClick += nodeItem_ShowCodeButtonClick;1409
1410// установить сохраненное значение кнопки ShowCode для ноды1411if (NodeCanvasItem.showCode != -1) {1412nd.SetStateShowNodeCodeButton();1413nd.ShowCodeNodeButton = (NodeCanvasItem.showCode != 0);1414} else {1415nd.ShowCodeNodeButton = tsbShowAllCode.Checked;1416}1417canvasitem.ViewAllNodeCode = nd.ShowCodeNodeButton;1418if (!nd.ShowCodeNodeButton) {1419canvasitem.RemoveItemContex();1420}1421
1422if (!canvasitem.Hidden)1423nodesCanvas.AddCanvasItem(canvasitem);1424else1425HideNodes.Add(nodeName, canvasitem);1426} else1427MessageBox.Show("Deleted existing dialog node: " + nodeName + ", that does not exist in the script code.", "Loading...");1428}1429
1430ni = nav.Select(@"/NodesDiagram/Note");1431while (ni.MoveNext())1432{1433NoteCanvasItem note = new NoteCanvasItem();1434note.LoadFromXml(ni.Current);1435nodesCanvas.AddCanvasItem(note);1436}1437
1438nodesCanvas.Zoom = zoom;1439nodesCanvas.SetCanvasScrollPosition = new Point(positionX, positionY);1440}1441#endregion1442
1443#region Handles drawing for ToolTip1444private void toolTip_Draw(object sender, DrawToolTipEventArgs e)1445{1446if (((ToolTip)sender).Tag != null) {1447TipPainter.DrawSizeMessage(e);1448} else {1449TipPainter.DrawMessage(e);1450}1451}1452
1453private void msgPopup_Popup(object sender, PopupEventArgs e) {1454Size sz = TextRenderer.MeasureText((string)msgPopup.Tag, new Font("Arial", 12.0f, FontStyle.Regular, GraphicsUnit.Point));;1455sz.Height += 6;1456e.ToolTipSize = sz;1457}1458#endregion1459}1460}
1461