private static LinkedInstanceProperties DuplicateElements(Document recipientDoc, LinkedInstanceProperties lip, CategoryProperties cp, UpdateMode updateMode) { var updatedLIP = lip; try { var collector = new FilteredElementCollector(updatedLIP.LinkedDocument); var elementsToCopy = collector.OfCategoryId(cp.CategoryId).WhereElementIsNotElementType().ToElements().ToList(); var updatePbDelegate = new UpdateProgressBarDelegate(progressBar.SetValue); progressBar.Value = 0; progressBar.Maximum = elementsToCopy.Count; var duplicated = 0; using (var tGroup = new TransactionGroup(recipientDoc)) { tGroup.Start("Duplicate Elements"); tGroup.IsFailureHandlingForcedModal = false; var failureHanlder = new FailureHandler(); try { var options = new CopyPasteOptions(); options.SetDuplicateTypeNamesHandler(new HideAndAcceptDuplicateTypeNamesHandler()); double value = 0; foreach (var sourceElement in elementsToCopy) //elements from link { value++; System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(updatePbDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { ProgressBar.ValueProperty, value }); var foundElements = from element in updatedLIP.LinkedElements.Values where element.SourceUniqueId == sourceElement.UniqueId && element.SourceLinkInstanceId == updatedLIP.InstanceId select element; if (foundElements.Count() > 0) { var linkInfo = foundElements.First(); var linkedElement = recipientDoc.GetElement(linkInfo.LinkedElementId); if (null != linkedElement) { if (linkInfo.LinkElementType == LinkType.ByMap || updateMode == UpdateMode.UpdateLocationOnly) { if (!linkInfo.Matched) { using (var trans = new Transaction(recipientDoc)) { trans.Start("Move Element"); var failureOption = trans.GetFailureHandlingOptions(); failureOption.SetForcedModalHandling(false); failureOption.SetFailuresPreprocessor(failureHanlder); failureOption.SetClearAfterRollback(true); trans.SetFailureHandlingOptions(failureOption); try { var moved = LinkedElementInfo.MoveLocation(sourceElement, linkedElement, updatedLIP.TransformValue); linkInfo.Matched = moved; if (updatedLIP.LinkedElements.ContainsKey(linkedElement.Id)) { updatedLIP.LinkedElements.Remove(linkedElement.Id); updatedLIP.LinkedElements.Add(linkedElement.Id, linkInfo); } trans.Commit(); duplicated++; } catch (Exception ex) { trans.RollBack(); var message = ex.Message; } } } continue; } else if (updateMode == UpdateMode.ReplaceElements) { using (var trans = new Transaction(recipientDoc)) { trans.Start("Delete Element"); var failureOption = trans.GetFailureHandlingOptions(); failureOption.SetForcedModalHandling(false); failureOption.SetFailuresPreprocessor(failureHanlder); failureOption.SetClearAfterRollback(true); trans.SetFailureHandlingOptions(failureOption); try { var deletedIds = recipientDoc.Delete(linkInfo.LinkedElementId); if (updatedLIP.LinkedElements.ContainsKey(linkInfo.LinkedElementId)) { updatedLIP.LinkedElements.Remove(linkInfo.LinkedElementId); } trans.Commit(); } catch (Exception ex) { var message = ex.Message; trans.RollBack(); } } } } } var elementIds = new List <ElementId>(); elementIds.Add(sourceElement.Id); try { Element copiedElement = null; var linkType = LinkType.None; using (var trans = new Transaction(recipientDoc)) { trans.Start("Copy Element"); var failureOption = trans.GetFailureHandlingOptions(); failureOption.SetForcedModalHandling(false); failureOption.SetFailuresPreprocessor(failureHanlder); failureOption.SetClearAfterRollback(true); trans.SetFailureHandlingOptions(failureOption); try { copiedElement = CopyByFamilyMaps(recipientDoc, updatedLIP, sourceElement, options); if (null != copiedElement) { linkType = LinkType.ByMap; } else { linkType = LinkType.ByCopy; var copiedElementIds = ElementTransformUtils.CopyElements(updatedLIP.LinkedDocument, elementIds, recipientDoc, updatedLIP.TransformValue, options); if (copiedElementIds.Count > 0) { var copiedElementId = copiedElementIds.First(); copiedElement = recipientDoc.GetElement(copiedElementId); } } trans.Commit(); } catch (Exception ex) { trans.RollBack(); var message = ex.Message; } } if (null != copiedElement) { using (var trans = new Transaction(recipientDoc)) { trans.Start("Update Link Info"); var failureOption = trans.GetFailureHandlingOptions(); failureOption.SetForcedModalHandling(false); failureOption.SetFailuresPreprocessor(failureHanlder); failureOption.SetClearAfterRollback(true); trans.SetFailureHandlingOptions(failureOption); try { var linkInfo = new LinkedElementInfo(linkType, sourceElement, copiedElement, updatedLIP.InstanceId, updatedLIP.TransformValue); if (!linkInfo.Matched) { var moved = LinkedElementInfo.MoveLocation(sourceElement, copiedElement, updatedLIP.TransformValue); linkInfo.Matched = moved; } var updated = MoverDataStorageUtil.UpdateLinkedElementInfo(linkInfo, copiedElement); if (!updatedLIP.LinkedElements.ContainsKey(linkInfo.LinkedElementId)) { updatedLIP.LinkedElements.Add(linkInfo.LinkedElementId, linkInfo); } duplicated++; trans.Commit(); } catch (Exception ex) { trans.RollBack(); var message = ex.Message; } } } } catch (Exception ex) { var message = ex.Message; } } if (updatedLIP.Categories.ContainsKey(cp.CategoryId)) { cp.Selected = false; updatedLIP.Categories.Remove(cp.CategoryId); updatedLIP.Categories.Add(cp.CategoryId, cp); } tGroup.Assimilate(); } catch (Exception ex) { tGroup.RollBack(); MessageBox.Show("Failed to duplicate elements in the category " + cp.CategoryName + "\n" + ex.Message, "Duplicate Elements", MessageBoxButton.OK, MessageBoxImage.Warning); } } messageBuilder.AppendLine(duplicated.ToString() + " of " + elementsToCopy.Count.ToString() + " elements in " + cp.CategoryName + " has been successfully copied or updated."); } catch (Exception ex) { MessageBox.Show("Failed to duplicate elements.\n" + ex.Message, "Duplicate Elements", MessageBoxButton.OK, MessageBoxImage.Warning); } return(updatedLIP); }
private bool PickMappingElements(out Element sourceElement /*in link*/, out Element targetElement /*in host*/) { var picked = false; sourceElement = null; targetElement = null; using (var trans = new Transaction(CurrentDocument)) { trans.Start("Pick Mapping Elements"); try { var selection = m_app.ActiveUIDocument.Selection; var reference = PickLinkedElement(); if (null != reference) { var linkedInstanceId = reference.ElementId; if (LinkInstances.ContainsKey(linkedInstanceId) && reference.LinkedElementId != ElementId.InvalidElementId) { var lip = LinkInstances[linkedInstanceId]; var linkedDoc = lip.LinkedDocument; var linkedElement = linkedDoc.GetElement(reference.LinkedElementId); //element in linked model if (null != linkedElement) { if (null != linkedElement.Category) { var categoryId = linkedElement.Category.Id; var categoryName = linkedElement.Category.Name; ISelectionFilter selFilter = new TargetElementSelectionFilter(categoryId); var secondReference = selection.PickObject(ObjectType.Element, "Pick a target item in the host model. The required category should be " + categoryName); if (null != secondReference) { var eId = secondReference.ElementId; var element = CurrentDocument.GetElement(eId); if (null != element) { ElementTypeInfo sourceTypeInfo = null; var sourceTypeId = linkedElement.GetTypeId(); var sourceType = linkedDoc.GetElement(sourceTypeId) as ElementType; if (null != sourceType) { sourceTypeInfo = new ElementTypeInfo(sourceType); } ElementTypeInfo targetTypeInfo = null; var targetTypeId = element.GetTypeId(); var targetType = CurrentDocument.GetElement(targetTypeId) as ElementType; if (null != targetType) { targetTypeInfo = new ElementTypeInfo(targetType); } if (null != sourceTypeInfo && null != targetType) { sourceElement = linkedElement; targetElement = element; picked = true; } else { var strBuilder = new StringBuilder(); strBuilder.AppendLine("Source Family Name: " + sourceTypeInfo.FamilyName + ", Source Type Name: " + sourceTypeInfo.Name); strBuilder.AppendLine("Target Family Name: " + targetTypeInfo.FamilyName + ", Target Type Name: " + targetTypeInfo.Name); strBuilder.AppendLine(""); strBuilder.AppendLine("Would you like to proceed with creating a map?"); var result = MessageBox.Show(strBuilder.ToString(), "Mismatch Name", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { sourceElement = linkedElement; targetElement = element; picked = true; } else { picked = false; } } } } } } } } if (picked && null != sourceElement && null != targetElement) { var linkInfo = new LinkedElementInfo(LinkType.ByMap, sourceElement, targetElement, selectedLink.InstanceId, selectedLink.TransformValue); if (selectedLink.LinkedElements.ContainsKey(linkInfo.LinkedElementId)) { selectedLink.LinkedElements.Remove(linkInfo.LinkedElementId); } selectedLink.LinkedElements.Add(linkInfo.LinkedElementId, linkInfo); var updated = MoverDataStorageUtil.UpdateLinkedElementInfo(linkInfo, targetElement); } trans.Commit(); } catch (Exception ex) { trans.RollBack(); MessageBox.Show("Failed to pick mapping elements.\n" + ex.Message, "Pick Mapping Elements", MessageBoxButton.OK, MessageBoxImage.Warning); } } return(picked); }