Sfall-ScriptEditor
623 строки · 25.4 Кб
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Drawing.Text;
5using System.IO;
6using System.Text;
7using System.Windows.Forms;
8
9namespace ScriptEditor
10{
11public enum SavedWindows { Main, Count }
12public enum EncodingType : byte { Default, OEM866 }
13
14public static class Settings
15{
16public static Encoding EncCodePage;
17public static Size HeadersFormSize;
18
19public static readonly string ProgramFolder = Application.StartupPath;
20public static readonly string SettingsFolder = Path.Combine(ProgramFolder, "settings");
21public static readonly string ResourcesFolder = Path.Combine(ProgramFolder, "resources");
22public static readonly string DescriptionsFolder = Path.Combine(ProgramFolder, "descriptions");
23public static readonly string scriptTempPath = Path.Combine(ProgramFolder, "scrTemp");
24
25private static readonly string RecentPath = Path.Combine(SettingsFolder, "recent.dat");
26private static readonly string SettingsPath = Path.Combine(SettingsFolder, "settings.dat");
27
28public static readonly string SearchHistoryPath = Path.Combine(SettingsFolder, "SearchHistory.ini");
29public static readonly string SearchFoldersPath = Path.Combine(SettingsFolder, "SearchPaths.ini");
30public static readonly string PreprocDefPath = Path.Combine(SettingsFolder, "PreprocDefine.ini");
31
32public static PrivateFontCollection Fonts = new PrivateFontCollection();
33public static readonly Dictionary<string, float> FontAdjustSize = new Dictionary<string, float>() {
34{"Anonymous Pro", 10.5f}, {"Consolas", 10.5f}, {"Cousine", 10.5f},
35{"InconsolataCyr", 11.0f}, {"InputMono", 9.5f}, {"InputMonoCondensed", 9.5f},
36{"Liberation Mono", 10.25f}, {"Meslo LG S DZ", 9.75f}, {"Ubuntu Mono", 11.75f}
37};
38
39public static List<string> searchListPath = new List<string>();
40public static readonly List<string> msgListPath = new List<string>();
41
42private static List<string> recent = new List<string>();
43private static List<string> recentMsg = new List<string>();
44private static Dictionary<string, ushort> scriptPosition = new Dictionary<string, ushort>();
45private static readonly WindowPos[] windowPositions = new WindowPos[(int)SavedWindows.Count];
46
47const int MAX_RECENT = 40;
48
49public static byte optimize = 1;
50public static bool showWarnings = true;
51public static bool showDebug = true; //show additional information when compiling script
52public static bool searchIncludePath = true;
53public static bool warnOnFailedCompile = true;
54public static bool multiThreaded = true;
55public static bool autoOpenMsgs = false;
56public static bool openMsgEditor = false;
57public static string outputDir;
58public static string pathScriptsHFile;
59public static string lastMassCompile;
60public static string lastSearchPath;
61public static int editorSplitterPosition = -1;
62public static int editorSplitterPosition2 = -1;
63public static string language = "english";
64public static bool tabsToSpaces = true;
65public static int tabSize = 3;
66public static bool enableParser = true;
67public static bool shortCircuit = false;
68public static bool autocomplete = true;
69public static bool showLog = true;
70public static byte hintsLang = 0;
71public static byte highlight = 2; // 0 = Original, 1 = FGeck, 2 = Dark
72public static byte encoding = (byte)EncodingType.Default; // 0 = DEFAULT, 1 = DOS(cp866)
73public static bool allowDefine = false;
74public static bool parserWarn = true;
75public static bool useWatcom = false;
76public static string preprocDef = null;
77public static bool ignoreCompPath = true;
78public static bool userCmdCompile = false;
79public static bool msgHighlightComment = true;
80public static byte msgHighlightColor = 0;
81public static byte msgFontSize = 0;
82public static string pathHeadersFiles;
83public static bool associateID = false;
84public static bool useMcpp = true;
85public static bool autocompleteColor = true;
86public static bool autoInputPaired = true;
87public static bool showTabsChar = false;
88public static bool autoTrailingSpaces = true;
89public static bool showTips = true;
90public static bool shortDesc = false;
91public static byte selectFont = 11; // 0 - default
92public static sbyte sizeFont = 0; // 0 - default
93public static bool showVRuler = true;
94public static bool storeLastPosition = true;
95public static bool saveScriptUTF8 = false;
96public static bool decompileF1 = false;
97public static bool oldDecompile = false;
98public static bool winAPITextRender = true;
99public static int compileBackwardMode = 0;
100private static string ExternalEditorExePath;
101public static bool searchIgnoreCase = false;
102public static bool searchWholeWord = false;
103public static string solutionProjectFolder;
104
105// for Flowchart
106public static bool autoUpdate = false;
107public static bool autoSaveChart = true;
108public static bool autoArrange = false;
109public static bool woExitNode = true;
110public static bool autoHideNodes = false;
111
112// no saved settings
113public static bool msgLipColumn = false;
114public static bool firstRun = false;
115
116public static void SetupWindowPosition(SavedWindows window, Form f)
117{
118WindowPos wp = windowPositions[(int)window];
119if (wp.width == 0)
120return;
121f.Location = new System.Drawing.Point(wp.x, wp.y);
122if (wp.maximized)
123f.WindowState = FormWindowState.Maximized;
124else
125f.ClientSize = new System.Drawing.Size(wp.width, wp.height);
126f.StartPosition = FormStartPosition.Manual;
127}
128
129public static void SaveWindowPosition(SavedWindows window, Form f)
130{
131WindowPos wp = new WindowPos();
132wp.maximized = f.WindowState == FormWindowState.Maximized;
133wp.x = f.Location.X;
134wp.y = f.Location.Y;
135wp.width = f.ClientSize.Width;
136wp.height = f.ClientSize.Height;
137windowPositions[(int)window] = wp;
138}
139
140public static void SetLastScriptPosition(string script, int line)
141{
142if (!storeLastPosition || line < 10)
143return;
144if (scriptPosition.ContainsKey(script))
145scriptPosition[script] = (ushort)line;
146else
147scriptPosition.Add(script, (ushort)line);
148}
149
150public static int GetLastScriptPosition(string script)
151{
152if (scriptPosition.ContainsKey(script))
153return (ushort)scriptPosition[script];
154else
155return 0;
156}
157
158public static void AddMsgRecentFile(string s, bool b = false)
159{
160SubRecentFile(ref recentMsg, s, b);
161}
162
163public static void AddRecentFile(string s, bool b = false)
164{
165SubRecentFile(ref recent, s, b, true);
166}
167
168public static void SubRecentFile(ref List<string> recent, string s, bool b, bool p = false)
169{
170for (int i = 0; i < recent.Count; i++) {
171if (string.Compare(recent[i], s, true) == 0)
172recent.RemoveAt(i--);
173}
174if (!b && recent.Count >= MAX_RECENT) {
175if (p) scriptPosition.Remove(Path.GetFileName(recent[0]));
176recent.RemoveAt(0);
177}
178if (!b) recent.Add(s);
179}
180
181public static void ClearRecent()
182{
183recent.Clear();
184}
185
186public static bool IsSearchIncludes
187{
188get { return (searchIncludePath && pathScriptsHFile != null); }
189}
190
191public static string[] GetRecent() { return recent.ToArray(); }
192public static string[] GetMsgRecent() { return recentMsg.ToArray(); }
193
194private static void LoadWindowPos(BinaryReader br, int i)
195{
196windowPositions[i].maximized = br.ReadBoolean();
197windowPositions[i].x = br.ReadInt32();
198windowPositions[i].y = br.ReadInt32();
199windowPositions[i].width = br.ReadInt32();
200windowPositions[i].height = br.ReadInt32();
201}
202
203private static void LoadInternal(BinaryReader br, BinaryReader brRecent)
204{
205if (br != null) {
206string temp;
207try {
208firstRun = br.ReadBoolean();
209allowDefine = br.ReadBoolean();
210hintsLang = br.ReadByte();
211highlight = br.ReadByte();
212encoding = br.ReadByte();
213optimize = br.ReadByte();
214showWarnings = br.ReadBoolean();
215showDebug = br.ReadBoolean();
216searchIncludePath = br.ReadBoolean();
217
218temp = br.ReadString();
219if (temp.Length > 0) outputDir = temp;
220
221warnOnFailedCompile = br.ReadBoolean();
222multiThreaded = br.ReadBoolean();
223
224temp = br.ReadString();
225if (temp.Length > 0) lastMassCompile = temp;
226
227temp = br.ReadString();
228if (temp.Length > 0) lastSearchPath = temp;
229
230LoadWindowPos(br, 0);
231editorSplitterPosition = br.ReadInt32();
232autoOpenMsgs = br.ReadBoolean();
233editorSplitterPosition2 = br.ReadInt32();
234
235temp = br.ReadString();
236if (temp.Length > 0) pathHeadersFiles = temp;
237
238language = br.ReadString();
239if (language.Length == 0) language = "english";
240
241tabsToSpaces = br.ReadBoolean();
242tabSize = br.ReadInt32();
243enableParser = br.ReadBoolean();
244shortCircuit = br.ReadBoolean();
245autocomplete = br.ReadBoolean();
246showLog = br.ReadBoolean();
247parserWarn = br.ReadBoolean();
248useWatcom = br.ReadBoolean();
249
250temp = br.ReadString();
251if (temp.Length > 0) preprocDef = temp;
252
253ignoreCompPath = br.ReadBoolean();
254
255byte MsgItems = br.ReadByte();
256for (byte i = 0; i < MsgItems; i++) msgListPath.Add(br.ReadString());
257
258openMsgEditor = br.ReadBoolean();
259userCmdCompile = br.ReadBoolean();
260msgHighlightComment = br.ReadBoolean();
261msgHighlightColor = br.ReadByte();
262msgFontSize = br.ReadByte();
263
264temp = br.ReadString();
265if (temp.Length > 0) pathScriptsHFile = temp;
266
267associateID = br.ReadBoolean();
268//
269autoUpdate = br.ReadBoolean();
270autoSaveChart = br.ReadBoolean();
271autoArrange = br.ReadBoolean();
272woExitNode = br.ReadBoolean();
273useMcpp = br.ReadBoolean();
274autocompleteColor = br.ReadBoolean();
275autoInputPaired = br.ReadBoolean();
276showTabsChar = br.ReadBoolean();
277autoTrailingSpaces = br.ReadBoolean();
278showTips = br.ReadBoolean();
279shortDesc = br.ReadBoolean();
280autoHideNodes = br.ReadBoolean();
281selectFont = br.ReadByte();
282sizeFont = br.ReadSByte();
283showVRuler = br.ReadBoolean();
284storeLastPosition = br.ReadBoolean();
285saveScriptUTF8 = br.ReadBoolean();
286decompileF1 = br.ReadBoolean();
287winAPITextRender = br.ReadBoolean();
288
289temp = br.ReadString();
290if (temp.Length > 0) ExternalEditorExePath = temp;
291
292oldDecompile = br.ReadBoolean();
293searchIgnoreCase = br.ReadBoolean();
294searchWholeWord = br.ReadBoolean();
295
296temp = br.ReadString();
297if (temp.Length > 0) solutionProjectFolder = temp;
298} catch {
299MessageBox.Show("An error occurred while reading configuration file.\n"
300+ "File setting.dat may be in wrong format.", "Setting read error");
301}
302br.Close();
303}
304// Recent files
305if (brRecent == null) return;
306int recentItems = brRecent.ReadByte();
307int recentMsgItems = brRecent.ReadByte();
308for (int i = 0; i < recentItems; i++)
309recent.Add(brRecent.ReadString());
310for (int i = 0; i < recentMsgItems; i++)
311recentMsg.Add(brRecent.ReadString());
312//
313int positionItems = brRecent.ReadByte();
314for (int i = 0; i < positionItems; i++)
315scriptPosition.Add(brRecent.ReadString(), brRecent.ReadUInt16());
316brRecent.Close();
317}
318
319public static void Load()
320{
321Program.printLog(" Load configuration setting.");
322
323if (!Directory.Exists(scriptTempPath)) {
324Directory.CreateDirectory(scriptTempPath);
325} else
326foreach (string file in Directory.GetFiles(scriptTempPath))
327File.Delete(file);
328File.Delete("errors.txt");
329
330if (!Directory.Exists(SettingsFolder)) {
331Directory.CreateDirectory(SettingsFolder);
332}
333if (!Directory.Exists(ResourcesFolder)) {
334Directory.CreateDirectory(ResourcesFolder);
335}
336var templatesFolder = Path.Combine(ResourcesFolder, "templates");
337if (!Directory.Exists(templatesFolder)) {
338Directory.CreateDirectory(templatesFolder);
339}
340
341BinaryReader brRecent = null, brSettings = null;
342if (File.Exists(RecentPath))
343brRecent = new BinaryReader(File.OpenRead(RecentPath));
344if (File.Exists(SettingsPath))
345brSettings = new BinaryReader(File.OpenRead(SettingsPath));
346LoadInternal(brSettings, brRecent);
347
348LoadScriptsProceduresFolding();
349
350if (!File.Exists(SearchHistoryPath))
351File.Create(SearchHistoryPath).Close();
352if (!File.Exists(PreprocDefPath))
353File.Create(PreprocDefPath).Close();
354
355if (!firstRun) {
356var culture = System.Globalization.CultureInfo.CurrentCulture;
357Settings.hintsLang = (byte)((culture.ToString() == "ru-RU") ? 1 : 0);
358FileAssociation.Associate();
359}
360
361EncCodePage = (encoding == (byte)EncodingType.OEM866) ? Encoding.GetEncoding("cp866") : Encoding.Default;
362
363//Load custom fonts
364try {
365foreach (string file in Directory.GetFiles(Settings.ResourcesFolder + @"\fonts\", "*.ttf"))
366Fonts.AddFontFile(file);
367} catch (DirectoryNotFoundException ) { }
368}
369
370public static void SetTextAreaFont(ICSharpCode.TextEditor.TextEditorControl TE)
371{
372if (Fonts.Families.Length == 0)
373return;
374
375int indexFont = selectFont - 1;
376Font font;
377if (indexFont > -1) {
378FontFamily family = Fonts.Families[indexFont];
379float sz;
380if (!FontAdjustSize.TryGetValue(family.Name, out sz))
381sz = 10.0f;
382font = new Font(family, sz + sizeFont, FontStyle.Regular, GraphicsUnit.Point);
383} else
384font = new Font("Courier New", 10.0f + sizeFont, FontStyle.Regular);
385TE.TextEditorProperties.Font = font;
386}
387
388private static void WriteWindowPos(BinaryWriter bw, int i)
389{
390bw.Write(windowPositions[i].maximized);
391bw.Write(windowPositions[i].x);
392bw.Write(windowPositions[i].y);
393bw.Write(windowPositions[i].width);
394bw.Write(windowPositions[i].height);
395}
396
397public static void Save()
398{
399if (!Directory.Exists(SettingsFolder))
400Directory.CreateDirectory(SettingsFolder);
401BinaryWriter bw = new BinaryWriter(File.Create(SettingsPath));
402bw.Write((byte)255);
403bw.Write(allowDefine);
404bw.Write(hintsLang);
405bw.Write(highlight);
406bw.Write(encoding);
407bw.Write(optimize);
408bw.Write(showWarnings);
409bw.Write(showDebug);
410bw.Write(searchIncludePath);
411bw.Write(outputDir ?? "");
412bw.Write(warnOnFailedCompile);
413bw.Write(multiThreaded);
414bw.Write(lastMassCompile ?? "");
415bw.Write(lastSearchPath ?? "");
416WriteWindowPos(bw, 0);
417bw.Write(editorSplitterPosition);
418bw.Write(autoOpenMsgs);
419bw.Write(editorSplitterPosition2);
420bw.Write(pathHeadersFiles ?? "");
421bw.Write(language ?? "english");
422bw.Write(tabsToSpaces);
423bw.Write(tabSize);
424bw.Write(enableParser);
425bw.Write(shortCircuit);
426bw.Write(autocomplete);
427bw.Write(showLog);
428bw.Write(parserWarn);
429bw.Write(useWatcom);
430bw.Write(preprocDef ?? string.Empty);
431bw.Write(ignoreCompPath);
432bw.Write((byte)msgListPath.Count);
433for (int i = 0; i < msgListPath.Count; i++)
434bw.Write(msgListPath[i]);
435bw.Write(openMsgEditor);
436bw.Write(userCmdCompile);
437bw.Write(msgHighlightComment);
438bw.Write(msgHighlightColor);
439bw.Write(msgFontSize);
440bw.Write(pathScriptsHFile ?? "");
441bw.Write(associateID);
442//
443bw.Write(autoUpdate);
444bw.Write(autoSaveChart);
445bw.Write(autoArrange);
446bw.Write(woExitNode);
447bw.Write(useMcpp);
448bw.Write(autocompleteColor);
449bw.Write(autoInputPaired);
450bw.Write(showTabsChar);
451bw.Write(autoTrailingSpaces);
452bw.Write(showTips);
453bw.Write(shortDesc);
454bw.Write(autoHideNodes);
455bw.Write(selectFont);
456bw.Write(sizeFont);
457bw.Write(showVRuler);
458bw.Write(storeLastPosition);
459bw.Write(saveScriptUTF8);
460bw.Write(decompileF1);
461bw.Write(winAPITextRender);
462bw.Write(ExternalEditorExePath ?? "");
463bw.Write(oldDecompile);
464bw.Write(searchIgnoreCase);
465bw.Write(searchWholeWord);
466bw.Write(solutionProjectFolder ?? "");
467bw.Close();
468
469// Recent files
470BinaryWriter bwRecent = new BinaryWriter(File.Create(RecentPath));
471bwRecent.Write((byte)recent.Count);
472bwRecent.Write((byte)recentMsg.Count);
473for (int i = 0; i < recent.Count; i++)
474bwRecent.Write(recent[i]);
475for (int i = 0; i < recentMsg.Count; i++)
476bwRecent.Write(recentMsg[i]);
477//
478string[] key = new string[scriptPosition.Count];
479ushort[] value = new ushort[scriptPosition.Count];
480scriptPosition.Keys.CopyTo(key, 0);
481scriptPosition.Values.CopyTo(value, 0);
482bwRecent.Write((byte)scriptPosition.Count);
483for (int i = 0; i < scriptPosition.Count; i++) {
484bwRecent.Write(key[i]);
485bwRecent.Write(value[i]);
486}
487bwRecent.Close();
488// Store folding procedures
489SaveScriptsProceduresFolding();
490}
491
492public static void SaveSettingData(Form mainfrm)
493{
494TextEditor frm = mainfrm as TextEditor;
495StreamWriter sw = new StreamWriter(Settings.SearchHistoryPath);
496int capHSearchHistory = 150;
497foreach (var item in frm.SearchTextComboBox.Items)
498{
499sw.WriteLine(item.ToString());
500if (--capHSearchHistory < 0) break;
501}
502sw.Close();
503File.WriteAllLines(Settings.SearchFoldersPath, searchListPath);
504openMsgEditor = frm.msgAutoOpenEditorStripMenuItem.Checked;
505if (frm.WindowState != FormWindowState.Minimized) SaveWindowPosition(SavedWindows.Main, mainfrm);
506Save();
507Directory.Delete(scriptTempPath, true);
508}
509
510public static void OpenInExternalEditor(string file)
511{
512if (ExternalEditorExePath != null && File.Exists(ExternalEditorExePath))
513System.Diagnostics.Process.Start(ExternalEditorExePath, file);
514else {
515var ofd = new OpenFileDialog() {
516InitialDirectory = Settings.ProgramFolder,
517DefaultExt = "exe",
518Filter = "Executable file (.exe)|*.exe",
519Title = "Select executable file"
520};
521if (ofd.ShowDialog() == DialogResult.OK) {
522ExternalEditorExePath = ofd.FileName;
523OpenInExternalEditor(file);
524}
525}
526}
527
528struct WindowPos
529{
530public bool maximized;
531public int x, y, width, height;
532}
533
534#region Folding save/load data
535private static readonly string FoldingPath = Path.Combine(SettingsFolder, "folding.dat");
536
537private static Dictionary<string, int> scriptsFolding = new Dictionary<string,int>(); // имя скрипта => позиция в массиве proceduresFolding
538private static HashSet<string>[] proceduresFolding; // имена процедур которые являются свернутыми
539
540public static void SetScriptProcedureFold(string scriptName, string procedure)
541{
542int index;
543if (!scriptsFolding.TryGetValue(scriptName, out index)) {
544index = proceduresFolding.Length;
545Array.Resize(ref proceduresFolding, index + 1);
546proceduresFolding[index] = new HashSet<string>();
547proceduresFolding[index].Add(procedure);
548scriptsFolding.Add(scriptName, index);
549} else {
550proceduresFolding[index].Add(procedure);
551}
552}
553
554public static void UsSetScriptProcedureFold(string scriptName, string procedure)
555{
556int index;
557if (!scriptsFolding.TryGetValue(scriptName, out index)) return;
558proceduresFolding[index].Remove(procedure);
559}
560
561public static bool ScriptProcedureIsFold(string scriptName, string procedure)
562{
563int index;
564if (!scriptsFolding.TryGetValue(scriptName, out index)) return false;
565return proceduresFolding[index].Contains(procedure);
566}
567
568private static void SaveScriptsProceduresFolding()
569{
570int sCount = scriptsFolding.Count;
571if (sCount == 0) {
572File.Delete(FoldingPath);
573return;
574}
575string[] keys = new string[sCount];
576scriptsFolding.Keys.CopyTo(keys, 0);
577int[] indexes = new int[sCount];
578scriptsFolding.Values.CopyTo(indexes, 0);
579
580BinaryWriter bwFolding = new BinaryWriter(File.Create(FoldingPath));
581bwFolding.Write(sCount);
582for (int i = 0; i < sCount; i++) {
583bwFolding.Write(keys[i]);
584int pCount = proceduresFolding[indexes[i]].Count;
585bwFolding.Write(pCount);
586string[] procedures = new string[pCount];
587proceduresFolding[indexes[i]].CopyTo(procedures, 0);
588for (int j = 0; j < pCount; j++) {
589bwFolding.Write(procedures[j]);
590}
591}
592bwFolding.Close();
593}
594
595private static void LoadScriptsProceduresFolding()
596{
597if (File.Exists(FoldingPath)) {
598BinaryReader brFolding = new BinaryReader(File.OpenRead(FoldingPath));
599if (brFolding.BaseStream.Length == 0) {
600brFolding.Close();
601proceduresFolding = new HashSet<string>[0];
602return;
603}
604int sCount = brFolding.ReadInt32();
605proceduresFolding = new HashSet<string>[sCount];
606for (int i = 0; i < sCount; i++) {
607string script = brFolding.ReadString();
608int pCount = brFolding.ReadInt32();
609if (pCount == 0) continue;
610proceduresFolding[i] = new HashSet<string>();
611for (int j = 0; j < pCount; j++) {
612proceduresFolding[i].Add(brFolding.ReadString());
613}
614scriptsFolding.Add(script, i);
615}
616brFolding.Close();
617} else {
618proceduresFolding = new HashSet<string>[0];
619}
620}
621#endregion
622}
623}
624