示例#1
0
        void _GetPanelXmlFromDefaultFile(string defFile)
        {
            var xml = AExtXml.LoadElem(defFile);

            foreach (var c in _initControls.Values)
            {
                if (_aPanel.Exists(v => v.Content == c))
                {
                    continue;
                }
                var x  = xml.Desc("panel", "name", c.Name);
                var gp = new _Panel(this, null, x)
                {
                    DockState             = _DockState.Hidden,
                    SavedVisibleDockState = _DockState.Floating
                };
                c.Visible = false;
                AOutput.Write($"Info: new {(gp.HasToolbar ? "toolbar" : "panel")} '{gp.Text}' added in this aplication version. Currently it is hidden.");
            }
        }
示例#2
0
	/// <summary>
	/// Adds templates to File -> New.
	/// </summary>
	public void ZFillMenuNew(ToolStripDropDownMenu ddm)
	{
		if(_newMenuDone) return; _newMenuDone = true;

		var templDir = FileNode.Templates.DefaultDirBS;
		var xroot = AExtXml.LoadElem(FileNode.Templates.DefaultFilesXml);

		_CreateMenu(ddm, xroot, null, 0);

		void _CreateMenu(ToolStripDropDownMenu ddParent, XElement xParent, string dir, int level)
		{
			ddParent.SuspendLayout();
			int i = level == 0 ? 4 : 0;
			foreach(var x in xParent.Elements()) {
				string tag = x.Name.LocalName, name = x.Attr("n");
				int isFolder = tag == "d" ? 1 : 0;
				if(isFolder == 1) {
					isFolder = name[0] switch { '@' => 2, '!' => 3, _ => 1 }; //@ project, ! simple folder
				} else {
					if(level == 0 && FileNode.Templates.IsStandardTemplateName(name, out _)) continue;
				}
				string relPath = dir + name;
				if(isFolder == 3) name = name[1..];
				var item = new ToolStripMenuItem(name, null, (unu, sed) => ZModel.NewItem(relPath, beginRenaming: true));
				if(isFolder == 1) {
					var ddSub = new ToolStripDropDownMenu();
					item.DropDown = ddSub;
					_CreateMenu(ddSub, x, dir + name + "\\", level + 1);
				} else {
					string si = null;
					if(isFolder != 0) si = nameof(Au.Editor.Resources.Resources.folder);
					else if(tag == "s") si = nameof(Au.Editor.Resources.Resources.fileScript);
					else if(tag == "c") si = nameof(Au.Editor.Resources.Resources.fileClass);
					Bitmap im = si != null
						? EdResources.GetImageUseCache(si)
						: FileNode.IconCache.GetImage(templDir + relPath, useExt: true);
					if(im != null) item.Image = im;
				}
				ddParent.Items.Insert(i++, item);
			}
示例#3
0
        /// <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;
        }
示例#4
0
        /// <summary>
        /// Creates a menu or toolbar item.
        /// </summary>
        /// <param name="x">XML element containing item properties.</param>
        /// <param name="isMenu">false if toolbar item, true if menu item (also if menu bar item).</param>
        ToolStripItem _CreateChildItem(XElement x, bool isMenu)
        {
            string s, tag = x.Name.LocalName;

            if (tag == "sep")
            {
                return new ToolStripSeparator()
                       {
                           Tag = x
                       }
            }
            ;

            ToolStripItem item; ToolStripMenuItem mi;
            bool          isControl = false, needHandler = false;

            if (isMenu)
            {
                mi = new ToolStripMenuItem();

                item = mi;
                if (x.HasElements || x.HasAttr("dd"))
                {
                    _Submenu(x, mi, tag);
                }
                else
                {
                    needHandler = true;
                }
            }
            else if (x.HasAttr("type"))
            {
                isControl = true;
                string cue = x.Attr("cue");
                s = x.Attr("type");
                switch (s)
                {
                case "edit":
                    var ed = new ToolStripSpringTextBox();
                    if (cue != null)
                    {
                        ed.ZSetCueBanner(cue);
                    }
                    item = ed;
                    break;

                case "combo":
                    var combo = new ToolStripSpringComboBox();
                    if (cue != null)
                    {
                        combo.ZSetCueBanner(cue);
                    }
                    item = combo;
                    break;

                default:
                    Debug.Assert(false);
                    return(null);
                }
                if (cue != null)
                {
                    item.AccessibleName = cue;
                }
            }
            else if (x.HasElements || x.HasAttr("dd"))
            {
                ToolStripDropDownItem ddi;
                var handler = _callbacks.GetClickHandler(tag);
                if (handler != null)
                {
                    var sb = new ToolStripSplitButton();
                    sb.ButtonClick += handler;
                    ddi             = sb;
                }
                else
                {
                    ddi = new ToolStripDropDownButton();
                }
                item = ddi;
                _Submenu(x, ddi, tag);
            }
            else
            {
                needHandler = true;
                var b = new ToolStripButton();
                item = b;
            }

            item.Name = tag;
            item.Tag  = x;

            _SetItemProperties(x, item, isMenu, isControl);

            if (needHandler)
            {
                var handler = _callbacks.GetClickHandler(tag);
                if (handler != null)
                {
                    item.Click += handler;
                }
                else
                {
                    ADebug.Print("no handler of " + tag);
                    //return null;
                    //item.Enabled = false;
                    item.Visible = false;
                }
            }

            return(item);
        }

        void _Submenu(XElement x, ToolStripDropDownItem ddItem, string tag)
        {
            var s = x.Attr("dd");

            if (!s.NE())
            {
                ddItem.DropDown = Submenus[s];
            }
            else
            {
                var dd = ddItem.DropDown as ToolStripDropDownMenu;                 //note: not ddItem.DropDown=new ToolStripDropDownMenu(). Then eg hotkeys don't work.
                dd.Name = tag;
                dd.Tag  = x;
                Submenus.Add(tag, dd);

                if (s != null)                              //attribute dd="". Will be filled later, eg on Opening event.
                {
                    dd.Items.Add(new ToolStripSeparator()); //else no drop arrow and no Opening event
                    return;
                }
#if !LAZY_MENUS
                dd.SuspendLayout();                 //with this don't need lazy menus
                _AddChildItems(x, dd, true);
                dd.ResumeLayout(false);
#else
                //Fill menu items later. This saves ~50 ms of startup time if not using dd.SuspendLayout. With dd.SuspendLayout - just 5 ms.
                //Can do it with Opening event or with timer. With timer easier. With event users cannot use MSAA etc to automate clicking menu items (with timer cannot use it only the first 1-2 seconds).
#if true
                ATimer.After(500, t =>
                {
                    dd.SuspendLayout();
                    _AddChildItems(x, dd, true);
                    dd.ResumeLayout(false);
                });
#else
                dd.Items.Add(new ToolStripSeparator());
                CancelEventHandler eh = null;
                eh = (sender, e) =>
                {
                    dd.Opening -= eh;
                    dd.Items.Clear();
                    _AddChildItems(x, dd, true);
                };
                dd.Opening += eh;
#endif
#endif
            }
        }

        void _SetItemProperties(XElement x, ToolStripItem item, bool isMenu, bool isControl)
        {
            string s, defaultText = null;

            var tt = x.Attr("tt");             //tooltip

            item.ToolTipText = tt ?? (isMenu ? null : (defaultText = _GetDefaultItemText(x)));

            if (!isMenu)
            {
                if (x.HasAttr("hide"))
                {
                    item.Overflow = ToolStripItemOverflow.Always;
                }
                else if (!_inBuildAll)
                {
                    item.Overflow = ToolStripItemOverflow.AsNeeded;
                }
            }
            if (isControl)
            {
                return;
            }

            Image im = null;

            if (x.Attr(out s, "i2"))              //custom image as icon file
            {
                im = AIcon.GetFileIconImage(s);
                if (im == null)
                {
                    AOutput.Write($"Failed to get {(isMenu ? "menu item" : "toolbar button")} {x.Name} icon from file {s}\n\tTo fix this, right-click it and select Properties...");
                }
                //SHOULDDO: async or cache
            }
            if (im == null && x.Attr(out s, "i"))
            {
                im = _callbacks.GetImage(s);                                              //image from resources
            }
            item.Image = im;

            if (x.Attr(out s, "color") && ColorInt.FromString(s, out var color))
            {
                item.ForeColor = (Color)color;
            }
            else if (!_inBuildAll)
            {
                item.ForeColor = Color.FromKnownColor(KnownColor.ControlText);
            }

            bool hasCustomText = x.Attr(out s, "t2");             //custom text

            item.Text = s ?? defaultText ?? _GetDefaultItemText(x);

            if (isMenu)
            {
                var mi = item as ToolStripMenuItem;
                if (!_inBuildAll)
                {
                    mi.ShortcutKeys             = 0;
                    mi.ShortcutKeyDisplayString = null;
                }
                if (x.Attr(out s, "hk"))
                {
                    bool ok = AKeys.More.ParseHotkeyString(s, out var hk);
                    if (ok)
                    {
                        try { mi.ShortcutKeys = hk; } catch { ok = false; }
                    }
                    if (!ok)
                    {
                        ADebug.Print("Invalid hotkey: " + s);
                    }
                }
                if (x.Attr(out string ss, "hkText"))
                {
                    mi.ShortcutKeyDisplayString = (s == null) ? ss : s + ", " + ss;
                }
            }
            else
            {
                var style = item.Image == null ? ToolStripItemDisplayStyle.ImageAndText : (ToolStripItemDisplayStyle)x.Attr("style", 0);
                if (style == 0)
                {
                    style = hasCustomText ? ToolStripItemDisplayStyle.ImageAndText : ToolStripItemDisplayStyle.Image;                            //0 is ToolStripItemDisplayStyle.None
                }
                item.DisplayStyle = style;
            }
        }

        /// <summary>
        /// If x has attribute t, gets its value.
        /// Else gets its name and converts to text, eg "File_OneTwo" to "One Two".
        /// </summary>
        string _GetDefaultItemText(XElement x)
        {
            if (!x.Attr(out string s, "t"))
            {
                string tag = x.Name.LocalName;
                s = tag.Remove(0, tag.LastIndexOf('_') + 1);                 //eg "Edit_Copy" -> "Copy"
                s = s.RegexReplace("(?<=[^A-Z])(?=[A-Z])", " ");             //"OneTwoThree" -> "One Two Three". //speed: don't need to optimize.
            }
            return(s);
        }

        /// <summary>
        /// Merges custom attributes into default menubar or toolbar XML.
        /// Reorders toolbar buttons if need.
        /// </summary>
        /// <param name="xCustom">Root element of customizations file.</param>
        /// <param name="xtsDef">Default menustrip or toolstrip. For custom toolbars the function can replace it.</param>
        /// <param name="name">xtsDef name, just to avoid getting it again.</param>
        /// <param name="isMenu"></param>
        void _MergeCustom(XElement xCustom, ref XElement xtsDef, string name, bool isMenu)
        {
            var xtsCust = xCustom.Element(xtsDef.Name); if (xtsCust == null)

            {
                return;
            }

            if (isMenu)
            {
            }
            else if (name.Starts("Custom"))
            {
                var xc = xCustom.Element(name); if (xc == null)
                {
                    return;
                }
                xc.Remove();
                xtsDef.ReplaceWith(xc);
                xtsDef = xc;
                return;
                //MSDN: "if the new content has no parent, then the objects are simply attached to the XML tree. If the new content already is parented and is part of another XML tree, then the new content is cloned". Tested, it's true.
            }
            else
            {
                //reorder toolbar buttons
                if (xtsCust.Attr(out string s, "order"))
                {
                    xtsDef.Elements("sep").Remove();                     //remove all default <sep/>, because all separators now are in the 'order' attribute
                    var a = s.SegSplit(" ");
                    for (int i = a.Length - 1; i >= 0; i--)
                    {
                        if (a[i] == "sep")
                        {
                            xtsDef.AddFirst(new XElement("sep"));
                        }
                        else
                        {
                            var xb = xtsDef.Element(a[i]); if (xb == null)
                            {
                                continue;
                            }
                            xb.Remove(); xtsDef.AddFirst(xb);
                        }
                    }
                }
            }

            foreach (var xCust in xtsCust.Elements())
            {
                foreach (var xDef in xtsDef.Descendants(xCust.Name))
                {
                    foreach (var att in xCust.Attributes())
                    {
                        xDef.SetAttributeValue(att.Name, att.Value);
                    }
                }
            }
        }

        /// <summary>
        /// Extracts differences between _xmlFileDefault and _xStrips and saves to _xmlFileCustom.
        /// </summary>
        void _DiffCustom()
        {
            var    xStripsDefault = AExtXml.LoadElem(_xmlFileDefault);
            var    xStripsCustom  = new XElement("strips");
            string s;

            //menus
            _DiffDescendants(MenuBar.Tag as XElement, true);

            //standard toolbars
            foreach (var ts in Toolbars.Values)
            {
                if (ts == _tsCustom1 || ts == _tsCustom2)
                {
                    continue;
                }
                _DiffDescendants(ts.Tag as XElement, false);
            }

            void _DiffDescendants(XElement xts, bool isMenu)
            {
                XElement xtsDef = xStripsDefault.Element(xts.Name), xtsCust = null;

                foreach (var x in xts.Descendants())
                {
                    var name = x.Name; if (name == "sep")
                    {
                        continue;
                    }
                    XElement xDef = xtsDef.Desc(name), xCust = null;
                    foreach (var att in x.Attributes())
                    {
                        var aname = att.Name;
                        if (att.Value == xDef.Attr(aname))
                        {
                            continue;
                        }
                        if (xtsCust == null)
                        {
                            xStripsCustom.Add(xtsCust = new XElement(xts.Name));
                        }
                        if (xCust == null)
                        {
                            xtsCust.Add(xCust = new XElement(name));
                        }
                        xCust.SetAttributeValue(aname, att.Value);
                    }
                }
                if (isMenu)
                {
                    return;
                }
                //order
                var s1 = new StringBuilder();
                var s2 = new StringBuilder();

                foreach (var x in xts.Elements())
                {
                    if (s1.Length > 0)
                    {
                        s1.Append(' ');
                    }
                    s1.Append(x.Name);
                }
                foreach (var x in xtsDef.Elements())
                {
                    if (s2.Length > 0)
                    {
                        s2.Append(' ');
                    }
                    s2.Append(x.Name);
                }
                s = s1.ToString();
                if (s != s2.ToString())
                {
                    if (xtsCust == null)
                    {
                        xStripsCustom.Add(xtsCust = new XElement(xts.Name));
                    }
                    xtsCust.SetAttributeValue("order", s);
                }
            }

            //custom toolbars. Temporarily move them from _xStrips to xCustom.
            var xCust1 = _tsCustom1.Tag as XElement;
            var xCust2 = _tsCustom2.Tag as XElement;

            if (xCust1.HasElements)
            {
                xCust1.Remove(); xStripsCustom.Add(xCust1);
            }
            if (xCust2.HasElements)
            {
                xCust2.Remove(); xStripsCustom.Add(xCust2);
            }

            //AOutput.Clear();
            //AOutput.Write(xStripsCustom);
#if true
            //save
            try {
                AFile.CreateDirectoryFor(_xmlFileCustom);
                xStripsCustom.SaveElem(_xmlFileCustom);
            }
            catch (Exception e) {
                AOutput.Write("Failed to save XML file", _xmlFileCustom, e.Message);
            }
#endif

            if (xCust1.HasElements)
            {
                xCust1.Remove(); _xStrips.Add(xCust1);
            }
            if (xCust2.HasElements)
            {
                xCust2.Remove(); _xStrips.Add(xCust2);
            }
        }
示例#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
            /// <summary>
            /// Creates documentation provider for assembly <i>asmPath</i>.
            /// Returns null if its xml file does not exist.
            /// Returns _DocumentationProvider if xml file is big and found or successfully created and successfully loaded database for it.
            /// Else returns XmlDocumentationProvider.
            /// </summary>
            public static DocumentationProvider Create(string asmPath)
            {
                if (s_d.TryGetValue(asmPath, out var dp))
                {
                    return(dp);
                }

                var xmlPath = Path.ChangeExtension(asmPath, "xml");

                if (!AFile.GetProperties(xmlPath, out var px))
                {
                    return(null);
                }

                if (px.Size >= 10_000)
                {
                    var md5    = new Au.Util.AHash.MD5(); md5.Add(xmlPath.Lower());
                    var dbPath = AFolders.ThisAppTemp + md5.Hash.ToString() + ".db";
                    try {
                        if (!AFile.GetProperties(dbPath, out var pd) || pd.LastWriteTimeUtc != px.LastWriteTimeUtc)
                        {
                            //ADebug.Print($"creating db: {asmPath}  ->  {dbPath}");
                            AFile.Delete(dbPath);
                            using (var d = new ASqlite(dbPath)) {
                                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 (?, ?)");

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

                                    //remove <remarks> and <example>.
                                    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);

                                    statInsert.BindAll(name, xml).Step();
                                    statInsert.Reset();
                                }
                                trans.Commit();
                                d.Execute("VACUUM");
                            }
                            File.SetLastWriteTimeUtc(dbPath, px.LastWriteTimeUtc);
                        }
                        var db = new ASqlite(dbPath, SLFlags.SQLITE_OPEN_READONLY);                         //never mind: we don't dispose it on process exit
                        s_d[asmPath] = dp = new _DocumentationProvider {
                            _db = db
                        };
                        return(dp);
                    }
                    catch (Exception ex) { ADebug.Print(ex.ToStringWithoutStack()); }
                }
                return(XmlDocumentationProvider.CreateFromFile(xmlPath));
            }
示例#7
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();
            }
        }
    }
示例#8
0
    //static int s_test;
    public static void AddSnippets(List <CiComplItem> items, TextSpan span, SyntaxNode node)
    {
        //don't add snippets if in arguments etc.
        //	Add only where can be a statement or declaration or likely a directive.
        //	The caller also does some simple filtering.
        //AOutput.Clear(); AOutput.Write(++s_test);
        int pos = span.Start;

        //find ancestor/self that contains pos inside
        while (node != null && !node.Span.ContainsInside(pos))
        {
            node = node.Parent;
        }
        if (node is ArgumentListSyntax als)          //return unless => is at left (lambda expression)
        {
            var left = node.FindToken(pos).GetPreviousToken().Parent;
            //CiUtil.PrintNode(left);
            if (!(left is SimpleLambdaExpressionSyntax))
            {
                return;
            }
        }
        else
        {
            //for(var v = node; v != null; v = v.Parent) AOutput.Write(v.GetType().Name);
            switch (node)
            {
            case null:
            case CompilationUnitSyntax _:
            case BlockSyntax _:
            case SimpleLambdaExpressionSyntax _:
            case ArrowExpressionClauseSyntax _:     //like void F() =>
            case SwitchSectionSyntax _:             //between case: and break;
            case ElseClauseSyntax _:
            case IfStatementSyntax s1 when pos > s1.CloseParenToken.SpanStart:
            case WhileStatementSyntax s2 when pos > s2.CloseParenToken.SpanStart:
            case DoStatementSyntax s3 when pos <s3.WhileKeyword.SpanStart:
                                            case ForStatementSyntax s4 when pos> s4.CloseParenToken.SpanStart:
            case CommonForEachStatementSyntax s5 when pos > s5.CloseParenToken.SpanStart:
            case LockStatementSyntax s6 when pos > s6.CloseParenToken.SpanStart:
            case FixedStatementSyntax s7 when pos > s7.CloseParenToken.SpanStart:
            case UsingStatementSyntax s8 when pos > s8.CloseParenToken.SpanStart:
            case TypeDeclarationSyntax td when pos > td.OpenBraceToken.Span.Start:             //{ } of class, struct, interface
            case NamespaceDeclarationSyntax ns when pos > ns.OpenBraceToken.Span.Start:
                break;

            default:
                return;
            }
        }

        DateTime fileTime = default;

        if (Program.Settings.ci_complCustomSnippets == 1 && AFile.GetProperties(CustomFile, out var fp, FAFlags.DontThrow | FAFlags.UseRawPath))
        {
            fileTime = fp.LastWriteTimeUtc;
        }
        if (fileTime != s_customFileTime)
        {
            s_customFileTime = fileTime; s_items = null;
        }

        if (s_items == null)
        {
            string file = fileTime == default ? DefaultFile : CustomFile;
            try {
                var xroot = AExtXml.LoadElem(file);
                var a     = new List <_CiComplItemSnippet>();
                foreach (var x in xroot.Elements("snippet"))
                {
                    var ci = CompletionItem.Create(x.Attr("name"), tags: s_tags);
                    a.Add(new _CiComplItemSnippet(ci, x));
                }
                s_items = a;
            }
            catch (Exception ex) { AOutput.Write("Failed to load snippets from " + file + "\r\n\t" + ex.ToStringWithoutStack()); return; }
        }

        foreach (var v in s_items)
        {
            v.group   = 0; v.hidden = 0; v.hilite = 0; v.moveDown = 0;
            v.ci.Span = span;
            items.Add(v);
        }

        items.Sort((i1, i2) => {
            var r = string.Compare(i1.DisplayText, i2.DisplayText, StringComparison.OrdinalIgnoreCase);
            if (r == 0)
            {
                r = i1.kind - i2.kind;
            }
            return(r);
        });
    }