Sfall-ScriptEditor

Форк
0
/
TextEditor.FunctionsControl.cs 
1360 строк · 58.0 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Drawing;
4
using System.IO;
5
using System.Windows.Forms;
6

7
using ICSharpCode.TextEditor;
8
using ICSharpCode.TextEditor.Document;
9

10
using ScriptEditor.CodeTranslation;
11

12
using ScriptEditor.TextEditorUI;
13
using ScriptEditor.TextEditorUI.Nodes;
14

15
using ScriptEditor.TextEditorUtilities;
16

17
namespace ScriptEditor
18
{
19
    partial class TextEditor
20
    {
21
        #region Main functions
22

23
        public enum OpenType { None, File, Text }
24

25
        public TabInfo Open(string file, OpenType type, bool addToMRU = true, bool alwaysNew = false, bool recent = false, bool seltab = true,
26
                            bool commandline = false, bool fcdOpen = false, bool alreadyOpen = true, bool outputFolder = false, bool clearBuildLog = true)
27
        {
28
            bool decompileSuccess = false;
29
            string infile = null;
30

31
            if (type == OpenType.File) {
32
                if (!Path.IsPathRooted(file))
33
                    file = Path.GetFullPath(file);
34

35
                if (commandline && Path.GetExtension(file).ToLowerInvariant() == ".msg") {
36
                    if (currentTab == null)
37
                        wState = FormWindowState.Minimized;
38
                    MessageEditor.MessageEditorOpen(file, this).SendMsgLine += AcceptMsgLine;
39
                    return null;
40
                }
41
                // Check file
42
                bool Exists;
43
                if (!FileAssociation.CheckFileAllow(file, out Exists))
44
                    return null;
45
                //Add this file to the recent files list
46
                if (addToMRU) {
47
                    if (!Exists && recent && MessageBox.Show("This recent file not found. Delete recent link to file?", "Open file error", MessageBoxButtons.YesNo) == DialogResult.Yes)
48
                        recent = true;
49
                    else
50
                        recent = false; // don't delete file link from recent list
51
                    Settings.AddRecentFile(file, recent);
52
                    UpdateRecentList();
53
                }
54
                if (!Exists)
55
                    return null;
56
                //If this is an int, decompile
57
                if (string.Compare(Path.GetExtension(file), ".int", true) == 0) {
58
                    if (!this.Focused)
59
                        ShowMe();
60

61
                    infile = file;
62
                    if (clearBuildLog) tbOutput.Clear();
63
                    tabControl2.SelectedIndex = 1;
64
                    MaximizeLog();
65

66
                    string decomp = new Compiler(roundTrip).Decompile(file, this);
67
                    if (decomp == null) {
68
                        MessageBox.Show("Decompilation of '" + file + "' was not successful", "Error");
69
                        return null;
70
                    } else {
71
                        file = decomp;
72
                        decompileSuccess = true;
73
                        // fix for procedure begin
74
                        ParserInternal.FixProcedureBegin(file);
75
                    }
76
                } else {
77
                    //Check if the file is already open
78
                    var tab = CheckTabs(tabs, file);
79
                    if (tab != null) {
80
                        if (seltab)
81
                            tabControl1.SelectTab(tab.index);
82
                        ShowMe();
83
                        if (!alreadyOpen || MessageBox.Show("This file is already open!\nDo you want to open another one same file?", "Question",
84
                            MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
85
                            return tab;
86
                    }
87
                }
88
            }
89
            //Create the text editor and set up the tab
90
            ICSharpCode.TextEditor.TextEditorControl te = new ICSharpCode.TextEditor.TextEditorControl();
91

92
            if (caretSoftwareModeToolStripMenuItem.CheckState == CheckState.Indeterminate)
93
                caretSoftwareModeToolStripMenuItem.Checked = (Caret.GraphicsMode == ImplementationMode.SoftwareMode);
94

95
            te.TextEditorProperties.LineViewerStyle = LineViewerStyle.FullRow;
96
            te.TextEditorProperties.TabIndent = Settings.tabSize;
97
            te.TextEditorProperties.IndentationSize = Settings.tabSize;
98
            te.TextEditorProperties.ShowTabs = Settings.showTabsChar;
99
            te.TextEditorProperties.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
100
            te.TextEditorProperties.NativeDrawText = Settings.winAPITextRender;
101
            te.TextEditorProperties.DarkScheme = ColorTheme.IsDarkTheme;
102

103
            if (type == OpenType.File && String.Compare(Path.GetExtension(file), ".msg", true) == 0) {
104
                te.Document.TextEditorProperties.Encoding = Settings.EncCodePage;
105
                te.SetHighlighting(ColorTheme.IsDarkTheme ? "MessageDark": "Message");
106
                te.TextEditorProperties.EnableFolding = false;
107
                te.TextEditorProperties.ConvertTabsToSpaces = false;
108
                te.TextEditorProperties.ShowVerticalRuler = false;
109
                te.TextEditorProperties.IndentStyle = IndentStyle.None;
110
                te.TextEditorProperties.ShowLineNumbers = false;
111
                te.TextEditorProperties.Font = new Font("Verdana", 10 + Settings.sizeFont, FontStyle.Regular, GraphicsUnit.Point);
112
            } else {
113
                te.SetHighlighting(ColorTheme.HighlightingScheme); // Activate the highlighting, use the name from the SyntaxDefinition node.
114
                te.Document.FoldingManager.FoldingStrategy = new CodeFolder();
115
                te.TextEditorProperties.ConvertTabsToSpaces = Settings.tabsToSpaces;
116
                te.TextEditorProperties.ShowSpaces = Settings.showTabsChar;
117
                te.TextEditorProperties.IndentStyle = IndentStyle.Smart;
118
                te.TextEditorProperties.ShowVerticalRuler = Settings.showVRuler;
119
                te.TextEditorProperties.VerticalRulerRow = Settings.tabSize;
120
                te.TextEditorProperties.AllowCaretBeyondEOL = true;
121
                //te.TextEditorProperties.CaretLine = true;
122
                Settings.SetTextAreaFont(te);
123
            }
124

125
            if (type == OpenType.File)
126
                te.LoadFile(file, false, true);
127
            else if (type == OpenType.Text)
128
                te.Text = file;
129

130
            // set tabinfo
131
            TabInfo ti = new TabInfo();
132
            ti.index = tabControl1.TabCount;
133
            ti.history.linePosition = new List<TextLocation>();
134
            ti.history.pointerCur = -1;
135
            ti.textEditor = te;
136

137
            bool createNew = false;
138
            if (type == OpenType.None) { // only for new create script
139
                sfdScripts.FileName = "NewScript";
140
                if (sfdScripts.ShowDialog() == DialogResult.OK) {
141
                    file = sfdScripts.FileName;
142
                    type = OpenType.File;
143
                    ti.changed = true;
144
                    te.Text = Properties.Resources.newScript;
145
                } else
146
                    return null;
147
                createNew = true;
148
            } //else
149
              //  ti.changed = false;
150

151
            if (type == OpenType.File ) { //&& !alwaysNew
152
                if (alwaysNew) {
153
                    string temp = Path.Combine(Settings.scriptTempPath, unsaved);
154
                    File.Copy(file, temp, true);
155
                    file = temp;
156
                }
157
                ti.filepath = file;
158
                ti.filename = Path.GetFileName(file);
159
            } else {
160
                ti.filepath = null;
161
                ti.filename = unsaved;
162
            }
163

164
            tabs.Add(ti);
165
            TabPage tp = new TabPage(ti.filename);
166
            tp.ImageIndex = (ti.changed) ? 1 : 0;
167
            tp.Controls.Add(te);
168
            te.Dock = DockStyle.Fill;
169
            tabControl1.TabPages.Add(tp);
170
            if (tabControl1.TabPages.Count == 1)
171
                EnableFormControls();
172
            if (type == OpenType.File) {
173
                if (!alwaysNew)
174
                    tp.ToolTipText = ti.filepath;
175
                string ext = Path.GetExtension(file).ToLowerInvariant();
176
                if (ext == ".ssl" || ext == ".h") {
177
                    te.Text = Utilities.NormalizeNewLine(te.Text);
178
                    if (formatCodeToolStripMenuItem.Checked)
179
                        te.Text = Utilities.FormattingCode(te.Text);
180
                    ti.shouldParse = true;
181
                    //ti.needsParse = true; // set 'true' only edit text
182

183
                    FirstParseScript(ti); // First Parse
184

185
                    if (!createNew && Settings.storeLastPosition) {
186
                        int pos = Settings.GetLastScriptPosition(ti.filename.ToLowerInvariant());
187
                        te.ActiveTextAreaControl.Caret.Line = pos;
188
                        te.ActiveTextAreaControl.CenterViewOn(pos, -1);
189
                    }
190
                    if (Settings.autoOpenMsgs && ti.filepath != null)
191
                        AssociateMsg(ti, false);
192
                }
193
                ti.FileTime = File.GetLastWriteTime(ti.filepath);
194
            }
195
            te.OptionsChanged();
196
            // TE events
197
            te.TextChanged += textChanged;
198
            SetActiveAreaEvents(te);
199
            te.ContextMenuStrip = editorMenuStrip;
200
            //
201
            if (tabControl1.TabPages.Count > 1) {
202
                if (seltab)
203
                    tabControl1.SelectTab(tp);
204
            } else
205
                tabControl1_Selected(null, null);
206

207
            if (fcdOpen)
208
                dialogNodesDiagramToolStripMenuItem_Click(null, null);
209

210
            if (!roundTrip && decompileSuccess) {
211
                SaveFileDialog sfDecomp = new SaveFileDialog();
212
                sfDecomp.Title = "Enter name to save decompile file";
213
                sfDecomp.Filter = "Script files|*.ssl";
214
                sfDecomp.RestoreDirectory = true;
215
                sfDecomp.InitialDirectory = (!outputFolder || Settings.outputDir == null) ? Path.GetDirectoryName(infile) : Settings.outputDir;
216
                sfDecomp.FileName = Path.GetFileNameWithoutExtension(infile);
217

218
                if (sfDecomp.ShowDialog() == DialogResult.OK) {
219
                    ti.filename = Path.GetFileName(sfDecomp.FileName);
220
                    ti.filepath = sfDecomp.FileName;
221

222
                    File.Copy(file, ti.filepath, true);
223
                    File.Delete(file);
224
                    ti.FileTime = File.GetLastWriteTime(ti.filepath);
225

226
                    tabControl1.TabPages[ti.index].Text = tabs[ti.index].filename;
227
                    tabControl1.TabPages[ti.index].ToolTipText = tabs[ti.index].filepath;
228
                    this.Text = SSE + ti.filepath + ((pDefineStripComboBox.SelectedIndex > 0) ? " [" + pDefineStripComboBox.Text + "]" : "");
229

230
                    ForceParseScript();
231
                }
232
                sfDecomp.Dispose();
233
            }
234
            return ti;
235
        }
236

237
        private void CheckChandedFile()
238
        {
239
            if (!currentTab.CheckFileTime()) {
240
                this.Activated -= TextEditor_Activated;
241
                DialogResult result = MessageBox.Show(currentTab.filepath +
242
                                                      "\nThe script file was changed outside the editor." +
243
                                                      "\nDo you want to update the script file?",
244
                                                      "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
245
                if (result == DialogResult.Yes) {
246
                    currentTab.FileTime = File.GetLastWriteTime(currentTab.filepath);
247
                    int caretLine = currentActiveTextAreaCtrl.Caret.Line;
248
                    int scrollValue = currentActiveTextAreaCtrl.VScrollBar.Value;
249
                    currentTab.textEditor.BeginUpdate();
250
                    currentTab.textEditor.LoadFile(currentTab.filepath, false, true);
251
                    currentActiveTextAreaCtrl.VScrollBar.Value = scrollValue;
252
                    currentActiveTextAreaCtrl.Caret.Line = caretLine;
253
                    currentTab.textEditor.EndUpdate();
254

255
                    currentTab.changed = false;
256
                    SetTabTextChange(currentTab.index);
257
                } else
258
                    currentTab.FileTime = File.GetLastWriteTime(currentTab.filepath);
259
                this.Activated += TextEditor_Activated;
260
            }
261
        }
262

263
        private void Save(TabInfo tab, bool close = false)
264
        {
265
            if (tab != null) {
266
                if (tab.filepath == null) {
267
                    SaveAs(tab, close);
268
                    return;
269
                }
270
                while (bwSyntaxParser.IsBusy) {
271
                    System.Threading.Thread.Sleep(50); // Avoid stomping on files while the parser is running
272
                    Application.DoEvents();
273
                }
274
                savingRunning = true;
275
                bool msg = (Path.GetExtension(tab.filename) == ".msg");
276

277
                if (Settings.autoTrailingSpaces && !msg) {
278
                    new ICSharpCode.TextEditor.Actions.RemoveTrailingWS().Execute(currentActiveTextAreaCtrl.TextArea);
279
                }
280
                if (close && tab.textEditor.Document.FoldingManager.FoldMarker.Count > 0) {
281
                    CodeFolder.SetProceduresCollapsed(tab.textEditor.Document, tab.filename);
282
                }
283
                string saveText = tab.textEditor.Text;
284
                if (msg && Settings.EncCodePage.CodePage == 866) {
285
                    saveText = saveText.Replace('\u0425', '\u0058'); // Replacement russian letter "X", to english letter
286
                }
287
                Utilities.ConvertToUnixPlatform(ref saveText);
288

289
                tab.SaveInternal(saveText, tab.textEditor.Encoding, msg, close, tab.shouldParse);
290

291
                if (tab.changed && Settings.pathHeadersFiles != null && Path.GetExtension(tab.filename).ToLowerInvariant() == ".h" &&
292
                    String.Equals(Settings.pathHeadersFiles, Path.GetDirectoryName(tab.filepath), StringComparison.OrdinalIgnoreCase)) {
293
                    GetMacros.GetGlobalMacros(Settings.pathHeadersFiles);
294
                }
295

296
                tab.changed = false;
297
                SetTabTextChange(tab.index);
298
                savingRunning = false;
299
            }
300
        }
301

302
        private void SaveAs(TabInfo tab, bool close = false)
303
        {
304
            if (tab == null)
305
                return;
306

307
            switch (Path.GetExtension(tab.filename).ToLowerInvariant()) {
308
                case ".ssl":
309
                    sfdScripts.FilterIndex = 1;
310
                    break;
311
                case ".h":
312
                    sfdScripts.FilterIndex = 2;
313
                    break;
314
                case ".msg":
315
                    sfdScripts.FilterIndex = 3;
316
                    break;
317
                default:
318
                    sfdScripts.FilterIndex = 4;
319
                    break;
320
            }
321
            sfdScripts.FileName = tab.filename;
322

323
            if (sfdScripts.ShowDialog() == DialogResult.OK) {
324
                tab.filepath = sfdScripts.FileName;
325
                tab.filename = Path.GetFileName(tab.filepath);
326
                tabControl1.TabPages[tab.index].Text = tabs[tab.index].filename;
327
                tabControl1.TabPages[tab.index].ToolTipText = tabs[tab.index].filepath;
328
                Save(tab, close);
329
                Settings.AddRecentFile(tab.filepath);
330
                string ext = Path.GetExtension(tab.filepath).ToLowerInvariant();
331
                if (Settings.enableParser && (ext == ".ssl" || ext == ".h")) {
332
                    tab.shouldParse = true;
333
                    tab.needsParse = true;
334
                    tab.parseInfo.reParseData = true;
335
                    parserLabel.Text = "Parser: Wait for update";
336
                    ParseScript();
337
                }
338
                this.Text = SSE + tab.filepath + ((pDefineStripComboBox.SelectedIndex > 0) ? " [" + pDefineStripComboBox.Text + "]" : "");
339
            }
340
        }
341

342
        private void Close(TabInfo tab)
343
        {
344
            if (tab == null | tab.index == -1)
345
                return;
346

347
            int i = tab.index;
348
            var tag = tabControl1.TabPages[i].Tag;
349
            if (tag != null)
350
                ((NodeDiagram)tag).Close(); //also close diagram editor
351

352
            while (tab.nodeFlowchartTE.Count > 0)
353
                tab.nodeFlowchartTE[0].CloseEditor(true);
354

355
            bool skip = tab.changed; // если изменен, то пропустить сохранение состояний Folds в методе KeepScriptSetting
356
            if (tab.changed) {
357
                switch (MessageBox.Show("Save changes to " + tab.filename + "?", "Message", MessageBoxButtons.YesNoCancel)) {
358
                    case DialogResult.Yes:
359
                        Save(tab, true);
360
                        if (tab.changed)
361
                            return;
362
                        break;
363
                    case DialogResult.No:
364
                        break;
365
                    default:
366
                        return;
367
                }
368
            }
369
            KeepScriptSetting(tab, skip);
370

371
            if (i == tabControl1.SelectedIndex && tabControl1.TabPages.Count >= 3) {
372
                if (previousTabIndex != -1) {
373
                    tabControl1.SelectedIndex = previousTabIndex; // переход к предыдущей выбранной вкладке
374
                }
375
                else if (tabControl1.SelectedIndex < tabControl1.TabPages.Count - 1) {
376
                    if (i > 0) tabControl1.SelectedIndex++; // переход к следущей по номеру вкладки
377
                } else {
378
                    tabControl1.SelectedIndex--;
379
                }
380
            }
381
            tabControl1.TabPages.RemoveAt(i);
382
            tabs.RemoveAt(i);
383

384
            for (int j = i; j < tabs.Count; j++) tabs[j].index--;
385

386
            for (int j = 0; j < tabs.Count; j++)
387
            {
388
                if (tabs[j].msgFileTab == tab) {
389
                    tabs[j].msgFileTab = null;
390
                    tabs[j].messages.Clear();
391
                }
392
            }
393
            tab.index = -1;
394
            previousTabIndex = -1; // сбросить после удаления вкладки
395
        }
396

397
        private bool Compile(TabInfo tab, out string msg, bool showMessages = true, bool preprocess = false, bool showIcon = true)
398
        {
399
            msg = String.Empty;
400
            if (string.Compare(Path.GetExtension(tab.filename), ".ssl", true) != 0) {
401
                if (showMessages) MessageBox.Show("You cannot compile this file.", "Compile Error");
402
                return false;
403
            }
404
            if (!Settings.ignoreCompPath && !preprocess && Settings.outputDir == null) {
405
                if (showMessages) MessageBox.Show("No output path selected.\nPlease select your scripts directory before compiling", "Compile Error");
406
                return false;
407
            }
408
            if (tab.changed) Save(tab);
409
            if (tab.changed || tab.filepath == null) return false;
410

411
            bool success = new Compiler(roundTrip).Compile(tab.filepath, out msg, tab.buildErrors, preprocess, tab.parseInfo.ShortCircuitEvaluation);
412

413
            foreach (ErrorType et in new ErrorType[] { ErrorType.Error, ErrorType.Warning, ErrorType.Message })
414
            {
415
                foreach (Error e in tab.buildErrors)
416
                {
417
                    if (e.type == et) {
418
                        dgvErrors.Rows.Add(e.type.ToString(), Path.GetFileName(e.fileName), e.line, e);
419
                        if (et == ErrorType.Error) dgvErrors.Rows[dgvErrors.Rows.Count - 1].Cells[0].Style.ForeColor = Color.Red;
420
                    }
421
                }
422
            }
423

424
            if (dgvErrors.RowCount > 0) dgvErrors.Rows[0].Cells[0].Selected = false;
425

426
            if (preprocess) return success;
427

428
            if (!success) {
429
                parserLabel.Text = "Failed to compiled: " + tab.filename;
430
                parserLabel.ForeColor = Color.Firebrick;
431
                msg += "\r\n Compilation Failed! (See the output build and errors window log for details).";
432
                CompileFail.Play();
433

434
                if (showMessages) {
435
                    if (Settings.warnOnFailedCompile) {
436
                        tabControl2.SelectedIndex = 2 - Convert.ToInt32(Settings.userCmdCompile);
437
                        MaximizeLog();
438
                    }// else
439
                     //   new CompiledStatus(false, this).ShowCompileStatus();
440
                }
441
            } else {
442
                if (showMessages && showIcon)
443
                    new CompiledStatus(true, this).ShowCompileStatus();
444
                parserLabel.Text = "Compiled: " + tab.filename + " at " + DateTime.Now.ToString("HH:mm:ss");
445
                parserLabel.ForeColor = Color.DarkGreen;
446
                msg += "\r\n Compilation Successfully!\r\n";
447
            }
448
            return success;
449
        }
450
        #endregion
451

452
        #region Tabs control functions
453

454
        internal static TabInfo CheckTabs(List<TabInfo> tabs, string filepath)
455
        {
456
            foreach (TabInfo tab in tabs)
457
            {
458
                if (String.Equals(tab.filepath, filepath, StringComparison.OrdinalIgnoreCase)) return tab;
459
            }
460
            return null;
461
        }
462

463
        internal static bool CheckTabs(string filepath, List<TabInfo> tabs)
464
        {
465
            return CheckTabs(tabs, filepath) != null;
466
        }
467

468
        private void SetTabTextChange(int i) { tabControl1.TabPages[i].ImageIndex = (tabs[i].changed ? 1 : 0); }
469

470
        private void SwitchToTab(int index)
471
        {
472
            if (tabControl1.TabPages.Count > 1) tabControl1.SelectTab(index);
473
        }
474

475
        // Called when creating a new document and when switching tabs
476
        private void tabControl1_Selected(object sender, TabControlEventArgs e)
477
        {
478
            // останавливаем таймеры парсеров
479
            intParserTimer.Stop();
480
            extParserTimer.Stop();
481

482
            if (tabControl1.SelectedIndex == -1) {
483
                currentTab = null;
484
                parserLabel.Text = (Settings.enableParser) ? "Parser: No file" : parseoff;
485
                SetFormControlsOff();
486
            } else {
487
                if (currentTab != null) {
488
                    previousTabIndex = currentTab.index;
489
                }
490
                currentTab = tabs[tabControl1.SelectedIndex];
491
                //if (!Settings.enableParser && currentTab.parseInfo != null)
492
                //    currentTab.parseInfo.parseData = false;
493

494
                if (currentTab.msgFileTab != null)
495
                    MessageFile.ParseMessages(currentTab);
496

497
                // Create or Delete Variable treeview
498
                if (!Settings.enableParser && tabControl3.TabPages.Count > 2) {
499
                    if (currentTab.parseInfo != null) {
500
                        if (!currentTab.parseInfo.parseData) {
501
                            tabControl3.TabPages.RemoveAt(1);
502
                        }
503
                    } else {
504
                        tabControl3.TabPages.RemoveAt(1);
505
                    }
506
                } else if (tabControl3.TabPages.Count < 3 && (Settings.enableParser || currentTab.parseInfo != null)) {
507
                    if (currentTab.parseInfo != null && currentTab.parseInfo.parseData) {
508
                        CreateTabVarTree();
509
                    }
510
                }
511
                if (currentTab.shouldParse) {
512
                    if (Settings.enableParser && currentTab.parseInfo.parseError && !currentTab.needsParse) {
513
                        parserLabel.Text = "Parser: Parsing script error (see parser errors log)";
514
                    } else
515
                    if (currentTab.needsParse) {
516
                        parserLabel.Text = (Settings.enableParser) ? "Parser: Waiting to update..." : parseoff;
517
                        // Update parse info
518
                        ParseScript();
519
                    } else
520
                        parserLabel.Text = (Settings.enableParser) ? "Parser: Idle" : parseoff;
521
                } else
522
                    parserLabel.Text = (Settings.enableParser) ? "Parser: Not an SSL file" : parseoff;
523

524
                UpdateLog();
525
                currentHighlightProc = null;
526
                UpdateNames(true);
527
                // text editor set focus
528
                currentActiveTextAreaCtrl.Select();
529
                ControlFormStateOn_Off();
530
                this.Text = SSE + currentTab.filepath + ((pDefineStripComboBox.SelectedIndex > 0) ? " [" + pDefineStripComboBox.Text + "]" : "");
531

532
                if (sender != null) CheckChandedFile();
533
            }
534
        }
535
        #endregion
536

537
        // Goto script text of selected Variable or Procedure in treeview
538
        public void SelectLine(string file, int line, bool pselect = false, int column = -1, int sLen = -1)
539
        {
540
            if (line <= 0) return;
541

542
            bool not_this = false;
543
            if (currentTab == null || file != currentTab.filepath) {
544
                if (Open(file, OpenType.File, false, alreadyOpen: false) == null) {
545
                    MessageBox.Show("Could not open file '" + file + "'", "Error");
546
                    return;
547
                }
548
                not_this = true;
549
            }
550
            LineSegment ls;
551
            if (line > currentDocument.TotalNumberOfLines)
552
                ls = currentDocument.GetLineSegment(currentDocument.TotalNumberOfLines - 1);
553
            else
554
                ls = currentDocument.GetLineSegment(line - 1);
555

556
            TextLocation start, end;
557
            if (column == -1 || column > ls.Length) {
558
                start = new TextLocation(0, ls.LineNumber);
559
                if (column == -1)
560
                    end = new TextLocation(ls.Length, ls.LineNumber);
561
                else
562
                    end = new TextLocation(0, ls.LineNumber);
563
            } else {
564
                column--;
565
                if (sLen == -1) {
566
                    foreach (var w in ls.Words)
567
                    {
568
                        if (w.Type != TextWordType.Word)
569
                            continue;
570
                        int pos = w.Offset + w.Length;
571
                        if ((column >= w.Offset) && (column <= pos)) {
572
                            column = w.Offset;
573
                            sLen = w.Length;
574
                            break;
575
                        }
576
                    }
577
                }
578
                start = new TextLocation(column, ls.LineNumber);
579
                end = new TextLocation(start.Column + sLen, ls.LineNumber);
580
            }
581
            // Expand or Collapse folding
582
            foreach (FoldMarker fm in currentDocument.FoldingManager.FoldMarker) {
583
                if (OnlyProcStripButton.Checked) {
584
                    if (fm.FoldType == FoldType.MemberBody || fm.FoldType == FoldType.Region) {
585
                        if (fm.StartLine == start.Line)
586
                            fm.IsFolded = false;
587
                        else if (fm.FoldType != FoldType.Region)
588
                            fm.IsFolded = true;
589
                    }
590
                } else {
591
                    if (fm.StartLine == start.Line) {
592
                        fm.IsFolded = false;
593
                        break;
594
                    }
595
                }
596
            }
597
            // Scroll and select
598
            currentActiveTextAreaCtrl.Caret.Position = start;
599
            if (not_this || !pselect || !OnlyProcStripButton.Checked)
600
                currentActiveTextAreaCtrl.SelectionManager.SetSelection(start, end);
601
            else
602
                currentActiveTextAreaCtrl.SelectionManager.ClearSelection();
603

604
            if (!not_this) {
605
                if (pselect)
606
                    currentActiveTextAreaCtrl.TextArea.TextView.FirstVisibleLine = start.Line - 1;
607
                else
608
                    currentActiveTextAreaCtrl.CenterViewOn(start.Line + 10, 0);
609
            } else
610
                currentActiveTextAreaCtrl.CenterViewOn(start.Line - 15, 0);
611
            currentTab.textEditor.Refresh();
612
        }
613

614
        #region Tree browser control
615

616
        private void CreateTabVarTree() { tabControl3.TabPages.Insert(1, VarTab); }
617

618
        private enum TreeStatus { idle, update, freeze }
619

620
        internal static Procedure currentHighlightProc = null;
621
        private  static TreeNode currentHighlightNode = null;
622
        private bool updateHighlightPocedure = true;
623

624
        // подсветить процедуру в дереве
625
        private void HighlightCurrentPocedure(int curLine)
626
        {
627
            Procedure proc;
628
            if (curLine == -2) {
629
                proc = currentHighlightProc;
630
                currentHighlightProc = null;
631
                currentHighlightNode = null;
632
            } else {
633
                proc = currentTab.parseInfo.GetProcedureFromPosition(curLine);
634
            }
635
            if (proc != null && proc != currentHighlightProc) {
636
                if (currentHighlightProc != null && currentHighlightProc.name.Equals(proc.name, StringComparison.OrdinalIgnoreCase)) return;
637
                TreeNodeCollection nodes;
638
                if (ProcTree.Nodes.Count > 1)
639
                    nodes = ProcTree.Nodes[1].Nodes;
640
                else
641
                    nodes = ProcTree.Nodes[0].Nodes; // for parser off
642
                foreach (TreeNode node in nodes)
643
                {
644
                    string name = ((Procedure)node.Tag).name;
645
                    if (name == proc.name) {
646
                        node.Text = node.Text.Insert(0, "► ");
647
                        node.ForeColor = ColorTheme.HighlightProcedureTree;
648
                        if (currentHighlightNode != null) {
649
                            currentHighlightNode.ForeColor = ProcTree.ForeColor;
650
                            currentHighlightNode.Text = currentHighlightNode.Text.Substring(2);
651
                        }
652
                        currentHighlightProc = proc;
653
                        currentHighlightNode = node;
654
                        break;
655
                    }
656
                }
657
            } else if (currentHighlightProc != null && currentHighlightProc != proc) {
658
                currentHighlightNode.Text = currentHighlightNode.Text.Substring(2);
659
                currentHighlightNode.ForeColor = ProcTree.ForeColor;
660
                currentHighlightProc = null;
661
                currentHighlightNode = null;
662
            }
663
        }
664

665
        // Create names for procedures and variables in treeview
666
        private void UpdateNames(bool newCreate = false)
667
        {
668
            if (ProcTree.Tag != null && (TreeStatus)ProcTree.Tag == TreeStatus.freeze) {
669
                ProcTree.Tag = TreeStatus.idle;
670
                return;
671
            }
672

673
            if (currentTab == null || !currentTab.shouldParse || currentTab.parseInfo == null) return;
674

675
            object selectedNode = null;
676
            if (ProcTree.SelectedNode != null)
677
                selectedNode = ProcTree.SelectedNode.Tag;
678

679
            ProcTree.Tag = TreeStatus.update;
680

681
            string scrollNode = null;
682
            if (!newCreate && ProcTree.Nodes.Count != 0) {
683
                for (int i = ProcTree.Nodes.Count -1; i >= 0; i--)
684
                {
685
                    if (!ProcTree.Nodes[i].IsExpanded) continue;
686
                    for (int j = ProcTree.Nodes[i].Nodes.Count - 1; j >= 0; j--)
687
                    {
688
                        if (ProcTree.Nodes[i].Nodes[j].IsVisible) {
689
                            scrollNode = ProcTree.Nodes[i].Nodes[j].Name;
690
                            break;
691
                        }
692
                    }
693
                    if (scrollNode != null) break;
694
                }
695
            }
696
            ProcTree.BeginUpdate();
697
            ProcTree.Nodes.Clear();
698

699
            TreeNode rootNode;
700
            foreach (var s in TREEPROCEDURES) {
701
                rootNode = ProcTree.Nodes.Add(s, s);
702
                rootNode.ForeColor = Color.DodgerBlue;
703
                rootNode.NodeFont = new Font("Arial", 9F, FontStyle.Bold, GraphicsUnit.Point);
704
            }
705
            ProcTree.Nodes[0].ToolTipText = "Procedures declared and located in headers files." + treeTipProcedure;
706
            ProcTree.Nodes[0].Tag = 0; // global tag
707
            ProcTree.Nodes[1].ToolTipText = "Procedures declared and located in this script." + treeTipProcedure;
708
            ProcTree.Nodes[1].Tag = 1; // local tag
709

710
            foreach (Procedure p in currentTab.parseInfo.procs) {
711
                // TODO: Это нужно только для отключенного парсера?
712
                if (!Settings.enableParser && p.d.end == -1) continue; //skip imported or broken procedures
713

714
                TreeNode tn = new TreeNode((!ViewArgsStripButton.Checked)? p.name : p.ToString(false));
715
                tn.Name = p.name;
716
                tn.Tag = p;
717
                foreach (Variable var in p.variables) {
718
                    TreeNode tn2 = new TreeNode(var.name);
719
                    tn2.Name = var.name;
720
                    tn2.Tag = var;
721
                    tn2.ToolTipText = var.ToString();
722
                    tn.Nodes.Add(tn2);
723
                }
724
                if (p.filename.Equals(currentTab.filename, StringComparison.OrdinalIgnoreCase) == false || p.IsImported) {
725
                    tn.ToolTipText = p.ToString() + "\ndeclarate file: " + p.filename;
726
                    ProcTree.Nodes[0].Nodes.Add(tn);
727
                    ProcTree.Nodes[0].Expand();
728
                } else {
729
                    tn.ToolTipText = p.ToString();
730
                    ProcTree.Nodes[1].Nodes.Add(tn);
731
                    ProcTree.Nodes[1].Expand();
732
                }
733
            }
734

735
            if (!Settings.enableParser && !currentTab.parseInfo.parseData) {
736
                ProcTree.Nodes.RemoveAt(0);
737
                if (tabControl3.TabPages.Count > 2) // удалить и вкладку если отсутсвует информация
738
                    tabControl3.TabPages.RemoveAt(1);
739
            } else {
740
                VarTree.BeginUpdate();
741
                VarTree.Nodes.Clear();
742

743
                foreach (var s in TREEVARIABLES) {
744
                    rootNode = VarTree.Nodes.Add(s);
745
                    rootNode.ForeColor = Color.DodgerBlue;
746
                    rootNode.NodeFont = new Font("Arial", 9F, FontStyle.Bold, GraphicsUnit.Point);
747
                }
748
                VarTree.Nodes[0].ToolTipText = "Variables declared and located in headers files." + treeTipVariable;
749
                VarTree.Nodes[1].ToolTipText = "Variables declared and located in this script." + treeTipVariable;
750

751
                foreach (Variable var in currentTab.parseInfo.vars) {
752
                    TreeNode tn = new TreeNode(var.name);
753
                    tn.Tag = var;
754
                    if (var.filename.Equals(currentTab.filename, StringComparison.OrdinalIgnoreCase) == false) {
755
                        tn.ToolTipText = var.ToString() + "\ndeclarate file: " + var.filename;
756
                        VarTree.Nodes[0].Nodes.Add(tn);
757
                        VarTree.Nodes[0].Expand();
758
                    } else {
759
                        tn.ToolTipText = var.ToString();
760
                        VarTree.Nodes[1].Nodes.Add(tn);
761
                        VarTree.Nodes[1].Expand();
762
                    }
763
                }
764
                if (VarTree.Nodes[0].Nodes.Count == 0) VarTree.Nodes[0].ForeColor = Color.Gray;
765
                if (VarTree.Nodes[1].Nodes.Count == 0) VarTree.Nodes[1].ForeColor = Color.Gray;
766

767
                foreach (TreeNode node in VarTree.Nodes)
768
                    SetNodeCollapseStatus(node);
769

770
                VarTree.EndUpdate();
771
            }
772
            foreach (TreeNode node in ProcTree.Nodes)
773
                SetNodeCollapseStatus(node);
774

775
            if (ProcTree.Nodes[0].Nodes.Count == 0) ProcTree.Nodes[0].ForeColor = Color.Gray;
776
            if (ProcTree.Nodes.Count > 1) {
777
                if (ProcTree.Nodes[1].Nodes.Count == 0)
778
                    ProcTree.Nodes[1].ForeColor = Color.Gray;
779
                //ProcTree.Nodes[1].EnsureVisible();
780
            }
781

782
            if (selectedNode != null) {
783
                TreeNode[] nodes = null;
784
                if (selectedNode is Procedure)
785
                    nodes = ProcTree.Nodes.Find(((Procedure)selectedNode).name, true);
786
                else if (selectedNode is Variable)
787
                    nodes = ProcTree.Nodes.Find(((Variable)selectedNode).name, true);
788
                if (nodes != null && nodes.Length > 0)
789
                    ProcTree.SelectedNode = nodes[0];
790
            }
791
            ProcTree.EndUpdate();
792
            HighlightCurrentPocedure((currentHighlightProc == null) ? currentActiveTextAreaCtrl.Caret.Line : -2);
793

794
            // scroll to node
795
            if (scrollNode != null) {
796
                foreach (TreeNode nodes in ProcTree.Nodes) {
797
                    foreach (TreeNode node in nodes.Nodes) {
798
                        if (node.Name == scrollNode) {
799
                            if (node.PrevNode != null) node.PrevNode.EnsureVisible();
800
                            scrollNode = null;
801
                            break;
802
                        }
803
                    }
804
                    if (scrollNode == null) break;
805
                }
806
                if (scrollNode != null && currentHighlightNode != null) currentHighlightNode.EnsureVisible();
807
            }
808
            ProcTree.Tag = TreeStatus.idle;
809
        }
810

811
        // обновляет процедуры в nodes.Tag
812
        private void UpdateNodesTags()
813
        {
814
            // Avoid stomping on files while the parser is running
815
            while (parserIsRunning) System.Threading.Thread.Sleep(10);
816

817
            TreeNodeCollection nodes;
818
            if (ProcTree.Nodes.Count > 1)
819
                nodes = ProcTree.Nodes[1].Nodes;
820
            else
821
                nodes = ProcTree.Nodes[0].Nodes; // for parser off
822

823
            for (int i = 0; i < nodes.Count; i++)
824
            {
825
                Procedure np = nodes[i].Tag as Procedure;
826
                if (np == null) continue;
827

828
                foreach (Procedure p in currentTab.parseInfo.procs)
829
                {
830
                    if (p.Name == np.Name) {
831
                        //if (p.d.declared != np.d.declared)
832
                        nodes[i].Tag = p;
833
                        break;
834
                    }
835
                }
836
            }
837
        }
838

839
        private string GetCorrectNodeKeyName(TreeNode node)
840
        {
841
            string nodeKey = node.FullPath;
842
            int n = nodeKey.IndexOf('\\');
843
            if (n != -1) nodeKey = nodeKey.Remove(n + 1) + node.Name;
844
            return nodeKey;
845
        }
846

847
        private void SetNodeCollapseStatus(TreeNode node)
848
        {
849
            string nodeKey = GetCorrectNodeKeyName(node);
850
            if (currentTab.treeExpand.ContainsKey(nodeKey)) {
851
                    if (currentTab.treeExpand[nodeKey])
852
                        node.Collapse();
853
                    else
854
                        node.Expand();
855
            }
856
            foreach (TreeNode nd in node.Nodes) SetNodeCollapseStatus(nd);
857
        }
858

859
        bool treeExpandCollapse = false;
860

861
        private void TreeExpandCollapse(TreeViewEventArgs e)
862
        {
863
            TreeNode tn = e.Node;
864
            if (tn == null) return;
865

866
            bool collapsed = (e.Action == TreeViewAction.Collapse);
867
            string nodeKey = GetCorrectNodeKeyName(tn);
868
            if (!currentTab.treeExpand.ContainsKey(nodeKey))
869
                currentTab.treeExpand.Add(nodeKey, collapsed);
870
            else
871
                currentTab.treeExpand[nodeKey] = collapsed;
872
            if (tn.Parent == null) treeExpandCollapse = true;
873
        }
874

875
        private void TreeView_DClickMouse(object sender, MouseEventArgs e) {
876
            if (e.X <= 20) return;
877
            TreeNode node = (!treeExpandCollapse) ? ((TreeView)sender).GetNodeAt(e.Location) : null;
878
            treeExpandCollapse = false;
879
            if (node != null) TreeView_ClickBehavior(node);
880
        }
881

882
        // Click on node tree Procedures/Variables
883
        private void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
884
        {
885
            if (!ctrlKeyPress || e.Action == TreeViewAction.Unknown) return;
886
            TreeView_ClickBehavior(e.Node);
887
        }
888

889
        private void TreeView_ClickBehavior(TreeNode node)
890
        {
891
            string file = null, name = null;
892
            int line = 0;
893
            bool pSelect = false;
894
            if (node.Tag is Variable) {
895
                Variable var = (Variable)node.Tag;
896
                if (!ctrlKeyPress) {
897
                    file = var.fdeclared;
898
                    line = var.d.declared;
899
                } else {
900
                    name = var.name;
901
                }
902
            } else if (node.Tag is Procedure) {
903
                Procedure proc = (Procedure)node.Tag;
904
                if (!ctrlKeyPress) {
905
                    file = proc.fstart;
906
                    line = proc.d.start;
907
                    if (line == -1 || file == null) { // goto declared
908
                        file = proc.fdeclared;
909
                        line = proc.d.declared;
910
                    }
911
                    pSelect = true;
912
                } else {
913
                    name = proc.name;
914
                }
915
            }
916
            if (file != null) {
917
                SelectLine(file, line, pSelect);
918
            } else if (name != null) {
919
                Utilities.InsertText(name, currentActiveTextAreaCtrl);
920
            }
921
        }
922

923
        void Tree_AfterExpandCollapse(object sender, TreeViewEventArgs e)
924
        {
925
            if ((TreeStatus)ProcTree.Tag == TreeStatus.idle)
926
                TreeExpandCollapse(e);
927
        }
928

929
        private void ProcTree_Leave(object sender, EventArgs e)
930
        {
931
            ProcTree.SelectedNode = null;
932
        }
933

934
        private void ProcTree_MouseDown(object sender, MouseEventArgs e)
935
        {
936
            dbClick = false;
937
            if (e.Button == MouseButtons.Right || e.Button == MouseButtons.Left && e.Clicks == 2) {
938
                TreeNode tn = ProcTree.GetNodeAt(e.X, e.Y);
939
                if (tn != null) dbClick = true;
940
                if (e.Button == MouseButtons.Right) {
941
                    ProcTree.SelectedNode = tn;
942
                }
943
            }
944
        }
945

946
        private void ProcTree_BeforeExpandCollapse(object sender, TreeViewCancelEventArgs e) {
947
            if (e.Action == TreeViewAction.Expand || e.Action == TreeViewAction.Collapse) {
948
                 if (dbClick || ctrlKeyPress) {
949
                    if (e.Node.Tag is Procedure) e.Cancel = true;
950
                    dbClick = false;
951
                }
952
            }
953
        }
954
        #endregion
955

956
        #region Refactoring Control
957

958
        private void UpdateEditorToolStripMenu()
959
        {
960
            TextLocation tl = currentActiveTextAreaCtrl.Caret.Position;
961

962
            // includes
963
            string line = TextUtilities.GetLineAsString(currentDocument, tl.Line).Trim();
964
            if (!line.TrimStart().StartsWith(ParserInternal.INCLUDE)) {
965
                openIncludeToolStripMenuItem.Enabled = false;
966
            }
967

968
            // skip for specific color text
969
            if (ColorTheme.CheckColorPosition(currentDocument, tl))
970
                return;
971

972
            //Refactor name
973
            if (!Settings.enableParser) {
974
                renameToolStripMenuItem.Text += ": Disabled";
975
                renameToolStripMenuItem.ToolTipText = "It is required to enable the parser in the settings.";
976
                return;
977
            }
978

979
            if (currentTab.parseInfo != null) {
980
                NameType itemType = NameType.None;
981
                IParserInfo item = null;
982

983
                string word = TextUtilities.GetWordAt(currentDocument, currentDocument.PositionToOffset(tl));
984
                item = currentTab.parseInfo.Lookup(word, currentTab.filepath, tl.Line + 1);
985
                if (item != null) {
986
                    itemType = item.Type();
987
                    renameToolStripMenuItem.Tag = item;
988
                    if (!currentTab.needsParse)
989
                        renameToolStripMenuItem.Enabled = true;
990
                }
991

992
                switch (itemType)
993
                {
994
                    case NameType.LVar: // variable procedure
995
                    case NameType.GVar: // variable script
996
                        findReferencesToolStripMenuItem.Enabled = true;
997
                        findDeclerationToolStripMenuItem.Enabled = true;
998
                        findDefinitionToolStripMenuItem.Enabled = false;
999
                        renameToolStripMenuItem.Text += (itemType == NameType.LVar)
1000
                                                        ? (((Variable)item).IsArgument ? ": Argument variable" : ": Local variable")
1001
                                                        : ": Script variable";
1002
                        if (item.IsExported)
1003
                            renameToolStripMenuItem.ToolTipText = "Note: Renaming exported variables will result in an error in the scripts using this variable.";
1004
                        break;
1005

1006
                    case NameType.Proc:
1007
                        findReferencesToolStripMenuItem.Enabled = currentTab.parseInfo.parseData; //true;
1008
                        findDeclerationToolStripMenuItem.Enabled = true;
1009
                        findDefinitionToolStripMenuItem.Enabled = !item.IsImported;
1010
                        renameToolStripMenuItem.Text += ": Procedure";
1011
                        if (item.IsExported)
1012
                            renameToolStripMenuItem.ToolTipText = "Note: Renaming exported procedures will result in an error in the scripts using this procedure.";
1013
                        break;
1014

1015
                    case NameType.Macro:
1016
                        findReferencesToolStripMenuItem.Enabled = false;
1017
                        findDeclerationToolStripMenuItem.Enabled = true;
1018
                        findDefinitionToolStripMenuItem.Enabled = false;
1019
                        Macro macro = (Macro)item;
1020
                        if (!ProgramInfo.macrosGlobal.ContainsKey(macro.token) && macro.fdeclared == currentTab.filepath)
1021
                            renameToolStripMenuItem.Text += ": Local macro";
1022
                        else
1023
                            renameToolStripMenuItem.Text += ": Global macro";
1024
                        break;
1025

1026
                    default:
1027
                        if (!currentTab.parseInfo.parseData) {
1028
                            renameToolStripMenuItem.Text += ": Out of data";
1029
                            renameToolStripMenuItem.ToolTipText = "The parser data is missing.";
1030
                        } else
1031
                            renameToolStripMenuItem.Text += ": None";
1032
                        break;
1033
                }
1034
                if (item != null && item.IsImported) {
1035
                    renameToolStripMenuItem.Enabled = !item.IsImported;
1036
                    renameToolStripMenuItem.ToolTipText = "The feature is disabled, will be available in future versions.";
1037
                }
1038
            } else {
1039
                renameToolStripMenuItem.Text += ": Out of data";
1040
                renameToolStripMenuItem.ToolTipText = "The parser data is missing.";
1041
            }
1042
        }
1043

1044
        private void editorMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
1045
        {
1046
            if (currentTab == null /*&& !treeView1.Focused*/) {
1047
                e.Cancel = true;
1048
                return;
1049
            }
1050
            if (currentActiveTextAreaCtrl.SelectionManager.HasSomethingSelected) {
1051
                highlightToolStripMenuItem.Visible = true;
1052
                renameToolStripMenuItem.Visible = false;
1053
            } else {
1054
                highlightToolStripMenuItem.Visible = false;
1055
                renameToolStripMenuItem.Visible = true;
1056
                renameToolStripMenuItem.Text = "Rename";
1057
                renameToolStripMenuItem.Enabled = false;
1058
                renameToolStripMenuItem.ToolTipText = (currentTab.needsParse) ? "Waiting get parsing data..." : "";
1059
            }
1060
            //openIncludeToolStripMenuItem.Enabled = false;
1061
            findReferencesToolStripMenuItem.Enabled = false;
1062
            findDeclerationToolStripMenuItem.Enabled = false;
1063
            findDefinitionToolStripMenuItem.Enabled = false;
1064
            UpdateEditorToolStripMenu();
1065
        }
1066

1067
        private void editorMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)
1068
        {
1069
            findReferencesToolStripMenuItem.Enabled = true;
1070
            findDeclerationToolStripMenuItem.Enabled = true;
1071
            findDefinitionToolStripMenuItem.Enabled = true;
1072
            openIncludeToolStripMenuItem.Enabled = true;
1073
        }
1074
        #endregion
1075

1076
        private void AssociateMsg(TabInfo tab, bool create)
1077
        {
1078
            if (tab.filepath == null || tab.msgFileTab != null)
1079
                return;
1080

1081
            if (Settings.autoOpenMsgs && msgAutoOpenEditorStripMenuItem.Checked && !create) {
1082
                MessageEditor.MessageEditorInit(tab, this);
1083
                Focus();
1084
            } else {
1085
                string path;
1086
                if (MessageFile.GetAssociatePath(tab, create, out path)) {
1087
                    tab.msgFilePath = path;
1088
                    tab.msgFileTab = Open(tab.msgFilePath, OpenType.File, false);
1089
                }
1090
            }
1091
        }
1092

1093
        public void AcceptMsgLine(string line)
1094
        {
1095
            if (currentTab != null) {
1096
                Utilities.InsertText(line, currentActiveTextAreaCtrl);
1097
                this.Focus();
1098
            }
1099
        }
1100

1101
        private void UpdateRecentList()
1102
        {
1103
            string[] items = Settings.GetRecent();
1104
            int count = Open_toolStripSplitButton.DropDownItems.Count-1;
1105
            for (int i = 3; i <= count; i++) {
1106
                Open_toolStripSplitButton.DropDownItems.RemoveAt(3);
1107
            }
1108
            for (int i = items.Length - 1; i >= 0; i--) {
1109
                Open_toolStripSplitButton.DropDownItems.Add(items[i], null, recentItem_Click);
1110
            }
1111
        }
1112

1113
        private void AddSearchTextComboBox(string world)
1114
        {
1115
            if (world.Length == 0) return;
1116

1117
            bool addSearchText = true;
1118
            foreach (var item in SearchTextComboBox.Items)
1119
            {
1120
                if (world == item.ToString()) {
1121
                    addSearchText = false;
1122
                    break;
1123
                }
1124
            }
1125
            if (addSearchText) {
1126
                SearchTextComboBox.Items.Insert(0, world);
1127
                if (sf != null) sf.cbSearch.Items.Insert(0, world); // add to advanced search form
1128
            }
1129
        }
1130

1131
        private void KeepScriptSetting(TabInfo tab, bool skip)
1132
        {
1133
            if (!skip && tab.filepath != null && tab.textEditor.Document.FoldingManager.FoldMarker.Count > 0) {
1134
                CodeFolder.SetProceduresCollapsed(tab.textEditor.Document, tab.filename);
1135
            }
1136
            // store last script position
1137
            if (Path.GetExtension(tab.filepath).ToLowerInvariant() == ".ssl" && tab.filename != unsaved)
1138
                Settings.SetLastScriptPosition(tab.filename.ToLowerInvariant(), tab.textEditor.ActiveTextAreaControl.Caret.Line);
1139
        }
1140

1141
        #region Dialog System
1142

1143
        private void dialogNodesDiagramToolStripMenuItem_Click(object sender, EventArgs e)
1144
        {
1145
            if (currentTab == null || currentTab.parseInfo == null) return;
1146

1147
            if (!Path.GetExtension(currentTab.filename).Equals(".ssl", StringComparison.OrdinalIgnoreCase)) {
1148
                MessageBox.Show(MessageFile.WrongTypeFile, currentTab.filename);
1149
                return;
1150
            }
1151

1152
            var tag = tabControl1.TabPages[currentTab.index].Tag;
1153
            if (tag != null) {
1154
                NodeDiagram ndForm = ((NodeDiagram)tag);
1155
                if (ndForm.WindowState == FormWindowState.Minimized)
1156
                    ndForm.WindowState = FormWindowState.Maximized;
1157
                ndForm.Activate();
1158
                return;
1159
            }
1160

1161
            string msgPath;
1162
            if (!MessageFile.GetAssociatePath(currentTab, false, out msgPath)) {
1163
                MessageBox.Show(MessageFile.MissingFile, "Nodes Flowchart Editor");
1164
                return;
1165
            }
1166
            ScriptEditor.TextEditorUI.Function.DialogFunctionsRules.BuildOpcodesDictionary();
1167

1168
            currentTab.msgFilePath = msgPath;
1169

1170
            NodeDiagram NodesView = new NodeDiagram(currentTab);
1171
            NodesView.FormClosed += delegate { tabControl1.TabPages[currentTab.index].Tag = null; };
1172
            NodesView.ChangeNodes += delegate { ForceParseScript(); }; //Force Parse Script;
1173
            NodesView.Show();
1174

1175
            tabControl1.TabPages[currentTab.index].Tag = NodesView;
1176

1177
            this.ParserUpdatedInfo += delegate
1178
            {
1179
                if (NodesView != null)
1180
                    NodesView.NeedUpdate = true;
1181
            };
1182
        }
1183

1184
        private void previewDialogToolStripMenuItem_Click(object sender, EventArgs e)
1185
        {
1186
            if (currentTab == null || currentTab.parseInfo == null) return;
1187

1188
            if (!Path.GetExtension(currentTab.filename).Equals(".ssl", StringComparison.OrdinalIgnoreCase)) {
1189
                MessageBox.Show(MessageFile.WrongTypeFile, currentTab.filename) ;
1190
                return;
1191
            }
1192

1193
            string msgPath;
1194
            if (!MessageFile.GetAssociatePath(currentTab, false, out msgPath)) {
1195
                MessageBox.Show(MessageFile.MissingFile, "Dialog Preview");
1196
                return;
1197
            }
1198
            currentTab.msgFilePath = msgPath;
1199

1200
            ScriptEditor.TextEditorUI.Function.DialogFunctionsRules.BuildOpcodesDictionary();
1201

1202
            DialogPreview DialogView = new DialogPreview(currentTab);
1203
            if (!DialogView.InitReady) {
1204
                DialogView.Dispose();
1205
                MessageBox.Show("This script does not contain dialog procedures.", "Dialog Preview");
1206
            }
1207
            else
1208
                DialogView.Show(this);
1209
        }
1210

1211
        private void dialogFunctionConfigToolStripMenuItem_Click(object sender, EventArgs e) {
1212
            ScriptEditor.TextEditorUI.Function.DialogFunctionsRules.BuildOpcodesDictionary();
1213
            new ScriptEditor.TextEditorUI.Function.FunctionsRules().ShowDialog(this);
1214
        }
1215

1216
        private void editNodeCodeToolStripMenuItem_Click(object sender, EventArgs e)
1217
        {
1218
            Procedure proc = (Procedure)ProcTree.SelectedNode.Tag;
1219

1220
            if (currentTab.messages.Count == 0) {
1221
                string msgPath;
1222
                if (!MessageFile.GetAssociatePath(currentTab, false, out msgPath)) {
1223
                    MessageBox.Show(MessageFile.MissingFile, "Node Editor");
1224
                    return;
1225
                }
1226
                currentTab.msgFilePath = msgPath;
1227
                MessageFile.ParseMessages(currentTab, File.ReadAllLines(currentTab.msgFilePath, Settings.EncCodePage));
1228
            }
1229

1230
            foreach (var nodeTE in currentTab.nodeFlowchartTE)
1231
            {
1232
                if (nodeTE.NodeName == proc.name) {
1233
                    nodeTE.Activate();
1234
                    return;
1235
                }
1236
            }
1237

1238
            ScriptEditor.TextEditorUI.Function.DialogFunctionsRules.BuildOpcodesDictionary();
1239

1240
            FlowchartTE nodeEditor = new FlowchartTE(proc, currentTab);
1241
            nodeEditor.Disposed += delegate(object s, EventArgs e1) { currentTab.nodeFlowchartTE.Remove((FlowchartTE)s); };
1242
            nodeEditor.ApplyCode += new EventHandler<FlowchartTE.CodeArgs>(nodeEditor_ApplyCode);
1243
            nodeEditor.ShowEditor(this);
1244

1245
            currentTab.nodeFlowchartTE.Add(nodeEditor);
1246
        }
1247

1248
        private void nodeEditor_ApplyCode(object sender, FlowchartTE.CodeArgs e)
1249
        {
1250
            if (e.Change) {
1251
                if (Utilities.ReplaceProcedureCode(currentDocument, currentTab.parseInfo, e.Name, e.Code)) {
1252
                    MessageBox.Show("In the source script, there is no dialog node with this name.", "Apply code error");
1253
                    return;
1254
                }
1255
                e.Change = false;
1256
                ForceParseScript();
1257
            }
1258
        }
1259
        #endregion
1260

1261
        #region Misc Control
1262

1263
        private void ShowTabsSpaces()
1264
        {
1265
            if (currentTab == null)
1266
                return;
1267

1268
            if (Path.GetExtension(currentTab.filename).ToLowerInvariant() != ".msg")
1269
                currentDocument.TextEditorProperties.ShowSpaces = showTabsAndSpacesToolStripMenuItem.Checked;
1270

1271
            currentDocument.TextEditorProperties.ShowTabs = showTabsAndSpacesToolStripMenuItem.Checked;;
1272
            currentTab.textEditor.Refresh();
1273
        }
1274

1275
        private void SizeFontToString()
1276
        {
1277
            // base 10 (min 5,  max 30)
1278
            float percent = (float)((10 + Settings.sizeFont) / 10.0f) * 100.0f;
1279
            FontSizeStripStatusLabel.Text = percent.ToString() + '%';
1280

1281
            if (currentTab != null) {
1282
                var fontName = currentTab.textEditor.TextEditorProperties.Font.Name;
1283
                var font = new Font(fontName, 10.0f + Settings.sizeFont, FontStyle.Regular);
1284
                currentTab.textEditor.TextEditorProperties.Font = font;
1285
                currentTab.textEditor.Refresh();
1286
                currentActiveTextAreaCtrl.Caret.RecreateCaret();
1287
            }
1288
        }
1289

1290
        public void SetFocusDocument()
1291
        {
1292
            TextArea_SetFocus(null, null);
1293
        }
1294

1295
        private Control FindFocus(Control cnt)
1296
        {
1297
            if (cnt == null)
1298
                return null;
1299

1300
            foreach (Control c in cnt.Controls)
1301
            {
1302
                if (c.CanFocus && c.Focused)
1303
                    return c;
1304

1305
                Control fc = FindFocus(c);
1306

1307
                if (fc != null)
1308
                    return fc;
1309
            }
1310
            return null;
1311
        }
1312

1313
        private void SetProjectFolderText()
1314
        {
1315
            tslProject.Text = "Project: " + Settings.solutionProjectFolder;
1316
            tslProject.Enabled = true;
1317
        }
1318
        #endregion
1319

1320
        #region Log
1321

1322
        private void MaximizeLog()
1323
        {
1324
            if (currentTab == null && splitContainer1.Panel2Collapsed) {
1325
                showLogWindowToolStripMenuItem.Checked = true;
1326
                splitContainer1.Panel2Collapsed = false;
1327
            }
1328
            if (minimizeLogSize == 0) return;
1329

1330
            if (Settings.editorSplitterPosition == -1) {
1331
                Settings.editorSplitterPosition = Size.Height - (Size.Height / 4);
1332
            }
1333
            splitContainer1.SplitterDistance = Settings.editorSplitterPosition;
1334
            minimizeLogSize = 0;
1335
        }
1336

1337
        private void UpdateLog()
1338
        {
1339
            if (autoRefreshToolStripMenuItem.Checked &&
1340
               (currentTab.parserErrors.Count > 0 || currentTab.buildErrors.Count > 0))
1341
            {
1342
                OutputErrorLog(currentTab);
1343
            } else {
1344
                if (Settings.enableParser)
1345
                    tbOutputParse.Text = currentTab.parserLog;
1346

1347
                if (currentTab.buildLog != null)
1348
                    tbOutput.Text = currentTab.buildLog;
1349
            }
1350
        }
1351

1352
        public void PrintBuildLog(object sender, System.Diagnostics.DataReceivedEventArgs e)
1353
        {
1354
            tbOutput.BeginInvoke((MethodInvoker)(() =>
1355
                tbOutput.AppendText(e.Data + Environment.NewLine))
1356
            );
1357
        }
1358
        #endregion
1359
    }
1360
}
1361

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.