diff --git a/RookieStation/CommonTools/ExecuteCmd/CmdDecryptFamily.cs b/RookieStation/CommonTools/ExecuteCmd/CmdDecryptFamily.cs new file mode 100644 index 0000000..481f1fe --- /dev/null +++ b/RookieStation/CommonTools/ExecuteCmd/CmdDecryptFamily.cs @@ -0,0 +1,78 @@ +using Autodesk.Revit.DB; +using Autodesk.Revit.UI; +using Autodesk.Revit.UI.Selection; +using RookieStation.CommonTools.ViewModels; +using RookieStation.Extension; +using RookieStation.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RookieStation.CommonTools.ExecuteCmd +{ + [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] + [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)] + internal class CmdDecryptFamily : IExternalCommand + { + public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) + { + UIApplication uiapp = commandData.Application; + UIDocument uidoc = uiapp.ActiveUIDocument; + Autodesk.Revit.ApplicationServices.Application app = uiapp.Application; + Document doc = uidoc.Document; + DocumentSet docset = uiapp.Application.Documents; + TaskDialog dialog = new TaskDialog("解密族"); + dialog.MainInstruction = "请选择当前项目解密族的范围"; + dialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "已使用的族"); + dialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink2, "所有族"); + TaskDialogResult taskDialogResult = dialog.Show(); + if (TaskDialogResult.CommandLink1 == taskDialogResult) + { + var instances = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).Cast(); + var distinctFamiliesUsed = instances.GroupBy(f => f.Symbol.FamilyName).Select(f => f.FirstOrDefault()).ToList().ConvertAll(f => f.Symbol.Family); + try + { + doc.InvokeGroup(tg => + { + EncryptOrDecryptFamily decryptFamily = new EncryptOrDecryptFamily(distinctFamiliesUsed); + decryptFamily.IsEncrypt = false; + decryptFamily.ProgressModal(); + }, "解密使用族"); + } + catch (Exception ex) + { + if (!(ex is Autodesk.Revit.Exceptions.OperationCanceledException)) + { + Log.WriteLog(ex.Message); + return Result.Failed; + } + } + } + else if (TaskDialogResult.CommandLink2 == taskDialogResult) + { + var families = new FilteredElementCollector(doc).OfClass(typeof(Family)).Cast().ToList(); + try + { + doc.InvokeGroup(tg => + { + EncryptOrDecryptFamily decryptFamily = new EncryptOrDecryptFamily(families); + decryptFamily.IsEncrypt = false; + decryptFamily.ProgressModal(); + }, "解密所有族"); + } + catch (Exception ex) + { + if (!(ex is Autodesk.Revit.Exceptions.OperationCanceledException)) + { + Log.WriteLog(ex.Message); + return Result.Failed; + } + } + } + + return Result.Succeeded; + } + } +} \ No newline at end of file diff --git a/RookieStation/CommonTools/ExecuteCmd/CmdEncryptFamily.cs b/RookieStation/CommonTools/ExecuteCmd/CmdEncryptFamily.cs index 0de61cc..1f1c46f 100644 --- a/RookieStation/CommonTools/ExecuteCmd/CmdEncryptFamily.cs +++ b/RookieStation/CommonTools/ExecuteCmd/CmdEncryptFamily.cs @@ -1,6 +1,7 @@ using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; +using RookieStation.CommonTools.ViewModels; using RookieStation.Extension; using RookieStation.Utils; using System; @@ -22,69 +23,56 @@ namespace RookieStation.CommonTools.ExecuteCmd Autodesk.Revit.ApplicationServices.Application app = uiapp.Application; Document doc = uidoc.Document; DocumentSet docset = uiapp.Application.Documents; - var instances = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).Cast(); - var distinctInstances = instances.GroupBy(f => f.Symbol.FamilyName).Select(f => f.FirstOrDefault()); + TaskDialog dialog = new TaskDialog("加密族"); + dialog.MainInstruction = "请选择当前项目加密族的范围"; + dialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "已使用的族"); + dialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink2, "所有族"); + TaskDialogResult taskDialogResult = dialog.Show(); - try + if (TaskDialogResult.CommandLink1 == taskDialogResult) { - doc.InvokeGroup(tg => - { - foreach (var ins in distinctInstances) + var instances = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).Cast(); + var distinctFamiliesUsed = instances.GroupBy(f => f.Symbol.FamilyName).Select(f => f.FirstOrDefault()).ToList().ConvertAll(f => f.Symbol.Family); + try { - var famdoc = doc.EditFamily(ins.Symbol.Family); - var formcol = new FilteredElementCollector(famdoc).OfClass(typeof(GenericForm)).Cast(); - var vcol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.View)).Cast(); - var dimcol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.Dimension)).Cast(); - var curvecol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.CurveElement)).Cast(); - - famdoc.Invoke(ts => + doc.InvokeGroup(tg => { - foreach (var view in vcol) - { - var elemidtohide = new List(); - foreach (GenericForm form in formcol) - { - if (form.CanBeHidden(view)) - { - elemidtohide.Add(form.Id); - } - } - foreach (Dimension dim in dimcol) - { - if (dim.CanBeHidden(view)) - { - elemidtohide.Add(dim.Id); - } - } - foreach (CurveElement curve in curvecol) - { - if (curve.CanBeHidden(view)) - { - elemidtohide.Add(curve.Id); - } - } - - if (elemidtohide.Count > 0) - { - view.HideElements(elemidtohide); - } - } - }); - - famdoc.LoadFamily(doc, new RsFamilyLoadOption()); - - famdoc.Close(false); + EncryptOrDecryptFamily encryptFamily = new EncryptOrDecryptFamily(distinctFamiliesUsed); + encryptFamily.IsEncrypt = true; + encryptFamily.ProgressModal(); + }, "加密使用族"); } - }, "加密族"); - } - catch (Exception ex) - { - if (!(ex is Autodesk.Revit.Exceptions.OperationCanceledException)) + catch (Exception ex) { - message = ex.Message; - return Result.Failed; + if (!(ex is Autodesk.Revit.Exceptions.OperationCanceledException)) + { + Log.WriteLog(ex.Message); + return Result.Failed; + } } } + else if (TaskDialogResult.CommandLink2 == taskDialogResult) + { + var families = new FilteredElementCollector(doc).OfClass(typeof(Family)).Cast().ToList(); + try + { + doc.InvokeGroup(tg => + { + EncryptOrDecryptFamily encryptFamily = new EncryptOrDecryptFamily(families); + encryptFamily.IsEncrypt = true; + encryptFamily.ProgressModal(); + }, "加密所有族"); + } + catch (Exception ex) + { + if (!(ex is Autodesk.Revit.Exceptions.OperationCanceledException)) + { + Log.WriteLog(ex.Message); + return Result.Failed; + } + } + } + return Result.Succeeded; } } diff --git a/RookieStation/CommonTools/ViewModels/EncryptOrDecryptFamily.cs b/RookieStation/CommonTools/ViewModels/EncryptOrDecryptFamily.cs new file mode 100644 index 0000000..aa83b54 --- /dev/null +++ b/RookieStation/CommonTools/ViewModels/EncryptOrDecryptFamily.cs @@ -0,0 +1,191 @@ +using Autodesk.Revit.DB; +using RookieStation.CommonTools.Views; +using RookieStation.Extension; +using RookieStation.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RookieStation.CommonTools.ViewModels +{ + internal class EncryptOrDecryptFamily + { + public EncryptOrDecryptFamily(List families) + { + Families = families; + } + + public bool IsEncrypt { get; set; } + private ProgressMonitorControl viewmodel { get; set; } + private ProgressMonitorView CurrentUI { get; set; } + private bool Cancel { get; set; } + + private List Families { get; set; } + + private delegate void ProgressBarDelegate(); + + public void ProgressModal() + { + if (Families.Count() == 0) + throw new Exception("当前项目不存在族"); + + viewmodel = new ProgressMonitorControl(); + viewmodel.MaxValue = Families.Count; + viewmodel.ProgressTitle = "族加密"; + CurrentUI = new Views.ProgressMonitorView(); + CurrentUI.DataContext = viewmodel; + CurrentUI.Closed += CurrentUI_Closed; + CurrentUI.ContentRendered += FireUPModal; + + CurrentUI.ShowDialog(); + } + + private void FireUPModal(object sender, EventArgs e) + { + CurrentUI.ContentRendered -= FireUPModal; + + for (int i = 0; i < Families.Count; i++) + { + if (Cancel) + break; + viewmodel.CurrentValue += 1; + viewmodel.CurrentContext = string.Format("总进度{1}/{2}\r\n正在对<{0}>进行处理", Families[i].Name, viewmodel.CurrentValue, viewmodel.MaxValue); + try + { + if (IsEncrypt) + { + HideFamilyElem(Families[i]); + } + else + { + UnHideFamilyElem(Families[i]); + } + } + catch (Exception ex) + { + CloseWindow(); + Log.WriteLog(ex.Message); + } + + CurrentUI.Dispatcher.Invoke(new ProgressBarDelegate(viewmodel.NotifyUI), System.Windows.Threading.DispatcherPriority.Background); + } + + CloseWindow(); + } + + private void HideFamilyElem(Family family) + { + if (!family.IsEditable) + { + return; + } + var famdoc = family.Document.EditFamily(family); + var formcol = new FilteredElementCollector(famdoc).OfClass(typeof(GenericForm)).Cast(); + var vcol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.View)).Cast(); + var dimcol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.Dimension)).Cast(); + var curvecol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.CurveElement)).Cast(); + + famdoc.Invoke(ts => + { + foreach (var view in vcol) + { + var elemidtohide = new List(); + foreach (GenericForm form in formcol) + { + if (form.CanBeHidden(view)) + { + elemidtohide.Add(form.Id); + } + } + foreach (Dimension dim in dimcol) + { + if (dim.CanBeHidden(view)) + { + elemidtohide.Add(dim.Id); + } + } + foreach (CurveElement curve in curvecol) + { + if (curve.CanBeHidden(view)) + { + elemidtohide.Add(curve.Id); + } + } + + if (elemidtohide.Count > 0) + { + view.HideElements(elemidtohide); + } + } + }); + + famdoc.LoadFamily(family.Document, new RsFamilyLoadOption()); + + famdoc.Close(false); + } + + private void UnHideFamilyElem(Family family) + { + if (!family.IsEditable) + { + return; + } + var famdoc = family.Document.EditFamily(family); + var formcol = new FilteredElementCollector(famdoc).OfClass(typeof(GenericForm)).Cast(); + var vcol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.View)).Cast(); + var dimcol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.Dimension)).Cast(); + var curvecol = new FilteredElementCollector(famdoc).OfClass(typeof(Autodesk.Revit.DB.CurveElement)).Cast(); + + famdoc.Invoke(ts => + { + foreach (var view in vcol) + { + var elemidtounHide = new List(); + foreach (GenericForm form in formcol) + { + if (form.IsHidden(view)) + { + elemidtounHide.Add(form.Id); + } + } + foreach (Dimension dim in dimcol) + { + if (dim.IsHidden(view)) + { + elemidtounHide.Add(dim.Id); + } + } + foreach (CurveElement curve in curvecol) + { + if (curve.IsHidden(view)) + { + elemidtounHide.Add(curve.Id); + } + } + + if (elemidtounHide.Count > 0) + { + view.UnhideElements(elemidtounHide); + } + } + }); + + famdoc.LoadFamily(family.Document, new RsFamilyLoadOption()); + + famdoc.Close(false); + } + + private void CloseWindow() + { + CurrentUI.Closed -= CurrentUI_Closed; + CurrentUI.Close(); + } + + private void CurrentUI_Closed(object sender, EventArgs e) + { + Cancel = true; + } + } +} \ No newline at end of file diff --git a/RookieStation/CommonTools/ViewModels/ProgressMonitorControl.cs b/RookieStation/CommonTools/ViewModels/ProgressMonitorControl.cs new file mode 100644 index 0000000..72007d8 --- /dev/null +++ b/RookieStation/CommonTools/ViewModels/ProgressMonitorControl.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RookieStation.CommonTools.ViewModels +{ + internal class ProgressMonitorControl : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public int MaxValue { get; set; } + public int CurrentValue { get; set; } + public string CurrentContext { get; set; } + public string ProgressTitle { get; set; } + + public ProgressMonitorControl() + { + MaxValue = 100; + CurrentValue = 0; + CurrentContext = string.Empty; + } + + public void NotifyUI() + { + Type classType = this.GetType(); + if (classType != null) + { + System.Reflection.PropertyInfo[] currentProperties = classType.GetProperties(); + foreach (System.Reflection.PropertyInfo currentProperty in currentProperties) + OnPropertyChanged(currentProperty.Name); + } + } + + private void OnPropertyChanged(string targetProperty) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(targetProperty)); + } + } +} \ No newline at end of file diff --git a/RookieStation/CommonTools/Views/ProgressMonitorView.xaml b/RookieStation/CommonTools/Views/ProgressMonitorView.xaml new file mode 100644 index 0000000..c31549b --- /dev/null +++ b/RookieStation/CommonTools/Views/ProgressMonitorView.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + +