コード例 #1
0
ファイル: Log_.cs プロジェクト: alexfordc/Au
 public void Show()
 {
     if (_path != null && AFile.ExistsAsFile(_path))
     {
         AExec.TryRun(_path);
     }
 }
コード例 #2
0
ファイル: PanelFiles.cs プロジェクト: alexfordc/Au
	//protected override void OnGotFocus(EventArgs e) { _c.Focus(); }

	/// <summary>
	/// Loads existing or new workspace.
	/// If fails, shows a task dialog with several choices - retry, load another, create new, cancel. If then fails, ends process.
	/// Sets Model and Text properties of the main form. Updates recent files.
	/// By default runs startup script.
	/// </summary>
	/// <param name="wsDir">
	/// Workspace's directory. The directory should contain file "files.xml" and subdirectory "files".
	/// If null, loads the last used workspace (its path is in settings).
	/// If the setting does not exist, uses AFolders.ThisAppDocuments + @"Main".
	/// If the file does not exist, copies from AFolders.ThisApp + @"Default\Workspace".
	/// </param>
	public FilesModel ZLoadWorkspace(string wsDir = null)
	{
		wsDir ??= Program.Settings.workspace;
		if(wsDir.NE()) wsDir = AFolders.ThisAppDocuments + "Main";
		var xmlFile = wsDir + @"\files.xml";
		var oldModel = _model;
		FilesModel m = null;
		_isNewWorkspace = false;
		g1:
		try {
			//SHOULDDO: if editor runs as admin, the workspace directory should be write-protected from non-admin processes.

			if(_isNewWorkspace = !AFile.ExistsAsFile(xmlFile)) {
				AFile.Copy(AFolders.ThisAppBS + @"Default\Workspace", wsDir);
			}

			_model?.UnloadingWorkspace(); //saves all, closes documents, sets current file = null

			m = new FilesModel(_c, xmlFile);
			_c.Model = m;
		}
		catch(Exception ex) {
			m?.Dispose();
			m = null;
			//AOutput.Write($"Failed to load '{wsDir}'. {ex.Message}");
			switch(ADialog.ShowError("Failed to load workspace", wsDir,
				"1 Retry|2 Load another|3 Create new|0 Cancel",
				owner: this, expandedText: ex.ToString())) {
			case 1: goto g1;
			case 2: m = ZLoadAnotherWorkspace(); break;
			case 3: m = ZLoadNewWorkspace(); break;
			}
			if(m != null) return m;
			if(_model != null) return _model;
			Environment.Exit(1);
		}

		oldModel?.Dispose();
		Program.Model = _model = m;

		//CONSIDER: unexpand path
		if(wsDir != Program.Settings.workspace) {
			if(Program.Settings.workspace != null) {
				var ar = Program.Settings.recentWS ?? Array.Empty<string>();
				int i = Array.IndexOf(ar, wsDir); if(i >= 0) ar = ar.RemoveAt(i);
				Program.Settings.recentWS = ar.InsertAt(0, Program.Settings.workspace);
			}
			Program.Settings.workspace = wsDir;
		}

		Program.MainForm.ZSetTitle();
		if(Program.Loaded >= EProgramState.LoadedWorkspace) {
			ZOpenDocuments();
			ZModel.RunStartupScripts();
		}

		return _model;
	}
