private bool GetOrMakeLayer(string layerName, AcadDb.Transaction tr, out string cleanName)
        {
            cleanName = Utils.RemoveInvalidChars(layerName);
            try
            {
                AcadDb.LayerTable lyrTbl = tr.GetObject(Doc.Database.LayerTableId, AcadDb.OpenMode.ForRead) as AcadDb.LayerTable;
                if (lyrTbl.Has(cleanName))
                {
                    return(true);
                }
                else
                {
                    lyrTbl.UpgradeOpen();
                    var _layer = new AcadDb.LayerTableRecord();

                    // Assign the layer properties
                    _layer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByColor, 7); // white
                    _layer.Name  = cleanName;

                    // Append the new layer to the layer table and the transaction
                    lyrTbl.Add(_layer);
                    tr.AddNewlyCreatedDBObject(_layer, true);
                }
            }
            catch { return(false); }
            return(true);
        }
        private void DeleteLayersWithPrefix(string prefix, AcadDb.Transaction tr)
        {
            // Open the Layer table for read
            var lyrTbl = (AcadDb.LayerTable)tr.GetObject(Doc.Database.LayerTableId, AcadDb.OpenMode.ForRead);

            foreach (AcadDb.ObjectId layerId in lyrTbl)
            {
                AcadDb.LayerTableRecord layer = (AcadDb.LayerTableRecord)tr.GetObject(layerId, AcadDb.OpenMode.ForRead);
                string layerName = layer.Name;
                if (layerName.StartsWith(prefix))
                {
                    layer.UpgradeOpen();

                    // cannot delete current layer: swap current layer to default layer "0" if current layer is to be deleted
                    if (Doc.Database.Clayer == layerId)
                    {
                        var defaultLayerID = lyrTbl["0"];
                        Doc.Database.Clayer = defaultLayerID;
                    }
                    layer.IsLocked = false;

                    // delete all objects on this layer
                    // TODO: this is ugly! is there a better way to delete layer objs instead of looping through each one?
                    var bt = (AcadDb.BlockTable)tr.GetObject(Doc.Database.BlockTableId, AcadDb.OpenMode.ForRead);
                    foreach (var btId in bt)
                    {
                        var block = (AcadDb.BlockTableRecord)tr.GetObject(btId, AcadDb.OpenMode.ForRead);
                        foreach (var entId in block)
                        {
                            var ent = (AcadDb.Entity)tr.GetObject(entId, AcadDb.OpenMode.ForRead);
                            if (ent.Layer == layerName)
                            {
                                ent.UpgradeOpen();
                                ent.Erase();
                            }
                        }
                    }

                    layer.Erase();
                }
            }
        }
        public override List <ISelectionFilter> GetSelectionFilters()
        {
            var layers = new List <string>();

            using (AcadDb.Transaction tr = Doc.Database.TransactionManager.StartTransaction())
            {
                AcadDb.LayerTable lyrTbl = tr.GetObject(Doc.Database.LayerTableId, AcadDb.OpenMode.ForRead) as AcadDb.LayerTable;
                foreach (AcadDb.ObjectId objId in lyrTbl)
                {
                    AcadDb.LayerTableRecord lyrTblRec = tr.GetObject(objId, AcadDb.OpenMode.ForRead) as AcadDb.LayerTableRecord;
                    layers.Add(lyrTblRec.Name);
                }
                tr.Commit();
            }
            return(new List <ISelectionFilter>()
            {
                new ListSelectionFilter {
                    Name = "Layers", Icon = "Filter", Description = "Selects objects based on their layers.", Values = layers
                }
            });
        }