コード例 #3
0
ファイル: FProperties.cs プロジェクト: alexfordc/Au
    async void _ConvertTypeLibrary(object tlDef, object button)
    {
        string comDll = null;

        switch (tlDef)
        {
        case string path:
            comDll = path;
            break;

        case _RegTypelib r:
            //can be several locales
            var aloc  = new List <string>();           //registry keys like "0" or "409"
            var aloc2 = new List <string>();           //locale names for display in the list dialog
            using (var verKey = Registry.ClassesRoot.OpenSubKey($@"TypeLib\{r.guid}\{r.version}")) {
                foreach (var s1 in verKey.GetSubKeyNames())
                {
                    int lcid = s1.ToInt(0, out int iEnd, STIFlags.IsHexWithout0x);
                    if (iEnd != s1.Length)
                    {
                        continue;                                       //"FLAGS" etc; must be hex number without 0x
                    }
                    aloc.Add(s1);
                    var s2 = "Neutral";
                    if (lcid > 0)
                    {
                        try { s2 = new CultureInfo(lcid).DisplayName; } catch { s2 = s1; }
                    }
                    aloc2.Add(s2);
                }
            }
            string locale;
            if (aloc.Count == 1)
            {
                locale = aloc[0];
            }
            else
            {
                int i = ADialog.ShowList(aloc2, "Locale", owner: this);
                if (i == 0)
                {
                    return;
                }
                locale = aloc[i - 1];
            }
            comDll = r.GetPath(locale);
            if (comDll == null || !AFile.ExistsAsFile(comDll))
            {
                ADialog.ShowError(comDll == null ? "Failed to get file path." : "File does not exist.", owner: this);
                return;
            }
            break;
        }

        await Task.Run(() => {
            this.Enabled = false;
            AOutput.Write($"Converting COM type library to .NET assembly.");
            try {
                if (_convertedDir == null)
                {
                    _convertedDir = AFolders.Workspace + @".interop\";
                    AFile.CreateDirectory(_convertedDir);
                }
                List <string> converted  = new List <string>();
                Action <string> callback = s => {
                    AOutput.Write(s);
                    if (s.Starts("Converted: "))
                    {
                        s.RegexMatch(@"""(.+?)"".$", 1, out s);
                        converted.Add(s);
                    }
                };
                int rr = AExec.RunConsole(callback, AFolders.ThisAppBS + "Au.Net45.exe", $"/typelib \"{_convertedDir}|{comDll}\"", encoding: Encoding.UTF8);
                if (rr == 0)
                {
                    foreach (var v in converted)
                    {
                        if (!_meta.com.Contains(v))
                        {
                            _meta.com.Add(v);
                        }
                    }
                    AOutput.Write(@"<>Converted and saved in <link>%AFolders.Workspace%\.interop<>.");
                    _Added(button, _meta.com);
                }
            }
            catch (Exception ex) { ADialog.ShowError("Failed to convert type library", ex.ToStringWithoutStack(), owner: this); }
            this.Enabled = true;
        });
    }
コード例 #4
0
ファイル: AuStripManager.cs プロジェクト: alexfordc/Au
        /// <summary>
        /// Opens XML file and creates toolbars/menus/submenus from XML tags.
        /// </summary>
        /// <param name="xmlFile">XML file containing menus/toolbars without user customizations.</param>
        /// <param name="xmlFileCustom">XML file containing user customizations. It will be created or updated when saving customizations.</param>
        /// <param name="tsRenderer"></param>
        public void BuildAll(string xmlFile, string xmlFileCustom, ToolStripRenderer tsRenderer = null)
        {
            Debug.Assert(_xStrips == null); if (_xStrips != null)
            {
                throw new InvalidOperationException();
            }

            _xmlFileDefault = xmlFile;
            _xmlFileCustom  = xmlFileCustom;
            try { _xStrips = AExtXml.LoadElem(xmlFile); }
            catch (Exception ex) { ADialog.ShowError("Failed to load file", ex.ToString()); throw; }
            XElement xCustom = null;

            if (AFile.ExistsAsFile(_xmlFileCustom))
            {
                try { xCustom = AExtXml.LoadElem(_xmlFileCustom); }
                catch (Exception e) { AOutput.Write("Failed to load file", _xmlFileCustom, e.Message); }
            }

            Size imageScalingSize = Au.Util.ADpi.SmallIconSize_;             //if high DPI, auto scale images

            //create top-level toolstrips (menu bar and toolbars), and call _AddChildItems to add items and create drop-down menus and submenus
            _inBuildAll = true;
            bool isMenu = true;

            foreach (var xe in _xStrips.Elements().ToArray())              //info: ToArray() because _MergeCustom replaces XML elements of custom toolbars
            {
                string name = xe.Name.LocalName;
                var    x    = xe;
                if (xCustom != null)
                {
                    _MergeCustom(xCustom, ref x, name, isMenu);
                }

                ToolStrip t;
                if (isMenu)
                {
                    t = MenuBar = new Util.AMenuStrip();
                }
                else
                {
                    var cts = new Util.AToolStrip();
                    Toolbars.Add(name, cts);
                    t = cts;
                    switch (name)
                    {
                    case "Custom1": _tsCustom1 = cts; break;

                    case "Custom2": _tsCustom2 = cts; break;
                    }
                }

                t.SuspendLayout();

                t.Tag  = x;
                t.Text = t.Name = name;
                //t.AllowItemReorder = true; //don't use, it's has bugs etc, we know better how to do it
                if (tsRenderer != null)
                {
                    t.Renderer = tsRenderer;
                }
                if (isMenu)
                {
                    t.Padding = new Padding();                     //remove menu bar paddings
                }
                else
                {
                }
                if (imageScalingSize.Height != 16)
                {
                    t.ImageScalingSize = imageScalingSize;                                               //info: all submenus will inherit it from menubar
                }
                _AddChildItems(x, t, isMenu);

                t.ResumeLayout(false);
                isMenu = false;
            }
            _inBuildAll = false;
        }
コード例 #5
0
        //Loads and parses XML. Creates the _aX lists, _firstSplit and the tree structure.
        void _LoadXmlAndCreateLayout(string xmlFileDefault, string xmlFileCustomized)
        {
            //We have 1 or 2 XML files containing panel/toolbar layout.
            //xmlFileDefault contains default XML. It eg can be in AFolders.ThisApp.
            //xmlFileCustomized contains previously saved XML (user-modified layout).
            //At first try to load xmlFileCustomized. If it does not exist or is invalid, load xmlFileDefault; or get missing data from xmlFileDefault, if possible.
            //Also loads xmlFileDefault when xmlFileCustomized XML does not match panels of new app version and cannot resolve it (eg some panels removed).
            bool   usesDefaultXML = false;
            string xmlFile = xmlFileCustomized, xmlVersion = null, outInfo = null;

            for (int i = 0; i < 2; i++)
            {
                if (i == 0)
                {
                    if (!AFile.ExistsAsFile(xmlFile))
                    {
                        continue;
                    }
                }
                else
                {
                    usesDefaultXML = true;
                    xmlFile        = xmlFileDefault;
                }

                bool fileLoaded = false;
                try {
                    var x = AExtXml.LoadElem(xmlFile);
                    fileLoaded = true;
                    if (!usesDefaultXML)
                    {
                        xmlVersion = x.Attr("version");
                    }
                    x = x.Element("split");

                    //THIS DOES THE MAIN JOB
                    _firstSplit = new _Split(this, null, x);

                    if (_aPanel.Count < _initControls.Count)                      //more panels added in this app version
                    {
                        if (usesDefaultXML)
                        {
                            throw new Exception("debug1");
                        }
                        _GetPanelXmlFromDefaultFile(xmlFileDefault);
                    }

                    break;

                    //speed: xml.Load takes 170 microseconds.
                    //tested: XML can be added to Application Settings, but var xml=Properties.Settings.Default.PanelsXML takes 61 MILLIseconds.
                }
                catch (Exception e) {
                    var sErr = $"Failed to load file '{xmlFile}'.\r\n\t{e.ToStringWithoutStack()}";
                    if (usesDefaultXML)
                    {
                        _xmlFile = null;
                        ADialog.ShowError("Cannot load panel/toolbar layout.", $"{sErr}\r\n\r\nReinstall the application.");
                        Environment.Exit(1);
                    }
                    else
                    {
                        //probably in this version there are less panels, most likely when downgraded. Or the file is corrupt.
                        if (fileLoaded && xmlVersion != _asmVersion)
                        {
                            outInfo = "Info: this application version resets the panel/toolbar layout, sorry.";
                        }
                        else
                        {
                            AWarning.Write(sErr, -1);
                        }
                    }
                    _aSplit.Clear(); _aTab.Clear(); _aPanel.Clear();
                }
            }

            //if(usesDefaultXML || xmlVersion == _asmVersion) return;
            if (outInfo != null)
            {
                AOutput.Write(outInfo);
            }
        }
コード例 #6
0
ファイル: DocFX.cs プロジェクト: alexfordc/Au
    static bool ProcessHtmlFile(ref string s, bool isApi, string siteDir)
    {
        int nr = 0;

        if (isApi)
        {
            //Remove the <au><!--<code>*xml*</code>--></au> enclosing.
            nr += s.RegexReplace(@"<au><!--(<code>.+?</code>)--></au>", @"$1", out s);

            //Link Method(parameters) -> Type.Method. And remove #jump. Works for properties too.
            //Exclude those in auto-generated tables of class methods and properties.
            nr += s.RegexReplace(@"(<a class=""xref"" href=""Au\.(?:Types\.|Triggers\.|Util\.)?+([\w\.\-]+\.\w+)\.html)#\w+"">.+?</a>(?!\s*</td>\s*<td class=""markdown level1 summary"">)", @"$1"">$2</a>", out s);
            //the same for enum
            nr += s.RegexReplace(@"(<a class=""xref"" href=""Au\.(?:Types\.|Triggers\.|Util\.)?+(\w+)\.html)#\w+"">(\w+</a>)", @"$1"">$2.$3", out s);             //note: enums must not be nested in types

            //In class member pages, in title insert a link to the type.
            nr += s.RegexReplace(@"<h1\b[^>]* data-uid=""(Au\.(?:Types\.|Triggers\.|Util\.)?+([\w\.`]+))\.\w+\*?""[^>]*>(?:Method|Property|Field|Event|Operator|Constructor) (?=\w)",
                                 m => m.ExpandReplacement(@"$0<a href=""$1.html"">$2</a>.").Replace("`", "-"),
                                 out s);

            //Remove anchor from the first hidden overload <hr>, to prevent scrolling.
            nr += s.RegexReplace(@"(</h1>\s*<hr class=""overload"") id="".+?"" data-uid="".+?""", @"$1", out s);

            //Add "(+ n overloads)" link in h1 and "(next/top)" links in h2 if need.
            if (s.RegexFindAll(@"<h2 class=""overload"" id=""(.+?)"".*?>Overload", out var a) && a.Length > 1)
            {
                var b     = new StringBuilder();
                int jPrev = 0;
                for (int i = 0; i < a.Length; i++)
                {
                    bool first = i == 0, last = i == a.Length - 1;
                    int  j = first ? s.Find("</h1>") : a[i].End;
                    b.Append(s, jPrev, j - jPrev);
                    jPrev = j;
                    b.Append("<span style='font-size:14px; font-weight: 400; margin-left:20px;'>(");
                    if (first)
                    {
                        b.Append("+ ").Append(a.Length - 1).Append(" ");
                    }
                    var href = last ? "top" : a[i + 1][1].Value;
                    b.Append("<a href='#").Append(href).Append("'>");
                    if (first)
                    {
                        b.Append("overload").Append(a.Length == 2 ? "" : "s");
                    }
                    else
                    {
                        b.Append(last ? "back to top" : "next");
                    }
                    b.Append("</a>)</span>");
                }
                b.Append(s, jPrev, s.Length - jPrev);
                s = b.ToString();
                nr++;
            }
        }
        else
        {
            //in .md we use this for links to api: [Class]() or [Class.Func]().
            //	DocFX converts it to <a href="">Class</a> etc without warning.
            //	Now convert it to a working link.
            nr += s.RegexReplace(@"<a href="""">(.+?)</a>", m => {
                var k       = m[1].Value;
                string href = null;
                foreach (var ns in s_ns)
                {
                    if (AFile.ExistsAsFile(siteDir + "/api/" + ns + k + ".html"))
                    {
                        href = "../api/" + ns + k + ".html";
                        break;
                    }
                }
                if (href == null)
                {
                    AOutput.Write($"cannot resolve link: [{k}]()"); return(m.Value);
                }
                return(m.ExpandReplacement($@"<a href=""{href}"">$1</a>"));
            }, out s);
        }

        //<msdn>...</msdn> -> <a href="google search">
        nr += s.RegexReplace(@"<msdn>(.+?)</msdn>", @"<a href=""https://www.google.com/search?q=site:docs.microsoft.com+$1"">$1</a>", out s);

        //javascript renderTables() replacement, to avoid it at run time. Also remove class table-striped.
        nr += s.RegexReplace(@"(?s)<table(>.+?</table>)", @"<div class=""table-responsive""><table class=""table table-bordered table-condensed""$1</div>", out s);

        //the same for renderAlerts
        nr += s.RegexReplace(@"<div class=""(NOTE|TIP|WARNING|IMPORTANT|CAUTION)\b",
                             o => {
            string k = "info"; switch (o[1].Value[0])
            {
            case 'W': k = "warning"; break;

            case 'I':
            case 'C': k = "danger"; break;
            }
            return(o.Value + " alert alert-" + k);
        },
                             out s);

        //replace something in syntax code blocks
        nr += s.RegexReplace(@"(?<=<div class=""codewrapper"">)\s*<pre><code.+?(?=</code></pre>)",
                             m => {
            var k = m.Value;
            k     = k.RegexReplace(@"\(\w+\)0", @"0");
            k     = k.RegexReplace(@"default\([^)?]+\? *\)", @"null");
            k     = k.RegexReplace(@"default\(.+?\)", @"default");
            return(k);
        }
                             , out s);

        //nr += s.RegexReplace(@"", @"", out s);

        return(nr > 0);
    }
コード例 #7
0
ファイル: ImageUtil.cs プロジェクト: alexfordc/Au
        /// <summary>
        /// Loads image and returns its data in .bmp file format.
        /// Returns null if fails, for example file not found or invalid Base64 string.
        /// </summary>
        /// <param name="s">Depends on t. File path or resource name without prefix or Base64 image data without prefix.</param>
        /// <param name="t">Image type and string format.</param>
        /// <param name="searchPath">Use <see cref="AFile.SearchPath"/></param>
        /// <remarks>Supports environment variables etc. If not full path, searches in <see cref="AFolders.ThisAppImages"/>.</remarks>
        public static byte[] BmpFileDataFromString(string s, ImageType t, bool searchPath = false)
        {
            //AOutput.Write(t, s);
            try {
                switch (t)
                {
                case ImageType.Bmp:
                case ImageType.PngGifJpg:
                case ImageType.Cur:
                    if (searchPath)
                    {
                        s = AFile.SearchPath(s, AFolders.ThisAppImages);
                        if (s == null)
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        if (!APath.IsFullPathExpandEnvVar(ref s))
                        {
                            return(null);
                        }
                        s = APath.Normalize(s, AFolders.ThisAppImages);
                        if (!AFile.ExistsAsFile(s))
                        {
                            return(null);
                        }
                    }
                    break;
                }

                switch (t)
                {
                case ImageType.Base64CompressedBmp:
                    return(AConvert.Decompress(Convert.FromBase64String(s)));

                case ImageType.Base64PngGifJpg:
                    using (var stream = new MemoryStream(Convert.FromBase64String(s), false)) {
                        return(_ImageToBytes(Image.FromStream(stream)));
                    }

                case ImageType.Resource:
                    return(_ImageToBytes(AResources.GetAppResource(s) as Image));

                case ImageType.Bmp:
                    return(File.ReadAllBytes(s));

                case ImageType.PngGifJpg:
                    return(_ImageToBytes(Image.FromFile(s)));

                case ImageType.Ico:
                case ImageType.IconLib:
                case ImageType.ShellIcon:
                case ImageType.Cur:
                    return(_IconToBytes(s, t == ImageType.Cur, searchPath));
                }
            }
            catch (Exception ex) { ADebug.Print(ex.Message + "    " + s); }
            return(null);
        }
コード例 #8
0
    static void _CreateDoc(string dbFile, string dir1, string dir2)
    {
        AFile.Delete(dbFile);
        using var d     = new ASqlite(dbFile, sql: "PRAGMA page_size = 8192;");     //8192 makes file smaller by 2-3 MB.
        using var trans = d.Transaction();
        d.Execute("CREATE TABLE doc (name TEXT PRIMARY KEY, xml TEXT)");
        using var statInsert = d.Statement("INSERT INTO doc VALUES (?, ?)");
        using var statDupl   = d.Statement("SELECT xml FROM doc WHERE name=?");
        var haveRefs = new List <string>();
        var uniq     = new Dictionary <string, string>();    //name -> asmName

        //using var textFile = File.CreateText(Path.ChangeExtension(dbFile, "txt")); //test. Compresses almost 2 times better than db.

        _AddDir(dir1, "WindowsBase");
        _AddDir(dir2);

        statInsert.BindAll(".", string.Join("\n", haveRefs)).Step();

        trans.Commit();
        d.Execute("VACUUM");

        AOutput.Write("Created " + dbFile);

        void _AddDir(string dir, params string[] skip)
        {
            foreach (var f in AFile.EnumDirectory(dir))
            {
                if (f.IsDirectory)
                {
                    continue;
                }
                if (!f.Name.Ends(".xml", true))
                {
                    continue;
                }
                var asmName = f.Name.RemoveSuffix(4);
                if (skip.Contains(asmName))
                {
                    continue;
                }
                if (!AFile.ExistsAsFile(dir + asmName + ".dll"))
                {
                    AOutput.Write("<><c 0x808080>" + f.Name + "</c>");
                    continue;
                }
                _AddFile(asmName, f.FullPath);
                //break;
            }
        }

        void _AddFile(string asmName, string xmlFile)
        {
            //AOutput.Write(asmName);
            haveRefs.Add(asmName);
            var xr = AExtXml.LoadElem(xmlFile);

            foreach (var e in xr.Descendants("member"))
            {
                var name = e.Attr("name");

                //remove <remarks> and <example>. Does not save much space, because .NET xmls don't have it.
                foreach (var v in e.Descendants("remarks").ToArray())
                {
                    v.Remove();
                }
                foreach (var v in e.Descendants("example").ToArray())
                {
                    v.Remove();
                }

                using var reader = e.CreateReader();
                reader.MoveToContent();
                var xml = reader.ReadInnerXml();
                //AOutput.Write(name, xml);

                //textFile.WriteLine(name); textFile.WriteLine(xml); textFile.WriteLine("\f");

                if (uniq.TryGetValue(name, out var prevRef))
                {
                    if (!statDupl.Bind(1, name).Step())
                    {
                        throw new AuException();
                    }
                    var prev = statDupl.GetText(0);
                    if (xml != prev && asmName != "System.Linq")
                    {
                        AOutput.Write($"<>\t{name} already defined in {prevRef}\r\n<c 0xc000>{prev}</c>\r\n<c 0xff0000>{xml}</c>");
                    }
                    statDupl.Reset();
                }
                else
                {
                    statInsert.BindAll(name, xml).Step();
                    uniq.Add(name, asmName);
                }
                statInsert.Reset();
            }
        }
    }